All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.konig.core.io.JsonldParser Maven / Gradle / Ivy

There is a newer version: 2.11.0
Show newest version
package io.konig.core.io;

/*
 * #%L
 * konig-core
 * %%
 * Copyright (C) 2015 - 2016 Gregory McFall
 * %%
 * Licensed 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.
 * #L%
 */


import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import org.openrdf.model.BNode;
import org.openrdf.model.Namespace;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.rio.helpers.RDFParserBase;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import io.konig.core.Context;
import io.konig.core.ContextManager;
import io.konig.core.KonigValueFactory;
import io.konig.core.ListHandler;
import io.konig.core.NamespaceManager;
import io.konig.core.Term;
import io.konig.core.UidGenerator;

public class JsonldParser extends RDFParserBase {
	
	private ContextReader contextReader;
	private NamespaceManager namespaceManager;

	public JsonldParser(ContextManager contextManager) {
		this(contextManager, new KonigValueFactory());
	}
	
	
	public JsonldParser(ContextManager contextManager, NamespaceManager nsManager) {
		this(contextManager, nsManager, new KonigValueFactory());
	}

	public JsonldParser(ContextManager contextManager, NamespaceManager namespaceManager, ValueFactory valueFactory) {
		super(valueFactory);
		this.contextReader = new ContextReader(contextManager);
		this.namespaceManager = namespaceManager;
	}



	public JsonldParser(ContextManager contextManager, ValueFactory valueFactory) {
		this(contextManager, null, valueFactory);
	}

	@Override
	public RDFFormat getRDFFormat() {
		return RDFFormat.JSONLD;
	}

	@Override
	public void parse(InputStream stream, String baseURI) throws IOException, RDFParseException, RDFHandlerException {
		
		parse(new InputStreamReader(stream), baseURI);
	}

	@Override
	public void parse(Reader reader, String baseURI) throws IOException, RDFParseException, RDFHandlerException {
		
		
		ObjectMapper mapper = new ObjectMapper();
		JsonNode node = mapper.readTree(reader);
		if (!(node instanceof ObjectNode)) {
			throw new RDFParseException("Root element is not an object");
		}
		Worker worker = new Worker(baseURI);
		worker.parseObject((ObjectNode)node);
		rdfHandler.endRDF();
	}
	
	private class Worker {
		private String baseURI;

		public Worker(String baseURI) {
			this.baseURI = baseURI;
			
		}

		private Context context;
		private String valueKey="@value";
		private String idKey="@id";
		private String typeKey="@type";
		private String languageKey="@language";


		private BNode bnode() {
			return valueFactory.createBNode(UidGenerator.INSTANCE.next());
		}

		private Resource parseObject(ObjectNode object) throws RDFParseException, RDFHandlerException {
			
			Context saveContext = context;
			String saveIdKey = idKey;
			String saveValueKey = valueKey;
			String saveTypeKey = typeKey;
			String saveLanguageKey = languageKey;
			
			Resource subject = null;
			
			JsonNode contextNode = object.get("@context");
			if (contextNode != null) {
				try {
					context = contextReader.parse(object);
					context.compile();
				} catch (Throwable oops) {
					throw new RDFHandlerException(oops);
				}

				valueKey = context.alias("@value");
				idKey = context.alias("@id");
				typeKey = context.alias("@type");
				languageKey = context.alias("@language");
			}
			
			JsonNode idNode = object.get(idKey);
			if (idNode == null) {
				subject = bnode();
			} else {
				String idValue = idNode.asText();
				if (idValue.startsWith("_:")) {
					idValue = idValue.substring(2);
					subject = valueFactory.createBNode(idValue);
				} else {
					subject = iri(idValue);
				}
				
			}
			
			
			Iterator> sequence = object.fields();
			
			while (sequence.hasNext()) {
				Entry e = sequence.next();
				
				String fieldName = e.getKey();
				JsonNode value = e.getValue();
				
				if ("@context".equals(fieldName) || "@id".equals(fieldName)) {
					continue;
				}
				
				if ("@graph".equals(fieldName)) {
					
					if (value instanceof ArrayNode) {
						parseGraph((ArrayNode)value);
					} else {
						throw new RDFParseException("@graph must have array value");
					}
					continue;
				}
				Term term = null;
				URI predicate = null;
				if (typeKey.equals(fieldName)) {
					predicate = RDF.TYPE;
				} else {

					term = context==null ? null : context.getTerm(fieldName);
					
					if (term != null) {
						fieldName = term.getExpandedIdValue();
					} else if (context != null) {
						fieldName = context.expandIRI(fieldName);
					}
					
					predicate = valueFactory.createURI(fieldName);
				}
				
				// TODO: handle @list
				if (value instanceof ArrayNode) {
					
					
					if (term!=null && "@list".equals(term.getContainer())) {
						handleListField(subject, predicate, term, (ArrayNode) value);
					} else {
						handleSetField(subject, predicate, term, (ArrayNode) value);
					}
					
					
//					ArrayNode array = (ArrayNode) value;
//					for (int i=0; i valueList = toValueList(subject, predicate, term, array);
				ListHandler listHandler = (ListHandler) rdfHandler;
				listHandler.handleList(subject, predicate, valueList);
			} else {
				BNode bnode = valueFactory.createBNode();
				rdfHandler.handleStatement(valueFactory.createStatement(subject, predicate, bnode));
				for (int i=0; i toValueList(Resource subject, URI predicate, Term term, ArrayNode array) throws RDFParseException, RDFHandlerException {
			List list = new ArrayList<>();
			
			for (int i=0; i= 0) {
				if (context == null) {
					throw new RDFParseException("Cannot expand IRI '" + idValue + "' because context is not defined");
				}
				String prefix = idValue.substring(0, colon);
				Term term = context.getTerm(prefix);
				if (term != null) {
					String localName = idValue.substring(colon+1);
					String namespace = term.getExpandedIdValue();
					if (namespaceManager != null) {
						Namespace ns = namespaceManager.findByName(namespace);
						if (ns == null) {
							namespaceManager.add(prefix, namespace);
						}
					}
					return valueFactory.createURI(namespace + localName);
				}
				return valueFactory.createURI(idValue);
			} else {
				Term term = context.getTerm(idValue);
				if (term != null) {
					return term.getExpandedId();
				}
				
				return valueFactory.createURI(baseURI + idValue);
			}
		}
	}
	
	

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy