jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rve...@apache.org
Subject [1/6] jena git commit: Work towards dynamic loading of readers and writers in Hadoop RDF IO
Date Wed, 12 Nov 2014 14:35:28 GMT
Repository: jena
Updated Branches:
  refs/heads/hadoop-rdf f08fff2a9 -> 6a35e6765


Work towards dynamic loading of readers and writers in Hadoop RDF IO

This commit adds the first stage of work towards supporting entirely
dynamic loading of readers and writers in the Hadoop RDF IO module.
This is intended for use with the TriplesReader, QuadsReader and
TriplesOrQuadsReader to allow them to dynamically select the appropriate
reader to use for a given input file.  Making the loading dynamic allows
users to plug in custom RDF formats to ARQ and register them with the
Hadoop RDF IO module such that no core code changes are required to
start supporting a new input format under Hadoop.


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

Branch: refs/heads/hadoop-rdf
Commit: c429c8cf6a8f60f9bb3f758d56a05e63ee45c451
Parents: f08fff2
Author: Rob Vesse <rvesse@apache.org>
Authored: Tue Nov 11 15:44:28 2014 +0000
Committer: Rob Vesse <rvesse@apache.org>
Committed: Tue Nov 11 15:44:28 2014 +0000

----------------------------------------------------------------------
 .../hadoop/rdf/io/input/TriplesInputFormat.java |  48 +++---
 .../rdf/io/input/readers/QuadsReader.java       |  65 ++++----
 .../io/input/readers/TriplesOrQuadsReader.java  | 117 +++++++-------
 .../rdf/io/input/readers/TriplesReader.java     |  70 ++++-----
 .../rdf/io/registry/HadoopRdfIORegistry.java    | 151 +++++++++++++++++++
 .../hadoop/rdf/io/registry/ReaderFactory.java   |  65 ++++++++
 .../hadoop/rdf/io/registry/WriterFactory.java   |  65 ++++++++
 .../readers/AbstractQuadsOnlyReaderFactory.java |  65 ++++++++
 .../registry/readers/AbstractReaderFactory.java |  62 ++++++++
 .../AbstractTriplesOnlyReaderFactory.java       |  65 ++++++++
 .../registry/readers/JsonLDReaderFactory.java   |  49 ++++++
 .../registry/readers/NQuadsReaderFactory.java   |  42 ++++++
 .../registry/readers/NTriplesReaderFactory.java |  38 +++++
 .../registry/readers/RdfJsonReaderFactory.java  |  41 +++++
 .../registry/readers/RdfXmlReaderFactory.java   |  40 +++++
 .../registry/readers/ThriftReaderFactory.java   |  49 ++++++
 .../io/registry/readers/TriGReaderFactory.java  |  42 ++++++
 .../io/registry/readers/TriXReaderFactory.java  |  41 +++++
 .../registry/readers/TurtleReaderFactory.java   |  40 +++++
 ...he.jena.hadoop.rdf.io.registry.ReaderFactory |  10 ++
 ...he.jena.hadoop.rdf.io.registry.WriterFactory |   1 +
 .../io/registry/TestHadoopRdfIORegistry.java    | 128 ++++++++++++++++
 22 files changed, 1129 insertions(+), 165 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/TriplesInputFormat.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/TriplesInputFormat.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/TriplesInputFormat.java
index 24d93ba..03f394a 100644
--- a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/TriplesInputFormat.java
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/TriplesInputFormat.java
@@ -16,31 +16,27 @@
  * limitations under the License.
  */
 
-package org.apache.jena.hadoop.rdf.io.input;
-
-import java.io.IOException;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.mapreduce.InputSplit;
-import org.apache.hadoop.mapreduce.RecordReader;
-import org.apache.hadoop.mapreduce.TaskAttemptContext;
+package org.apache.jena.hadoop.rdf.io.input;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
 import org.apache.jena.hadoop.rdf.io.input.readers.TriplesReader;
 import org.apache.jena.hadoop.rdf.types.TripleWritable;
-
-
-/**
- * RDF input format that can handle any RDF triples format that ARQ supports
- * selecting the format to use for each file based upon the file extension
- * 
- * 
- * 
- */
-public class TriplesInputFormat extends AbstractWholeFileInputFormat<LongWritable, TripleWritable> {
-
-    @Override
-    public RecordReader<LongWritable, TripleWritable> createRecordReader(InputSplit split, TaskAttemptContext context)
-            throws IOException, InterruptedException {
-        return new TriplesReader();
-    }
-
-}
+
+/**
+ * RDF input format that can handle any RDF triples format that ARQ supports
+ * selecting the format to use for each file based upon the file extension
+ */
+public class TriplesInputFormat extends AbstractWholeFileInputFormat<LongWritable, TripleWritable> {
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createRecordReader(InputSplit split, TaskAttemptContext context)
+            throws IOException, InterruptedException {
+        return new TriplesReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/QuadsReader.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/QuadsReader.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/QuadsReader.java
index 4ea6e04..26b0a8b 100644
--- a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/QuadsReader.java
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/QuadsReader.java
@@ -16,39 +16,34 @@
  * limitations under the License.
  */
 
-package org.apache.jena.hadoop.rdf.io.input.readers;
-
-import java.io.IOException;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.mapreduce.RecordReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.nquads.WholeFileNQuadsReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.trig.TriGReader;
+package org.apache.jena.hadoop.rdf.io.input.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.registry.HadoopRdfIORegistry;
 import org.apache.jena.hadoop.rdf.types.QuadWritable;
-import org.apache.jena.riot.Lang;
-import org.apache.jena.riot.RDFLanguages;
-
-import com.hp.hpl.jena.sparql.core.Quad;
-
-/**
- * A record reader that reads triples from any RDF quads format
- * 
- * 
- * 
- */
-public class QuadsReader extends AbstractRdfReader<Quad, QuadWritable> {
-
-    @Override
-    protected RecordReader<LongWritable, QuadWritable> selectRecordReader(Lang lang) throws IOException {
-        if (!RDFLanguages.isQuads(lang))
-            throw new IOException(lang.getLabel() + " is not a RDF quads format, perhaps you wanted TriplesInputFormat or TriplesOrQuadsInputFormat instead?");
-
-        if (lang.equals(Lang.NQ) || lang.equals(Lang.NQUADS)) {
-            return new WholeFileNQuadsReader();
-        } else if (lang.equals(Lang.TRIG)) {
-            return new TriGReader();
-        }
-        throw new IOException(lang.getLabel() + " has no associated RecordReader implementation");
-    }
-
-}
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFLanguages;
+
+import com.hp.hpl.jena.sparql.core.Quad;
+
+/**
+ * A record reader that reads triples from any RDF quads format
+ */
+public class QuadsReader extends AbstractRdfReader<Quad, QuadWritable> {
+
+    @Override
+    protected RecordReader<LongWritable, QuadWritable> selectRecordReader(Lang lang) throws IOException {
+        if (!RDFLanguages.isQuads(lang))
+            throw new IOException(
+                    lang.getLabel()
+                            + " is not a RDF quads format, perhaps you wanted TriplesInputFormat or TriplesOrQuadsInputFormat instead?");
+
+        // This will throw an appropriate error if the language does not support
+        // triples
+        return HadoopRdfIORegistry.createQuadReader(lang);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesOrQuadsReader.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesOrQuadsReader.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesOrQuadsReader.java
index c4fd860..b071f67 100644
--- a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesOrQuadsReader.java
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesOrQuadsReader.java
@@ -16,68 +16,57 @@
  * limitations under the License.
  */
 
-package org.apache.jena.hadoop.rdf.io.input.readers;
-
-import java.io.IOException;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.mapreduce.RecordReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.nquads.WholeFileNQuadsReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.ntriples.WholeFileNTriplesReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.rdfjson.RdfJsonReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.rdfxml.RdfXmlReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.trig.TriGReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.turtle.TurtleReader;
+package org.apache.jena.hadoop.rdf.io.input.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.registry.HadoopRdfIORegistry;
 import org.apache.jena.hadoop.rdf.types.QuadWritable;
-import org.apache.jena.riot.Lang;
-import org.apache.jena.riot.RDFLanguages;
-
-import com.hp.hpl.jena.graph.Node;
-import com.hp.hpl.jena.sparql.core.Quad;
-
-/**
- * A record reader that reads RDF from any triples/quads format. Triples are
- * converted into quads in the default graph. This behaviour can be changed by
- * deriving from this class and overriding the {@link #getGraphNode()} method
- * 
- * 
- * 
- */
-@SuppressWarnings("javadoc")
-public class TriplesOrQuadsReader extends AbstractRdfReader<Quad, QuadWritable> {
-
-    @Override
-    protected RecordReader<LongWritable, QuadWritable> selectRecordReader(Lang lang) throws IOException {
-        if (!RDFLanguages.isQuads(lang) && !RDFLanguages.isTriples(lang))
-            throw new IOException(lang.getLabel() + " is not a RDF triples/quads format");
-
-        if (lang.equals(Lang.NQ) || lang.equals(Lang.NQUADS)) {
-            return new WholeFileNQuadsReader();
-        } else if (lang.equals(Lang.TRIG)) {
-            return new TriGReader();
-        } else if (lang.equals(Lang.NTRIPLES) || lang.equals(Lang.NT)) {
-            return new TriplesToQuadsReader(new WholeFileNTriplesReader());
-        } else if (lang.equals(Lang.TTL) || lang.equals(Lang.TURTLE) || lang.equals(Lang.N3)) {
-            return new TriplesToQuadsReader(new TurtleReader());
-        } else if (lang.equals(Lang.RDFXML)) {
-            return new TriplesToQuadsReader(new RdfXmlReader());
-        } else if (lang.equals(Lang.RDFJSON)) {
-            return new TriplesToQuadsReader(new RdfJsonReader());
-        }
-        throw new IOException(lang.getLabel() + " has no associated RecordReader implementation");
-    }
-
-    /**
-     * Gets the graph node which represents the graph into which triples will be
-     * indicated to belong to when they are converting into quads.
-     * <p>
-     * Defaults to {@link Quad#defaultGraphNodeGenerated} which represents the
-     * default graph
-     * </p>
-     * 
-     * @return Graph node
-     */
-    protected Node getGraphNode() {
-        return Quad.defaultGraphNodeGenerated;
-    }
-}
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFLanguages;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.sparql.core.Quad;
+
+/**
+ * A record reader that reads RDF from any triples/quads format. Triples are
+ * converted into quads in the default graph. This behaviour can be changed by
+ * deriving from this class and overriding the {@link #getGraphNode()} method
+ * 
+ * 
+ * 
+ */
+@SuppressWarnings("javadoc")
+public class TriplesOrQuadsReader extends AbstractRdfReader<Quad, QuadWritable> {
+
+    @Override
+    protected RecordReader<LongWritable, QuadWritable> selectRecordReader(Lang lang) throws IOException {
+        if (!RDFLanguages.isQuads(lang) && !RDFLanguages.isTriples(lang))
+            throw new IOException(lang.getLabel() + " is not a RDF triples/quads format");
+
+        if (HadoopRdfIORegistry.hasQuadReader(lang)) {
+            // Supports quads directly
+            return HadoopRdfIORegistry.createQuadReader(lang);
+        } else {
+            // Try to create a triples reader and wrap upwards into quads
+            // This will throw an error if a triple reader is not available
+            return new TriplesToQuadsReader(HadoopRdfIORegistry.createTripleReader(lang));
+        }
+    }
+
+    /**
+     * Gets the graph node which represents the graph into which triples will be
+     * indicated to belong to when they are converting into quads.
+     * <p>
+     * Defaults to {@link Quad#defaultGraphNodeGenerated} which represents the
+     * default graph
+     * </p>
+     * 
+     * @return Graph node
+     */
+    protected Node getGraphNode() {
+        return Quad.defaultGraphNodeGenerated;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesReader.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesReader.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesReader.java
index 2f6e87c..96c4a65 100644
--- a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesReader.java
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/input/readers/TriplesReader.java
@@ -16,44 +16,34 @@
  * limitations under the License.
  */
 
-package org.apache.jena.hadoop.rdf.io.input.readers;
-
-import java.io.IOException;
-
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.mapreduce.RecordReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.ntriples.WholeFileNTriplesReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.rdfjson.RdfJsonReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.rdfxml.RdfXmlReader;
-import org.apache.jena.hadoop.rdf.io.input.readers.turtle.TurtleReader;
+package org.apache.jena.hadoop.rdf.io.input.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.registry.HadoopRdfIORegistry;
 import org.apache.jena.hadoop.rdf.types.TripleWritable;
-import org.apache.jena.riot.Lang;
-import org.apache.jena.riot.RDFLanguages;
-
-import com.hp.hpl.jena.graph.Triple;
-
-/**
- * A record reader that reads triples from any RDF triples format
- * 
- *
- */
-public class TriplesReader extends AbstractRdfReader<Triple, TripleWritable> {
-
-    @Override
-    protected RecordReader<LongWritable, TripleWritable> selectRecordReader(Lang lang) throws IOException {
-        if (!RDFLanguages.isTriples(lang))
-            throw new IOException(lang.getLabel() + " is not a RDF triples format, perhaps you wanted QuadsInputFormat or TriplesOrQuadsInputFormat instead?");
-
-        if (lang.equals(Lang.NTRIPLES) || lang.equals(Lang.NT)) {
-            return new WholeFileNTriplesReader();
-        } else if (lang.equals(Lang.TTL) || lang.equals(Lang.TURTLE) || lang.equals(Lang.N3)) {
-            return new TurtleReader();
-        } else if (lang.equals(Lang.RDFXML)) {
-            return new RdfXmlReader();
-        } else if (lang.equals(Lang.RDFJSON)) {
-            return new RdfJsonReader();
-        }
-        throw new IOException(lang.getLabel() + " has no associated RecordReader implementation");
-    }
-
-}
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFLanguages;
+
+import com.hp.hpl.jena.graph.Triple;
+
+/**
+ * A record reader that reads triples from any RDF triples format
+ */
+public class TriplesReader extends AbstractRdfReader<Triple, TripleWritable> {
+
+    @Override
+    protected RecordReader<LongWritable, TripleWritable> selectRecordReader(Lang lang) throws IOException {
+        if (!RDFLanguages.isTriples(lang))
+            throw new IOException(
+                    lang.getLabel()
+                            + " is not a RDF triples format, perhaps you wanted QuadsInputFormat or TriplesOrQuadsInputFormat instead?");
+
+        // This will throw an appropriate error if the language does not support
+        // triples
+        return HadoopRdfIORegistry.createTripleReader(lang);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/HadoopRdfIORegistry.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/HadoopRdfIORegistry.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/HadoopRdfIORegistry.java
new file mode 100644
index 0000000..af7c486
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/HadoopRdfIORegistry.java
@@ -0,0 +1,151 @@
+package org.apache.jena.hadoop.rdf.io.registry;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ * A registry which is used by various classes to dynamically select record
+ * readers and writers based on a provided {@link Lang}
+ * <p>
+ * Readers and writers are dynamically discovered using the Java
+ * {@link ServiceLoader} mechanism. This will look for files under
+ * {@code META-INF/services} named
+ * {@code org.apache.jena.hadoop.rdf.io.registry.ReaderFactory} and
+ * {@code org.apache.jena.hadoop.rdf.io.registry.WriterFactory}. These follow
+ * the standard {@linkplain ServiceLoader} format of provided one class name per
+ * line which implements the relevant interface.
+ * </p>
+ * 
+ */
+public class HadoopRdfIORegistry {
+
+    private static Map<Lang, ReaderFactory> readers = new HashMap<Lang, ReaderFactory>();
+    private static boolean init = false;
+
+    static {
+        init();
+    }
+
+    private static synchronized void init() {
+        if (init)
+            return;
+
+        // Dynamically load and register reader factories
+        ServiceLoader<ReaderFactory> readerFactoryLoader = ServiceLoader.load(ReaderFactory.class);
+        Iterator<ReaderFactory> iter = readerFactoryLoader.iterator();
+        while (iter.hasNext()) {
+            ReaderFactory f = iter.next();
+            addReaderFactory(f);
+        }
+
+        init = true;
+    }
+
+    /**
+     * Resets the registry to the default configuration
+     */
+    public static synchronized void reset() {
+        if (!init)
+            return;
+
+        init = false;
+        init();
+    }
+
+    public static void addReaderFactory(ReaderFactory f) {
+        if (f == null)
+            throw new NullPointerException("Factory cannot be null");
+
+        readers.put(f.getPrimaryLanguage(), f);
+        for (Lang altLang : f.getAlternativeLanguages()) {
+            readers.put(altLang, f);
+        }
+    }
+
+    /**
+     * Gets whether there is a quad reader available for the given language
+     * 
+     * @param lang
+     *            Language
+     * @return True if available, false otherwise
+     */
+    public static boolean hasQuadReader(Lang lang) {
+        if (lang == null)
+            return false;
+
+        ReaderFactory f = readers.get(lang);
+        if (f == null)
+            return false;
+        return f.canReadQuads();
+    }
+
+    /**
+     * Gets whether there is a triple reader available for the given language
+     * 
+     * @param lang
+     *            Language
+     * @return True if available, false otherwise
+     */
+    public static boolean hasTriplesReader(Lang lang) {
+        if (lang == null)
+            return false;
+
+        ReaderFactory f = readers.get(lang);
+        if (f == null)
+            return false;
+        return f.canReadTriples();
+    }
+
+    /**
+     * Tries to create a quad reader for the given language
+     * 
+     * @param lang
+     *            Language
+     * @return Quad reader if one is available
+     * @throws IOException
+     *             Thrown if a quad reader is not available or the given
+     *             language does not support quads
+     */
+    public static RecordReader<LongWritable, QuadWritable> createQuadReader(Lang lang) throws IOException {
+        if (lang == null)
+            throw new IOException("Cannot create a quad reader for an undefined language");
+
+        ReaderFactory f = readers.get(lang);
+        if (f == null)
+            throw new IOException("No factory registered for language " + lang.getName());
+        if (!f.canReadQuads())
+            throw new IOException(lang.getName() + " does not support reading quads");
+        return f.createQuadReader();
+    }
+
+    /**
+     * Tries to create a triple reader for the given language
+     * 
+     * @param lang
+     *            Language
+     * @return Triple reader if one is available
+     * @throws IOException
+     *             Thrown if a triple reader is not available or the given
+     *             language does not support triple
+     */
+    public static RecordReader<LongWritable, TripleWritable> createTripleReader(Lang lang) throws IOException {
+        if (lang == null)
+            throw new IOException("Cannot create a triple reader for an undefined language");
+
+        ReaderFactory f = readers.get(lang);
+        if (f == null)
+            throw new IOException("No factory registered for language " + lang.getName());
+        if (!f.canReadTriples())
+            throw new IOException(lang.getName() + " does not support reading triples");
+        return f.createTripleReader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/ReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/ReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/ReaderFactory.java
new file mode 100644
index 0000000..a925141
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/ReaderFactory.java
@@ -0,0 +1,65 @@
+package org.apache.jena.hadoop.rdf.io.registry;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ * Interface for reader factories
+ * 
+ */
+public interface ReaderFactory {
+
+    /**
+     * Gets the primary language this factory produces readers for
+     * 
+     * @return Primary language
+     */
+    public abstract Lang getPrimaryLanguage();
+
+    /**
+     * Gets the alternative languages this factory can produce readers for
+     * 
+     * @return Alternative languages
+     */
+    public abstract Collection<Lang> getAlternativeLanguages();
+
+    /**
+     * Gets whether this factory can produce readers that are capable of reading
+     * quads
+     * 
+     * @return True if quads can be read, false if not
+     */
+    public abstract boolean canReadQuads();
+
+    /**
+     * Gets whether this factory can produce readers that are capable of reading
+     * triples
+     * 
+     * @return True if triples can be read, false if not
+     */
+    public abstract boolean canReadTriples();
+
+    /**
+     * Creates a quad reader
+     * 
+     * @return Quad reader
+     * @throws IOException
+     *             May be thrown if a quad reader cannot be created
+     */
+    public abstract RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException;
+
+    /**
+     * Creates a triples reader
+     * 
+     * @return Triples reader
+     * @throws IOException
+     *             May be thrown if a triple reader cannot be created
+     */
+    public abstract RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/WriterFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/WriterFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/WriterFactory.java
new file mode 100644
index 0000000..9e21eb5
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/WriterFactory.java
@@ -0,0 +1,65 @@
+package org.apache.jena.hadoop.rdf.io.registry;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordWriter;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ * Interface for writer factories
+ * 
+ */
+public interface WriterFactory {
+
+    /**
+     * Gets the primary language this factory produces writers for
+     * 
+     * @return Primary language
+     */
+    public abstract Lang getPrimaryLanguage();
+
+    /**
+     * Gets the alternative languages this factory can produce writers for
+     * 
+     * @return Alternative languages
+     */
+    public abstract Collection<Lang> getAlternativeLanguages();
+
+    /**
+     * Gets whether this factory can produce writer that are capable of reading
+     * quads
+     * 
+     * @return True if quads can be written, false if not
+     */
+    public abstract boolean canWriteQuads();
+
+    /**
+     * Gets whether this factory can produce writers that are capable of reading
+     * triples
+     * 
+     * @return True if triples can be written, false if not
+     */
+    public abstract boolean canWriteTriples();
+
+    /**
+     * Creates a quad writer
+     * 
+     * @return Quad writer
+     * @throws IOException
+     *             May be thrown if a quad writer cannot be created
+     */
+    public abstract RecordWriter<LongWritable, QuadWritable> createQuadWriter() throws IOException;
+
+    /**
+     * Creates a triples writer
+     * 
+     * @return Triples writer
+     * @throws IOException
+     *             May be thrown if a triple writer cannot be created
+     */
+    public abstract RecordWriter<LongWritable, TripleWritable> createTripleWriter() throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractQuadsOnlyReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractQuadsOnlyReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractQuadsOnlyReaderFactory.java
new file mode 100644
index 0000000..8902f2e
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractQuadsOnlyReaderFactory.java
@@ -0,0 +1,65 @@
+package org.apache.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.registry.ReaderFactory;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ * Abstract reader factory for languages that only support quads
+ */
+public abstract class AbstractQuadsOnlyReaderFactory implements ReaderFactory {
+
+    private Lang lang;
+    private Collection<Lang> alternateLangs = Collections.unmodifiableList(Collections.<Lang>emptyList());
+
+    public AbstractQuadsOnlyReaderFactory(Lang lang) {
+        this(lang, (Collection<Lang>)null);
+    }
+    
+    public AbstractQuadsOnlyReaderFactory(Lang lang, Lang...altLangs) {
+        this(lang, Arrays.asList(altLangs));
+    }
+
+    public AbstractQuadsOnlyReaderFactory(Lang lang, Collection<Lang> altLangs) {
+        this.lang = lang;
+        if (altLangs != null)
+            this.alternateLangs = Collections.unmodifiableCollection(altLangs);
+    }
+
+    @Override
+    public final Lang getPrimaryLanguage() {
+        return this.lang;
+    }
+    
+    @Override
+    public final Collection<Lang> getAlternativeLanguages() {
+        return this.alternateLangs;
+    }
+
+    @Override
+    public final boolean canReadQuads() {
+        return true;
+    }
+
+    @Override
+    public final boolean canReadTriples() {
+        return false;
+    }
+
+    @Override
+    public abstract RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException;
+
+    @Override
+    public final RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        throw new IOException(this.lang.getName() + " does not support reading triples");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractReaderFactory.java
new file mode 100644
index 0000000..fe00289
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractReaderFactory.java
@@ -0,0 +1,62 @@
+package org.apache.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.registry.ReaderFactory;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ * Abstract reader factory for languages that support triples and quads
+ */
+public abstract class AbstractReaderFactory implements ReaderFactory {
+
+    private Lang lang;
+    private Collection<Lang> alternateLangs = Collections.unmodifiableList(Collections.<Lang>emptyList());
+
+    public AbstractReaderFactory(Lang lang) {
+        this(lang, (Collection<Lang>)null);
+    }
+    
+    public AbstractReaderFactory(Lang lang, Lang...altLangs) {
+        this(lang, Arrays.asList(altLangs));
+    }
+
+    public AbstractReaderFactory(Lang lang, Collection<Lang> altLangs) {
+        this.lang = lang;
+        if (altLangs != null)
+            this.alternateLangs = Collections.unmodifiableCollection(altLangs);
+    }
+
+    @Override
+    public final Lang getPrimaryLanguage() {
+        return this.lang;
+    }
+    
+    @Override
+    public final Collection<Lang> getAlternativeLanguages() {
+        return this.alternateLangs;
+    }
+
+    @Override
+    public final boolean canReadQuads() {
+        return true;
+    }
+
+    @Override
+    public final boolean canReadTriples() {
+        return true;
+    }
+
+    @Override
+    public abstract RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException;
+
+    @Override
+    public abstract RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException;
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractTriplesOnlyReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractTriplesOnlyReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractTriplesOnlyReaderFactory.java
new file mode 100644
index 0000000..d802123
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/AbstractTriplesOnlyReaderFactory.java
@@ -0,0 +1,65 @@
+package org.apache.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.registry.ReaderFactory;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ * Abstract reader factory for languages that only support triples
+ */
+public abstract class AbstractTriplesOnlyReaderFactory implements ReaderFactory {
+
+    private Lang lang;
+    private Collection<Lang> alternateLangs = Collections.unmodifiableList(Collections.<Lang>emptyList());
+
+    public AbstractTriplesOnlyReaderFactory(Lang lang) {
+        this(lang, (Collection<Lang>)null);
+    }
+    
+    public AbstractTriplesOnlyReaderFactory(Lang lang, Lang...altLangs) {
+        this(lang, Arrays.asList(altLangs));
+    }
+
+    public AbstractTriplesOnlyReaderFactory(Lang lang, Collection<Lang> altLangs) {
+        this.lang = lang;
+        if (altLangs != null)
+            this.alternateLangs = Collections.unmodifiableCollection(altLangs);
+    }
+
+    @Override
+    public final Lang getPrimaryLanguage() {
+        return this.lang;
+    }
+    
+    @Override
+    public final Collection<Lang> getAlternativeLanguages() {
+        return this.alternateLangs;
+    }
+    
+    @Override
+    public final boolean canReadQuads() {
+        return false;
+    }
+
+    @Override
+    public final boolean canReadTriples() {
+        return true;
+    }
+
+    @Override
+    public final RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException {
+        throw new IOException(this.lang.getName() + " does not support reading quads");
+    }
+
+    @Override
+    public abstract RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException;
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/JsonLDReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/JsonLDReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/JsonLDReaderFactory.java
new file mode 100644
index 0000000..6b064a4
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/JsonLDReaderFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.jsonld.JsonLDQuadReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.jsonld.JsonLDTripleReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ *
+ */
+public class JsonLDReaderFactory extends AbstractReaderFactory {
+    
+    public JsonLDReaderFactory() {
+        super(Lang.JSONLD);
+    }
+
+    @Override
+    public RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException {
+        return new JsonLDQuadReader();
+    }
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        return new JsonLDTripleReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NQuadsReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NQuadsReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NQuadsReaderFactory.java
new file mode 100644
index 0000000..2296296
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NQuadsReaderFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.nquads.WholeFileNQuadsReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ *
+ */
+public class NQuadsReaderFactory extends AbstractQuadsOnlyReaderFactory {
+    
+    public NQuadsReaderFactory() {
+        super(Lang.NQUADS, Lang.NQ);
+    }
+
+    @Override
+    public RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException {
+        return new WholeFileNQuadsReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NTriplesReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NTriplesReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NTriplesReaderFactory.java
new file mode 100644
index 0000000..a98a1ae
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/NTriplesReaderFactory.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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.ntriples.WholeFileNTriplesReader;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+public class NTriplesReaderFactory extends AbstractTriplesOnlyReaderFactory {
+
+    public NTriplesReaderFactory() {
+        super(Lang.NTRIPLES, Lang.NT);
+    }
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        return new WholeFileNTriplesReader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfJsonReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfJsonReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfJsonReaderFactory.java
new file mode 100644
index 0000000..ccf5feb
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfJsonReaderFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.rdfjson.RdfJsonReader;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ *
+ */
+public class RdfJsonReaderFactory extends AbstractTriplesOnlyReaderFactory {
+
+    public RdfJsonReaderFactory() {
+        super(Lang.RDFJSON);
+    }
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        return new RdfJsonReader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfXmlReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfXmlReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfXmlReaderFactory.java
new file mode 100644
index 0000000..1aa88d7
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/RdfXmlReaderFactory.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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.rdfxml.RdfXmlReader;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+public class RdfXmlReaderFactory extends AbstractTriplesOnlyReaderFactory {
+
+    public RdfXmlReaderFactory() {
+        super(Lang.RDFXML);
+    }
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        return new RdfXmlReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/ThriftReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/ThriftReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/ThriftReaderFactory.java
new file mode 100644
index 0000000..25e8234
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/ThriftReaderFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.thrift.ThriftQuadReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.thrift.ThriftTripleReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.RDFLanguages;
+
+/**
+ *
+ */
+public class ThriftReaderFactory extends AbstractReaderFactory {
+    
+    public ThriftReaderFactory() {
+        super(RDFLanguages.THRIFT);
+    }
+
+    @Override
+    public RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException {
+        return new ThriftQuadReader();
+    }
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        return new ThriftTripleReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriGReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriGReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriGReaderFactory.java
new file mode 100644
index 0000000..83ea818
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriGReaderFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.trig.TriGReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ *
+ */
+public class TriGReaderFactory extends AbstractQuadsOnlyReaderFactory {
+
+    public TriGReaderFactory() {
+        super(Lang.TRIG);
+    }
+
+    @Override
+    public RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException {
+        return new TriGReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriXReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriXReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriXReaderFactory.java
new file mode 100644
index 0000000..cb8795c
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TriXReaderFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.trix.TriXReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.riot.Lang;
+
+/**
+ *
+ */
+public class TriXReaderFactory extends AbstractQuadsOnlyReaderFactory {
+
+    public TriXReaderFactory() {
+        super(Lang.TRIX);
+    }
+
+    @Override
+    public RecordReader<LongWritable, QuadWritable> createQuadReader() throws IOException {
+        return new TriXReader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TurtleReaderFactory.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TurtleReaderFactory.java b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TurtleReaderFactory.java
new file mode 100644
index 0000000..7800376
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/java/org/apache/jena/hadoop/rdf/io/registry/readers/TurtleReaderFactory.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.jena.hadoop.rdf.io.registry.readers;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.io.input.readers.turtle.TurtleReader;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+
+public class TurtleReaderFactory extends AbstractTriplesOnlyReaderFactory {
+    
+    public TurtleReaderFactory() {
+        super(Lang.TURTLE, Lang.TTL, Lang.N3);
+    }
+
+    @Override
+    public RecordReader<LongWritable, TripleWritable> createTripleReader() throws IOException {
+        return new TurtleReader();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.ReaderFactory
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.ReaderFactory b/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.ReaderFactory
new file mode 100644
index 0000000..ec0e48a
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.ReaderFactory
@@ -0,0 +1,10 @@
+# Default Reader Factory implementations
+org.apache.jena.hadoop.rdf.io.registry.readers.JsonLDReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.NQuadsReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.NTriplesReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.RdfJsonReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.RdfXmlReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.ThriftReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.TriGReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.TriXReaderFactory
+org.apache.jena.hadoop.rdf.io.registry.readers.TurtleReaderFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.WriterFactory
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.WriterFactory b/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.WriterFactory
new file mode 100644
index 0000000..e29267a
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/main/resources/META-INF/services/org.apache.jena.hadoop.rdf.io.registry.WriterFactory
@@ -0,0 +1 @@
+# Default Writer Factory implementations
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/c429c8cf/jena-hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/registry/TestHadoopRdfIORegistry.java
----------------------------------------------------------------------
diff --git a/jena-hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/registry/TestHadoopRdfIORegistry.java b/jena-hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/registry/TestHadoopRdfIORegistry.java
new file mode 100644
index 0000000..48a3559
--- /dev/null
+++ b/jena-hadoop-rdf/hadoop-rdf-io/src/test/java/org/apache/jena/hadoop/rdf/io/registry/TestHadoopRdfIORegistry.java
@@ -0,0 +1,128 @@
+/*
+ * 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.jena.hadoop.rdf.io.registry;
+
+import java.io.IOException;
+
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.jena.hadoop.rdf.types.QuadWritable;
+import org.apache.jena.hadoop.rdf.types.TripleWritable;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFLanguages;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link HadoopRdfIORegistry}
+ */
+public class TestHadoopRdfIORegistry {
+    
+    private void testLang(Lang lang, boolean triples, boolean quads) {
+        Assert.assertEquals(triples, HadoopRdfIORegistry.hasTriplesReader(lang));
+        Assert.assertEquals(quads, HadoopRdfIORegistry.hasQuadReader(lang));
+        
+        if (triples) {
+            RecordReader<LongWritable, TripleWritable> tripleReader;
+            try {
+                tripleReader = HadoopRdfIORegistry.createTripleReader(lang);
+                Assert.assertNotNull(tripleReader);
+            } catch (IOException e) {
+                Assert.fail("Registry indicates that " + lang.getName() + " can read triples but fails to produce a triple reader when asked: " + e.getMessage());
+            }
+        } else {
+            try {
+                HadoopRdfIORegistry.createTripleReader(lang);
+                Assert.fail("Registry indicates that " + lang.getName() + " cannot read triples but produced a triple reader when asked (error was expected)");
+            } catch (IOException e) {
+                // This is expected
+            }
+        }
+        
+        if (quads) {
+            RecordReader<LongWritable, QuadWritable> quadReader;
+            try {
+                quadReader = HadoopRdfIORegistry.createQuadReader(lang);
+                Assert.assertNotNull(quadReader);
+            } catch (IOException e) {
+                Assert.fail("Registry indicates that " + lang.getName() + " can read quads but fails to produce a quad reader when asked: " + e.getMessage());
+            }
+        } else {
+            try {
+                HadoopRdfIORegistry.createQuadReader(lang);
+                Assert.fail("Registry indicates that " + lang.getName() + " cannot read quads but produced a quad reader when asked (error was expected)");
+            } catch (IOException e) {
+                // This is expected
+            }
+        }
+    }
+
+    @Test
+    public void json_ld_registered() {
+        testLang(Lang.JSONLD, true, true);
+    }
+    
+    @Test
+    public void nquads_registered() {
+        testLang(Lang.NQUADS, false, true);
+        testLang(Lang.NQ, false, true);
+    }
+    
+    @Test
+    public void ntriples_registered() {
+        testLang(Lang.NTRIPLES, true, false);
+        testLang(Lang.NT, true, false);
+    }
+    
+    @Test
+    public void rdf_json_registered() {
+        testLang(Lang.RDFJSON, true, false);
+    }
+    
+    @Test
+    public void rdf_xml_registered() {
+        testLang(Lang.RDFXML, true, false);
+    }
+    
+    @Test
+    public void rdf_thrift_registered() {
+        testLang(RDFLanguages.THRIFT, true, true);
+    }
+    
+    @Test
+    public void trig_registered() {
+        testLang(Lang.TRIG, false, true);
+    }
+    
+    @Test
+    public void trix_registered() {
+        testLang(Lang.TRIX, false, true);
+    }
+    
+    @Test
+    public void turtle_registered() {
+        testLang(Lang.TURTLE, true, false);
+        testLang(Lang.TTL, true, false);
+        testLang(Lang.N3, true, false);
+    }
+    
+    @Test
+    public void unregistered() {
+        testLang(Lang.RDFNULL, false, false);
+    }
+}


Mime
View raw message