Skip to content
Permalink
Browse files
BATCHEE-80 adding jsonp reader/writer
  • Loading branch information
Romain Manni-Bucau committed Dec 2, 2015
1 parent 276d709 commit 468a01f34b556102fd53ad87b32b742702a9ae92
Showing 12 changed files with 772 additions and 0 deletions.
@@ -87,6 +87,11 @@
<artifactId>batchee-shiro</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.batchee</groupId>
<artifactId>batchee-jsonp</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<artifactId>batchee-extensions</artifactId>
<groupId>org.apache.batchee</groupId>
<version>0.3-incubating-SNAPSHOT</version>
</parent>

<artifactId>batchee-jsonp</artifactId>
<name>BatchEE :: Extensions :: Jackson</name>

<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-json_1.0_spec</artifactId>
<version>1.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.batchee</groupId>
<artifactId>batchee-extras</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.apache.johnzon</groupId>
<artifactId>johnzon-core</artifactId>
<version>0.9.2-incubating</version>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<jackson.version>2.2.3</jackson.version>
</properties>
</project>
@@ -0,0 +1,170 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.batchee.jsonp;

import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.json.JsonStructure;
import javax.json.spi.JsonProvider;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParsingException;

public class JsonPartialReader {
private final JsonParser parser;
private final JsonProvider provider;
private boolean closed = false;

public JsonPartialReader(final JsonProvider provider, final JsonParser parser) {
this.parser = parser;
this.provider = provider == null ? JsonProvider.provider() : provider;
}

public JsonStructure read(final JsonParser.Event event) {
switch (event) {
case START_OBJECT:
final JsonObjectBuilder objectBuilder = provider.createObjectBuilder();
parseObject(objectBuilder);
return objectBuilder.build();
case START_ARRAY:
final JsonArrayBuilder arrayBuilder = provider.createArrayBuilder();
parseArray(arrayBuilder);
return arrayBuilder.build();
default:
throw new JsonParsingException("Unknown structure: " + parser.next(), parser.getLocation());
}

}

public void close() {
if (!closed) {
closed = true;
parser.close();
}
}

private void parseObject(final JsonObjectBuilder builder) {
String key = null;
while (parser.hasNext()) {
final JsonParser.Event next = parser.next();
switch (next) {
case KEY_NAME:
key = parser.getString();
break;

case VALUE_STRING:
builder.add(key, parser.getString());
break;

case START_OBJECT:
final JsonObjectBuilder subObject = provider.createObjectBuilder();
parseObject(subObject);
builder.add(key, subObject);
break;

case START_ARRAY:
final JsonArrayBuilder subArray = provider.createArrayBuilder();
parseArray(subArray);
builder.add(key, subArray);
break;

case VALUE_NUMBER:
if (parser.isIntegralNumber()) {
builder.add(key, parser.getLong());
} else {
builder.add(key, parser.getBigDecimal());
}
break;

case VALUE_NULL:
builder.addNull(key);
break;

case VALUE_TRUE:
builder.add(key, true);
break;

case VALUE_FALSE:
builder.add(key, false);
break;

case END_OBJECT:
return;

case END_ARRAY:
throw new JsonParsingException("']', shouldn't occur", parser.getLocation());

default:
throw new JsonParsingException(next.name() + ", shouldn't occur", parser.getLocation());
}
}
}

private void parseArray(final JsonArrayBuilder builder) {
while (parser.hasNext()) {
final JsonParser.Event next = parser.next();
switch (next) {
case VALUE_STRING:
builder.add(parser.getString());
break;

case VALUE_NUMBER:
if (parser.isIntegralNumber()) {
builder.add(parser.getLong());
} else {
builder.add(parser.getBigDecimal());
}
break;

case START_OBJECT:
JsonObjectBuilder subObject = provider.createObjectBuilder();
parseObject(subObject);
builder.add(subObject);
break;

case START_ARRAY:
JsonArrayBuilder subArray = provider.createArrayBuilder();
parseArray(subArray);
builder.add(subArray);
break;

case END_ARRAY:
return;

case VALUE_NULL:
builder.addNull();
break;

case VALUE_TRUE:
builder.add(true);
break;

case VALUE_FALSE:
builder.add(false);
break;

case KEY_NAME:
throw new JsonParsingException("array doesn't have keys", parser.getLocation());

case END_OBJECT:
throw new JsonParsingException("'}', shouldn't occur", parser.getLocation());

default:
throw new JsonParsingException(next.name() + ", shouldn't occur", parser.getLocation());
}
}
}
}
@@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.batchee.jsonp;

import org.apache.batchee.doc.api.Documentation;
import org.apache.batchee.extras.transaction.CountedReader;

import javax.batch.api.BatchProperty;
import javax.inject.Inject;
import javax.json.spi.JsonProvider;
import javax.json.stream.JsonParser;
import java.io.FileInputStream;
import java.io.Serializable;

@Documentation("Reads a JSON file using JSON-P providing JsonStructure as item.")
public class JsonpReader extends CountedReader {
@Inject
@BatchProperty
@Documentation("Incoming file")
private String file;

@Inject
@BatchProperty
@Documentation("Should root be skipped (default: true)")
private String skipRoot;

@Inject
@BatchProperty
@Documentation("JSON-P provider if not using the default")
private String provider;

private JsonParser parser;
private JsonPartialReader reader;
private JsonParser.Event end = null;

@Override
public void open(final Serializable checkpoint) throws Exception {
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final JsonProvider provider = this.provider == null ? JsonProvider.provider() : JsonProvider.class.cast(loader.loadClass(this.provider));
parser = provider.createParser(new FileInputStream(file));
reader = new JsonPartialReader(provider, parser);

if (skipRoot == null || "true".equalsIgnoreCase(skipRoot)) {
final JsonParser.Event event = parser.next();
if (event == JsonParser.Event.START_ARRAY) {
end = JsonParser.Event.END_ARRAY;
} else {
end = JsonParser.Event.END_OBJECT;
}
}
super.open(checkpoint);
}

@Override
protected Object doRead() throws Exception {
JsonParser.Event event;
do {
event = parser.next();
} while (
(event != JsonParser.Event.START_OBJECT && event != end) ||
(end == null && (event == JsonParser.Event.END_ARRAY ||
event == JsonParser.Event.END_OBJECT)));
if (!parser.hasNext()) {
return null;
}

return reader.read(event);
}

@Override
public void close() throws Exception {
if (reader != null) {
reader.close();
}
}
}

0 comments on commit 468a01f

Please sign in to comment.