You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2017/10/30 14:57:18 UTC

[18/22] commons-rdf git commit: Module names, directory names, and artifact names should match.

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Dataset.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Dataset.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Dataset.java
new file mode 100644
index 0000000..cea8e5a
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Dataset.java
@@ -0,0 +1,354 @@
+/**
+ * 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.api;
+
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * An <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset">RDF
+ * 1.1 Dataset</a>, a set of RDF quads, as defined by
+ * <a href="http://www.w3.org/TR/rdf11-concepts/#section-rdf-dataset">RDF-1.1 Concepts and Abstract
+ * Syntax</a>, a W3C Recommendation published on 25 February 2014.
+ * 
+ * @since 0.3.0-incubating
+ * @see RDF#createDataset()
+ */
+public interface Dataset extends AutoCloseable, GraphLike<Quad> {
+
+    /**
+     * Add a quad to the dataset, possibly mapping any of the components of the
+     * Quad to those supported by this dataset.
+     *
+     * @param quad
+     *            The quad to add
+     */
+    @Override
+    void add(Quad quad);
+
+    /**
+     * Add a quad to the dataset, possibly mapping any of the components to
+     * those supported by this dataset.
+     *
+     * @param graphName
+     *            The graph the quad belongs to, or <code>null</code> for the
+     *            default graph
+     * @param subject
+     *            The quad subject
+     * @param predicate
+     *            The quad predicate
+     * @param object
+     *            The quad object
+     */
+    void add(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * Check if dataset contains quad.
+     *
+     * @param quad
+     *            The quad to check.
+     * @return True if the dataset contains the given Quad.
+     */
+    @Override
+    boolean contains(Quad quad);
+
+    /**
+     * Check if dataset contains a pattern of quads.
+     *
+     * @param graphName
+     *            The graph the quad belongs to, wrapped as an {@link Optional}
+     *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
+     *            the default graph)
+     * @param subject
+     *            The quad subject (<code>null</code> is a wildcard)
+     * @param predicate
+     *            The quad predicate (<code>null</code> is a wildcard)
+     * @param object
+     *            The quad object (<code>null</code> is a wildcard)
+     * @return True if the dataset contains any quads that match the given
+     *         pattern.
+     */
+    boolean contains(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * Close the dataset, relinquishing any underlying resources.
+     * <p>
+     * For example, this would close any open file and network streams and free
+     * database locks held by the dataset implementation.
+     * <p>
+     * The behaviour of the other dataset methods are undefined after closing
+     * the dataset.
+     * <p>
+     * Implementations might not need {@link #close()}, hence the default
+     * implementation does nothing.
+     */
+    @Override
+    default void close() throws Exception {
+    }
+
+    /**
+     * Get the default graph of this dataset.
+     * <p>
+     * The {@link Triple}s of the default graph are equivalent to the
+     * {@link Quad}s in this Dataset which has the {@link Quad#getGraphName()}
+     * set to {@link Optional#empty()}.
+     * <p>
+     * It is unspecified if modifications to the returned Graph are reflected in
+     * this Dataset.
+     * <p>
+     * The returned graph MAY be empty.
+     * 
+     * @see #getGraph(BlankNodeOrIRI)
+     * @return The default graph of this Dataset
+     */
+    Graph getGraph();
+
+    /**
+     * Get a named graph in this dataset.
+     * <p>
+     * The {@link Triple}s of the named graph are equivalent to the the Quads of
+     * this Dataset which has the {@link Quad#getGraphName()} equal to the
+     * provided <code>graphName</code>, or equal to {@link Optional#empty()} if
+     * the provided <code>graphName</code> is <code>null</code>.
+     * <p>
+     * It is unspecified if modifications to the returned Graph are reflected in
+     * this Dataset.
+     * <p>
+     * It is unspecified if requesting an unknown or empty graph will return
+     * {@link Optional#empty()} or create a new empty {@link Graph}.
+     * 
+     * @see #getGraph()
+     * @see #getGraphNames()
+     * @param graphName
+     *            The name of the graph, or <code>null</code> for the default
+     *            graph.
+     * @return The named Graph, or {@link Optional#empty()} if the dataset do
+     *         not contain the named graph.
+     */
+    Optional<Graph> getGraph(BlankNodeOrIRI graphName);
+
+    /**
+     * Get the graph names in this Dataset.
+     * <p>
+     * The set of returned graph names is equivalent to the set of unique
+     * {@link Quad#getGraphName()} of all the {@link #stream()} of this dataset
+     * (excluding the default graph).
+     * <p>
+     * The returned {@link Stream} SHOULD NOT contain duplicate graph names.
+     * <p>
+     * The graph names can be used with {@link #getGraph(BlankNodeOrIRI)} to
+     * retrieve the corresponding {@link Graph}, however callers should be aware
+     * of any concurrent modifications to the Dataset may cause such calls to
+     * return {@link Optional#empty()}.
+     * <p>
+     * Note that a Dataset always contains a <strong>default graph</strong>
+     * which is not named, and thus is not represented in the returned Stream.
+     * The default graph is accessible via {@link #getGraph()} or by using
+     * {@link Optional#empty()} in the Quad access methods).
+     * 
+     * @return A {@link Stream} of the graph names of this Dataset.
+     */
+    Stream<BlankNodeOrIRI> getGraphNames();
+
+    /**
+     * Remove a concrete quad from the dataset.
+     *
+     * @param quad
+     *            quad to remove
+     */
+    @Override
+    void remove(Quad quad);
+
+    /**
+     * Remove a concrete pattern of quads from the default graph of the dataset.
+     *
+     * @param graphName
+     *            The graph the quad belongs to, wrapped as an {@link Optional}
+     *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
+     *            the default graph)
+     * @param subject
+     *            The quad subject (<code>null</code> is a wildcard)
+     * @param predicate
+     *            The quad predicate (<code>null</code> is a wildcard)
+     * @param object
+     *            The quad object (<code>null</code> is a wildcard)
+     */
+    void remove(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * Clear the dataset, removing all quads.
+     */
+    @Override
+    void clear();
+
+    /**
+     * Number of quads contained by the dataset.
+     * <p>
+     * The count of a set does not include duplicates, consistent with the
+     * {@link Quad#equals(Object)} equals method for each {@link Quad}.
+     *
+     * @return The number of quads in the dataset
+     */
+    @Override
+    long size();
+
+    /**
+     * Get all quads contained by the dataset.<br>
+     * <p>
+     * The iteration does not contain any duplicate quads, as determined by the
+     * {@link Quad#equals(Object)} method for each {@link Quad}.
+     * <p>
+     * The behaviour of the {@link Stream} is not specified if
+     * {@link #add(Quad)}, {@link #remove(Quad)} or {@link #clear()} are called
+     * on the {@link Dataset} before it terminates.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Stream methods if they detect a conflict while the Stream is active.
+     *
+     * @return A {@link Stream} over all of the quads in the dataset
+     */
+    @Override
+    Stream<? extends Quad> stream();
+
+    /**
+     * Get all quads contained by the dataset matched with the pattern.
+     * <p>
+     * The iteration does not contain any duplicate quads, as determined by the
+     * {@link Quad#equals(Object)} method for each {@link Quad}.
+     * <p>
+     * The behaviour of the {@link Stream} is not specified if
+     * {@link #add(Quad)}, {@link #remove(Quad)} or {@link #clear()} are called
+     * on the {@link Dataset} before it terminates.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Stream methods if they detect a conflict while the Stream is active.
+     *
+     * @param graphName
+     *            The graph the quad belongs to, wrapped as an {@link Optional}
+     *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
+     *            the default graph)
+     * @param subject
+     *            The quad subject (<code>null</code> is a wildcard)
+     * @param predicate
+     *            The quad predicate (<code>null</code> is a wildcard)
+     * @param object
+     *            The quad object (<code>null</code> is a wildcard)
+     * @return A {@link Stream} over the matched quads.
+     */
+    Stream<? extends Quad> stream(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate,
+            RDFTerm object);
+
+    /**
+     * Get an Iterable for iterating over all quads in the dataset.
+     * <p>
+     * This method is meant to be used with a Java for-each loop, e.g.:
+     * 
+     * <pre>
+     * for (Quad t : dataset.iterate()) {
+     *     System.out.println(t);
+     * }
+     * </pre>
+     * 
+     * The behaviour of the iterator is not specified if {@link #add(Quad)},
+     * {@link #remove(Quad)} or {@link #clear()}, are called on the
+     * {@link Dataset} before it terminates. It is undefined if the returned
+     * {@link Iterator} supports the {@link Iterator#remove()} method.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Iterator methods if they detect a concurrency conflict while the Iterator
+     * is active.
+     * <p>
+     * The {@link Iterable#iterator()} must only be called once, that is the
+     * Iterable must only be iterated over once. A {@link IllegalStateException}
+     * may be thrown on attempt to reuse the Iterable.
+     * <p>
+     * The default implementation of this method will call {@link #stream()} to
+     * return its {@link Stream#iterator()}.
+     *
+     * @return A {@link Iterable} that returns {@link Iterator} over all of the
+     *         quads in the dataset
+     * @throws IllegalStateException
+     *             if the {@link Iterable} has been reused
+     * @throws ConcurrentModificationException
+     *             if a concurrency conflict occurs while the Iterator is
+     *             active.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    default Iterable<Quad> iterate() throws ConcurrentModificationException, IllegalStateException {
+        return ((Stream<Quad>) stream())::iterator;
+    }
+
+    /**
+     * Get an Iterable for iterating over the quads in the dataset that match
+     * the pattern.
+     * <p>
+     * This method is meant to be used with a Java for-each loop, e.g.:
+     * 
+     * <pre>
+     * IRI alice = factory.createIRI("http://example.com/alice");
+     * IRI knows = factory.createIRI("http://xmlns.com/foaf/0.1/");
+     * for (Quad t : dataset.iterate(null, alice, knows, null)) {
+     *     System.out.println(t.getGraphName());
+     *     System.out.println(t.getObject());
+     * }
+     * </pre>
+     * <p>
+     * The behaviour of the iterator is not specified if {@link #add(Quad)},
+     * {@link #remove(Quad)} or {@link #clear()}, are called on the
+     * {@link Dataset} before it terminates. It is undefined if the returned
+     * {@link Iterator} supports the {@link Iterator#remove()} method.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Iterator methods if they detect a concurrency conflict while the Iterator
+     * is active.
+     * <p>
+     * The {@link Iterable#iterator()} must only be called once, that is the
+     * Iterable must only be iterated over once. A {@link IllegalStateException}
+     * may be thrown on attempt to reuse the Iterable.
+     * <p>
+     * The default implementation of this method will call
+     * {@link #stream(Optional, BlankNodeOrIRI, IRI, RDFTerm)} to return its
+     * {@link Stream#iterator()}.
+     *
+     * @param graphName
+     *            The graph the quad belongs to, wrapped as an {@link Optional}
+     *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
+     *            the default graph)
+     * @param subject
+     *            The quad subject (<code>null</code> is a wildcard)
+     * @param predicate
+     *            The quad predicate (<code>null</code> is a wildcard)
+     * @param object
+     *            The quad object (<code>null</code> is a wildcard)
+     * @return A {@link Iterable} that returns {@link Iterator} over the
+     *         matching quads in the dataset
+     * @throws IllegalStateException
+     *             if the {@link Iterable} has been reused
+     * @throws ConcurrentModificationException
+     *             if a concurrency conflict occurs while the Iterator is
+     *             active.
+     */
+    @SuppressWarnings("unchecked")
+    default Iterable<Quad> iterate(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate,
+            final RDFTerm object) throws ConcurrentModificationException, IllegalStateException {
+        return ((Stream<Quad>) stream(graphName, subject, predicate, object))::iterator;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Graph.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Graph.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Graph.java
new file mode 100644
index 0000000..0df5186
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Graph.java
@@ -0,0 +1,298 @@
+/**
+ * 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.api;
+
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.stream.Stream;
+
+/**
+ * An <a href="http://www.w3.org/TR/rdf11-concepts/#section-rdf-graph"> RDF 1.1
+ * Graph</a>, a set of RDF triples, as defined by
+ * <a href="http://www.w3.org/TR/rdf11-concepts/" >RDF-1.1 Concepts and Abstract
+ * Syntax</a>, a W3C Recommendation published on 25 February 2014.
+ * 
+ * @see RDF#createGraph()
+ */
+public interface Graph extends AutoCloseable, GraphLike<Triple> {
+
+    /**
+     * Add a triple to the graph, possibly mapping any of the components of the
+     * Triple to those supported by this Graph.
+     *
+     * @param triple
+     *            The triple to add
+     */
+    @Override
+    void add(Triple triple);
+
+    /**
+     * Add a triple to the graph, possibly mapping any of the components to
+     * those supported by this Graph.
+     *
+     * @param subject
+     *            The triple subject
+     * @param predicate
+     *            The triple predicate
+     * @param object
+     *            The triple object
+     */
+    void add(BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * Check if graph contains triple.
+     *
+     * @param triple
+     *            The triple to check.
+     * @return True if the Graph contains the given Triple.
+     */
+    @Override
+    boolean contains(Triple triple);
+
+    /**
+     * Check if graph contains a pattern of triples.
+     *
+     * @param subject
+     *            The triple subject (null is a wildcard)
+     * @param predicate
+     *            The triple predicate (null is a wildcard)
+     * @param object
+     *            The triple object (null is a wildcard)
+     * @return True if the Graph contains any Triples that match the given
+     *         pattern.
+     */
+    boolean contains(BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * Close the graph, relinquishing any underlying resources.
+     * <p>
+     * For example, this would close any open file and network streams and free
+     * database locks held by the Graph implementation.
+     * <p>
+     * The behaviour of the other Graph methods are undefined after closing the
+     * graph.
+     * <p>
+     * Implementations might not need {@link #close()}, hence the default
+     * implementation does nothing.
+     */
+    @Override
+    default void close() throws Exception {
+    }
+
+    /**
+     * Remove a concrete triple from the graph.
+     *
+     * @param triple
+     *            triple to remove
+     */
+    @Override
+    void remove(Triple triple);
+
+    /**
+     * Remove a concrete pattern of triples from the graph.
+     *
+     * @param subject
+     *            The triple subject (null is a wildcard)
+     * @param predicate
+     *            The triple predicate (null is a wildcard)
+     * @param object
+     *            The triple object (null is a wildcard)
+     */
+    void remove(BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * Clear the graph, removing all triples.
+     */
+    @Override
+    void clear();
+
+    /**
+     * Number of triples contained by the graph.
+     * <p>
+     * The count of a set does not include duplicates, consistent with the
+     * {@link Triple#equals(Object)} equals method for each {@link Triple}.
+     *
+     * @return The number of triples in the graph
+     */
+    @Override
+    long size();
+
+    /**
+     * Get all triples contained by the graph.<br>
+     * <p>
+     * The iteration does not contain any duplicate triples, as determined by
+     * the {@link Triple#equals(Object)} method for each {@link Triple}.
+     * <p>
+     * The behaviour of the {@link Stream} is not specified if
+     * {@link #add(Triple)}, {@link #remove(Triple)} or {@link #clear()} are
+     * called on the {@link Graph} before it terminates.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Stream methods if they detect a conflict while the Stream is active.
+     * 
+     * @since 0.3.0-incubating
+     * @return A {@link Stream} over all of the triples in the graph
+     */
+    @Override
+    Stream<? extends Triple> stream();
+
+    /**
+     * Get all triples contained by the graph matched with the pattern.
+     * <p>
+     * The iteration does not contain any duplicate triples, as determined by
+     * the {@link Triple#equals(Object)} method for each {@link Triple}.
+     * <p>
+     * The behaviour of the {@link Stream} is not specified if
+     * {@link #add(Triple)}, {@link #remove(Triple)} or {@link #clear()} are
+     * called on the {@link Graph} before it terminates.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Stream methods if they detect a conflict while the Stream is active.
+     * <p>
+     * 
+     * @since 0.3.0-incubating
+     * @param subject
+     *            The triple subject (null is a wildcard)
+     * @param predicate
+     *            The triple predicate (null is a wildcard)
+     * @param object
+     *            The triple object (null is a wildcard)
+     * @return A {@link Stream} over the matched triples.
+     */
+    Stream<? extends Triple> stream(BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+    /**
+     * This method is deprecated, use the equivalent method {@link #stream()}
+     * instead.
+     * 
+     * @return A {@link Stream} over all triples.
+     */
+    @Deprecated
+    default Stream<? extends Triple> getTriples() {
+        return stream();
+    }
+
+    /**
+     * This method is deprecated, use the equivalent method
+     * {@link #stream(BlankNodeOrIRI, IRI, RDFTerm)} instead.
+     * 
+     * @param subject
+     *            The triple subject (null is a wildcard)
+     * @param predicate
+     *            The triple predicate (null is a wildcard)
+     * @param object
+     *            The triple object (null is a wildcard)
+     * @return A {@link Stream} over the matched triples.
+     */
+    @Deprecated
+    default Stream<? extends Triple> getTriples(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        return stream(subject, predicate, object);
+    }
+
+    /**
+     * Get an Iterable for iterating over all triples in the graph.
+     * <p>
+     * This method is meant to be used with a Java for-each loop, e.g.:
+     * 
+     * <pre>
+     * for (Triple t : graph.iterate()) {
+     *     System.out.println(t);
+     * }
+     * </pre>
+     * 
+     * The behaviour of the iterator is not specified if {@link #add(Triple)},
+     * {@link #remove(Triple)} or {@link #clear()}, are called on the
+     * {@link Graph} before it terminates. It is undefined if the returned
+     * {@link Iterator} supports the {@link Iterator#remove()} method.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Iterator methods if they detect a concurrency conflict while the Iterator
+     * is active.
+     * <p>
+     * The {@link Iterable#iterator()} must only be called once, that is the
+     * Iterable must only be iterated over once. A {@link IllegalStateException}
+     * may be thrown on attempt to reuse the Iterable.
+     * <p>
+     * The default implementation of this method will call {@link #stream()} to return
+     * its {@link Stream#iterator()}.
+     *
+     * @return A {@link Iterable} that returns {@link Iterator} over all of the
+     *         triples in the graph
+     * @throws IllegalStateException
+     *             if the {@link Iterable} has been reused
+     * @throws ConcurrentModificationException
+     *             if a concurrency conflict occurs while the Iterator is
+     *             active.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    default Iterable<Triple> iterate() throws ConcurrentModificationException, IllegalStateException {
+        return ((Stream<Triple>) stream())::iterator;
+    }
+
+    /**
+     * Get an Iterable for iterating over the triples in the graph that match
+     * the pattern.
+     * <p>
+     * This method is meant to be used with a Java for-each loop, e.g.:
+     * 
+     * <pre>
+     * IRI alice = factory.createIRI("http://example.com/alice");
+     * IRI knows = factory.createIRI("http://xmlns.com/foaf/0.1/");
+     * for (Triple t : graph.iterate(alice, knows, null)) {
+     *     System.out.println(t.getObject());
+     * }
+     * </pre>
+     * <p>
+     * The behaviour of the iterator is not specified if {@link #add(Triple)},
+     * {@link #remove(Triple)} or {@link #clear()}, are called on the
+     * {@link Graph} before it terminates. It is undefined if the returned
+     * {@link Iterator} supports the {@link Iterator#remove()} method.
+     * <p>
+     * Implementations may throw {@link ConcurrentModificationException} from
+     * Iterator methods if they detect a concurrency conflict while the Iterator
+     * is active.
+     * <p>
+     * The {@link Iterable#iterator()} must only be called once, that is the
+     * Iterable must only be iterated over once. A {@link IllegalStateException}
+     * may be thrown on attempt to reuse the Iterable.
+     * <p>
+     * The default implementation of this method will call
+     * {@link #stream(BlankNodeOrIRI, IRI, RDFTerm)} to return its
+     * {@link Stream#iterator()}.
+     *
+     * @param subject
+     *            The triple subject (null is a wildcard)
+     * @param predicate
+     *            The triple predicate (null is a wildcard)
+     * @param object
+     *            The triple object (null is a wildcard)
+     * @return A {@link Iterable} that returns {@link Iterator} over the
+     *         matching triples in the graph
+     * @throws IllegalStateException
+     *             if the {@link Iterable} has been reused
+     * @throws ConcurrentModificationException
+     *             if a concurrency conflict occurs while the Iterator is
+     *             active.
+     */
+    @SuppressWarnings("unchecked")
+    default Iterable<Triple> iterate(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object)
+            throws ConcurrentModificationException, IllegalStateException {
+        return ((Stream<Triple>) stream(subject, predicate, object))::iterator;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/GraphLike.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/GraphLike.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/GraphLike.java
new file mode 100644
index 0000000..e971801
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/GraphLike.java
@@ -0,0 +1,106 @@
+/**
+ * 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.api;
+
+import java.util.ConcurrentModificationException;
+import java.util.stream.Stream;
+
+/**
+ * A "graph-like" interface that contains {@link TripleLike} statements.
+ * <p>
+ * Extended by {@link Graph} (for {@link Triple}) and {@link Dataset} (for
+ * {@link Quad}).
+ * <p>
+ * Unlike {@link Graph} and {@link Dataset}, this interface can support
+ * generalised {@link TripleLike} or {@link QuadLike} statements, but does not
+ * imply semantics like {@link #size()} or the requirement of mapping
+ * {@link RDFTerm} instances from different implementations.
+ * <p>
+ * As {@link TripleLike} do not have a specific {@link Object#equals(Object)}
+ * semantics, the behaviour of methods like {@link #contains(TripleLike)} and
+ * {@link #remove(TripleLike)} is undefined for arguments that are not object
+ * identical to previously added or returned {@link TripleLike} statements.
+ * 
+ * @param <T>
+ *            A {@link TripleLike} type used by the graph methods, typically
+ *            {@link Triple} or {@link Quad}
+ * 
+ * @since 0.3.0-incubating
+ * @see Graph
+ * @see Dataset
+ * @see TripleLike
+ */
+public interface GraphLike<T extends TripleLike> {
+
+    /**
+     * Add a statement.
+     * 
+     * @param statement
+     *            The TripleLike statement to add
+     */
+    void add(T statement);
+
+    /**
+     * Check if statement is contained.
+     * 
+     * @param statement
+     *            The {@link TripleLike} statement to check
+     * @return True if the statement is contained
+     */
+    boolean contains(T statement);
+
+    /**
+     * Add a statement.
+     * 
+     * @param statement
+     *            The TripleLike statement to add
+     */
+    void remove(T statement);
+
+    /**
+     * Remove all statements.
+     */
+    void clear();
+
+    /**
+     * Number of statements.
+     * 
+     * @return Number of statements
+     */
+    long size();
+
+    /**
+     * Return a Stream of contained statements.
+     * 
+     * @return A {@link Stream} of {@link TripleLike} statements.
+     */
+    Stream<? extends T> stream();
+
+    /**
+     * Iterate over contained statements.
+     * 
+     * @return An {@link Iterable} of {@link TripleLike} statements.
+     * @throws IllegalStateException
+     *             if the {@link Iterable} has been reused
+     * @throws ConcurrentModificationException
+     *             if a concurrency conflict occurs while the Iterator is
+     *             active.
+     */
+    Iterable<T> iterate() throws ConcurrentModificationException, IllegalStateException;
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/IRI.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/IRI.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/IRI.java
new file mode 100644
index 0000000..00605bb
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/IRI.java
@@ -0,0 +1,77 @@
+/**
+ * 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.api;
+
+/**
+ * An <a href= "http://www.w3.org/TR/rdf11-concepts/#dfn-iri" >RDF-1.1 IRI</a>,
+ * as defined by <a href= "http://www.w3.org/TR/rdf11-concepts/#section-IRIs" >RDF-1.1
+ * Concepts and Abstract Syntax</a>, a W3C Recommendation published on 25
+ * February 2014.
+ * 
+ * @see RDF#createIRI(String)
+ */
+public interface IRI extends BlankNodeOrIRI {
+
+    /**
+     * Return the IRI encoded as a native Unicode String.<br>
+     *
+     * The returned string must not include URL-encoding to escape non-ASCII
+     * characters.
+     *
+     * @return The IRI encoded as a native Unicode String.
+     */
+    String getIRIString();
+
+    /**
+     * Check it this IRI is equal to another IRI. <blockquote>
+     * <a href="http://www.w3.org/TR/rdf11-concepts/#section-IRIs">IRI
+     * equality</a>: Two IRIs are equal if and only if they are equivalent under
+     * Simple String Comparison according to section 5.1 of [RFC3987]. Further
+     * normalization MUST NOT be performed when comparing IRIs for equality.
+     * </blockquote>
+     *
+     * Two IRI instances are equal if and only if their {@link #getIRIString()}
+     * are equal.
+     *
+     * Implementations MUST also override {@link #hashCode()} so that two equal
+     * IRIs produce the same hash code.
+     *
+     * @param other
+     *            Another object
+     * @return true if other is an IRI and is equal to this
+     * @see Object#equals(Object)
+     */
+    @Override
+    public boolean equals(Object other);
+
+    /**
+     * Calculate a hash code for this IRI.
+     * <p>
+     * The returned hash code MUST be equal to the {@link String#hashCode()} of
+     * the {@link #getIRIString()}.
+     * <p>
+     * This method MUST be implemented in conjunction with
+     * {@link #equals(Object)} so that two equal IRIs produce the same hash
+     * code.
+     *
+     * @return a hash code value for this IRI.
+     * @see Object#hashCode()
+     */
+    @Override
+    public int hashCode();
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Literal.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Literal.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Literal.java
new file mode 100644
index 0000000..a5a0df6
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Literal.java
@@ -0,0 +1,144 @@
+/**
+ * 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.api;
+
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * An <a href= "https://www.w3.org/TR/rdf11-concepts/#dfn-literal"
+ * >RDF-1.1 Literal</a>, as defined by
+ * <a href= "http://www.w3.org/TR/rdf11-concepts/#section-Graph-Literal"
+ * >RDF-1.1 Concepts and Abstract Syntax</a>, a W3C Recommendation published on
+ * 25 February 2014.
+ * 
+ * @see RDF#createLiteral(String)
+ * @see RDF#createLiteral(String, IRI)
+ * @see RDF#createLiteral(String, String)
+ */
+public interface Literal extends RDFTerm {
+
+    /**
+     * The lexical form of this literal, represented by a
+     * <a href="http://www.unicode.org/versions/latest/">Unicode string</a>.
+     *
+     * @return The lexical form of this literal.
+     * @see <a href=
+     *      "http://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form">RDF-1.1
+     *      Literal lexical form</a>
+     */
+    String getLexicalForm();
+
+    /**
+     * The IRI identifying the datatype that determines how the lexical form
+     * maps to a literal value.
+     *
+     * If the datatype IRI is
+     * <a href="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
+     * >http://www.w3.org/1999/02/22-rdf-syntax-ns#langString</a>,
+     * {@link #getLanguageTag()} must not return {@link Optional#empty()}, and
+     * it must return a valid
+     * <a href="http://tools.ietf.org/html/bcp47">BCP47</a> language tag.
+     *
+     * @return The datatype IRI for this literal.
+     * @see <a href=
+     *      "http://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri">RDF-1.1
+     *      Literal datatype IRI</a>
+     */
+    IRI getDatatype();
+
+    /**
+     * If and only if the datatype IRI is
+     * <a href="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
+     * >http://www.w3.org/1999/02/22-rdf-syntax-ns#langString</a>, the language
+     * tag for this Literal is a non-empty language tag as defined by
+     * <a href="http://tools.ietf.org/html/bcp47">BCP47</a>.<br>
+     * If the datatype IRI is not
+     * <a href="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
+     * >http://www.w3.org/1999/02/22-rdf-syntax-ns#langString</a>, this method
+     * must return {@link Optional#empty()}.
+     * <p>
+     * The value space of language tags is always in lower case; although 
+     * RDF implementations MAY convert all language tags to lower case,
+     * safe comparisons of language tags should be done using
+     * {@link String#toLowerCase(Locale)} with the locale
+     * {@link Locale#ROOT}. 
+     * <p>
+     * Implementation note: If your application requires {@link Serializable}
+     * objects, it is best not to store an {@link Optional} in a field. It is
+     * recommended to use {@link Optional#ofNullable(Object)} to create the
+     * return value for this method.
+     *
+     * @return The {@link Optional} language tag for this literal. If
+     *         {@link Optional#isPresent()} returns true, the value returned by
+     *         {@link Optional#get()} must be a non-empty language tag string
+     *         conforming to BCP47.
+     * @see <a href=
+     *      "http://www.w3.org/TR/rdf11-concepts/#dfn-language-tag">RDF-1.1
+     *      Literal language tag</a>
+     */
+    Optional<String> getLanguageTag();
+
+    /**
+     * Check it this Literal is equal to another Literal. 
+     * <blockquote>
+     * <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-literal-term">Literal
+     * term equality</a>: 
+     * Two literals are term-equal (the same RDF literal) if
+     * and only if the two lexical forms, the two datatype IRIs, and the two
+     * language tags (if any) compare equal, character by character. Thus, two
+     * literals can have the same value without being the same RDF term.
+     * </blockquote>
+     * As the value space for language tags is lower-space, if they are present,
+     * they MUST be compared character by character
+     * using the equivalent of {@link String#toLowerCase(java.util.Locale)} with
+     * the locale {@link Locale#ROOT}.
+     * <p>
+     * Implementations MUST also override {@link #hashCode()} so that two equal
+     * Literals produce the same hash code.
+     *
+     * @param other
+     *            Another object
+     * @return true if other is a Literal and is equal to this
+     * @see Object#equals(Object)
+     */
+    @Override
+    public boolean equals(Object other);
+
+    /**
+     * Calculate a hash code for this Literal.
+     * <p>
+     * The returned hash code MUST be equal to the result of
+     * {@link Objects#hash(Object...)} with the arguments
+     * {@link #getLexicalForm()}, {@link #getDatatype()},
+     * {@link #getLanguageTag()}<code>.map(s-&gt;s.toLowerString(Locale.ROOT))</code>.
+     * <p>
+     * This method MUST be implemented in conjunction with
+     * {@link #equals(Object)} so that two equal Literals produce the same hash
+     * code.
+     *
+     * @return a hash code value for this Literal.
+     * @see Object#hashCode()
+     * @see Objects#hash(Object...)
+     */
+    @Override
+    public int hashCode();
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Quad.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Quad.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Quad.java
new file mode 100644
index 0000000..c007aff
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/Quad.java
@@ -0,0 +1,240 @@
+/**
+ * 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.api;
+
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * A Quad is a statement in a
+ * <a href= "http://www.w3.org/TR/rdf11-concepts/#section-dataset" >RDF-1.1
+ * Dataset</a>, as defined by <a href=
+ * "https://www.w3.org/TR/2014/NOTE-rdf11-datasets-20140225/#quad-semantics"
+ * >RDF-1.1 Concepts and Abstract Syntax</a>, a W3C Working Group Note published
+ * on 25 February 2014.
+ * <p>
+ * A <code>Quad</code> object in Commons RDF is considered
+ * <strong>immutable</strong>, that is, over its life time it will have
+ * consistent behaviour for its {@link #equals(Object)}, and the instances
+ * returned from {@link #getGraphName()}, {@link #getSubject()},
+ * {@link #getPredicate()}, {@link #getObject()} and {@link #asTriple()} will
+ * have consistent {@link Object#equals(Object)} behaviour.
+ * <p>
+ * Note that <code>Quad</code> methods are not required to return object
+ * identical (<code>==</code>) instances as long as they are equivalent
+ * according to {@link Object#equals(Object)}. Specialisations of
+ * <code>Quad</code> may provide additional methods that are documented to be
+ * mutable.
+ * <p>
+ * <code>Quad</code> methods are <strong>thread-safe</strong>, however
+ * specialisations may provide additional methods that are documented to not be
+ * thread-safe.
+ * <p>
+ * <code>Quad</code>s can be safely used in hashing collections like
+ * {@link java.util.HashSet} and {@link java.util.HashMap}.
+ * <p>
+ * Any <code>Quad</code> can be used interchangeably across Commons RDF
+ * implementations.
+ *
+ * @since 0.3.0-incubating
+ * @see Dataset
+ * @see RDF#createQuad(BlankNodeOrIRI,BlankNodeOrIRI,IRI,RDFTerm)
+ * @see <a href="http://www.w3.org/TR/2014/NOTE-rdf11-datasets-20140225/">RDF
+ *      1.1: On Semantics of RDF Datasets</a>
+ * @see <a href="http://www.w3.org/TR/rdf11-concepts/#section-dataset"> </a>
+ */
+public interface Quad extends QuadLike<BlankNodeOrIRI> {
+
+    /**
+     * The graph name (graph label) of this quad, if present.
+     *
+     * If {@link Optional#isPresent()}, then the {@link Optional#get()} is
+     * either a {@link BlankNode} or an {@link IRI}, indicating the
+     * <a href="https://www.w3.org/TR/rdf11-concepts/#dfn-named-graph">graph
+     * name</a> of this Quad. If the graph name is not present, e.g. the value
+     * is {@link Optional#empty()}, it indicates that this Quad is in the
+     * <a href="https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph">default
+     * graph</a>.
+     *
+     * @return If {@link Optional#isPresent()}, the graph name
+     *         {@link BlankNodeOrIRI} of this quad, otherwise
+     *         {@link Optional#empty()}, indicating the default graph.
+     *
+     * @see <a href="https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset">RDF-
+     *      1.1 Dataset</a>
+     */
+    @Override
+    Optional<BlankNodeOrIRI> getGraphName();
+
+    /**
+     * The subject of this quad, which may be either a {@link BlankNode} or an
+     * {@link IRI}, which are represented in Commons RDF by the interface
+     * {@link BlankNodeOrIRI}.
+     *
+     * @return The subject {@link BlankNodeOrIRI} of this quad.
+     * @see <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-subject">RDF-1.1
+     *      Triple subject</a>
+     */
+    @Override
+    BlankNodeOrIRI getSubject();
+
+    /**
+     * The predicate {@link IRI} of this quad.
+     *
+     * @return The predicate {@link IRI} of this quad.
+     * @see <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-predicate">RDF-1.1
+     *      Triple predicate</a>
+     */
+    @Override
+    IRI getPredicate();
+
+    /**
+     * The object of this quad, which may be either a {@link BlankNode}, an
+     * {@link IRI}, or a {@link Literal}, which are represented in Commons RDF
+     * by the interface {@link RDFTerm}.
+     *
+     * @return The object {@link RDFTerm} of this quad.
+     * @see <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-object">RDF-1.1
+     *      Triple object</a>
+     */
+    @Override
+    RDFTerm getObject();
+
+    /**
+     * Adapt this Quad to a Triple.
+     * <p>
+     * The returned {@link Triple} will have equivalent values returned from the
+     * methods {@link TripleLike#getSubject()},
+     * {@link TripleLike#getPredicate()} and {@link TripleLike#getObject()}.
+     * <p>
+     * The returned {@link Triple} MUST NOT be {@link #equals(Object)} to this
+     * {@link Quad}, even if this quad has a default graph
+     * {@link #getGraphName()} value of {@link Optional#empty()}, but MUST
+     * follow the {@link Triple#equals(Object)} semantics. This means that the
+     * following MUST be true:
+     *
+     * <pre>
+     * Quad q1, q2;
+     * if (q1.equals(q2)) {
+     *     assert (q1.asTriple().equals(q2.asTriple()));
+     * } else if (q1.asTriple().equals(q2.asTriple())) {
+     *     assert (q1.getSubject().equals(q2.getSubject()));
+     *     assert (q1.getPredicate().equals(q2.getPredicate()));
+     *     assert (q1.getObject().equals(q2.getObject()));
+     *     assert (!q1.getGraphName().equals(q2.getGraphName()));
+     * }
+     * </pre>
+     *
+     * The <code>default</code> implementation of this method return a proxy
+     * {@link Triple} instance that keeps a reference to this {@link Quad} to
+     * call the underlying {@link TripleLike} methods, but supplies a
+     * {@link Triple} compatible implementation of {@link Triple#equals(Object)}
+     * and {@link Triple#hashCode()}. Implementations may override this method,
+     * e.g. for a more efficient solution.
+     *
+     * @return A {@link Triple} that contains the same {@link TripleLike}
+     *         properties as this Quad.
+     */
+    default Triple asTriple() {
+        return new Triple() {
+            @Override
+            public BlankNodeOrIRI getSubject() {
+                return Quad.this.getSubject();
+            }
+
+            @Override
+            public IRI getPredicate() {
+                return Quad.this.getPredicate();
+            }
+
+            @Override
+            public RDFTerm getObject() {
+                return Quad.this.getObject();
+            }
+
+            @Override
+            public boolean equals(final Object obj) {
+                if (obj == this) {
+                    return true;
+                }
+                if (!(obj instanceof Triple)) {
+                    return false;
+                }
+                final Triple other = (Triple) obj;
+                return Objects.equals(getSubject(), other.getSubject())
+                        && Objects.equals(getPredicate(), other.getPredicate())
+                        && Objects.equals(getObject(), other.getObject());
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(getSubject(), getPredicate(), getObject());
+            }
+        };
+    }
+
+    /**
+     * Check it this Quad is equal to another Quad.
+     * <p>
+     * Two Quads are equal if and only if their {@link #getGraphName()},
+     * {@link #getSubject()}, {@link #getPredicate()} and {@link #getObject()}
+     * are equal.
+     * </p>
+     * <p>
+     * Implementations MUST also override {@link #hashCode()} so that two equal
+     * Quads produce the same hash code.
+     * </p>
+     * <p>
+     * Note that a {@link Quad} MUST NOT be equal to a {@link Triple}, even if
+     * this Quad's {@link #getGraphName()} is {@link Optional#empty()}. To test
+     * triple-like equivalence, callers can use:
+     * </p>
+     *
+     * <pre>
+     * Quad q1;
+     * Triple t2;
+     * q1.asTriple().equals(t2));
+     * </pre>
+     *
+     * @param other
+     *            Another object
+     * @return true if other is a Quad and is equal to this
+     * @see Object#equals(Object)
+     */
+    @Override
+    public boolean equals(Object other);
+
+    /**
+     * Calculate a hash code for this Quad.
+     * <p>
+     * The returned hash code MUST be equal to the result of
+     * {@link Objects#hash(Object...)} with the arguments {@link #getSubject()},
+     * {@link #getPredicate()}, {@link #getObject()}, {@link #getGraphName()}.
+     * <p>
+     * This method MUST be implemented in conjunction with
+     * {@link #equals(Object)} so that two equal {@link Quad}s produce the same
+     * hash code.
+     *
+     * @return a hash code value for this Quad.
+     * @see Object#hashCode()
+     * @see Objects#hash(Object...)
+     */
+    @Override
+    public int hashCode();
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/QuadLike.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/QuadLike.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/QuadLike.java
new file mode 100644
index 0000000..eab92ec
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/QuadLike.java
@@ -0,0 +1,56 @@
+/**
+ * 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.api;
+
+import java.util.Optional;
+
+/**
+ * A generalised "quad-like" interface, extended by {@link Quad}.
+ * <p>
+ * A QuadLike statement has at least a {@link #getSubject()},
+ * {@link #getPredicate()}, {@link #getObject()} and {@link #getGraphName()},
+ * but unlike a {@link Quad} does not have a formalised
+ * {@link Quad#equals(Object)} or {@link Quad#hashCode()} semantics and is not
+ * required to be <em>immutable</em> or <em>thread-safe</em>. This interface can
+ * also be used for <em>generalised quads</em> (e.g. a {@link BlankNode} as
+ * predicate).
+ * <p>
+ * Implementations should specialise which specific {@link RDFTerm} types they
+ * return by overriding {@link #getSubject()}, {@link #getPredicate()},
+ * {@link #getObject()} and {@link #getGraphName()}.
+ *
+ * @since 0.3.0-incubating
+ * @see Quad
+ */
+public interface QuadLike<G extends RDFTerm> extends TripleLike {
+
+    /**
+     * The graph name (graph label) of this statement, if present.
+     * <p>
+     * If {@link Optional#isPresent()}, then the {@link Optional#get()} indicate
+     * the graph name of this statement. If the graph name is not present,e.g.
+     * the value is {@link Optional#empty()}, it indicates that this Quad is in
+     * the default graph.
+     *
+     * @return If {@link Optional#isPresent()}, the graph name of this quad,
+     *         otherwise {@link Optional#empty()}, indicating the default graph.
+     *         The graph name is typically an {@link IRI} or {@link BlankNode}.
+     */
+    Optional<G> getGraphName();
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDF.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDF.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDF.java
new file mode 100644
index 0000000..b942b30
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDF.java
@@ -0,0 +1,258 @@
+/**
+ * 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.api;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * A RDF implementation.
+ * <p>
+ * A <code>RDF</code> implementation can create instances of the {@link RDFTerm}
+ * types {@link IRI}, {@link BlankNode} and {@link Literal}, as well as creating
+ * instances of the types {@link Triple}, {@link Quad}, {@link Graph} or
+ * {@link Dataset}.
+ * <p>
+ * A <em>partial RDF implementation</em> should be clearly documented as such,
+ * and may throw {@link UnsupportedOperationException} where applicable, e.g. if
+ * it does not support creating {@link Dataset}s or {@link Quad}s.
+ * <p>
+ * Instances of <code>RDF</code> work like a factory for creating Commons RDF
+ * instances. spezializations of this interface may also provide methods for
+ * conversions from/to their underlying RDF framework.
+ * <p>
+ * If a factory method of a particular implementation does not allow or support
+ * a provided parameter, e.g. because an IRI is considered invalid, then it
+ * SHOULD throw {@link IllegalArgumentException}.
+ *
+ * @since 0.3.0-incubating
+ * @see RDFTerm
+ * @see Graph
+ * @see Quad
+ */
+public interface RDF {
+
+    /**
+     * Create a new blank node.
+     * <p>
+     * The returned blank node MUST NOT be equal to any existing
+     * {@link BlankNode} instances according to
+     * {@link BlankNode#equals(Object)}.
+     *
+     * @return A new, unique {@link BlankNode}
+     */
+    public BlankNode createBlankNode();
+
+    /**
+     * Create a blank node based on the given name.
+     * <p>
+     * All {@link BlankNode}s created with the given <code>name</code> <em>on a
+     * particular instance</em> of <code>RDF</code> MUST be equivalent according
+     * to {@link BlankNode#equals(Object)},
+     * <p>
+     * The returned BlankNode MUST NOT be equal to <code>BlankNode</code>
+     * instances returned for any other <code>name</code> or those returned from
+     * {@link #createBlankNode()}.
+     * <p>
+     * The returned BlankNode SHOULD NOT be equivalent to any BlankNodes created
+     * on a <em>different</em> <code>RDF</code> instance, e.g. different
+     * instances of <code>RDF</code> should produce different blank nodes for
+     * the same <code>name</code> unless they purposely are intending to create
+     * equivalent {@link BlankNode} instances (e.g. a reinstated
+     * {@link Serializable} factory).
+     *
+     * @param name
+     *            A non-empty, non-null, String that is unique to this blank
+     *            node in the context of this {@link RDF}.
+     * @return A BlankNode for the given name
+     */
+    public BlankNode createBlankNode(String name);
+
+    /**
+     * Create a new graph.
+     *
+     * It is undefined if the graph will be persisted by any underlying storage
+     * mechanism.
+     *
+     * @return A new Graph
+     */
+    public Graph createGraph();
+
+    /**
+     * Create a new dataset.
+     *
+     * It is undefined if the dataset will be persisted by any underlying
+     * storage mechanism.
+     *
+     * @return A new Dataset
+     */
+    public Dataset createDataset();
+
+    /**
+     * Create an IRI from a (possibly escaped) String.
+     *
+     * The provided iri string MUST be valid according to the
+     * <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-iri">W3C RDF-1.1
+     * IRI</a> definition.
+     *
+     * @param iri
+     *            Internationalized Resource Identifier
+     * @return A new IRI
+     * @throws IllegalArgumentException
+     *             If the provided string is not acceptable, e.g. does not
+     *             conform to the RFC3987 syntax.
+     */
+    public IRI createIRI(String iri) throws IllegalArgumentException;
+
+    /**
+     * Create a simple literal.
+     *
+     * The provided lexical form should not be escaped in any sense, e.g. should
+     * not include "quotes" unless those are part of the literal value.
+     *
+     * The returned Literal MUST have a {@link Literal#getLexicalForm()} that is
+     * equal to the provided lexical form, MUST NOT have a
+     * {@link Literal#getLanguageTag()} present, and SHOULD return a
+     * {@link Literal#getDatatype()} that is equal to the IRI
+     * <code>http://www.w3.org/2001/XMLSchema#string</code>.
+     *
+     * @param lexicalForm
+     *            The literal value in plain text
+     * @return The created Literal
+     * @throws IllegalArgumentException
+     *             If the provided lexicalForm is not acceptable, e.g. because
+     *             it is too large for an underlying storage.
+     */
+    public Literal createLiteral(String lexicalForm) throws IllegalArgumentException;
+
+    /**
+     * Create a literal with the specified data type.
+     *
+     * The provided lexical form should not be escaped in any sense, e.g. should
+     * not include "quotes" unless those are part of the literal value.
+     *
+     * It is RECOMMENDED that the provided dataType is one of the <a href=
+     * "http://www.w3.org/TR/rdf11-concepts/#xsd-datatypes">RDF-compatible XSD
+     * types</a>.
+     *
+     * The provided lexical form SHOULD be in the
+     * <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-lexical-space">lexical
+     * space</a> of the provided dataType.
+     *
+     * The returned Literal SHOULD have a {@link Literal#getLexicalForm()} that
+     * is equal to the provided lexicalForm, MUST NOT have a
+     * {@link Literal#getLanguageTag()} present, and MUST return a
+     * {@link Literal#getDatatype()} that is equivalent to the provided dataType
+     * IRI.
+     *
+     * @param lexicalForm
+     *            The literal value
+     * @param dataType
+     *            The data type IRI for the literal value, e.g.
+     *            <code>http://www.w3.org/2001/XMLSchema#integer</code>
+     * @return The created Literal
+     * @throws IllegalArgumentException
+     *             If any of the provided arguments are not acceptable, e.g.
+     *             because the provided dataType is not permitted.
+     */
+    public Literal createLiteral(String lexicalForm, IRI dataType) throws IllegalArgumentException;
+
+    /**
+     * Create a language-tagged literal.
+     *
+     * The provided lexical form should not be escaped in any sense, e.g. should
+     * not include "quotes" unless those are part of the literal value.
+     *
+     * The provided language tag MUST be valid according to
+     * <a href="http://tools.ietf.org/html/bcp47">BCP47</a>, e.g.
+     * <code>en</code>.
+     *
+     * The provided language tag
+     * <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string"
+     * >MAY be converted to lower case</a>.
+     *
+     * The returned Literal SHOULD have a {@link Literal#getLexicalForm()} which
+     * is equal to the provided lexicalForm, MUST return a
+     * {@link Literal#getDatatype()} that is equal to the IRI
+     * <code>http://www.w3.org/1999/02/22-rdf-syntax-ns#langString</code>, and
+     * MUST have a {@link Literal#getLanguageTag()} present which SHOULD be
+     * equal to the provided language tag (compared as
+     * {@link String#toLowerCase(Locale)} using {@link Locale#ENGLISH}).
+     *
+     * @param lexicalForm
+     *            The literal value
+     * @param languageTag
+     *            The non-empty language tag as defined by
+     *            <a href="http://tools.ietf.org/html/bcp47">BCP47</a>
+     * @return The created Literal
+     * @throws IllegalArgumentException
+     *             If the provided values are not acceptable, e.g. because the
+     *             languageTag was syntactically invalid.
+     */
+    public Literal createLiteral(String lexicalForm, String languageTag) throws IllegalArgumentException;
+
+    /**
+     * Create a triple.
+     *
+     * The returned Triple SHOULD have a {@link Triple#getSubject()} that is
+     * equal to the provided subject, a {@link Triple#getPredicate()} that is
+     * equal to the provided predicate, and a {@link Triple#getObject()} that is
+     * equal to the provided object.
+     *
+     * @param subject
+     *            The IRI or BlankNode that is the subject of the triple
+     * @param predicate
+     *            The IRI that is the predicate of the triple
+     * @param object
+     *            The IRI, BlankNode or Literal that is the object of the triple
+     * @return The created Triple
+     * @throws IllegalArgumentException
+     *             If any of the provided arguments are not acceptable, e.g.
+     *             because a Literal has a lexicalForm that is too large for an
+     *             underlying storage.
+     */
+    public Triple createTriple(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) throws IllegalArgumentException;
+
+    /**
+     * Create a quad.
+     * <p>
+     * The returned Quad SHOULD have a {@link Quad#getGraphName()} that is equal
+     * to the provided graphName, a {@link Quad#getSubject()} that is equal to
+     * the provided subject, a {@link Quad#getPredicate()} that is equal to the
+     * provided predicate, and a {@link Quad#getObject()} that is equal to the
+     * provided object.
+     *
+     * @param graphName
+     *            The IRI or BlankNode that this quad belongs to, or
+     *            <code>null</code> for the public graph
+     * @param subject
+     *            The IRI or BlankNode that is the subject of the quad
+     * @param predicate
+     *            The IRI that is the predicate of the quad
+     * @param object
+     *            The IRI, BlankNode or Literal that is the object of the quad
+     * @return The created Quad
+     * @throws IllegalArgumentException
+     *             If any of the provided arguments are not acceptable, e.g.
+     *             because a Literal has a lexicalForm that is too large for an
+     *             underlying storage.
+     */
+    public Quad createQuad(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object)
+            throws IllegalArgumentException;
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFSyntax.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFSyntax.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFSyntax.java
new file mode 100644
index 0000000..954fe28
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFSyntax.java
@@ -0,0 +1,308 @@
+/**
+ * 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.api;
+
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * An RDF syntax, e.g. as used for parsing and writing RDF.
+ * <p>
+ * An RDF syntax is uniquely identified by its {@link #mediaType()}, and has a
+ * suggested {@link #fileExtension()}.
+ * <p>
+ * Some of the RDF syntaxes may {@link #supportsDataset()}, meaning they can
+ * represent {@link Quad}s.
+ * <p>
+ * An enumeration of the official RDF 1.1 syntaxes is available in 
+ * {@link W3CRDFSyntax} - for convenience they are also accessible
+ * as constants here, e.g. <code>RDFSyntax.JSONLD</code>.
+ * 
+ */
+public interface RDFSyntax {
+
+    /**
+     * JSON-LD 1.0
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/json-ld/">https://www.w3.org/TR/json-ld/</a>
+     * 
+     */
+    public static RDFSyntax JSONLD = W3CRDFSyntax.JSONLD;
+
+    /**
+     * RDF 1.1 Turtle
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/turtle/">https://www.w3.org/TR/turtle/</a>
+     *
+     */
+    public static RDFSyntax TURTLE = W3CRDFSyntax.TURTLE;
+
+    /**
+     * RDF 1.1 N-Quads
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/n-quads/">https://www.w3.org/TR/n-quads/</a>
+     */
+    public static RDFSyntax NQUADS = W3CRDFSyntax.NQUADS;
+
+    /**
+     * RDF 1.1 N-Triples
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/n-triples/">https://www.w3.org/TR/n-triples/</a>
+     */
+    public static RDFSyntax NTRIPLES = W3CRDFSyntax.NTRIPLES;
+
+    /**
+     * HTML+RDFa 1.1 and XHTML+RDFa 1.1 
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/html-rdfa/">https://www.w3.org/TR/html-rdfa/</a>
+     * @see <a href=
+     *      "https://www.w3.org/TR/xhtml-rdfa/">https://www.w3.org/TR/xhtml-rdfa/</a>
+     */
+    public static RDFSyntax RDFA = W3CRDFSyntax.RDFA;
+
+    /**
+     * RDF 1.1 XML Syntax
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/rdf-syntax-grammar/">https://www.w3.org/TR/rdf-syntax-grammar/</a>
+     */
+    public static RDFSyntax RDFXML = W3CRDFSyntax.RDFXML;
+
+    /**
+     * RDF 1.1 TriG
+     * 
+     * @see <a href=
+     *      "https://www.w3.org/TR/trig/">https://www.w3.org/TR/trig/</a>
+     */
+    public static RDFSyntax TRIG = W3CRDFSyntax.TRIG;
+    
+    /**
+     * A short name of the RDF Syntax e.g. <code>JSONLD</code>.
+     * <p>
+     * The name is specific to Commons RDF and carries no particular meaning. 
+     * 
+     * @return Short name for RDF syntax
+     */
+    public String name();
+
+    /**
+     * The title of the RDF Syntax.
+     * <p>
+     * This is generally the title of the corresponding standard, 
+     * e.g. <em>RDF 1.1 Turtle</em>.
+     * 
+     * @return Title of RDF Syntax
+     */
+    public String title();    
+    
+    /**
+     * The <a href="https://tools.ietf.org/html/rfc2046">IANA media type</a> for
+     * the RDF syntax.
+     * <p>
+     * The media type can be used as part of <code>Content-Type</code> and
+     * <code>Accept</code> for <em>content negotiation</em> in the
+     * <a href="https://tools.ietf.org/html/rfc7231#section-3.1.1.1">HTTP
+     * protocol</a>.
+     *
+     * @return The registered media type of the RDF Syntax
+     */
+    public String mediaType();
+
+    /**
+     * Set of <a href="https://tools.ietf.org/html/rfc2046">IANA media types</a> that
+     * covers this RDF syntax, including any non-official media types. 
+     * <p>
+     * The media type can be used as part of <code>Content-Type</code> and
+     * <code>Accept</code> for <em>content negotiation</em> in the
+     * <a href="https://tools.ietf.org/html/rfc7231#section-3.1.1.1">HTTP
+     * protocol</a>.
+     * <p>
+     * The returned Set MUST include the value {@link #mediaType()}; this is the
+     * behaviour of the default implementation.
+     *
+     * @return The media types corresponding to the RDF Syntax
+     */
+    default public Set<String> mediaTypes() {
+        return Collections.singleton(mediaType());
+    }
+    
+    /**
+     * The <a href="https://tools.ietf.org/html/rfc2046">IANA-registered</a>
+     * file extension.
+     * <p>
+     * The file extension includes the leading period, e.g. <code>.jsonld</code>
+     *
+     * @return The registered file extension of the RDF Syntax
+     */
+    public String fileExtension();
+
+    /**
+     * Set of file extensions for this RDF syntax, including any non-official extensions.
+     * <p>
+     * The file extension includes the leading period, e.g. <code>.jsonld</code>
+     * <p>
+     * The returned Set MUST include the value from {@link #fileExtension()}; this is
+     * the behaviour of the default implementation.
+     *
+     * @return The file extensions corresponding to the RDF Syntax
+     */
+    default public Set<String> fileExtensions() {
+        return Collections.singleton(fileExtension());
+    }
+    
+    /**
+     * Indicate if this RDF syntax supports
+     * <a href="https://www.w3.org/TR/rdf11-concepts/#section-dataset">RDF
+     * Datasets</a>.
+     *
+     * @return true if this RDF Syntax supports datasets; false otherwise
+     */
+    public boolean supportsDataset();
+
+    /**
+     * Return the {@link IRI} that <em>identifies</em> the RDF syntax.
+     * <p>
+     * Note that the identifying IRI is generally distinct from the IRI of the
+     * document that <em>specifies</em> the RDF syntax.
+     * 
+     * @return Identifying IRI, e.g.
+     *         <code>http://www.w3.org/ns/formats/JSON-LD</code>
+     */
+    public IRI iri();
+
+    /**
+     * Compare this RDFSyntax with another object.
+     * <p>
+     * Two {@link RDFSyntax}es are considered equal if their
+     * {@link #mediaType()}s are equal when compared as lower case strings
+     * according to {@link String#toLowerCase(Locale)} with the locale
+     * {@link Locale#ROOT}.
+     * 
+     * @param obj the object with which to compare
+     * @return true if this object is the same as the obj argument; false otherwise
+     */
+    @Override
+    boolean equals(Object obj);
+    
+    /**
+     * The hash code of an RDFSyntax is equivalent to the hash code 
+     * of the {@link #mediaType()} in lower case according to
+     * {@link String#toLowerCase(Locale)} with the locale
+     * {@link Locale#ROOT}. 
+     * 
+     * @return Hash code of RDFSyntax
+     */
+    @Override
+    int hashCode();
+    
+    /**
+     * Return the RDF 1.1 serialization syntaxes.
+     * <p>
+     * This lists the W3C standardized RDF 1.1 syntaxes like {@link #TURTLE} and
+     * {@link #JSONLD}. Note the existence of other RDF syntaxes that are not
+     * included here, e.g. <a href="http://www.w3.org/TeamSubmission/n3/">N3</a> and
+     * <a href="https://en.wikipedia.org/wiki/TriX_%28syntax%29">TriX</a>.
+     * <p>
+     * The syntaxes returned only support the {@link #mediaType()}
+     * and {@link #fileExtension()} as defined in the corresponding 
+     * W3C specification.
+     * 
+     * @return
+     *      A set of the official RDF 1.1 {@link RDFSyntax}es.
+     * 
+     * @see <a href="https://www.w3.org/TR/rdf11-primer/#section-graph-syntax">RDF
+     *      1.1 Primer</a>
+     * @see org.apache.commons.rdf.experimental.RDFParser
+     */
+
+    public static Set<RDFSyntax> w3cSyntaxes() {
+        return W3CRDFSyntax.syntaxes;
+    }
+
+    /**
+     * Return the RDFSyntax with the specified media type.
+     * <p>
+     * The <code>mediaType</code> is compared in lower case to all media types
+     * supported, therefore it might not be equal to the
+     * {@link RDFSyntax#mediaType} of the returned RDFSyntax.
+     * <p>
+     * If the media type specifies parameters, e.g.
+     * <code>text/turtle; charset=ascii</code>, only the part of the string to
+     * before <code>;</code> is considered.
+     * <p>
+     * This method support all syntaxes returned by {@link #w3cSyntaxes()}.
+     * 
+     * @param mediaType
+     *            The media type to match
+     * @return If {@link Optional#isPresent()}, the {@link RDFSyntax} which has
+     *         a matching {@link RDFSyntax#mediaType()}, otherwise
+     *         {@link Optional#empty()} indicating that no matching syntax was
+     *         found.
+     */
+    public static Optional<RDFSyntax> byMediaType(final String mediaType) {
+        final String type = mediaType.toLowerCase(Locale.ROOT).split("\\s*;", 2)[0];
+        return w3cSyntaxes().stream().filter(t -> t.mediaTypes().contains(type))
+                .findAny();
+    }
+
+    /**
+     * Return the RDFSyntax with the specified file extension.
+     * <p>
+     * The <code>fileExtension</code> is compared in lower case to all
+     * extensions supported, therefore it might not be equal to the
+     * {@link RDFSyntax#fileExtension} of the returned RDFSyntax.
+     * <p>
+     * This method support all syntaxes returned by {@link #w3cSyntaxes()}.
+     * 
+     * @param fileExtension
+     *            The fileExtension to match, starting with <code>.</code>
+     * @return If {@link Optional#isPresent()}, the {@link RDFSyntax} which has
+     *         a matching {@link RDFSyntax#fileExtension()}, otherwise
+     *         {@link Optional#empty()} indicating that no matching file
+     *         extension was found.
+     */
+    public static Optional<RDFSyntax> byFileExtension(final String fileExtension) {
+        final String ext = fileExtension.toLowerCase(Locale.ROOT);        
+        return w3cSyntaxes().stream().filter(t -> t.fileExtensions().contains(ext))
+                .findAny();
+    }
+    
+    /**
+     * Return the RDFSyntax with the specified {@link #name()}.
+     * <p>
+     * This method support all syntaxes returned by {@link #w3cSyntaxes()}.
+     * 
+     * @param name
+     *            The name to match, , e.g. <code>"JSONLD"</code>
+     * @return If {@link Optional#isPresent()}, the {@link RDFSyntax} which has
+     *         a matching {@link RDFSyntax#name()}, otherwise
+     *         {@link Optional#empty()} indicating that no matching name was found.
+     */    
+    public static Optional<RDFSyntax> byName(final String name) {
+        return w3cSyntaxes().stream().filter(t -> t.name().equals(name)).findAny();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTerm.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTerm.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTerm.java
new file mode 100644
index 0000000..dc095b7
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTerm.java
@@ -0,0 +1,107 @@
+/**
+ * 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.api;
+
+/**
+ * An <a href= "http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term" >RDF-1.1
+ * Term</a>, as defined by
+ * <a href= "http://www.w3.org/TR/rdf11-concepts/" >RDF-1.1 Concepts and
+ * Abstract Syntax</a>, a W3C Recommendation published on 25 February 2014.
+ * <p>
+ * A {@link RDFTerm} object in Commons RDF is considered
+ * <strong>immutable</strong>, that is, over its life time it will have
+ * consistent behaviour for its {@link #equals(Object)} and {@link #hashCode()},
+ * and objects returned from its getter methods (e.g. {@link IRI#getIRIString()}
+ * and {@link Literal#getLanguageTag()}) will have consistent
+ * {@link #equals(Object)} behaviour.
+ * <p>
+ * Note that methods in <code>RDFTerm</code> and its Commons RDF specialisations
+ * {@link IRI}, {@link BlankNode} and {@link Literal} are not required to return
+ * object identical (<code>==</code>) instances as long as they are equivalent
+ * according to their {@link Object#equals(Object)}. Further specialisations may
+ * provide additional methods that are documented to be mutable.
+ * <p>
+ * Methods in <code>RDFTerm</code> and its Commons RDF specialisations
+ * {@link IRI}, {@link BlankNode} and {@link Literal} are
+ * <strong>thread-safe</strong>, however further specialisations may add
+ * additional methods that are documented to not be thread-safe.
+ * <p>
+ * <code>RDFTerm</code>s can be safely used in hashing collections like
+ * {@link java.util.HashSet} and {@link java.util.HashMap}.
+ * <p>
+ * Any <code>RDFTerm</code> can be used interchangeably across Commons RDF
+ * implementations.
+ *
+ * @see <a href= "http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term" >RDF-1.1
+ *      Term</a>
+ */
+public interface RDFTerm {
+
+    /**
+     * Return the term serialised as specified by the RDF-1.1 N-Triples
+     * Canonical form.
+     *
+     * @return The term serialised as RDF-1.1 N-Triples.
+     * @see <a href="http://www.w3.org/TR/n-triples/#canonical-ntriples">
+     *      RDF-1.1 N-Triples Canonical form</a>
+     */
+    String ntriplesString();
+
+	/**
+	 * Check it this RDFTerm is equal to another RDFTerm.
+	 * <p>
+	 * If this object is an {@link IRI}, equality is checked using
+	 * {@link IRI#equals(Object)}, or if this object is a {@link BlankNode},
+	 * equality is checked using {@link BlankNode#equals(Object)}, or if this
+	 * object is a {@link Literal}, equality is checked using
+	 * {@link Literal#equals(Object)}.
+	 * <p>
+	 * Implementations MUST also override {@link #hashCode()} so that two equal
+	 * Literals produce the same hash code.
+	 *
+	 * @see IRI#equals(Object)
+	 * @see BlankNode#equals(Object)
+	 * @see Literal#equals(Object)
+	 *
+	 * @param other
+	 *            Another object
+	 * @return true if other is a RDFTerm and is equal to this
+	 */
+    @Override
+    public boolean equals(Object other);
+
+	/**
+	 * Calculate a hash code for this RDFTerm.
+	 * <p>
+	 * As an {@link RDFTerm} is <em>immutable</em>, this method will always
+	 * return the same hashCode over the lifetime of this object.
+	 * <p>
+	 * This method MUST be implemented in conjunction with
+	 * {@link #equals(Object)} so that two equal RDFTerm produce the same hash
+	 * code.
+	 *
+	 * @see IRI#hashCode()
+	 * @see Literal#hashCode()
+	 * @see BlankNode#hashCode()
+	 *
+	 * @return a hash code value for this RDFTerm.
+	 */
+    @Override
+    public int hashCode();
+
+}

http://git-wip-us.apache.org/repos/asf/commons-rdf/blob/d59203ce/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTermFactory.java
----------------------------------------------------------------------
diff --git a/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTermFactory.java b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTermFactory.java
new file mode 100644
index 0000000..321eebb
--- /dev/null
+++ b/commons-rdf-api/src/main/java/org/apache/commons/rdf/api/RDFTermFactory.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.api;
+
+/**
+ * Factory for creating RDFTerm instances..
+ * <p>
+ * This interface is <strong>deprecated</strong> in favour of the richer
+ * {@link RDF}.
+ * 
+ * @see RDF
+ */
+@Deprecated
+public interface RDFTermFactory {
+
+    default BlankNode createBlankNode() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("createBlankNode() not supported");
+    }
+
+    default BlankNode createBlankNode(final String name) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("createBlankNode(String) not supported");
+    }
+
+    default Graph createGraph() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("createGraph() not supported");
+    }
+
+    default IRI createIRI(final String iri) throws IllegalArgumentException, UnsupportedOperationException {
+        throw new UnsupportedOperationException("createIRI(String) not supported");
+    }
+
+    default Literal createLiteral(final String lexicalForm) throws IllegalArgumentException, UnsupportedOperationException {
+        throw new UnsupportedOperationException("createLiteral(String) not supported");
+    }
+
+    default Literal createLiteral(final String lexicalForm, final IRI dataType)
+            throws IllegalArgumentException, UnsupportedOperationException {
+        throw new UnsupportedOperationException("createLiteral(String) not supported");
+    }
+
+    default Literal createLiteral(final String lexicalForm, final String languageTag)
+            throws IllegalArgumentException, UnsupportedOperationException {
+        throw new UnsupportedOperationException("createLiteral(String,String) not supported");
+    }
+
+    default Triple createTriple(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object)
+            throws IllegalArgumentException, UnsupportedOperationException {
+        throw new UnsupportedOperationException("createTriple(BlankNodeOrIRI,IRI,RDFTerm) not supported");
+    }
+
+}