Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -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()); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -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(); | ||
} | ||
} | ||
} |
Oops, something went wrong.