/******************************************************************************* * Copyright (c) 2007 Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source$ * Created by: Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * Created on: Oct 12, 2007 * Revision: $Id$ * * Contributors: * Cambridge Semantics Incorporated - initial API and implementation *******************************************************************************/ package org.openanzo.rdf.utils; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Map; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonToken; import org.openanzo.exceptions.AnzoException; import org.openanzo.exceptions.ExceptionConstants; import org.openanzo.rdf.Constants; import org.openanzo.rdf.IRDFHandler; import org.openanzo.rdf.IRDFParser; import org.openanzo.rdf.Literal; import org.openanzo.rdf.RDFFormat; import org.openanzo.rdf.Resource; import org.openanzo.rdf.Statement; import org.openanzo.rdf.URI; /** * Parse JSON RDF input stream * * @author Matthew Roy ( <a href="mailto:mroy@us.ibm.com">mroy@us.ibm.com </a>) * */ public class JSONRdfParser implements IRDFParser { private final static JsonFactory factory = new JsonFactory(); private final IRDFHandler rdfHandler; /** * Create a new JSON RDF parser * * @param rdfHandler * Handler for this parser */ public JSONRdfParser(IRDFHandler rdfHandler) { this.rdfHandler = rdfHandler; } public RDFFormat getRDFFormat() { return RDFFormat.JSON; } public void parse(Reader inputStream, String baseURI) throws IOException, AnzoException { parse(inputStream, baseURI, rdfHandler); } /** * Parser data from a reader to a handler * * @param reader * source of data * @param baseURI * base uri for data * @param rdfHandler * handler for data * @throws IOException * @throws AnzoException */ static private void parse(Reader reader, String baseURI, IRDFHandler rdfHandler) throws IOException, AnzoException { try { rdfHandler.startRDF(); JsonParser parser = factory.createJsonParser(reader); while (parser.nextToken() != null) { JsonToken token = parser.getCurrentToken(); switch (token) { case START_ARRAY: break; case START_OBJECT: rdfHandler.handleStatement(parseStatement(parser)); break; } } rdfHandler.endRDF(); } catch (JsonParseException e) { throw new AnzoException(ExceptionConstants.IO.DESERIALIZATION_ERROR, e); } } /** * Parse a statement object from json * * @param parser * @return Parsed statement * @throws JsonParseException * @throws AnzoException */ @SuppressWarnings("unchecked") static public Statement parseStatement(JsonParser parser) throws JsonParseException, AnzoException { try { Map<String, Object> statement = new HashMap<String, Object>(); String currentName = null; String objectName = null; Map<String, Object> currentObject = null; boolean done = false; while (!done && parser.nextToken() != null) { JsonToken token = parser.getCurrentToken(); switch (token) { case START_OBJECT: currentObject = new HashMap<String, Object>(); objectName = currentName; break; case END_OBJECT: if (currentObject != null) { statement.put(objectName, currentObject); objectName = null; currentObject = null; } else { done = true; } break; case END_ARRAY: done = true; break; case FIELD_NAME: currentName = parser.getText(); break; case VALUE_FALSE: if (currentObject != null) { currentObject.put(parser.getCurrentName(), false); } else { statement.put(parser.getCurrentName(), false); } break; case VALUE_TRUE: if (currentObject != null) { currentObject.put(parser.getCurrentName(), true); } else { statement.put(parser.getCurrentName(), true); } break; case VALUE_NULL: break; case VALUE_NUMBER_FLOAT: if (currentObject != null) { currentObject.put(parser.getCurrentName(), parser.getNumberValue()); } else { statement.put(parser.getCurrentName(), parser.getNumberValue()); } break; case VALUE_NUMBER_INT: if (currentObject != null) { currentObject.put(parser.getCurrentName(), parser.getNumberValue()); } else { statement.put(parser.getCurrentName(), parser.getNumberValue()); } break; case VALUE_STRING: if (currentObject != null) { currentObject.put(parser.getCurrentName(), parser.getText()); } else { statement.put(parser.getCurrentName(), parser.getText()); } break; } } String namedGraph = (statement.containsKey(SerializationConstants.namedGraphUri)) ? (String) statement.get(SerializationConstants.namedGraphUri) : null; Map<String, Object> subject = (statement.containsKey(SerializationConstants.subject)) ? (Map<String, Object>) statement.get(SerializationConstants.subject) : null; String predicate = (statement.containsKey(SerializationConstants.predicate)) ? (String) statement.get(SerializationConstants.predicate) : null; Map<String, Object> object = (statement.containsKey(SerializationConstants.object)) ? (Map<String, Object>) statement.get(SerializationConstants.object) : null; if (subject != null && predicate != null && object != null) { URI namedGraphURI = (namedGraph != null) ? Constants.valueFactory.createURI(namedGraph) : null; String subjectType = subject.containsKey(SerializationConstants.objectType) ? (String) subject.get(SerializationConstants.objectType) : null; String subjectValue = subject.containsKey(SerializationConstants.value) ? (String) subject.get(SerializationConstants.value) : null; if (subjectType == null || subjectValue == null) { throw new AnzoException(ExceptionConstants.IO.DESERIALIZATION_ERROR); } Resource subjectResource = null; if (SerializationConstants.uri.equals(subjectType)) { subjectResource = Constants.valueFactory.createURI(subjectValue); } else { subjectResource = Constants.valueFactory.createBNode(subjectValue); } URI predicateURI = Constants.valueFactory.createURI(predicate); String type = object.containsKey(SerializationConstants.objectType) ? (String) object.get(SerializationConstants.objectType) : null; String value = object.containsKey(SerializationConstants.value) ? (String) object.get(SerializationConstants.value) : null; if (type == null || value == null) { throw new AnzoException(ExceptionConstants.IO.DESERIALIZATION_ERROR); } if (SerializationConstants.uri.equals(type)) { Statement stmt = Constants.valueFactory.createStatement(subjectResource, predicateURI, Constants.valueFactory.createURI(value), namedGraphURI); return stmt; } else if (SerializationConstants.literal.equals(type)) { String lang = object.containsKey(SerializationConstants.language) ? (String) object.get(SerializationConstants.language) : null; String datatype = object.containsKey(SerializationConstants.dataType) ? (String) object.get(SerializationConstants.dataType) : null; Literal literal = null; if (datatype != null) { literal = Constants.valueFactory.createLiteral(value, Constants.valueFactory.createURI(datatype)); } else if (lang != null) { literal = Constants.valueFactory.createLiteral(value, lang); } else { literal = Constants.valueFactory.createLiteral(value); } Statement stmt = Constants.valueFactory.createStatement(subjectResource, predicateURI, literal, namedGraphURI); return stmt; } else if (SerializationConstants.bnode.equals(type)) { Statement stmt = Constants.valueFactory.createStatement(subjectResource, predicateURI, Constants.valueFactory.createBNode(value), namedGraphURI); return stmt; } } } catch (IOException ioe) { throw new AnzoException(ExceptionConstants.IO.DESERIALIZATION_ERROR); } throw new AnzoException(ExceptionConstants.IO.DESERIALIZATION_ERROR); } }