You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commonsrdf.apache.org by st...@apache.org on 2016/06/20 08:59:22 UTC

[3/8] incubator-commonsrdf git commit: add getContextFilter() and draft of parser

add getContextFilter() and draft of parser


Project: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/commit/bd579759
Tree: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/tree/bd579759
Diff: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/diff/bd579759

Branch: refs/heads/rdf4j
Commit: bd5797590d2698e5fb24051f74c562c8d661a6b7
Parents: ea6b992
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Mon Jun 20 09:42:47 2016 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Mon Jun 20 09:42:47 2016 +0100

----------------------------------------------------------------------
 rdf4j/pom.xml                                   |   5 +
 .../apache/commons/rdf/rdf4j/RDF4JGraph.java    |  26 ++++
 .../commons/rdf/rdf4j/RDF4JTermFactory.java     |  48 +++++--
 .../commons/rdf/rdf4j/impl/ModelGraphImpl.java  |   7 +
 .../rdf/rdf4j/impl/RDF4JParserBuilder.java      | 139 +++++++++++++++++++
 .../rdf/rdf4j/impl/RepositoryGraphImpl.java     |   7 +
 6 files changed, 217 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/bd579759/rdf4j/pom.xml
----------------------------------------------------------------------
diff --git a/rdf4j/pom.xml b/rdf4j/pom.xml
index 204de4a..29aeb3f 100644
--- a/rdf4j/pom.xml
+++ b/rdf4j/pom.xml
@@ -43,6 +43,11 @@
 			<version>${project.version}</version>
 		</dependency>
 		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>commons-rdf-simple</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.eclipse.rdf4j</groupId>
 			<artifactId>rdf4j-runtime</artifactId>
 			<version>${rdf4j.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/bd579759/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
index 5333f31..f328be1 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
@@ -17,10 +17,13 @@
  */
 package org.apache.commons.rdf.rdf4j;
 
+import java.util.Optional;
+
 import org.apache.commons.rdf.api.Graph;
 import org.apache.commons.rdf.api.Triple;
 import org.apache.commons.rdf.rdf4j.impl.ModelGraphImpl;
 import org.apache.commons.rdf.rdf4j.impl.RepositoryGraphImpl;
+import org.eclipse.rdf4j.model.Resource;
 
 
 /**
@@ -31,4 +34,27 @@ import org.apache.commons.rdf.rdf4j.impl.RepositoryGraphImpl;
  */
 public interface RDF4JGraph extends Graph, RDF4JGraphLike<Triple> {
 	
+	/**
+	 * Return a copy of the context filter, if present.
+	 * <p>
+	 * If {@link Optional#isPresent()}, the filter determines which contexts
+	 * this graph reflect. Modifications to the graph (e.g. {@link #add(Triple)
+	 * will be performed for all the specified contexts, while retrieval (e.g.
+	 * {@link #contains(Triple)}) will succeed if the triple is in at least one
+	 * of the specified contexts.
+	 * <p>
+	 * The context filter array may contain <code>null</code>, indicating the
+	 * default context (the <em>default graph</em> in RDF datasets).
+	 * <p>
+	 * If the context filter is {@link Optional#empty()}, then this is a union
+	 * graph which triples reflecting statements in any contexts. Triples added
+	 * to the graph will be added in the default context <code>null</code>.
+	 * <p>
+	 * The returned filter is a copy and thus any modifications are not
+	 * reflected in the RDF4JGraph.
+	 * 
+	 * @return
+	 */
+	public Optional<Resource[]> getContextFilter();
+	
 }

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/bd579759/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JTermFactory.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JTermFactory.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JTermFactory.java
index 04b0030..2cd64e7 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JTermFactory.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JTermFactory.java
@@ -26,6 +26,7 @@ import org.apache.commons.rdf.api.BlankNode;
 import org.apache.commons.rdf.api.BlankNodeOrIRI;
 import org.apache.commons.rdf.api.Dataset;
 import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.api.IRI;
 import org.apache.commons.rdf.api.Quad;
 import org.apache.commons.rdf.api.RDFTerm;
 import org.apache.commons.rdf.api.RDFTermFactory;
@@ -116,7 +117,7 @@ public class RDF4JTermFactory implements RDFTermFactory {
 
 	private UUID salt = UUID.randomUUID();
 
-	private ValueFactory valueFactory;
+	private final ValueFactory valueFactory;
 
 	public RDF4JTermFactory() {
 		this.valueFactory = SimpleValueFactory.getInstance();
@@ -251,7 +252,7 @@ public class RDF4JTermFactory implements RDFTermFactory {
 			context = (org.eclipse.rdf4j.model.Resource) asValue(quad.getGraphName().orElse(null));
 		}
 
-		return valueFactory.createStatement(subject, predicate, object, context);
+		return getValueFactory().createStatement(subject, predicate, object, context);
 	}
 
 	/**
@@ -298,17 +299,17 @@ public class RDF4JTermFactory implements RDFTermFactory {
 		}
 		if (term instanceof org.apache.commons.rdf.api.IRI) {
 			org.apache.commons.rdf.api.IRI iri = (org.apache.commons.rdf.api.IRI) term;
-			return valueFactory.createIRI(iri.getIRIString());
+			return getValueFactory().createIRI(iri.getIRIString());
 		}
 		if (term instanceof org.apache.commons.rdf.api.Literal) {
 			org.apache.commons.rdf.api.Literal literal = (org.apache.commons.rdf.api.Literal) term;
 			String label = literal.getLexicalForm();
 			if (literal.getLanguageTag().isPresent()) {
 				String lang = literal.getLanguageTag().get();
-				return valueFactory.createLiteral(label, lang);
+				return getValueFactory().createLiteral(label, lang);
 			}
 			org.eclipse.rdf4j.model.IRI dataType = (org.eclipse.rdf4j.model.IRI) asValue(literal.getDatatype());
-			return valueFactory.createLiteral(label, dataType);
+			return getValueFactory().createLiteral(label, dataType);
 		}
 		if (term instanceof BlankNode) {
 			// This is where it gets tricky to support round trips!
@@ -316,20 +317,20 @@ public class RDF4JTermFactory implements RDFTermFactory {
 			// FIXME: The uniqueReference might not be a valid BlankNode
 			// identifier..
 			// does it have to be in RDF4J?
-			return valueFactory.createBNode(blankNode.uniqueReference());
+			return getValueFactory().createBNode(blankNode.uniqueReference());
 		}
 		throw new IllegalArgumentException("RDFTerm was not an IRI, Literal or BlankNode: " + term.getClass());
 	}
 
 	@Override
 	public RDF4JBlankNode createBlankNode() throws UnsupportedOperationException {
-		BNode bnode = valueFactory.createBNode();
+		BNode bnode = getValueFactory().createBNode();
 		return (RDF4JBlankNode) asRDFTerm(bnode);
 	}
 
 	@Override
 	public RDF4JBlankNode createBlankNode(String name) throws UnsupportedOperationException {
-		BNode bnode = valueFactory.createBNode(name);
+		BNode bnode = getValueFactory().createBNode(name);
 		return (RDF4JBlankNode) asRDFTerm(bnode);
 	}
 
@@ -340,37 +341,54 @@ public class RDF4JTermFactory implements RDFTermFactory {
 
 	@Override
 	public RDF4JIRI createIRI(String iri) throws IllegalArgumentException, UnsupportedOperationException {
-		return (RDF4JIRI) asRDFTerm(valueFactory.createIRI(iri));
+		return (RDF4JIRI) asRDFTerm(getValueFactory().createIRI(iri));
 	}
 
 	@Override
 	public RDF4JLiteral createLiteral(String lexicalForm)
 			throws IllegalArgumentException, UnsupportedOperationException {
-		org.eclipse.rdf4j.model.Literal lit = valueFactory.createLiteral(lexicalForm);
+		org.eclipse.rdf4j.model.Literal lit = getValueFactory().createLiteral(lexicalForm);
 		return (RDF4JLiteral) asRDFTerm(lit);
 	}
 
 	@Override
 	public org.apache.commons.rdf.api.Literal createLiteral(String lexicalForm, org.apache.commons.rdf.api.IRI dataType)
 			throws IllegalArgumentException, UnsupportedOperationException {
-		org.eclipse.rdf4j.model.IRI iri = valueFactory.createIRI(dataType.getIRIString());
-		org.eclipse.rdf4j.model.Literal lit = valueFactory.createLiteral(lexicalForm, iri);
+		org.eclipse.rdf4j.model.IRI iri = getValueFactory().createIRI(dataType.getIRIString());
+		org.eclipse.rdf4j.model.Literal lit = getValueFactory().createLiteral(lexicalForm, iri);
 		return (org.apache.commons.rdf.api.Literal) asRDFTerm(lit);
 	}
 
 	@Override
 	public org.apache.commons.rdf.api.Literal createLiteral(String lexicalForm, String languageTag)
 			throws IllegalArgumentException, UnsupportedOperationException {
-		org.eclipse.rdf4j.model.Literal lit = valueFactory.createLiteral(lexicalForm, languageTag);
+		org.eclipse.rdf4j.model.Literal lit = getValueFactory().createLiteral(lexicalForm, languageTag);
 		return (org.apache.commons.rdf.api.Literal) asRDFTerm(lit);
 	}
 
 	@Override
 	public RDF4JTriple createTriple(BlankNodeOrIRI subject, org.apache.commons.rdf.api.IRI predicate, RDFTerm object)
 			throws IllegalArgumentException, UnsupportedOperationException {
-		final Statement statement = valueFactory.createStatement((org.eclipse.rdf4j.model.Resource) asValue(subject),
-				(org.eclipse.rdf4j.model.IRI) asValue(predicate), asValue(object));
+		final Statement statement = getValueFactory().createStatement(
+				(org.eclipse.rdf4j.model.Resource) asValue(subject),
+				(org.eclipse.rdf4j.model.IRI) asValue(predicate), 
+				asValue(object));
 		return asTriple(statement);
 	}
 
+	@Override
+	public Quad createQuad(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object)
+			throws IllegalArgumentException, UnsupportedOperationException {
+		final Statement statement = getValueFactory().createStatement(
+				(org.eclipse.rdf4j.model.Resource) asValue(subject),
+				(org.eclipse.rdf4j.model.IRI) asValue(predicate), 
+				asValue(object), 
+				(org.eclipse.rdf4j.model.Resource)asValue(graphName));
+		return asQuad(statement);
+	}
+	
+	public ValueFactory getValueFactory() {
+		return valueFactory;
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/bd579759/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
index d016837..10347e3 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
@@ -124,4 +124,11 @@ public final class ModelGraphImpl implements RDF4JGraph {
 			.map(rdf4jTermFactory::asTriple);
 	}
 	
+	@Override
+	public Optional<Resource[]> getContextFilter() {
+		// ModelGraph always do the unionGraph
+		return Optional.empty();
+		// TODO: Should we support contextFilter like in RepositoryGraphImpl?
+	}
+	
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/bd579759/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RDF4JParserBuilder.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RDF4JParserBuilder.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RDF4JParserBuilder.java
new file mode 100644
index 0000000..855c526
--- /dev/null
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RDF4JParserBuilder.java
@@ -0,0 +1,139 @@
+package org.apache.commons.rdf.rdf4j.impl;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.api.RDFParserBuilder;
+import org.apache.commons.rdf.rdf4j.RDF4JDataset;
+import org.apache.commons.rdf.rdf4j.RDF4JGraph;
+import org.apache.commons.rdf.rdf4j.RDF4JTermFactory;
+import org.apache.commons.rdf.simple.AbstractRDFParserBuilder;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.repository.util.RDFInserter;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFHandler;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.Rio;
+import org.eclipse.rdf4j.rio.helpers.AbstractRDFHandler;
+
+public class RDF4JParserBuilder extends AbstractRDFParserBuilder implements RDFParserBuilder {
+
+	private final class AddToQuadConsumer extends AbstractRDFHandler {
+		private final Consumer<Quad> quadTarget;
+
+		private AddToQuadConsumer(Consumer<Quad> quadTarget) {
+			this.quadTarget = quadTarget;
+		}
+
+		public void handleStatement(org.eclipse.rdf4j.model.Statement st)
+				throws org.eclipse.rdf4j.rio.RDFHandlerException {
+			// TODO: if getRdfTermFactory() is a non-rdf4j factory, should
+			// we use factory.createQuad() instead?
+			// Unsure what is the promise of setting getRdfTermFactory() --
+			// does it go all the way down to creating BlankNode, IRI and
+			// Literal?
+			quadTarget.accept(rdf4jTermFactory.asQuad(st));
+			// Performance note:
+			// Graph/Quad.add should pick up again our
+			// RDF4JGraphLike.asStatement()
+			// and avoid double conversion.
+			// Additionally the RDF4JQuad and RDF4JTriple implementations
+			// are lazily converting subj/obj/pred/graph.s
+		}
+	}
+
+	private final static class AddToModel extends AbstractRDFHandler {
+		private final Model model;
+
+		public AddToModel(Model model) {
+			this.model = model;
+		}
+
+		public void handleStatement(org.eclipse.rdf4j.model.Statement st)
+				throws org.eclipse.rdf4j.rio.RDFHandlerException {
+			model.add(st);
+		}
+		
+		@Override
+		public void handleNamespace(String prefix, String uri) throws RDFHandlerException {
+			model.setNamespace(prefix, uri);
+		}
+	}
+
+	private RDF4JTermFactory rdf4jTermFactory;
+
+	@Override
+	protected RDF4JTermFactory createRDFTermFactory() {
+		return new RDF4JTermFactory();
+	}
+
+	@Override
+	protected AbstractRDFParserBuilder prepareForParsing() throws IOException, IllegalStateException {
+		RDF4JParserBuilder c = (RDF4JParserBuilder) prepareForParsing();
+		// Ensure we have an RDF4JTermFactory for conversion.
+		// We'll make a new one if user has provided a non-RDF4J factory
+		c.rdf4jTermFactory = (RDF4JTermFactory) getRdfTermFactory().filter(RDF4JTermFactory.class::isInstance)
+				.orElseGet(c::createRDFTermFactory);
+		return c;
+	}
+
+	@Override
+	protected void parseSynchronusly() throws IOException, RDFParseException {
+		if (getContentType().isPresent()) {
+			Rio.getParserFormatForMIMEType(getContentType().get());
+		}
+
+		Optional<RDFFormat> formatByMimeType = getContentType().flatMap(Rio::getParserFormatForMIMEType);
+		Optional<RDFFormat> formatByFilename = getSourceFile().map(Path::getFileName).map(Path::toString)
+				.flatMap(Rio::getParserFormatForFileName);
+		RDFFormat format = formatByMimeType.orElse(
+				formatByFilename.orElseThrow(() -> new RDFParseException("Unrecognized or missing content type")));
+
+		RDFParser parser = Rio.createParser(format);
+
+		parser.setRDFHandler(makeRDFHandler());
+	}
+
+	protected RDFHandler makeRDFHandler() {
+
+		// TODO: Can we join the below DF4JDataset and RDF4JGraph cases
+		// using RDF4JGraphLike<TripleLike<BlankNodeOrIRI,IRI,RDFTerm>>
+		// or will that need tricky generics types?
+
+		if (getTargetDataset().filter(RDF4JDataset.class::isInstance).isPresent()) {
+			// One of us, we can add them as Statements directly
+			RDF4JDataset dataset = (RDF4JDataset) getTargetDataset().get();
+			if (dataset.asRepository().isPresent()) {				
+				return new RDFInserter(dataset.asRepository().get().getConnection());
+			}
+			if (dataset.asModel().isPresent()) {
+				Model model = dataset.asModel().get();
+				return new AddToModel(model);
+			}
+			// Not backed by Repository or Model?
+			// Third-party RDF4JDataset subclass, so we'll fall through to the
+			// getTarget() handling further down
+		} else if (getTargetGraph().filter(RDF4JGraph.class::isInstance).isPresent()) {
+			RDF4JGraph graph = (RDF4JGraph) getTargetGraph().get();
+
+			if (graph.asRepository().isPresent()) {
+				RDFInserter inserter = new RDFInserter(graph.asRepository().get().getConnection());
+				graph.getContextFilter().ifPresent(inserter::enforceContext);
+				return inserter;
+			}
+			if (graph.asModel().isPresent() && graph.getContextFilter().isPresent()) {
+				Model model = graph.asModel().get();
+				return new AddToModel(model);
+			}
+			// else - fall through
+		}
+
+		// Fall thorough: let target() consume our converted quads.
+		return new AddToQuadConsumer(getTarget());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/bd579759/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
index 7c15d1d..73e1065 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
@@ -17,6 +17,8 @@
  */
 package org.apache.commons.rdf.rdf4j.impl;
 
+import java.util.Arrays;
+import java.util.Optional;
 import java.util.stream.Stream;
 
 import org.apache.commons.rdf.api.BlankNodeOrIRI;
@@ -154,4 +156,9 @@ public class RepositoryGraphImpl extends AbstractRepositoryGraphLike<Triple> imp
 		return rdf4jTermFactory.asTriple(statement);
 	}
 
+	public Optional<Resource[]> getContextFilter() {
+		// Make sure we clone
+		return Optional.ofNullable(contextFilter).map(f -> f.clone());		
+	}
+	
 }