package JSON2RDF; import java.io.InputStream; import java.io.Reader; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashMap; import java.util.Map; import javax.json.Json; import javax.json.stream.JsonParser; import org.apache.jena.datatypes.xsd.XSDDatatype; import org.apache.jena.graph.Node; import org.apache.jena.graph.NodeFactory; import org.apache.jena.graph.Triple; import org.apache.jena.riot.system.IRIResolver; import org.apache.jena.riot.system.StreamRDF; public class JsonStreamRDFWriter { private final JsonParser parser; private final StreamRDF rdfStream; private final IRIResolver iriResolver; public JsonStreamRDFWriter(Reader reader, StreamRDF rdfStream, String baseURI) { this(Json.createParser(reader), rdfStream, baseURI); } public JsonStreamRDFWriter(InputStream is, StreamRDF rdfStream, String baseURI) { this(Json.createParser(is), rdfStream, baseURI); } public JsonStreamRDFWriter(JsonParser parser, StreamRDF rdfStream, String baseURI) { this.parser = parser; this.rdfStream = rdfStream; this.iriResolver = IRIResolver.create(baseURI); } public void convert() { getStreamRDF().start(); write(getParser(), getStreamRDF(), getIRIResolver()); getStreamRDF().finish(); } public static void write(JsonParser parser, StreamRDF rdfStream, IRIResolver iriResolver) { Deque subjectStack = new ArrayDeque<>(); Map arrayProperties = new HashMap<>(); Node property = null; while (parser.hasNext()) { JsonParser.Event event = parser.next(); switch (event) { case START_ARRAY: if (!subjectStack.isEmpty() && property != null) arrayProperties.put(subjectStack.getLast(), property); break; case END_ARRAY: if (!subjectStack.isEmpty()) arrayProperties.remove(subjectStack.getLast()); break; case START_OBJECT: Node subject = NodeFactory.createBlankNode(); // add triple with current array property, if any if (property != null && !subjectStack.isEmpty()) rdfStream.triple(new Triple(subjectStack.getLast(), property, subject)); subjectStack.addLast(subject); break; case END_OBJECT: subjectStack.removeLast(); // restore previous array property, if there was any if (!subjectStack.isEmpty() && arrayProperties.containsKey(subjectStack.getLast())) property = arrayProperties.get(subjectStack.getLast()); break; case VALUE_FALSE: rdfStream.triple(new Triple(subjectStack.getLast(), property, NodeFactory.createLiteralByValue(Boolean.FALSE, XSDDatatype.XSDboolean))); break; case VALUE_TRUE: rdfStream.triple(new Triple(subjectStack.getLast(), property, NodeFactory.createLiteralByValue(Boolean.TRUE, XSDDatatype.XSDboolean))); break; case KEY_NAME: property = NodeFactory.createURI(iriResolver.resolveToString("#" + parser.getString())); break; case VALUE_STRING: if (property != null) rdfStream.triple(new Triple(subjectStack.getLast(), property, NodeFactory.createLiteral(parser.getString()))); break; case VALUE_NUMBER: try { rdfStream.triple(new Triple(subjectStack.getLast(), property,NodeFactory.createLiteralByValue(Integer.valueOf(parser.getString()), XSDDatatype.XSDint))); } catch (NumberFormatException ex) { rdfStream.triple(new Triple(subjectStack.getLast(), property,NodeFactory.createLiteralByValue(Float.valueOf(parser.getString()), XSDDatatype.XSDfloat))); } break; case VALUE_NULL: break; } } } protected JsonParser getParser() { return parser; } protected StreamRDF getStreamRDF() { return rdfStream; } protected IRIResolver getIRIResolver() { return iriResolver; } }