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/10/07 14:22:58 UTC

[04/50] incubator-commonsrdf git commit: GeneralizedQuadImpl common for QuadImpl and TripleImpl

GeneralizedQuadImpl common for QuadImpl and TripleImpl


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

Branch: refs/heads/rdf4j
Commit: a3cb3b13a74aede64603dd651b5e549b89bc4a60
Parents: 76dbe50
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Fri Jul 8 15:16:47 2016 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Jul 8 15:18:17 2016 +0100

----------------------------------------------------------------------
 .../org/apache/commons/rdf/jena/JenaQuad.java   |   8 +-
 .../apache/commons/rdf/jena/JenaQuadLike.java   |  35 +++++
 .../commons/rdf/jena/JenaRDFParserBuilder.java  |  38 ++++++
 .../commons/rdf/jena/JenaRDFTermFactory.java    |  70 +++++++++-
 .../rdf/jena/impl/GeneralizedQuadImpl.java      | 136 +++++++++++++++++++
 .../rdf/jena/impl/GeneralizedTripleImpl.java    |  74 ----------
 .../commons/rdf/jena/impl/JenaFactory.java      |  21 ++-
 .../apache/commons/rdf/jena/impl/QuadImpl.java  |  82 ++---------
 .../commons/rdf/jena/impl/TripleImpl.java       |  57 ++------
 9 files changed, 326 insertions(+), 195 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuad.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuad.java b/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuad.java
index 7fdb658..45d9d2c 100644
--- a/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuad.java
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuad.java
@@ -18,9 +18,11 @@
 
 package org.apache.commons.rdf.jena;
 
-import org.apache.jena.sparql.core.Quad;
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.RDFTerm;
 
 /** Access the Jena quad backing this object */
-public interface JenaQuad extends org.apache.commons.rdf.api.Quad {
-	public Quad asJenaQuad();
+public interface JenaQuad extends org.apache.commons.rdf.api.Quad, 
+	JenaQuadLike<BlankNodeOrIRI,IRI,RDFTerm,BlankNodeOrIRI> {	
 }

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuadLike.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuadLike.java b/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuadLike.java
new file mode 100644
index 0000000..015e8c9
--- /dev/null
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/JenaQuadLike.java
@@ -0,0 +1,35 @@
+/**
+ * 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.commons.rdf.jena;
+
+import org.apache.commons.rdf.api.QuadLike;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.jena.sparql.core.Quad;
+
+/** Access the Jena quad backing this object */
+public interface JenaQuadLike<S extends RDFTerm, P extends RDFTerm, O extends RDFTerm, G extends RDFTerm> 
+	extends JenaTripleLike<S,P,O>, QuadLike<S,P,O,G> {
+
+	/**
+	 * Return the adapted Jena quad
+	 * 
+	 * @return Adapted Jena {@link Quad}.
+	 */
+	public Quad asJenaQuad();
+}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFParserBuilder.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFParserBuilder.java b/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFParserBuilder.java
index 9b5ac29..2149932 100644
--- a/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFParserBuilder.java
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFParserBuilder.java
@@ -21,10 +21,14 @@ package org.apache.commons.rdf.jena;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Files;
+import java.util.function.Consumer;
 
 import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.QuadLike;
 import org.apache.commons.rdf.api.RDFParserBuilder;
+import org.apache.commons.rdf.api.RDFTerm;
 import org.apache.commons.rdf.api.RDFTermFactory;
+import org.apache.commons.rdf.api.TripleLike;
 import org.apache.commons.rdf.simple.AbstractRDFParserBuilder;
 import org.apache.jena.graph.Graph;
 import org.apache.jena.riot.Lang;
@@ -34,16 +38,44 @@ import org.apache.jena.riot.system.StreamRDFLib;
 
 public class JenaRDFParserBuilder extends AbstractRDFParserBuilder<JenaRDFParserBuilder> implements RDFParserBuilder {
 
+	private Consumer<TripleLike<RDFTerm, RDFTerm, RDFTerm>> generalizedConsumerTriple;
+	private Consumer<QuadLike<RDFTerm, RDFTerm, RDFTerm, RDFTerm>> generalizedConsumerQuad;
+
 	protected RDFTermFactory createRDFTermFactory() {
 		return new JenaRDFTermFactory();
 	}
 
+	public JenaRDFParserBuilder targetGeneralizedTriple(Consumer<TripleLike<RDFTerm,RDFTerm,RDFTerm>> consumer) {
+		JenaRDFParserBuilder c = this.clone();
+		c.resetTarget();		
+		c.generalizedConsumerTriple = consumer;
+		return c;
+	}
+
+	public JenaRDFParserBuilder targetGeneralizedQuad(Consumer<QuadLike<RDFTerm,RDFTerm,RDFTerm,RDFTerm>> consumer) {
+		JenaRDFParserBuilder c = this.clone();
+		c.resetTarget();		
+		c.generalizedConsumerQuad = consumer;
+		return c;
+	}
+	
+	@Override
+	protected void resetTarget() {		
+		super.resetTarget();
+		this.generalizedConsumerTriple = null;
+		this.generalizedConsumerQuad = null;
+	}
+	
 	@Override
 	protected void parseSynchronusly() throws IOException {
 		StreamRDF dest;
 		if (getTargetGraph().isPresent() && getTargetGraph().get() instanceof JenaGraph) {
 			Graph jenaGraph = ((JenaGraph) getTargetGraph().get()).asJenaGraph();
 			dest = StreamRDFLib.graph(jenaGraph);
+		} else if (generalizedConsumerQuad != null) {				
+			dest = getJenaFactory().streamJenaToGeneralizedQuad(generalizedConsumerQuad);			
+		} else if (generalizedConsumerTriple != null) {				
+			dest = getJenaFactory().streamJenaToGeneralizedTriple(generalizedConsumerTriple);			
 		} else {
 			dest = JenaRDFTermFactory.streamJenaToCommonsRDF(getRdfTermFactory().get(), getTarget());
 		}
@@ -62,4 +94,10 @@ public class JenaRDFParserBuilder extends AbstractRDFParserBuilder<JenaRDFParser
 		}
 	}
 
+	private JenaRDFTermFactory getJenaFactory() {
+		return (JenaRDFTermFactory) getRdfTermFactory()
+				.filter(JenaRDFTermFactory.class::isInstance)
+				.orElseGet(this::createRDFTermFactory);		
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFTermFactory.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFTermFactory.java b/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFTermFactory.java
index f31173b..12b152e 100644
--- a/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFTermFactory.java
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFTermFactory.java
@@ -28,6 +28,7 @@ import org.apache.commons.rdf.api.Graph;
 import org.apache.commons.rdf.api.IRI;
 import org.apache.commons.rdf.api.Literal;
 import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.api.QuadLike;
 import org.apache.commons.rdf.api.RDFSyntax;
 import org.apache.commons.rdf.api.RDFTerm;
 import org.apache.commons.rdf.api.RDFTermFactory;
@@ -106,6 +107,12 @@ public final class JenaRDFTermFactory implements RDFTermFactory {
 		return JenaFactory.createTriple(subject, predicate, object);
 	}
 	
+	@Override
+	public Quad createQuad(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object)
+			throws IllegalArgumentException, UnsupportedOperationException {
+		return JenaFactory.createQuad(subject, predicate, object, graphName);
+	}
+	
 	/**
 	 * Adapt a generalized Jena Triple to a CommonsRDF {@link TripleLike} statement.
 	 * <p>
@@ -280,10 +287,11 @@ public final class JenaRDFTermFactory implements RDFTermFactory {
 	}
 	
 	/**
-	 * Adapt a generalized Jena Triple to a CommonsRDF {@link TripleLike}.
+	 * Adapt a generalized Jena {@link org.apache.jena.graph.Triple} to a CommonsRDF {@link TripleLike}.
 	 * <p>
 	 * The generalized triple supports any {@link RDFTerm} as its {@link TripleLike#getSubject()}
-	 * {@link TripleLike#getPredicate()} or {@link TripleLike#getObject()}. 
+	 * {@link TripleLike#getPredicate()} or {@link TripleLike#getObject()}, including 
+	 * the extensions {@link JenaAny} and {@link JenaVariable}.
 	 * <p>
 	 * If the Jena triple contains any {@link Node#isBlank()}, then any corresponding
 	 * {@link BlankNode} will use a {@link UUID} salt from this
@@ -305,6 +313,38 @@ public final class JenaRDFTermFactory implements RDFTermFactory {
 	public JenaTripleLike<RDFTerm, RDFTerm, RDFTerm> fromJenaGeneralized(org.apache.jena.graph.Triple triple) throws ConversionException {
 		return JenaFactory.fromJenaGeneralized(triple, salt);
 	}
+
+	/**
+	 * Adapt a generalized Jena {@link org.apache.jena.sparql.core.Quad} to a CommonsRDF {@link QuadLike}.
+	 * <p>
+	 * The generalized quad supports any {@link RDFTerm} as its 
+	 * {@link QuadLike#getGraphName()}, 
+	 * {@link QuadLike#getSubject()}
+	 * {@link QuadLike#getPredicate()} or 
+	 * {@link QuadLike#getObject()}, including 
+	 * the extensions 
+	 * {@link JenaAny} and {@link JenaVariable}. 
+	 * <p>
+	 * If the Jena quad contains any {@link Node#isBlank()}, then any corresponding
+	 * {@link BlankNode} will use a {@link UUID} salt from this
+	 * {@link JenaRDFTermFactory} instance in combination with
+	 * {@link Node#getBlankNodeId()} for the purpose of its
+	 * {@link BlankNode#uniqueReference()}.
+	 *
+	 * @see #fromJena(org.apache.jena.graph.Quad, UUID)
+	 * @see #fromJena(RDFTermFactory, org.apache.jena.graph.Quad)
+	 * 
+	 * @param quad
+	 *            Jena quad
+	 * @return Adapted {@link QuadLike}. Note that the generalized quad does
+	 *         <strong>not</strong> implement {@link Quad#equals(Object)} or
+	 *         {@link Quad#hashCode()}.
+	 * @throws ConversionException
+	 *             if any of the quad nodes are not concrete
+	 */
+	public JenaQuadLike<RDFTerm, RDFTerm, RDFTerm, RDFTerm> fromJenaGeneralized(org.apache.jena.sparql.core.Quad quad) throws ConversionException {
+		return JenaFactory.fromJenaGeneralized(quad, salt);
+	}
 	
 	
 	/**
@@ -465,8 +505,34 @@ public final class JenaRDFTermFactory implements RDFTermFactory {
 			}
 		};
 	}
+	
+	/**
+	 * Create a {@link StreamRDF} that inserts into any RDFCommons
+	 * implementation of Graph
+	 */
+	public StreamRDF streamJenaToGeneralizedTriple(Consumer<TripleLike<RDFTerm, RDFTerm, RDFTerm>> generalizedConsumer) {
+		return new StreamRDFBase() {			
+			@Override
+			public void triple(org.apache.jena.graph.Triple triple) {
+				generalizedConsumer.accept(fromJenaGeneralized(triple));
+			}
+		};
+	}	
 
 	/**
+	 * Create a {@link StreamRDF} that inserts into any RDFCommons
+	 * implementation of Graph
+	 */
+	public StreamRDF streamJenaToGeneralizedQuad(Consumer<QuadLike<RDFTerm, RDFTerm, RDFTerm, RDFTerm>> generalizedConsumer) {
+		return new StreamRDFBase() {
+			@Override
+			public void quad(org.apache.jena.sparql.core.Quad quad) {
+				generalizedConsumer.accept(fromJenaGeneralized(quad));
+			}
+		};
+	}	
+	
+	/**
 	 * Convert a CommonsRDF Graph to a Jena Graph. If the Graph was from Jena
 	 * originally, return that original object else create a copy using Jena
 	 * objects.

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedQuadImpl.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedQuadImpl.java b/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedQuadImpl.java
new file mode 100644
index 0000000..25b148f
--- /dev/null
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedQuadImpl.java
@@ -0,0 +1,136 @@
+/**
+ * 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.commons.rdf.jena.impl;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.apache.commons.rdf.api.QuadLike;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.commons.rdf.jena.JenaQuad;
+import org.apache.commons.rdf.jena.JenaQuadLike;
+import org.apache.commons.rdf.jena.JenaRDFTermFactory;
+import org.apache.commons.rdf.jena.JenaTriple;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.Quad;
+
+/**
+ * A generalized {@link QuadLike}, backed by a Jena {@link Quad} or {@link Triple}.
+ * <p>
+ * This class does not implement any particular {@link #equals(Object)} or
+ * {@link #hashCode()} but can otherwise be used as a base class for both
+ * a {@link JenaTriple} and a {@link JenaQuad}.
+ * 
+ * @see TripleImpl
+ * @see QuadImpl
+ * @see JenaFactory#createGeneralizedTriple(RDFTerm, RDFTerm, RDFTerm)
+ * @see JenaFactory#createGeneralizedQuad(RDFTerm, RDFTerm, RDFTerm, Optional)
+ *
+ */
+public class GeneralizedQuadImpl<S extends RDFTerm, P extends RDFTerm, O extends RDFTerm, G extends RDFTerm> implements JenaQuadLike<S,P,O,G> {
+
+	final Optional<G> graphName;
+	final S subject;
+	final P predicate;
+	final O object;
+	org.apache.jena.sparql.core.Quad quad = null;
+	org.apache.jena.graph.Triple triple = null;
+	
+	GeneralizedQuadImpl(S subject, P predicate, O object, Optional<G> graphName) {		
+		this.subject = Objects.requireNonNull(subject);
+		this.predicate = Objects.requireNonNull(predicate);
+		this.object = Objects.requireNonNull(object);
+		this.graphName = Objects.requireNonNull(graphName);
+	}
+
+	GeneralizedQuadImpl(S subject, P predicate, O object) {
+		this(subject, predicate, object, Optional.empty());
+	}
+	 
+	@SuppressWarnings("unchecked")
+	GeneralizedQuadImpl(org.apache.jena.sparql.core.Quad quad, UUID salt) {
+		this.quad = Objects.requireNonNull(quad);
+		this.subject = (S) JenaFactory.fromJena(quad.getSubject(), salt);
+		this.predicate = (P) JenaFactory.fromJena(quad.getPredicate(), salt);
+		this.object = (O)JenaFactory.fromJena(quad.getObject(), salt);
+		this.graphName = Optional.of((G) JenaFactory.fromJena(quad.getGraph(), salt));		
+	}
+
+	@SuppressWarnings("unchecked")
+	GeneralizedQuadImpl(org.apache.jena.graph.Triple triple, UUID salt) {
+		this.triple = Objects.requireNonNull(triple);		
+		this.subject = (S) JenaFactory.fromJena(triple.getSubject(), salt);
+		this.predicate = (P) JenaFactory.fromJena(triple.getPredicate(), salt);
+		this.object = (O)JenaFactory.fromJena(triple.getObject(), salt);
+		this.graphName = Optional.empty();
+	}
+
+	@Override
+	public org.apache.jena.sparql.core.Quad asJenaQuad() {
+		if (quad == null) {
+			quad = org.apache.jena.sparql.core.Quad.create(
+					JenaRDFTermFactory.toJena(graphName.orElse(null)),
+					JenaRDFTermFactory.toJena(subject), 
+					JenaRDFTermFactory.toJena(predicate),
+					JenaRDFTermFactory.toJena(object));
+		}
+		return quad;
+	}
+
+	@Override
+	public org.apache.jena.graph.Triple asJenaTriple() {
+		if (triple == null) {
+			triple = org.apache.jena.graph.Triple.create(JenaRDFTermFactory.toJena(subject), 
+				JenaRDFTermFactory.toJena(predicate),
+				JenaRDFTermFactory.toJena(object));
+		}
+		return triple;
+	}	
+	
+	@Override
+	public S getSubject() {
+		return subject;
+	}
+
+	@Override
+	public P getPredicate() {
+		return predicate;
+	}
+	
+	@Override
+	public O getObject() {
+		return object;
+	}
+
+	@Override
+	public Optional<G> getGraphName() {
+		return graphName;
+	}
+
+	@Override
+	public String toString() {
+		// kind of nquad syntax
+		return getSubject().ntriplesString() + " " + 
+				getPredicate().ntriplesString() + " "
+				+ getObject().ntriplesString() + " " + 
+				getGraphName().map(RDFTerm::ntriplesString).orElse("") + ".";
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedTripleImpl.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedTripleImpl.java b/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedTripleImpl.java
deleted file mode 100644
index 97ff7c5..0000000
--- a/jena/src/main/java/org/apache/commons/rdf/jena/impl/GeneralizedTripleImpl.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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.commons.rdf.jena.impl;
-
-import java.util.UUID;
-
-import org.apache.commons.rdf.api.RDFTerm;
-import org.apache.commons.rdf.jena.ConversionException;
-import org.apache.commons.rdf.jena.JenaTripleLike;
-import org.apache.commons.rdf.jena.JenaRDFTermFactory;
-
-public class GeneralizedTripleImpl implements JenaTripleLike<RDFTerm, RDFTerm, RDFTerm> {
-	private final RDFTerm object;
-	private final RDFTerm predicate;
-	private final RDFTerm subject;
-	private org.apache.jena.graph.Triple triple = null;
-
-	/* package */ GeneralizedTripleImpl(RDFTerm subject, RDFTerm predicate, RDFTerm object) {
-		this.subject = subject;
-		this.predicate = predicate;
-		this.object = object;
-	}
-
-	/* package */ GeneralizedTripleImpl(org.apache.jena.graph.Triple triple, UUID salt) throws ConversionException {
-		this.subject = JenaFactory.fromJena(triple.getSubject(), salt);
-		this.predicate = JenaFactory.fromJena(triple.getPredicate(), salt);
-		this.object = JenaFactory.fromJena(triple.getObject(), salt);
-		this.triple = triple;
-	}
-
-	@Override
-	public org.apache.jena.graph.Triple asJenaTriple() {
-		if (triple == null)
-			triple = org.apache.jena.graph.Triple.create(JenaRDFTermFactory.toJena(subject),
-					JenaRDFTermFactory.toJena(predicate), JenaRDFTermFactory.toJena(object));
-		return triple;
-	}
-	@Override
-	public RDFTerm getObject() {
-		return object;
-	}
-
-	@Override
-	public RDFTerm getPredicate() {
-		return predicate;
-	}
-
-	@Override
-	public RDFTerm getSubject() {
-		return subject;
-	}
-
-	@Override
-	public String toString() {
-		return getSubject() + " " + getPredicate() + " " + getObject() + " .";
-	}
-	
-}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaFactory.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaFactory.java b/jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaFactory.java
index 4a6d44b..b685832 100644
--- a/jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaFactory.java
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaFactory.java
@@ -18,6 +18,7 @@
 
 package org.apache.commons.rdf.jena.impl;
 
+import java.util.Optional;
 import java.util.UUID;
 
 import org.apache.commons.rdf.api.BlankNode;
@@ -31,6 +32,8 @@ import org.apache.commons.rdf.jena.JenaBlankNode;
 import org.apache.commons.rdf.jena.JenaGraph;
 import org.apache.commons.rdf.jena.JenaIRI;
 import org.apache.commons.rdf.jena.JenaLiteral;
+import org.apache.commons.rdf.jena.JenaQuad;
+import org.apache.commons.rdf.jena.JenaQuadLike;
 import org.apache.commons.rdf.jena.JenaRDFTerm;
 import org.apache.commons.rdf.jena.JenaTriple;
 import org.apache.commons.rdf.jena.JenaTripleLike;
@@ -79,6 +82,10 @@ public class JenaFactory {
 	public static JenaTriple createTriple(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
 		return new TripleImpl(subject, predicate, object);
 	}
+
+	public static JenaQuad createQuad(BlankNodeOrIRI subject, IRI predicate, RDFTerm object, BlankNodeOrIRI graphName) {
+		return new QuadImpl(subject, predicate, object, Optional.ofNullable(graphName));
+	}
 	
 	public static JenaVariable createVariable(String name) {
 		return new VariableImpl(NodeFactory.createVariable(name));
@@ -88,8 +95,12 @@ public class JenaFactory {
 		return AnyImpl.Singleton.instance;
 	}
 
-	public static JenaTripleLike<RDFTerm, RDFTerm, RDFTerm> createGeneralizedTriple(RDFTerm subject, RDFTerm predicate, RDFTerm object) {
-		return new GeneralizedTripleImpl(subject, predicate, object);
+	public static JenaTripleLike<RDFTerm,RDFTerm,RDFTerm> createGeneralizedTriple(RDFTerm subject, RDFTerm predicate, RDFTerm object) {
+		return new GeneralizedQuadImpl<RDFTerm,RDFTerm,RDFTerm,RDFTerm>(subject, predicate, object);
+	}
+
+	public static JenaQuadLike<RDFTerm,RDFTerm,RDFTerm,RDFTerm> createGeneralizedQuad(RDFTerm subject, RDFTerm predicate, RDFTerm object, RDFTerm graphName) {
+		return new GeneralizedQuadImpl<RDFTerm,RDFTerm,RDFTerm,RDFTerm>(subject, predicate, object, Optional.ofNullable(graphName));
 	}
 	
 	public static JenaRDFTerm fromJena(Node node, UUID salt) throws ConversionException {
@@ -131,7 +142,11 @@ public class JenaFactory {
 	}
 
 	public static JenaTripleLike<RDFTerm, RDFTerm, RDFTerm> fromJenaGeneralized(org.apache.jena.graph.Triple triple, UUID salt) {
-		return new GeneralizedTripleImpl(triple, salt);
+		return new GeneralizedQuadImpl<RDFTerm,RDFTerm,RDFTerm,RDFTerm>(triple, salt);
+	}
+
+	public static JenaQuadLike<RDFTerm,RDFTerm,RDFTerm,RDFTerm> fromJenaGeneralized(org.apache.jena.sparql.core.Quad quad, UUID salt) {
+		return new GeneralizedQuadImpl<RDFTerm,RDFTerm,RDFTerm,RDFTerm>(quad, salt);
 	}
 	
 	public static Quad fromJena(org.apache.jena.sparql.core.Quad quad, UUID salt) {

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/impl/QuadImpl.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/impl/QuadImpl.java b/jena/src/main/java/org/apache/commons/rdf/jena/impl/QuadImpl.java
index 19f154c..d68fcaf 100644
--- a/jena/src/main/java/org/apache/commons/rdf/jena/impl/QuadImpl.java
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/impl/QuadImpl.java
@@ -26,56 +26,31 @@ import org.apache.commons.rdf.api.BlankNodeOrIRI;
 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.Triple;
+import org.apache.commons.rdf.jena.ConversionException;
 import org.apache.commons.rdf.jena.JenaQuad;
-import org.apache.commons.rdf.jena.JenaRDFTermFactory;
 
-public class QuadImpl implements JenaQuad {
+public class QuadImpl	extends GeneralizedQuadImpl<BlankNodeOrIRI,IRI,RDFTerm,BlankNodeOrIRI>
+	implements JenaQuad {
 
-	private final Optional<BlankNodeOrIRI> graphName;
-	private final RDFTerm object;
-	private final IRI predicate;
-	private org.apache.jena.sparql.core.Quad quad = null;
-	private final BlankNodeOrIRI subject;
-
-	/* package */ QuadImpl(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
-		this.graphName = Objects.requireNonNull(graphName);
-		this.subject = Objects.requireNonNull(subject);
-		this.predicate = Objects.requireNonNull(predicate);
-		this.object = Objects.requireNonNull(object);
-	}
-
-	/* package */ QuadImpl(org.apache.jena.sparql.core.Quad quad, UUID salt) {
-		this.quad = Objects.requireNonNull(quad);
-		this.graphName = Optional.of((BlankNodeOrIRI) JenaFactory.fromJena(quad.getGraph(), salt));
-		this.subject = (BlankNodeOrIRI) JenaFactory.fromJena(quad.getSubject(), salt);
-		this.predicate = (IRI) JenaFactory.fromJena(quad.getPredicate(), salt);
-		this.object = JenaFactory.fromJena(quad.getObject(), salt);
+	QuadImpl(BlankNodeOrIRI subject, IRI predicate, RDFTerm object, Optional<BlankNodeOrIRI> graphName) {
+		super(subject, predicate, object, graphName);
 	}
 
-	@Override
-	public org.apache.jena.sparql.core.Quad asJenaQuad() {
-		if (quad == null) {
-			quad = org.apache.jena.sparql.core.Quad.create(
-					JenaRDFTermFactory.toJena(graphName.orElse(null)),
-					JenaRDFTermFactory.toJena(subject), 
-					JenaRDFTermFactory.toJena(predicate),
-					JenaRDFTermFactory.toJena(object));
+	QuadImpl(org.apache.jena.sparql.core.Quad quad, UUID salt) {
+		super(quad, salt);
+		// Check the conversion
+		if ((graphName.isPresent() && ! (graphName.get() instanceof BlankNodeOrIRI)) ||
+			! (subject instanceof BlankNodeOrIRI) ||
+			! (predicate instanceof IRI) ||
+			! (object instanceof RDFTerm)) {
+			throw new ConversionException("Can't adapt generalized quad: " + quad);	
 		}
-		return quad;
-	}
-
-	@Override
-	public Triple asTriple() {
-		return new TripleImpl(getSubject(), getPredicate(), getObject());
 	}
 
 	@Override
 	public boolean equals(Object other) {
 		if (other == this)
 			return true;
-		if (other == null)
-			return false;
 		if (!(other instanceof Quad))
 			return false;
 		Quad quad = (Quad) other;
@@ -84,37 +59,8 @@ public class QuadImpl implements JenaQuad {
 	}
 
 	@Override
-	public Optional<BlankNodeOrIRI> getGraphName() {
-		return graphName;
-	}
-
-	@Override
-	public RDFTerm getObject() {
-		return object;
-	}
-
-	@Override
-	public IRI getPredicate() {
-		return predicate;
-	}
-
-	@Override
-	public BlankNodeOrIRI getSubject() {
-		return subject;
-	}
-
-	@Override
 	public int hashCode() {
 		return Objects.hash(getSubject(), getPredicate(), getObject(), getGraphName());
 	}
-
-	@Override
-	public String toString() {
-		// kind of nquad syntax
-		return getSubject().ntriplesString() + " " + 
-				getPredicate().ntriplesString() + " "
-				+ getObject().ntriplesString() + " " + 
-				getGraphName().map(RDFTerm::ntriplesString).orElse("") + ".";
-	}
-
+	
 }

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a3cb3b13/jena/src/main/java/org/apache/commons/rdf/jena/impl/TripleImpl.java
----------------------------------------------------------------------
diff --git a/jena/src/main/java/org/apache/commons/rdf/jena/impl/TripleImpl.java b/jena/src/main/java/org/apache/commons/rdf/jena/impl/TripleImpl.java
index cadbdf5..9207b38 100644
--- a/jena/src/main/java/org/apache/commons/rdf/jena/impl/TripleImpl.java
+++ b/jena/src/main/java/org/apache/commons/rdf/jena/impl/TripleImpl.java
@@ -27,37 +27,22 @@ import org.apache.commons.rdf.api.RDFTerm;
 import org.apache.commons.rdf.api.Triple;
 import org.apache.commons.rdf.jena.ConversionException;
 import org.apache.commons.rdf.jena.JenaTriple;
-import org.apache.commons.rdf.jena.JenaRDFTermFactory;
 
-public class TripleImpl implements Triple, JenaTriple {
-	private final RDFTerm object;
-	private final IRI predicate;
-	private final BlankNodeOrIRI subject;
-	private org.apache.jena.graph.Triple triple = null;
+public class TripleImpl extends GeneralizedQuadImpl<BlankNodeOrIRI, IRI, RDFTerm, RDFTerm>
+		implements JenaTriple {
 
-	/* package */ TripleImpl(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
-		this.subject = subject;
-		this.predicate = predicate;
-		this.object = object;
+	TripleImpl(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		super(subject, predicate, object);
 	}
 
-	/* package */ TripleImpl(org.apache.jena.graph.Triple triple, UUID salt) throws ConversionException {
-		try {
-			this.subject = (BlankNodeOrIRI) JenaFactory.fromJena(triple.getSubject(), salt);
-			this.predicate = (IRI) JenaFactory.fromJena(triple.getPredicate(), salt);
-		} catch (ClassCastException ex) {
-			throw new ConversionException("Can't adapt generalized triple: " + triple, ex);
+	TripleImpl(org.apache.jena.graph.Triple triple, UUID salt) throws ConversionException {
+		super(triple, salt);
+		// Check the conversion
+		if (! (subject instanceof BlankNodeOrIRI) ||
+			! (predicate instanceof IRI) ||
+			! (object instanceof RDFTerm)) {
+			throw new ConversionException("Can't adapt generalized triple: " + quad);	
 		}
-		this.object = JenaFactory.fromJena(triple.getObject(), salt);
-		this.triple = triple;
-	}
-
-	@Override
-	public org.apache.jena.graph.Triple asJenaTriple() {
-		if (triple == null)
-			triple = org.apache.jena.graph.Triple.create(JenaRDFTermFactory.toJena(subject),
-					JenaRDFTermFactory.toJena(predicate), JenaRDFTermFactory.toJena(object));
-		return triple;
 	}
 
 	@Override
@@ -74,27 +59,9 @@ public class TripleImpl implements Triple, JenaTriple {
 	}
 
 	@Override
-	public RDFTerm getObject() {
-		return object;
-	}
-
-	@Override
-	public IRI getPredicate() {
-		return predicate;
-	}
-
-	@Override
-	public BlankNodeOrIRI getSubject() {
-		return subject;
-	}
-
-	@Override
 	public int hashCode() {
 		return Objects.hash(getSubject(), getPredicate(), getObject());
 	}
 
-	@Override
-	public String toString() {
-		return getSubject() + " " + getPredicate() + " " + getObject() + " .";
-	}
+	
 }