commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ggreg...@apache.org
Subject [13/22] commons-rdf git commit: Module names, directory names, and artifact names should match.
Date Mon, 30 Oct 2017 14:57:13 GMT
http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/InternalJenaFactory.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/InternalJenaFactory.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/InternalJenaFactory.java
new file mode 100644
index 0000000..3e186a2
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/InternalJenaFactory.java
@@ -0,0 +1,171 @@
+/**
+ * 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.Optional;
+import java.util.UUID;
+
+import org.apache.commons.rdf.api.BlankNode;
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.commons.rdf.jena.ConversionException;
+import org.apache.commons.rdf.jena.JenaBlankNode;
+import org.apache.commons.rdf.jena.JenaDataset;
+import org.apache.commons.rdf.jena.JenaGeneralizedQuadLike;
+import org.apache.commons.rdf.jena.JenaGeneralizedTripleLike;
+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.JenaRDF;
+import org.apache.commons.rdf.jena.JenaRDFTerm;
+import org.apache.commons.rdf.jena.JenaTriple;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.DatasetGraphFactory;
+import org.apache.jena.sparql.graph.GraphFactory;
+import org.apache.jena.system.JenaSystem;
+
+/**
+ * Construct Jena implementations of Commons RDF.
+ * <p>
+ * This class is deliberately an abstract class, as it is an internal helper
+ * which <strong>may change</strong> in any minor version update; users should
+ * instead use {@link JenaRDF}.
+ * <p>
+ * For the purpose of blank node identity, some of these methods require a
+ * {@link UUID} to use as a salt. See {@link BlankNode#uniqueReference()} for
+ * details.
+ * 
+ */
+public abstract class InternalJenaFactory {
+
+    static { 
+        // http://jena.apache.org/documentation/notes/system-initialization.html
+        JenaSystem.init();
+    }
+    
+    
+    public JenaBlankNode createBlankNode(final String id, final UUID salt) {
+        return new JenaBlankNodeImpl(NodeFactory.createBlankNode(id), salt);
+    }
+
+    public JenaBlankNode createBlankNode(final UUID salt) {
+        return new JenaBlankNodeImpl(NodeFactory.createBlankNode(), salt);
+    }
+
+    public JenaDataset createDataset(final DatasetGraph datasetGraph, final UUID salt) {
+        return new JenaDatasetImpl(datasetGraph, salt);
+    }
+
+    public JenaDataset createDataset(final UUID salt) {
+        final DatasetGraph dg = DatasetGraphFactory.createGeneral();
+        // Or which createMethod() -- a bit confusing with lots of choice..
+        return new JenaDatasetImpl(dg, salt);
+    }
+
+    public JenaGeneralizedQuadLike createGeneralizedQuad(final org.apache.jena.sparql.core.Quad quad, final UUID salt) {
+        return new JenaGeneralizedQuadLikeImpl(quad, salt);
+    }
+
+    public JenaGeneralizedQuadLike createGeneralizedQuad(final RDFTerm subject, final RDFTerm predicate, final RDFTerm object,
+            final RDFTerm graphName) {
+        return new JenaGeneralizedQuadLikeImpl(subject, predicate, object, Optional.ofNullable(graphName));
+    }
+
+    public JenaGeneralizedTripleLike createGeneralizedTriple(final org.apache.jena.graph.Triple triple, final UUID salt) {
+        return new JenaGeneralizedTripleLikeImpl(triple, salt);
+    }
+
+    public JenaGeneralizedTripleLike createGeneralizedTriple(final RDFTerm subject, final RDFTerm predicate, final RDFTerm object) {
+        return new JenaGeneralizedTripleLikeImpl(subject, predicate, object);
+    }
+
+    public JenaGraph createGraph(final Model model, final UUID salt) {
+        return new JenaGraphImpl(model, salt);
+    }
+
+    public JenaGraph createGraph(final org.apache.jena.graph.Graph graph, final UUID salt) {
+        return new JenaGraphImpl(graph, salt);
+    }
+
+    public JenaGraph createGraph(final UUID salt) {
+        return new JenaGraphImpl(GraphFactory.createDefaultGraph(), salt);
+    }
+
+    public JenaIRI createIRI(final String iriStr) {
+        return new JenaIRIImpl(iriStr);
+    }
+
+    public JenaLiteral createLiteral(final String lexStr) {
+        return new JenaLiteralImpl(NodeFactory.createLiteral(lexStr));
+    }
+
+    public JenaLiteral createLiteralDT(final String lexStr, final String datatypeIRI) {
+        return new JenaLiteralImpl(NodeFactory.createLiteral(lexStr, NodeFactory.getType(datatypeIRI)));
+    }
+
+    public JenaLiteral createLiteralLang(final String lexStr, final String langTag) {
+        return new JenaLiteralImpl(NodeFactory.createLiteral(lexStr, langTag));
+    }
+
+    public JenaQuad createQuad(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object, final BlankNodeOrIRI graphName) {
+        return new JenaQuadImpl(subject, predicate, object, Optional.ofNullable(graphName));
+    }
+
+    public JenaQuad createQuad(final org.apache.jena.sparql.core.Quad quad, final UUID salt) {
+        return new JenaQuadImpl(quad, salt);
+    }
+
+    public JenaRDFTerm createRDFTerm(final Node node, final UUID salt) throws ConversionException {
+        if (!node.isConcrete()) {
+            throw new ConversionException("Node is not a concrete RDF Term: " + node);
+        }
+        if (node.isURI()) {
+            return new JenaIRIImpl(node);
+        }
+        if (node.isLiteral()) {
+            return new JenaLiteralImpl(node);
+        }
+        if (node.isBlank()) {
+            return new JenaBlankNodeImpl(node, salt);
+        }
+        if (node.equals(Node.ANY)) {
+            // NOTE: JenaAny no longer supported by Commons RDF
+            // return JenaAnyImpl.Singleton.instance;
+        }
+        if (node.isVariable()) {
+            // NOTE: JenaVariable no longer supported by Commons RDF
+            // return new JenaVariableImpl(node);
+        }
+        throw new ConversionException("Unrecognized node type: " + node);
+    }
+    
+    public JenaTriple createTriple(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        return new JenaTripleImpl(subject, predicate, object);
+    }
+
+    public JenaTriple createTriple(final org.apache.jena.graph.Triple triple, final UUID salt) {
+        return new JenaTripleImpl(triple, salt);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaBlankNodeImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaBlankNodeImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaBlankNodeImpl.java
new file mode 100644
index 0000000..89ed5b6
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaBlankNodeImpl.java
@@ -0,0 +1,64 @@
+/**
+ * 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.BlankNode;
+import org.apache.commons.rdf.jena.JenaBlankNode;
+import org.apache.jena.graph.Node;
+
+class JenaBlankNodeImpl extends AbstractJenaRDFTerm implements JenaBlankNode {
+
+    private final UUID salt;
+
+    JenaBlankNodeImpl(final Node node, final UUID salt) {
+        super(node);
+        if (!node.isBlank()) {
+            throw new IllegalArgumentException("Node is not a blank node: " + node);
+        }
+        this.salt = salt;
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (other == null) {
+            return false;
+        }
+        if (!(other instanceof BlankNode)) {
+            return false;
+        }
+        final BlankNode bNode = (BlankNode) other;
+        return uniqueReference().equals(bNode.uniqueReference());
+    }
+
+    @Override
+    public int hashCode() {
+        return uniqueReference().hashCode();
+    }
+
+    @Override
+    public String uniqueReference() {
+        return salt + asJenaNode().getBlankNodeLabel();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaDatasetImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaDatasetImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaDatasetImpl.java
new file mode 100644
index 0000000..486903a
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaDatasetImpl.java
@@ -0,0 +1,186 @@
+/**
+ * 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 static org.apache.jena.graph.Node.ANY;
+
+import java.io.StringWriter;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+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.jena.JenaDataset;
+import org.apache.commons.rdf.jena.JenaGraph;
+import org.apache.commons.rdf.jena.JenaRDF;
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.Node;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.GraphView;
+
+class JenaDatasetImpl implements JenaDataset {
+
+    private final DatasetGraph graph;
+    private final UUID salt;
+    private final JenaRDF factory;
+
+    JenaDatasetImpl(final DatasetGraph graph, final UUID salt) {
+        this.graph = graph;
+        this.salt = salt;
+        this.factory = new JenaRDF(salt);
+    }
+
+    @Override
+    public void add(final BlankNodeOrIRI graphName, final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        graph.add(org.apache.jena.sparql.core.Quad.create(factory.asJenaNode(graphName), factory.asJenaNode(subject),
+                factory.asJenaNode(predicate), factory.asJenaNode(object)));
+    }
+
+    @Override
+    public void add(final Quad quad) {
+        graph.add(factory.asJenaQuad(quad));
+    }
+
+    @Override
+    public DatasetGraph asJenaDatasetGraph() {
+        return graph;
+    }
+
+    @Override
+    public void clear() {
+        graph.clear();
+    }
+
+    @Override
+    public void close() {
+        graph.close();
+    }
+
+    @Override
+    public boolean contains(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        return graph.contains(toJenaPattern(graphName), toJenaPattern(subject), toJenaPattern(predicate),
+                toJenaPattern(object));
+    }
+
+    private Node toJenaPattern(final Optional<? extends RDFTerm> graphName) {
+        // In theory we could have done:
+        // factory.toJena(graphName.orElse(internalJenaFactory::createAnyVariable))
+        // but because of generics casting rules that doesn't work :(
+
+        if (graphName == null) {
+            return ANY;
+        }
+        // null: default graph
+        return factory.asJenaNode(graphName.orElse(null));
+    }
+
+    private Node toJenaPattern(final RDFTerm term) {
+        if (term == null) {
+            return ANY;
+        }
+        return factory.asJenaNode(term);
+    }
+
+    @Override
+    public boolean contains(final Quad quad) {
+        return graph.contains(factory.asJenaQuad(quad));
+    }
+
+    @Override
+    public void remove(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        graph.deleteAny(toJenaPattern(graphName), toJenaPattern(subject),
+                toJenaPattern(predicate), toJenaPattern(object));
+    }
+
+    @Override
+    public void remove(final Quad quad) {
+        // COMMONSRDF-51: 
+        graph.deleteAny(
+                toJenaPattern(quad.getGraphName()),
+                toJenaPattern(quad.getSubject()),
+                toJenaPattern(quad.getPredicate()),
+                toJenaPattern(quad.getObject()));
+    }
+
+    @Override
+    public long size() {
+        final long quads = Iter.asStream(graph.listGraphNodes())
+                .map(graph::getGraph)
+                .collect(Collectors.summingLong(org.apache.jena.graph.Graph::size));
+        return quads + graph.getDefaultGraph().size();
+    }
+
+    @Override
+    public Stream<? extends Quad> stream() {
+        final JenaRDF factory = new JenaRDF(salt);
+        return Iter.asStream(graph.find(ANY, ANY, ANY, ANY), true).map(factory::asQuad);
+    }
+
+    @Override
+    public Stream<? extends Quad> stream(final Optional<BlankNodeOrIRI> g, final BlankNodeOrIRI s, final IRI p, final RDFTerm o) {
+        final JenaRDF factory = new JenaRDF(salt);
+        return Iter.asStream(graph.find(toJenaPattern(g), toJenaPattern(s), toJenaPattern(p), toJenaPattern(o)), true)
+                .map(factory::asQuad);
+    }
+
+    @Override
+    public String toString() {
+        final StringWriter sw = new StringWriter();
+        RDFDataMgr.write(sw, graph, Lang.NT);
+        return sw.toString();
+    }
+
+    @Override
+    public Graph getGraph() {
+        final GraphView g = GraphView.createDefaultGraph(graph);
+        return new JenaGraphImpl(g, salt);
+    }
+
+    @Override
+    public JenaGraph getUnionGraph() {
+        final GraphView gv = GraphView.createUnionGraph(graph);
+        return new JenaGraphImpl(gv, salt);
+    }
+
+    @Override
+    public Optional<Graph> getGraph(final BlankNodeOrIRI graphName) {
+        final GraphView gv = GraphView.createNamedGraph(graph, factory.asJenaNode(graphName));
+        return Optional.of(new JenaGraphImpl(gv, salt));
+    }
+
+    @Override
+    public Stream<BlankNodeOrIRI> getGraphNames() {
+        final JenaRDF factory = new JenaRDF(salt);
+        return Iter.asStream(graph.listGraphNodes()).map(node -> (BlankNodeOrIRI) factory.asRDFTerm(node));
+    }
+
+    @Override
+    public Iterable<Quad> iterate() {
+        final JenaRDF factory = new JenaRDF(salt);
+        return Iter.asStream(graph.find(), false).map(q -> (Quad) factory.asQuad(q))::iterator;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedQuadLikeImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedQuadLikeImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedQuadLikeImpl.java
new file mode 100644
index 0000000..cff48f3
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedQuadLikeImpl.java
@@ -0,0 +1,38 @@
+/**
+ * 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.Optional;
+import java.util.UUID;
+
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.commons.rdf.jena.JenaGeneralizedQuadLike;
+import org.apache.jena.sparql.core.Quad;
+
+class JenaGeneralizedQuadLikeImpl extends AbstractQuadLike<RDFTerm, RDFTerm, RDFTerm, RDFTerm>
+        implements JenaGeneralizedQuadLike {
+
+    JenaGeneralizedQuadLikeImpl(final RDFTerm subject, final RDFTerm predicate, final RDFTerm object, final Optional<RDFTerm> ofNullable) {
+        super(subject, predicate, object, ofNullable);
+    }
+
+    JenaGeneralizedQuadLikeImpl(final Quad quad, final UUID salt) {
+        super(quad, salt);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedTripleLikeImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedTripleLikeImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedTripleLikeImpl.java
new file mode 100644
index 0000000..374717d
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGeneralizedTripleLikeImpl.java
@@ -0,0 +1,37 @@
+/**
+ * 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.JenaGeneralizedTripleLike;
+import org.apache.jena.graph.Triple;
+
+class JenaGeneralizedTripleLikeImpl extends AbstractQuadLike<RDFTerm, RDFTerm, RDFTerm, RDFTerm>
+        implements JenaGeneralizedTripleLike {
+
+    JenaGeneralizedTripleLikeImpl(final RDFTerm subject, final RDFTerm predicate, final RDFTerm object) {
+        super(subject, predicate, object);
+    }
+
+    JenaGeneralizedTripleLikeImpl(final Triple triple, final UUID salt) {
+        super(triple, salt);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGraphImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGraphImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGraphImpl.java
new file mode 100644
index 0000000..55256e2
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaGraphImpl.java
@@ -0,0 +1,170 @@
+/**
+ * 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.io.StringWriter;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.Literal;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.commons.rdf.api.Triple;
+import org.apache.commons.rdf.jena.JenaGraph;
+import org.apache.commons.rdf.jena.JenaRDF;
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.Node;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+
+class JenaGraphImpl implements JenaGraph {
+
+    private final org.apache.jena.graph.Graph graph;
+    private final UUID salt;
+    private final transient JenaRDF factory;
+    private Model model;
+
+    JenaGraphImpl(final org.apache.jena.graph.Graph graph, final UUID salt) {
+        this.graph = graph;
+        this.salt = salt;
+        this.factory = new JenaRDF(salt);
+    }
+
+    JenaGraphImpl(final Model model, final UUID salt) {
+        this.model = model;
+        this.graph = model.getGraph();
+        this.salt = salt;
+        this.factory = new JenaRDF(salt);
+    }
+
+    @Override
+    public void add(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        graph.add(org.apache.jena.graph.Triple.create(factory.asJenaNode(subject), factory.asJenaNode(predicate),
+                factory.asJenaNode(object)));
+    }
+
+    @Override
+    public void add(final Triple triple) {
+        graph.add(factory.asJenaTriple(triple));
+    }
+
+    @Override
+    public org.apache.jena.graph.Graph asJenaGraph() {
+        return graph;
+    }
+
+    @Override
+    public void clear() {
+        graph.clear();
+    }
+
+    @Override
+    public void close() {
+        graph.close();
+    }
+
+    @Override
+    public boolean contains(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        return graph.contains(toJenaPattern(subject), toJenaPattern(predicate), toJenaPattern(object));
+    }
+
+    @Override
+    public boolean contains(final Triple triple) {
+        return graph.contains(factory.asJenaTriple(triple));
+    }
+
+    @Override
+    public void remove(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        graph.remove(toJenaPattern(subject), toJenaPattern(predicate),
+                toJenaPattern(object));
+    }
+
+    private Node toJenaPattern(final RDFTerm pattern) {
+        if (pattern == null) { 
+            return Node.ANY;
+        }
+        return factory.asJenaNode(pattern);
+    }
+
+    @Override
+    public void remove(final Triple triple) {
+        if ((triple.getObject() instanceof Literal) && 
+                ((Literal) triple.getObject()).getLanguageTag().isPresent()) {
+            // COMMONSRDF-51: graph.delete(Triple) would be too restrictive
+            // as it won't delete triples with different lang tag - so 
+            // we'll need to use the pattern matching graph.remove instead()
+            graph.remove(
+                    factory.asJenaNode(triple.getSubject()), 
+                    factory.asJenaNode(triple.getPredicate()),
+                    factory.asJenaNode(triple.getObject()));
+        } else {
+            graph.delete(factory.asJenaTriple(triple));
+        }
+    }
+
+    @Override
+    public long size() {
+        return graph.size();
+    }
+
+    @Override
+    public Stream<? extends Triple> stream() {
+        final JenaRDF factory = new JenaRDF(salt);
+        return Iter.asStream(graph.find(null, null, null), true).map(factory::asTriple);
+    }
+
+    @Override
+    public Stream<? extends Triple> stream(final BlankNodeOrIRI s, final IRI p, final RDFTerm o) {
+        final JenaRDF factory = new JenaRDF(salt);
+        return Iter.asStream(graph.find(toJenaAny(s), toJenaAny(p), toJenaAny(o)), true).map(factory::asTriple);
+    }
+
+    private Node toJenaAny(final RDFTerm term) {
+        if (term == null) {
+            return Node.ANY;
+        }
+        return factory.asJenaNode(term);
+    }
+
+    @Override
+    public String toString() {
+        final StringWriter sw = new StringWriter();
+        RDFDataMgr.write(sw, graph, Lang.NT);
+        return sw.toString();
+    }
+
+    @Override
+    public Model asJenaModel() {
+        if (model == null) {
+            synchronized (this) {
+                // As Model can be used for locks, we should make sure we don't
+                // make
+                // more than one model
+                if (model == null) {
+                    model = ModelFactory.createModelForGraph(graph);
+                }
+            }
+        }
+        return model;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaIRIImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaIRIImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaIRIImpl.java
new file mode 100644
index 0000000..3ae449e
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaIRIImpl.java
@@ -0,0 +1,64 @@
+/**
+ * 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 org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.jena.JenaIRI;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+
+class JenaIRIImpl extends AbstractJenaRDFTerm implements JenaIRI {
+
+    JenaIRIImpl(final Node node) {
+        super(node);
+        if (!node.isURI()) {
+            throw new IllegalArgumentException("Node is not an IRI node: " + node);
+        }
+
+    }
+
+    JenaIRIImpl(final String iriStr) {
+        super(NodeFactory.createURI(iriStr));
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (other == null) {
+            return false;
+        }
+        if (!(other instanceof IRI)) {
+            return false;
+        }
+        final IRI iri = (IRI) other;
+        return getIRIString().equals(iri.getIRIString());
+    }
+
+    @Override
+    public String getIRIString() {
+        return asJenaNode().getURI();
+    }
+
+    @Override
+    public int hashCode() {
+        return getIRIString().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaLiteralImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaLiteralImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaLiteralImpl.java
new file mode 100644
index 0000000..8a0c9ee
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaLiteralImpl.java
@@ -0,0 +1,87 @@
+/**
+ * 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.Locale;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.Literal;
+import org.apache.commons.rdf.jena.JenaLiteral;
+import org.apache.jena.graph.Node;
+
+class JenaLiteralImpl extends AbstractJenaRDFTerm implements JenaLiteral {
+
+    private static InternalJenaFactory internalJenaFactory = new InternalJenaFactory() {
+    };
+
+    JenaLiteralImpl(final Node node) {
+        super(node);
+        if (!node.isLiteral()) {
+            throw new IllegalArgumentException("Node is not a literal: " + node);
+        }
+    }
+    
+    private static String lowerCase(String langTag) { 
+        return langTag.toLowerCase(Locale.ROOT);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (other == null) {
+            return false;
+        }
+        if (!(other instanceof Literal)) {
+            return false;
+        }
+        final Literal literal = (Literal) other;
+        return getLexicalForm().equals(literal.getLexicalForm()) &&
+                getDatatype().equals(literal.getDatatype()) &&
+                getLanguageTag().map(JenaLiteralImpl::lowerCase).equals(
+                        literal.getLanguageTag().map(JenaLiteralImpl::lowerCase));
+    }
+
+    @Override
+    public IRI getDatatype() {
+        return internalJenaFactory.createIRI(asJenaNode().getLiteralDatatype().getURI());
+    }
+
+    @Override
+    public Optional<String> getLanguageTag() {
+        final String x = asJenaNode().getLiteralLanguage();
+        if (x == null || x.isEmpty()) {
+            return Optional.empty();
+        }
+        return Optional.of(x);
+    }
+
+    @Override
+    public String getLexicalForm() {
+        return asJenaNode().getLiteralLexicalForm();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getLexicalForm(), getDatatype(), getLanguageTag().map(JenaLiteralImpl::lowerCase));
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaQuadImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaQuadImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaQuadImpl.java
new file mode 100644
index 0000000..4bdbf77
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaQuadImpl.java
@@ -0,0 +1,66 @@
+/**
+ * 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.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.jena.ConversionException;
+import org.apache.commons.rdf.jena.JenaQuad;
+
+class JenaQuadImpl extends AbstractQuadLike<BlankNodeOrIRI, IRI, RDFTerm, BlankNodeOrIRI> implements JenaQuad {
+
+    JenaQuadImpl(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object, final Optional<BlankNodeOrIRI> graphName) {
+        super(subject, predicate, object, graphName);
+    }
+
+    JenaQuadImpl(final org.apache.jena.sparql.core.Quad quad, final 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);
+        }
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (!(other instanceof Quad)) {
+            return false;
+        }
+        final Quad quad = (Quad) other;
+        return getGraphName().equals(quad.getGraphName()) && getSubject().equals(quad.getSubject())
+                && getPredicate().equals(quad.getPredicate()) && getObject().equals(quad.getObject());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getSubject(), getPredicate(), getObject(), getGraphName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaTripleImpl.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaTripleImpl.java b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaTripleImpl.java
new file mode 100644
index 0000000..cc268d5
--- /dev/null
+++ b/commons-rdf-jena/src/main/java/org/apache/commons/rdf/jena/impl/JenaTripleImpl.java
@@ -0,0 +1,66 @@
+/**
+ * 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.UUID;
+
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.IRI;
+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;
+
+class JenaTripleImpl extends AbstractQuadLike<BlankNodeOrIRI, IRI, RDFTerm, RDFTerm> implements JenaTriple {
+
+    JenaTripleImpl(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        super(subject, predicate, object);
+    }
+
+    JenaTripleImpl(final org.apache.jena.graph.Triple triple, final 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);
+        }
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (other == null) {
+            return false;
+        }
+        if (!(other instanceof Triple)) {
+            return false;
+        }
+        final Triple triple = (Triple) other;
+        return getSubject().equals(triple.getSubject()) && getPredicate().equals(triple.getPredicate())
+                && getObject().equals(triple.getObject());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getSubject(), getPredicate(), getObject());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/main/resources/META-INF/services/org.apache.commons.rdf.api.RDF
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/main/resources/META-INF/services/org.apache.commons.rdf.api.RDF b/commons-rdf-jena/src/main/resources/META-INF/services/org.apache.commons.rdf.api.RDF
new file mode 100644
index 0000000..afe6af3
--- /dev/null
+++ b/commons-rdf-jena/src/main/resources/META-INF/services/org.apache.commons.rdf.api.RDF
@@ -0,0 +1 @@
+org.apache.commons.rdf.jena.JenaRDF

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/site/resources/profile.jacoco
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/site/resources/profile.jacoco b/commons-rdf-jena/src/site/resources/profile.jacoco
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DatasetJenaTest.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DatasetJenaTest.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DatasetJenaTest.java
new file mode 100644
index 0000000..b07c36f
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DatasetJenaTest.java
@@ -0,0 +1,31 @@
+/**
+ * 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.AbstractDatasetTest;
+import org.apache.commons.rdf.api.RDF;
+
+public class DatasetJenaTest extends AbstractDatasetTest {
+
+    @Override
+    public RDF createFactory() {
+        return new JenaRDF();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DefaultGraphInQuadTest.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DefaultGraphInQuadTest.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DefaultGraphInQuadTest.java
new file mode 100644
index 0000000..1665d25
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/DefaultGraphInQuadTest.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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.simple.SimpleRDF;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.sparql.core.Quad;
+import org.junit.Test;
+
+/**
+ * COMMONSRDF-55: Handling of 
+ * Jena's default graph IRI urn:x-arq:DefaultGraph
+ */
+public class DefaultGraphInQuadTest {
+    
+    JenaRDF rdf = new JenaRDF();
+    SimpleRDF simpleRDF = new SimpleRDF();
+    IRI example = rdf.createIRI("http://example.com/");
+    Node exampleJena = NodeFactory.createURI("http://example.com/");
+    
+    @Test
+    public void createFromNull() throws Exception {        
+        JenaQuad q = rdf.createQuad(null, example, example, example);
+        assertFalse(q.getGraphName().isPresent());
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+        assertEquals(Quad.defaultGraphIRI,  q.asJenaQuad().getGraph());
+    }
+
+    @Test
+    public void createFromDefaultGraphIRI() throws Exception {
+        JenaIRI defaultGraph = (JenaIRI) rdf.asRDFTerm(Quad.defaultGraphIRI);        
+        JenaQuad q = rdf.createQuad(defaultGraph, example, example, example);
+        // NOTE: JenaRDF specially recognize this JenaIRI constant, 
+        // even if this breaks the SHOULD of RDF.createQuad()
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+        assertEquals(Quad.defaultGraphIRI,  q.asJenaQuad().getGraph());
+        assertFalse(q.getGraphName().isPresent());
+        // thus we can't require 
+        //assertEquals(defaultGraph, q.getGraphName().get());
+    }
+
+    @Test
+    public void createFromForeignDefaultGraph() throws Exception {
+        // What if <urn:x-arq:DefaultGraph> appear in a non-Jena IRI?
+        IRI foreignDefaultGraph = simpleRDF.createIRI(Quad.defaultGraphIRI.getURI());
+        JenaQuad q = rdf.createQuad(foreignDefaultGraph, example, example, example);
+        // As the IRI was NOT a JenaIRI we preserve it as-is,
+        // rather than replacing it with Optional.empty()        
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+        assertTrue(q.getGraphName().isPresent()); // INCONSISTENT with above
+        assertEquals(Quad.defaultGraphIRI,  q.asJenaQuad().getGraph());
+        assertEquals(foreignDefaultGraph, q.getGraphName().get());
+        // Note that adding such a quad to a Dataset would still "convert" it to
+        // Optional.empty() 
+    }
+    
+
+    @Test
+    public void createFromDefaultGraphNodeGeneratedIRINode() throws Exception {
+        // What if <urn:x-arq:DefaultGraphNode> appear as an IRI instance?
+        IRI foreignDefaultGraph = rdf.createIRI(Quad.defaultGraphNodeGenerated.getURI());
+        JenaQuad q = rdf.createQuad(foreignDefaultGraph, example, example, example);
+        // NOTE: JenaRDF specially recognize this JenaIRI constant, 
+        // even if this breaks the SHOULD of RDF.createQuad()
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+        assertFalse(q.getGraphName().isPresent()); // CONSISTENT with above 
+        // Unfortunately Quad.defaultGraphNodeGenerated is not preserved:
+        //assertEquals(Quad.defaultGraphNodeGenerated, q.asJenaQuad().getGraph());
+    }
+
+    @Test
+    public void createFromDefaultGraphNodeGeneratedIRIString() throws Exception {
+        // What if <urn:x-arq:DefaultGraphNode> appear in a non-Jena IRI?
+        IRI foreignDefaultGraph = (IRI) simpleRDF.createIRI(Quad.defaultGraphNodeGenerated.getURI());
+        JenaQuad q = rdf.createQuad(foreignDefaultGraph, example, example, example);
+        // We'll expect JenaRDF to preserve the graph IRI as-is        
+        assertTrue(q.asJenaQuad().isDefaultGraph()); 
+        assertTrue(q.getGraphName().isPresent()); // INCONSISTENT WITH above
+        // Now Quad.defaultGraphNodeGenerated is preserved at both ends
+        assertEquals(Quad.defaultGraphNodeGenerated,  q.asJenaQuad().getGraph());
+        assertEquals(foreignDefaultGraph, q.getGraphName().get());
+    }
+
+    
+    @Test
+    public void defaultGraphIRI() throws Exception {
+        Quad jenaQuad = Quad.create(Quad.defaultGraphIRI, exampleJena, exampleJena, exampleJena);
+        JenaQuad q = rdf.asQuad(jenaQuad);        
+        assertFalse(q.getGraphName().isPresent());
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+    }
+
+    @Test
+    public void defaultGraphNodeGenerated() throws Exception {        
+        // <urn:x-arq:DefaultGraphNode> might appear in parser output
+        Quad jenaQuad = Quad.create(Quad.defaultGraphNodeGenerated, exampleJena, exampleJena, exampleJena);
+        JenaQuad q = rdf.asQuad(jenaQuad);        
+        assertFalse(q.getGraphName().isPresent());
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+        // Preserves <urn:x-arq:DefaultGraphNode>
+        assertEquals(Quad.defaultGraphNodeGenerated, q.asJenaQuad().getGraph());
+    }
+
+    @Test
+    public void unionGraph() throws Exception {
+        // unionGraph shouldn't really appear as a quad except
+        // in a pattern
+        Quad jenaQuad = Quad.create(Quad.unionGraph, exampleJena, exampleJena, exampleJena);
+        JenaQuad q = rdf.asQuad(jenaQuad);
+        // But at least we can agree it is NOT (necessarily) in the
+        // default graph
+        assertFalse(q.asJenaQuad().isDefaultGraph());
+        assertTrue(q.getGraphName().isPresent());
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFQuadTest.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFQuadTest.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFQuadTest.java
new file mode 100644
index 0000000..aa81cf5
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFQuadTest.java
@@ -0,0 +1,127 @@
+/**
+ * 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 static org.junit.Assert.*;
+
+import org.apache.commons.rdf.api.BlankNode;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.sparql.core.Quad;
+import org.junit.Test;
+
+public class GeneralizedRDFQuadTest {
+
+    private JenaRDF jena = new JenaRDF();
+    
+    @Test
+    public void bnodeProperty() throws Exception {
+        BlankNode b1 = jena.createBlankNode("b1");
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        JenaIRI ex3 = jena.createIRI("http://example.com/ex3");
+        
+        JenaGeneralizedQuadLike q = jena.createGeneralizedQuad(ex1, b1, ex2, ex3);
+        assertEquals(ex1, q.getSubject());
+        assertEquals(ex2, q.getObject());
+        assertEquals(b1, q.getPredicate()); // it's a bnode!
+        assertEquals(ex3, q.getGraphName().get());
+        assertTrue(q.asJenaQuad().getPredicate().isBlank());
+    }
+
+    @Test
+    public void literalPredicate() throws Exception {
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        JenaIRI ex3 = jena.createIRI("http://example.com/ex3");
+        JenaLiteral lit = jena.createLiteral("Hello");
+        
+        JenaGeneralizedQuadLike q = jena.createGeneralizedQuad(ex1, lit, ex2, ex3);
+        assertEquals(ex1, q.getSubject());
+        assertEquals(ex2, q.getObject());
+        assertEquals(lit, q.getPredicate()); // it's a literal!
+        assertEquals(ex3, q.getGraphName().get());
+        assertTrue(q.asJenaQuad().getPredicate().isLiteral());
+    }
+
+
+    @Test
+    public void literalSubject() throws Exception {
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        JenaIRI ex3 = jena.createIRI("http://example.com/ex3");
+        JenaLiteral lit = jena.createLiteral("Hello");
+        
+        JenaGeneralizedQuadLike q = jena.createGeneralizedQuad(lit, ex1, ex2, ex3);
+        assertEquals(lit, q.getSubject()); // it's a literal!
+        assertEquals(ex1, q.getPredicate());
+        assertEquals(ex2, q.getObject());
+        assertEquals(ex3, q.getGraphName().get());
+        assertTrue(q.asJenaQuad().getSubject().isLiteral());
+    }
+    
+    @Test
+    public void literalSubjectDefaultGraphGen() throws Exception {
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        // No need to cast to JenaIRI
+        JenaRDFTerm defG = jena.asRDFTerm(Quad.defaultGraphNodeGenerated); 
+        JenaLiteral lit = jena.createLiteral("Hello");
+        
+        JenaGeneralizedQuadLike q = jena.createGeneralizedQuad(lit, ex1, ex2, defG);
+        assertEquals(lit, q.getSubject()); // it's a literal!
+        assertEquals(ex1, q.getPredicate());
+        assertEquals(ex2, q.getObject());
+        assertTrue(q.asJenaQuad().getSubject().isLiteral());
+        assertFalse(q.getGraphName().isPresent());
+        assertTrue(q.asJenaQuad().isDefaultGraph());
+    }
+
+    @Test
+    public void asGeneralizedQuad() throws Exception {
+        Node s = NodeFactory.createLiteral("Hello");
+        Node p = NodeFactory.createBlankNode();
+        Node o = NodeFactory.createURI("http://example.com/ex");
+        Node g = Quad.defaultGraphIRI;
+        Quad jq = Quad.create(g, s, p, o);
+        JenaQuadLike<RDFTerm> q = jena.asGeneralizedQuad(jq);
+        assertEquals(jena.createLiteral("Hello"), q.getSubject());
+        assertEquals(jena.asRDFTerm(p), q.getPredicate());
+        assertEquals(jena.createIRI("http://example.com/ex"), q.getObject());
+        assertFalse(q.getGraphName().isPresent());
+    }
+    
+    @Test
+    public void literalGraph() throws Exception {
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        JenaIRI ex3 = jena.createIRI("http://example.com/ex3");
+        JenaLiteral lit = jena.createLiteral("Hello");
+        
+        JenaGeneralizedQuadLike q = jena.createGeneralizedQuad(ex1, ex2, ex3, lit);
+        assertEquals(ex1, q.getSubject()); 
+        assertEquals(ex2, q.getPredicate());
+        assertEquals(ex3, q.getObject());
+        assertEquals(lit, q.getGraphName().get()); // it's a literal!
+        assertTrue(q.asJenaQuad().getGraph().isLiteral());
+    }
+    
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFTripleTest.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFTripleTest.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFTripleTest.java
new file mode 100644
index 0000000..97abbe5
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/GeneralizedRDFTripleTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.rdf.api.BlankNode;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.junit.Test;
+
+public class GeneralizedRDFTripleTest {
+
+    private JenaRDF jena = new JenaRDF();
+    
+    @Test
+    public void bnodeProperty() throws Exception {
+        BlankNode b1 = jena.createBlankNode("b1");
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        
+        JenaGeneralizedTripleLike t = jena.createGeneralizedTriple(ex1, b1, ex2);
+        assertEquals(ex1, t.getSubject());
+        assertEquals(ex2, t.getObject());
+        assertEquals(b1, t.getPredicate()); // it's a bnode!
+        assertTrue(t.asJenaTriple().getPredicate().isBlank());
+    }
+
+    @Test
+    public void literalPredicate() throws Exception {
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        JenaLiteral lit = jena.createLiteral("Hello");
+        
+        JenaGeneralizedTripleLike t = jena.createGeneralizedTriple(ex1, lit, ex2);
+        assertEquals(ex1, t.getSubject());
+        assertEquals(ex2, t.getObject());
+        assertEquals(lit, t.getPredicate()); // it's a literal!
+        assertTrue(t.asJenaTriple().getPredicate().isLiteral());
+    }
+
+
+    @Test
+    public void literalSubject() throws Exception {
+        JenaIRI ex1 = jena.createIRI("http://example.com/ex1");
+        JenaIRI ex2 = jena.createIRI("http://example.com/ex2");
+        JenaLiteral lit = jena.createLiteral("Hello");
+        
+        JenaGeneralizedTripleLike t = jena.createGeneralizedTriple(lit, ex1, ex2);
+        assertEquals(lit, t.getSubject()); // it's a literal!
+        assertEquals(ex1, t.getPredicate());
+        assertEquals(ex2, t.getObject());
+        assertTrue(t.asJenaTriple().getSubject().isLiteral());
+    }
+    
+    @Test
+    public void asGeneralizedTriple() throws Exception {
+        Node s = NodeFactory.createLiteral("Hello");
+        Node p = NodeFactory.createBlankNode();
+        Node o = NodeFactory.createURI("http://example.com/ex");
+        Triple jt = Triple.create(s, p, o);
+        JenaTripleLike t = jena.asGeneralizedTriple(jt);
+        assertEquals(jena.createLiteral("Hello"), t.getSubject());
+        assertEquals(jena.asRDFTerm(p), t.getPredicate());
+        assertEquals(jena.createIRI("http://example.com/ex"), t.getObject());
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaRDFTest.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaRDFTest.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaRDFTest.java
new file mode 100644
index 0000000..fd50421
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaRDFTest.java
@@ -0,0 +1,30 @@
+/**
+ * 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.AbstractRDFTest;
+import org.apache.commons.rdf.api.RDF;
+
+public class JenaRDFTest extends AbstractRDFTest {
+
+    @Override
+    public RDF createFactory() {
+        return new JenaRDF();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaServiceLoaderTest.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaServiceLoaderTest.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaServiceLoaderTest.java
new file mode 100644
index 0000000..ed99876
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/JenaServiceLoaderTest.java
@@ -0,0 +1,40 @@
+/**
+ * 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 static org.junit.Assert.fail;
+
+import java.util.ServiceLoader;
+
+import org.apache.commons.rdf.api.RDF;
+import org.junit.Test;
+
+public class JenaServiceLoaderTest {
+
+    @Test
+    public void testServiceLoaderLookup() {
+        final ServiceLoader<RDF> loader = ServiceLoader.load(RDF.class);
+        for (final RDF impl : loader) {
+            if (impl instanceof JenaRDF) {
+                return; // yay
+            }
+        }
+        fail("JenaRDF not found in ServiceLoader");
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestBlankNodeJena.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestBlankNodeJena.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestBlankNodeJena.java
new file mode 100644
index 0000000..d797015
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestBlankNodeJena.java
@@ -0,0 +1,46 @@
+/**
+ * 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 java.util.UUID;
+
+import org.apache.commons.rdf.api.AbstractBlankNodeTest;
+import org.apache.commons.rdf.api.BlankNode;
+import org.apache.commons.rdf.jena.impl.InternalJenaFactory;
+
+public class TestBlankNodeJena extends AbstractBlankNodeTest {
+
+    InternalJenaFactory internalJenaFactory = new InternalJenaFactory() {
+    };
+
+    /**
+     * Fixed salt for the purpose of this test.
+     */
+    private static final UUID SALT = UUID.fromString("ccfde817-55b8-4a5f-bc2d-6bfd8eaa41ce");
+
+    @Override
+    protected BlankNode getBlankNode() {
+        return internalJenaFactory.createBlankNode(SALT);
+    }
+
+    @Override
+    protected BlankNode getBlankNode(final String identifier) {
+        return internalJenaFactory.createBlankNode(identifier, SALT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestGraphJena.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestGraphJena.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestGraphJena.java
new file mode 100644
index 0000000..1ab01f9
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestGraphJena.java
@@ -0,0 +1,31 @@
+/**
+ * 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.AbstractGraphTest;
+import org.apache.commons.rdf.api.RDF;
+
+public class TestGraphJena extends AbstractGraphTest {
+
+    @Override
+    public RDF createFactory() {
+        return new JenaRDF();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestJenaGraphToCommonsRDFGraph.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestJenaGraphToCommonsRDFGraph.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestJenaGraphToCommonsRDFGraph.java
new file mode 100644
index 0000000..00e01e0
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestJenaGraphToCommonsRDFGraph.java
@@ -0,0 +1,123 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+
+import org.apache.commons.rdf.api.BlankNode;
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.commons.rdf.api.Triple;
+import org.apache.commons.rdf.simple.Types;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.sparql.graph.GraphFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/** Adapt a Jena Graph after parsing data into it */
+public class TestJenaGraphToCommonsRDFGraph {
+    private static final boolean DEBUG = false;
+    private Path turtleFile;
+
+    @Before
+    public void preparePath() throws IOException {
+        turtleFile = Files.createTempFile("commonsrdf", "test.ttl");
+        Files.copy(getClass().getResourceAsStream("/D.ttl"), turtleFile, StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    @After
+    public void deletePath() throws IOException {
+        if (turtleFile != null) {
+            Files.deleteIfExists(turtleFile);
+        }
+    }
+
+    @Test
+    public void jenaToCommonsRDF() throws Exception {
+        final org.apache.jena.graph.Graph jGraph = GraphFactory.createGraphMem();
+        RDFDataMgr.read(jGraph, turtleFile.toUri().toString());
+
+        final JenaRDF factory = new JenaRDF();
+
+        // "graph" is a CommonsRDF graph
+        final Graph graph = factory.asGraph(jGraph);
+
+        // The below check expected statements from D.ttl
+
+        final JenaIRI p = factory.createIRI("http://example.com/p");
+        final JenaIRI s = factory.createIRI("http://example.com/s");
+        final JenaLiteral literal123 = factory.createLiteral("123", Types.XSD_INTEGER);
+        assertTrue(graph.contains(s, p, literal123));
+
+        final JenaIRI p1 = factory.createIRI("http://example.com/p1");
+        // Let's look up the BlankNode
+        final BlankNodeOrIRI bnode1 = graph.stream(null, p1, null).findFirst().map(Triple::getSubject).get();
+        assertTrue(bnode1 instanceof BlankNode);
+
+        // Verify we can use BlankNode in query again
+        final RDFTerm obj = graph.stream(bnode1, p1, null).findFirst().map(Triple::getObject).get();
+
+        // Let's look up also that nested blank node
+        assertTrue(obj instanceof BlankNode);
+        final BlankNode bnode2 = (BlankNode) obj;
+
+        final JenaIRI q = factory.createIRI("http://example.com/q");
+        final JenaLiteral literalR = factory.createLiteral("r", "en");
+        assertTrue(graph.contains(bnode2, q, literalR));
+
+        // Can we add the same triple again as s/p/o
+        // without affecting graph size?
+        // Just to be evil we add a blanknode-iri-blanknode statement
+        assertEquals(3, graph.size());
+        graph.add(bnode1, p1, bnode2);
+        assertEquals(3, graph.size());
+
+        // Add the same Triple again
+        graph.stream(bnode2, null, null).findFirst().ifPresent(graph::add);
+        assertEquals(3, graph.size());
+
+        // Add to CommonsRDF Graph
+        final JenaIRI s2 = factory.createIRI("http://example/s2");
+        final JenaIRI p2 = factory.createIRI("http://example/p2");
+        final JenaLiteral foo = factory.createLiteral("foo");
+        graph.add(s2, p2, foo);
+        assertEquals(4, graph.size());
+        assertTrue(graph.contains(s2, p2, foo));
+
+        // Verify the corresponding Jena Nodes are in Jena graph
+        assertTrue(jGraph.contains(s2.asJenaNode(), p2.asJenaNode(), foo.asJenaNode()));
+
+        if (DEBUG) {
+            System.out.println("==== Write CommonsRDF graph\n");
+            graph.stream().forEach(System.out::println);
+            // And its in the Jena graph
+            System.out.println("\n==== Write Jena graph directly\n");
+            RDFDataMgr.write(System.out, jGraph, Lang.TTL);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestRDFParserBuilder.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestRDFParserBuilder.java b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestRDFParserBuilder.java
new file mode 100644
index 0000000..c1bf41e
--- /dev/null
+++ b/commons-rdf-jena/src/test/java/org/apache/commons/rdf/jena/TestRDFParserBuilder.java
@@ -0,0 +1,63 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.experimental.RDFParser.ParseResult;
+import org.apache.commons.rdf.jena.experimental.JenaRDFParser;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestRDFParserBuilder {
+
+    private Path turtleFile;
+
+    @Before
+    public void preparePath() throws IOException {
+        turtleFile = Files.createTempFile("commonsrdf", "test.ttl");
+        Files.copy(getClass().getResourceAsStream("/D.ttl"), turtleFile, StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    @After
+    public void deletePath() throws IOException {
+        if (turtleFile != null) {
+            Files.deleteIfExists(turtleFile);
+        }
+    }
+
+    @Test
+    public void parseTurtle() throws Exception {
+        final Graph g = new JenaRDF().createGraph();
+        final Future<ParseResult> gFuture = new JenaRDFParser().contentType(RDFSyntax.TURTLE).source(turtleFile).target(g)
+                .parse();
+        gFuture.get(5, TimeUnit.SECONDS);
+        assertEquals(3, g.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jena/src/test/resources/D.ttl
----------------------------------------------------------------------
diff --git a/commons-rdf-jena/src/test/resources/D.ttl b/commons-rdf-jena/src/test/resources/D.ttl
new file mode 100644
index 0000000..b713bf9
--- /dev/null
+++ b/commons-rdf-jena/src/test/resources/D.ttl
@@ -0,0 +1,20 @@
+# 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.
+
+prefix : <http://example.com/>
+
+:s :p 123 .
+[ :p1 [ :q "r"@en ] ] .

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jsonld-java/pom.xml
----------------------------------------------------------------------
diff --git a/commons-rdf-jsonld-java/pom.xml b/commons-rdf-jsonld-java/pom.xml
new file mode 100644
index 0000000..5dac9d4
--- /dev/null
+++ b/commons-rdf-jsonld-java/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-rdf-parent</artifactId>
+        <version>0.5.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>commons-rdf-jsonld-java</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Commons RDF impl: JSON-LD Java</name>
+    <description>Parser integration of JSON-LD Java</description>
+
+    <distributionManagement>
+      <site>
+        <id>commonsrdf-api-site</id>
+        <url>scm:svn:${commons.scmPubUrl}/jsonld-java/</url>
+      </site>
+    </distributionManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.parent.groupId}</groupId>
+            <artifactId>commons-rdf-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.parent.groupId}</groupId>
+            <artifactId>commons-rdf-api</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.parent.groupId}</groupId>
+            <artifactId>commons-rdf-simple</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+		    <groupId>com.github.jsonld-java</groupId>
+		    <artifactId>jsonld-java</artifactId>
+		    <version>${jsonldjava.version}</version>
+		</dependency>
+        
+    </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>org.apache.commons.rdf.jsonldjava</Bundle-SymbolicName>
+            <Automatic-Module-Name>org.apache.commons.rdf.jsonldjava</Automatic-Module-Name>
+            <Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional</Require-Capability>
+            <Provide-Capability>osgi.serviceloader; osgi.serviceloader=org.apache.commons.rdf.api.RDF</Provide-Capability>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdBlankNode.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdBlankNode.java b/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdBlankNode.java
new file mode 100644
index 0000000..c508e6b
--- /dev/null
+++ b/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdBlankNode.java
@@ -0,0 +1,67 @@
+/**
+ * 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.jsonldjava;
+
+import org.apache.commons.rdf.api.BlankNode;
+
+import com.github.jsonldjava.core.RDFDataset.Node;
+
+public interface JsonLdBlankNode extends JsonLdTerm, BlankNode {
+}
+
+final class JsonLdBlankNodeImpl extends JsonLdTermImpl implements JsonLdBlankNode {
+    private final String blankNodePrefix;
+
+    JsonLdBlankNodeImpl(final Node node, final String blankNodePrefix) {
+        super(node);
+        this.blankNodePrefix = blankNodePrefix;
+        if (!node.isBlankNode()) {
+            throw new IllegalArgumentException("Node is not a BlankNode:" + node);
+        }
+    }
+
+    @Override
+    public String ntriplesString() {
+        // TODO: Escape if this is not valid ntriples string (e.g. contains :)
+        return node.getValue();
+    }
+
+    @Override
+    public String uniqueReference() {
+        return blankNodePrefix + node.getValue();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (!(obj instanceof BlankNode)) {
+            return false;
+        }
+        final BlankNode other = (BlankNode) obj;
+        return uniqueReference().equals(other.uniqueReference());
+    }
+
+    @Override
+    public int hashCode() {
+        return uniqueReference().hashCode();
+    }
+    
+    @Override
+    public String toString() {
+        return ntriplesString() + " [" + uniqueReference() + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java
----------------------------------------------------------------------
diff --git a/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java b/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java
new file mode 100644
index 0000000..8788860
--- /dev/null
+++ b/commons-rdf-jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java
@@ -0,0 +1,111 @@
+/**
+ * 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.jsonldjava;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+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 com.github.jsonldjava.core.RDFDataset;
+
+public interface JsonLdDataset extends JsonLdGraphLike<org.apache.commons.rdf.api.Quad>, Dataset {
+}
+
+class JsonLdDatasetImpl extends AbstractJsonLdGraphLike<org.apache.commons.rdf.api.Quad> implements JsonLdDataset {
+
+    JsonLdDatasetImpl(final RDFDataset rdfDataSet) {
+        super(rdfDataSet);
+    }
+
+    JsonLdDatasetImpl(final RDFDataset rdfDataset, final String bnodePrefix) {
+        super(rdfDataset, bnodePrefix);
+    }
+
+    JsonLdDatasetImpl(final String bnodePrefix) {
+        super(bnodePrefix);
+    }
+
+    @Override
+    public void add(final BlankNodeOrIRI graphName, final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        super.add(graphName, subject, predicate, object);
+    }
+
+    @Override
+    public boolean contains(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        return super.contains(graphName, subject, predicate, object);
+    }
+
+    @Override
+    public Graph getGraph() {
+        return new JsonLdGraphImpl(rdfDataSet, Optional.empty(), bnodePrefix);
+    }
+
+    @Override
+    public Optional<Graph> getGraph(final BlankNodeOrIRI graphName) {
+        if (graphName == null) {
+            return Optional.of(getGraph());
+        }
+        
+        return Optional.of(new JsonLdGraphImpl(rdfDataSet, Optional.of(graphName), bnodePrefix));
+    }
+
+    @Override
+    public Stream<BlankNodeOrIRI> getGraphNames() {
+        return rdfDataSet.graphNames().parallelStream().filter(Predicate.isEqual("@default").negate())
+                .map(s -> s.startsWith("_:") ? new RDFDataset.BlankNode(s) : new RDFDataset.IRI(s))
+                .map(n -> (BlankNodeOrIRI) factory.asRDFTerm(n));
+    }
+
+    @Override
+    public void remove(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        super.remove(graphName, subject, predicate, object);
+    }
+
+    @Override
+    public void remove(final Quad q) {
+        remove(q.getGraphName(), q.getSubject(), q.getPredicate(), q.getObject());
+    }
+
+    @Override
+    public Stream<? extends Quad> stream(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate,
+            final RDFTerm object) {
+        return filteredGraphs(graphName).flatMap(List::stream).filter(quadFilter(subject, predicate, object))
+                .map(factory::asQuad);
+    }
+
+    @Override
+    public long size() {
+        return rdfDataSet.graphNames().stream().map(rdfDataSet::getQuads)
+                .collect(Collectors.summingLong(List::size));
+    }
+
+    @Override
+    Quad asTripleOrQuad(final com.github.jsonldjava.core.RDFDataset.Quad jsonldQuad) {
+        return factory.asQuad(jsonldQuad);
+    }
+
+}


Mime
View raw message