Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

rfe10452: support N-Quads responses in the Java client

<release-note>
rfe10452: support N-Quads responses in the Java client

With this change, the Java client now supports N-Quads responses from the
server.  The property -Dcom.franz.agraph.http.defaultRDFFormat=NQUADS can
now be used to configure the client to request N-Quads format by default
for RDF statement responses; when this property is not present, the default
format is TriX.  The method AGHttpRepoClient#setPreferredRDFFormat() can
also be used to override the default RDFFormat on a per connection basis.
</release-note>

'make prepush' passes (default still uses TriX)
'make -Dcom.franz.agraph.http.defaultRDFFormat=NQUADS prepush' passes
'ant tutorial' runs (default still using TriX)
'ant  -Dcom.franz.agraph.http.defaultRDFFormat=NQUADS tutorial' runs
A small events test passes with both TriX and NQUADS, using options:
--catalog java-tutorial --load 2 --query 2 --time 1 --size 10000
'make javadoc' runs clean

Performance:

The default RDFFormat of the client is still TriX.  When using the
option -Dcom.franz.agraph.http.defaultRDFFormat=NQUADS with make
prepush, ant tutorial, and a small events test, the performance is
comparable to marginally faster; if the performance on larger tests
is also comparable or faster, the default may be changed to NQUADS
in future.

Change-Id: I3d22315f5e3b12f7e7d901ee99cdf110a647b5a7
Reviewed-on: https://gerrit.franz.com:9080/1391
Reviewed-by: John O'Rourke <jor@franz.com>
Reviewed-by: Ahmon Dancy <dancy@franz.com>
Tested-by: Kevin Layer <layer@franz.com>
  • Loading branch information...
commit 3b58e048847716cf2803f27bc9a7ccabfbff9820 1 parent 1de745e
Bill Millar authored dklayer committed
View
2  build.xml
@@ -171,7 +171,7 @@
noindex="false"
nonavbar="false"
notree="false"
- packagenames="com.franz.agraph.jena,com.franz.util,com.franz.agraph.repository"
+ packagenames="com.franz.agraph.jena,com.franz.agraph.repository,com.franz.openrdf.rio.nquads,com.franz.util"
source="1.6"
sourcepath="src"
splitindex="true"
View
37 src/com/franz/agraph/http/AGHttpRepoClient.java
@@ -62,6 +62,7 @@
import com.franz.agraph.repository.AGCustomStoredProcException;
import com.franz.agraph.repository.AGQuery;
+import com.franz.agraph.repository.AGRDFFormat;
import com.franz.util.Closeable;
/**
@@ -107,7 +108,7 @@ public static void setDefaultSessionLifetime(int lifetimeInSeconds)
// TODO: choose proper defaults
private TupleQueryResultFormat preferredTQRFormat = TupleQueryResultFormat.SPARQL;
private BooleanQueryResultFormat preferredBQRFormat = BooleanQueryResultFormat.TEXT;
- private RDFFormat preferredRDFFormat = RDFFormat.TRIX;
+ private RDFFormat preferredRDFFormat = getDefaultRDFFormat();
private AGHTTPClient client;
private Repository repo;
@@ -188,11 +189,45 @@ public void setPreferredBQRFormat(
this.preferredBQRFormat = preferredBQRFormat;
}
+ /**
+ * Gets the default RDFFormat to use in making requests that
+ * return RDF statements; the format should support contexts.
+ *
+ * Gets System property com.franz.agraph.http.defaultRDFFormat
+ * (NQUADS and TRIX are currently supported), defaults to TRIX
+ * if the property is not present, and returns the corresponding
+ * RDFFormat.
+ *
+ * @return an RDFFormat, either NQUADS or TRIX
+ */
+ public RDFFormat getDefaultRDFFormat() {
+ RDFFormat format = System.getProperty("com.franz.agraph.http.defaultRDFFormat","TRIX").equalsIgnoreCase("NQUADS") ? AGRDFFormat.NQUADS : RDFFormat.TRIX;
+ logger.debug("Defaulting to " + format.getDefaultMIMEType() + " for requests that return RDF statements.");
+ return format;
+ }
+
+ /**
+ * Gets the RDFFormat to use in making requests that return
+ * RDF statements.
+ *
+ * Defaults to the format returned by {@link getDefaultRDFFormat()}
+ *
+ * @return an RDFFormat, either NQUADS or TRIX
+ */
public RDFFormat getPreferredRDFFormat() {
return preferredRDFFormat;
}
+ /**
+ * Sets the RDFFormat to use in making requests that return
+ * RDF statements; the format should support contexts.
+ *
+ * AGRDFFormat.NQUADS and RDFFormat.TRIX are currently supported.
+ * Defaults to the format returned by {@link getDefaultRDFFormat()}
+ *
+ */
public void setPreferredRDFFormat(RDFFormat preferredRDFFormat) {
+ logger.debug("Defaulting to " + preferredRDFFormat.getDefaultMIMEType() + " for requests that return RDF statements.");
this.preferredRDFFormat = preferredRDFFormat;
}
View
5 src/com/franz/agraph/http/AGResponseHandler.java
@@ -149,10 +149,7 @@ public void handleResponse(HttpMethod method) throws IOException, RepositoryExce
String mimeType = getResponseMIMEType(method);
try {
if (rdfhandler != null) {
- RDFFormat format = RDFFormat.forMIMEType(mimeType, RDFFormat.TRIX);
- // TODO:
- // .matchMIMEType(mimeType,
- // rdfFormats);
+ RDFFormat format = RDFFormat.forMIMEType(mimeType);
RDFParser parser = Rio.createParser(format, repository.getValueFactory());
parser.setPreserveBNodeIDs(true);
parser.setRDFHandler(rdfhandler);
View
5 src/com/franz/agraph/repository/AGFreetextQuery.java
@@ -12,7 +12,6 @@
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
-import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandler;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.helpers.StatementCollector;
@@ -77,8 +76,8 @@ public void evaluate(RDFHandler handler) throws QueryEvaluationException,
RDFHandlerException {
try {
conn.getHttpRepoClient().evalFreetextQuery(pattern, expression, index, sorted, limit, offset,
- new AGResponseHandler(conn.getRepository(), handler,
- RDFFormat.TRIX));
+ new AGResponseHandler(conn.getRepository(), handler,
+ conn.getHttpRepoClient().getPreferredRDFFormat()));
} catch (RepositoryException e) {
throw new QueryEvaluationException(e);
}
View
7 src/com/franz/openrdf/rio/nquads/META-INF/services/org.openrdf.rio.RDFParserFactory
@@ -0,0 +1,7 @@
+org.openrdf.rio.n3.N3ParserFactory
+org.openrdf.rio.ntriples.NTriplesParserFactory
+org.openrdf.rio.rdfxml.RDFXMLParserFactory
+org.openrdf.rio.trig.TriGParserFactory
+org.openrdf.rio.trix.TriXParserFactory
+org.openrdf.rio.turtle.TurtleParserFactory
+com.franz.openrdf.rio.nquads.NQuadsParserFactory
View
7 src/com/franz/openrdf/rio/nquads/META-INF/services/org.openrdf.rio.RDFWriterFactory
@@ -0,0 +1,7 @@
+org.openrdf.rio.n3.N3WriterFactory
+org.openrdf.rio.ntriples.NTriplesWriterFactory
+org.openrdf.rio.rdfxml.RDFXMLWriterFactory
+org.openrdf.rio.trig.TriGWriterFactory
+org.openrdf.rio.trix.TriXWriterFactory
+org.openrdf.rio.turtle.TurtleWriterFactory
+com.franz.openrdf.rio.nquads.NQuadsWriterFactory
View
30 src/com/franz/openrdf/rio/nquads/NQuadsFormat.java
@@ -0,0 +1,30 @@
+/******************************************************************************
+** Copyright (c) 2008-2011 Franz Inc.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v1.0
+** which accompanies this distribution, and is available at
+** http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************/
+package com.franz.openrdf.rio.nquads;
+
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParserRegistry;
+
+import java.nio.charset.Charset;
+
+/**
+ * An {@link RDFFormat} for N-Quads.
+ *
+ */
+public class NQuadsFormat extends RDFFormat {
+ public static NQuadsFormat NQUADS = new NQuadsFormat();
+
+ static {
+ RDFParserRegistry.getInstance().add(new NQuadsParserFactory());
+ }
+
+ private NQuadsFormat() {
+ super("N-Quads", "text/x-nquads", Charset.forName("US-ASCII"), "nq", true, true);
+
+ }
+}
View
589 src/com/franz/openrdf/rio/nquads/NQuadsParser.java
@@ -0,0 +1,589 @@
+/******************************************************************************
+** Copyright (c) 2008-2011 Franz Inc.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v1.0
+** which accompanies this distribution, and is available at
+** http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************/
+package com.franz.openrdf.rio.nquads;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.openrdf.model.Literal;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFHandlerException;
+import org.openrdf.rio.RDFParseException;
+import org.openrdf.rio.helpers.RDFParserBase;
+import org.openrdf.rio.ntriples.NTriplesUtil;
+
+/**
+ * RDF parser for N-Quads files.
+ *
+ * A specification of NQuads can be found <a href="http://sw.deri.org/2008/07/n-quads/">here</a>.
+ *
+ * This parser is not thread-safe, therefore its public methods are synchronized.
+ *
+ * Modified from openrdf's NTriplesParser.
+ *
+ */
+public class NQuadsParser extends RDFParserBase {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ private Reader reader;
+
+ private int lineNo;
+
+ private Resource subject;
+
+ private URI predicate;
+
+ private Value object;
+
+ private Resource context;
+
+ /*--------------*
+ * Constructors *
+ *--------------*/
+
+ /**
+ * Creates a new NQuadsParser that will use a {@link ValueFactoryImpl} to
+ * create object for resources, bNodes and literals.
+ */
+ public NQuadsParser() {
+ super();
+ }
+
+ /**
+ * Creates a new NQuadsParser that will use the supplied
+ * <tt>ValueFactory</tt> to create RDF model objects.
+ *
+ * @param valueFactory
+ * A ValueFactory.
+ */
+ public NQuadsParser(ValueFactory valueFactory) {
+ super(valueFactory);
+ }
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ // implements RDFParser.getRDFFormat()
+ public final RDFFormat getRDFFormat() {
+ return NQuadsFormat.NQUADS;
+ }
+
+ /**
+ * Implementation of the <tt>parse(InputStream, String)</tt> method defined
+ * in the RDFParser interface.
+ *
+ * @param in
+ * The InputStream from which to read the data, must not be
+ * <tt>null</tt>. The InputStream is supposed to contain 7-bit
+ * US-ASCII characters, as per the N-Triples specification.
+ * @param baseURI
+ * The URI associated with the data in the InputStream, must not be
+ * <tt>null</tt>.
+ * @throws IOException
+ * If an I/O error occurred while data was read from the InputStream.
+ * @throws RDFParseException
+ * If the parser has found an unrecoverable parse error.
+ * @throws RDFHandlerException
+ * If the configured statement handler encountered an unrecoverable
+ * error.
+ * @throws IllegalArgumentException
+ * If the supplied input stream or base URI is <tt>null</tt>.
+ */
+ public synchronized void parse(InputStream in, String baseURI)
+ throws IOException, RDFParseException, RDFHandlerException
+ {
+ if (in == null) {
+ throw new IllegalArgumentException("Input stream can not be 'null'");
+ }
+ // Note: baseURI will be checked in parse(Reader, String)
+
+ try {
+ parse(new InputStreamReader(in, "US-ASCII"), baseURI);
+ }
+ catch (UnsupportedEncodingException e) {
+ // Every platform should support the US-ASCII encoding...
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Implementation of the <tt>parse(Reader, String)</tt> method defined in
+ * the RDFParser interface.
+ *
+ * @param reader
+ * The Reader from which to read the data, must not be <tt>null</tt>.
+ * @param baseURI
+ * The URI associated with the data in the Reader, must not be
+ * <tt>null</tt>.
+ * @throws IOException
+ * If an I/O error occurred while data was read from the InputStream.
+ * @throws RDFParseException
+ * If the parser has found an unrecoverable parse error.
+ * @throws RDFHandlerException
+ * If the configured statement handler encountered an unrecoverable
+ * error.
+ * @throws IllegalArgumentException
+ * If the supplied reader or base URI is <tt>null</tt>.
+ */
+ public synchronized void parse(Reader reader, String baseURI)
+ throws IOException, RDFParseException, RDFHandlerException
+ {
+ if (reader == null) {
+ throw new IllegalArgumentException("Reader can not be 'null'");
+ }
+ if (baseURI == null) {
+ throw new IllegalArgumentException("base URI can not be 'null'");
+ }
+
+ rdfHandler.startRDF();
+
+ this.reader = reader;
+ lineNo = 1;
+
+ reportLocation(lineNo, 1);
+
+ try {
+ int c = reader.read();
+ c = skipWhitespace(c);
+
+ while (c != -1) {
+ if (c == '#') {
+ // Comment, ignore
+ c = skipLine(c);
+ }
+ else if (c == '\r' || c == '\n') {
+ // Empty line, ignore
+ c = skipLine(c);
+ }
+ else {
+ c = parseQuad(c);
+ }
+
+ c = skipWhitespace(c);
+ }
+ }
+ finally {
+ clear();
+ }
+
+ rdfHandler.endRDF();
+ }
+
+ /**
+ * Reads characters from reader until it finds a character that is not a
+ * space or tab, and returns this last character. In case the end of the
+ * character stream has been reached, -1 is returned.
+ */
+ private int skipWhitespace(int c)
+ throws IOException
+ {
+ while (c == ' ' || c == '\t') {
+ c = reader.read();
+ }
+
+ return c;
+ }
+
+ /**
+ * Reads characters from reader until the first EOL has been read. The first
+ * character after the EOL is returned. In case the end of the character
+ * stream has been reached, -1 is returned.
+ */
+ private int skipLine(int c)
+ throws IOException
+ {
+ while (c != -1 && c != '\r' && c != '\n') {
+ c = reader.read();
+ }
+
+ // c is equal to -1, \r or \n. In case of a \r, we should
+ // check whether it is followed by a \n.
+
+ if (c == '\n') {
+ c = reader.read();
+
+ lineNo++;
+
+ reportLocation(lineNo, 1);
+ }
+ else if (c == '\r') {
+ c = reader.read();
+
+ if (c == '\n') {
+ c = reader.read();
+ }
+
+ lineNo++;
+
+ reportLocation(lineNo, 1);
+ }
+
+ return c;
+ }
+
+ private int parseQuad(int c)
+ throws IOException, RDFParseException, RDFHandlerException
+ {
+ c = parseSubject(c);
+
+ c = skipWhitespace(c);
+
+ c = parsePredicate(c);
+
+ c = skipWhitespace(c);
+
+ c = parseObject(c);
+
+ c = skipWhitespace(c);
+
+ if (c != '.') {
+ c = parseContext(c);
+ c = skipWhitespace(c);
+ }
+
+ if (c == -1) {
+ throwEOFException();
+ }
+ else if (c != '.') {
+ reportFatalError("Expected '.', found: " + (char)c);
+ }
+
+ c = skipLine(c);
+
+ Statement st = createStatement(subject, predicate, object, context);
+ rdfHandler.handleStatement(st);
+
+ subject = null;
+ predicate = null;
+ object = null;
+ context = null;
+
+ return c;
+ }
+
+ private int parseSubject(int c)
+ throws IOException, RDFParseException
+ {
+ StringBuilder sb = new StringBuilder(100);
+
+ // subject is either an uriref (<foo://bar>) or a nodeID (_:node1)
+ if (c == '<') {
+ // subject is an uriref
+ c = parseUriRef(c, sb);
+ subject = createURI(sb.toString());
+ }
+ else if (c == '_') {
+ // subject is a bNode
+ c = parseNodeID(c, sb);
+ subject = createBNode(sb.toString());
+ }
+ else if (c == -1) {
+ throwEOFException();
+ }
+ else {
+ reportFatalError("Expected '<' or '_', found: " + (char)c);
+ }
+
+ return c;
+ }
+
+ private int parsePredicate(int c)
+ throws IOException, RDFParseException
+ {
+ StringBuilder sb = new StringBuilder(100);
+
+ // predicate must be an uriref (<foo://bar>)
+ if (c == '<') {
+ // predicate is an uriref
+ c = parseUriRef(c, sb);
+ predicate = createURI(sb.toString());
+ }
+ else if (c == -1) {
+ throwEOFException();
+ }
+ else {
+ reportFatalError("Expected '<', found: " + (char)c);
+ }
+
+ return c;
+ }
+
+ private int parseObject(int c)
+ throws IOException, RDFParseException
+ {
+ StringBuilder sb = new StringBuilder(100);
+
+ // object is either an uriref (<foo://bar>), a nodeID (_:node1) or a
+ // literal ("foo"-en or "1"^^<xsd:integer>).
+ if (c == '<') {
+ // object is an uriref
+ c = parseUriRef(c, sb);
+ object = createURI(sb.toString());
+ }
+ else if (c == '_') {
+ // object is a bNode
+ c = parseNodeID(c, sb);
+ object = createBNode(sb.toString());
+ }
+ else if (c == '"') {
+ // object is a literal
+ StringBuilder lang = new StringBuilder(8);
+ StringBuilder datatype = new StringBuilder(40);
+ c = parseLiteral(c, sb, lang, datatype);
+ object = createLiteral(sb.toString(), lang.toString(), datatype.toString());
+ }
+ else if (c == -1) {
+ throwEOFException();
+ }
+ else {
+ reportFatalError("Expected '<', '_' or '\"', found: " + (char)c);
+ }
+
+ return c;
+ }
+
+ private int parseContext(int c) throws IOException, RDFParseException {
+ StringBuilder sb = new StringBuilder(100);
+
+ // context is either an uriref (<foo://bar>) or a nodeID (_:node1)
+ if (c == '<') {
+ // context is an uriref
+ c = parseUriRef(c, sb);
+ context = createURI(sb.toString());
+ } else if (c == '_') {
+ // context is a bNode
+ c = parseNodeID(c, sb);
+ context = createBNode(sb.toString());
+ } else if (c == -1) {
+ throwEOFException();
+ } else {
+ reportFatalError("Expected '<' or '_', found: " + (char) c);
+ }
+
+ return c;
+ }
+
+ private int parseUriRef(int c, StringBuilder uriRef)
+ throws IOException, RDFParseException
+ {
+ assert c == '<' : "Supplied char should be a '<', is: " + c;
+
+ // Read up to the next '>' character
+ c = reader.read();
+ while (c != '>') {
+ if (c == -1) {
+ throwEOFException();
+ }
+ uriRef.append((char)c);
+ c = reader.read();
+ }
+
+ // c == '>', read next char
+ c = reader.read();
+
+ return c;
+ }
+
+ private int parseNodeID(int c, StringBuilder name)
+ throws IOException, RDFParseException
+ {
+ assert c == '_' : "Supplied char should be a '_', is: " + c;
+
+ c = reader.read();
+ if (c == -1) {
+ throwEOFException();
+ }
+ else if (c != ':') {
+ reportError("Expected ':', found: " + (char)c);
+ }
+
+ c = reader.read();
+ if (c == -1) {
+ throwEOFException();
+ }
+ else if (!NTriplesUtil.isLetter(c)) {
+ reportError("Expected a letter, found: " + (char)c);
+ }
+ name.append((char)c);
+
+ // Read all following letter and numbers, they are part of the name
+ c = reader.read();
+ while (c != -1 && NTriplesUtil.isLetterOrNumber(c)) {
+ name.append((char)c);
+ c = reader.read();
+ }
+
+ return c;
+ }
+
+ private int parseLiteral(int c, StringBuilder value, StringBuilder lang, StringBuilder datatype)
+ throws IOException, RDFParseException
+ {
+ assert c == '"' : "Supplied char should be a '\"', is: " + c;
+
+ // Read up to the next '"' character
+ c = reader.read();
+ while (c != '"') {
+ if (c == -1) {
+ throwEOFException();
+ }
+ value.append((char)c);
+
+ if (c == '\\') {
+ // This escapes the next character, which might be a double quote
+ c = reader.read();
+ if (c == -1) {
+ throwEOFException();
+ }
+ value.append((char)c);
+ }
+
+ c = reader.read();
+ }
+
+ // c == '"', read next char
+ c = reader.read();
+
+ if (c == '@') {
+ // Read language
+ c = reader.read();
+ while (c != -1 && c != '.' && c != '^' && c != ' ' && c != '\t') {
+ lang.append((char)c);
+ c = reader.read();
+ }
+ }
+ else if (c == '^') {
+ // Read datatype
+ c = reader.read();
+
+ // c should be another '^'
+ if (c == -1) {
+ throwEOFException();
+ }
+ else if (c != '^') {
+ reportError("Expected '^', found: " + (char)c);
+ }
+
+ c = reader.read();
+
+ // c should be a '<'
+ if (c == -1) {
+ throwEOFException();
+ }
+ else if (c != '<') {
+ reportError("Expected '<', found: " + (char)c);
+ }
+
+ c = parseUriRef(c, datatype);
+ }
+
+ return c;
+ }
+
+ @Override
+ protected URI createURI(String uri)
+ throws RDFParseException
+ {
+ try {
+ uri = NTriplesUtil.unescapeString(uri);
+ }
+ catch (IllegalArgumentException e) {
+ reportError(e.getMessage());
+ }
+
+ return super.createURI(uri);
+ }
+
+ protected Literal createLiteral(String label, String lang, String datatype)
+ throws RDFParseException
+ {
+ try {
+ label = NTriplesUtil.unescapeString(label);
+ }
+ catch (IllegalArgumentException e) {
+ reportError(e.getMessage());
+ }
+
+ if (lang.length() == 0) {
+ lang = null;
+ }
+
+ if (datatype.length() == 0) {
+ datatype = null;
+ }
+
+ URI dtURI = null;
+ if (datatype != null) {
+ dtURI = createURI(datatype);
+ }
+
+ return super.createLiteral(label, lang, dtURI);
+ }
+
+ /**
+ * Overrides {@link RDFParserBase#reportWarning(String)}, adding line number
+ * information to the error.
+ */
+ @Override
+ protected void reportWarning(String msg)
+ {
+ reportWarning(msg, lineNo, -1);
+ }
+
+ /**
+ * Overrides {@link RDFParserBase#reportError(String)}, adding line number
+ * information to the error.
+ */
+ @Override
+ protected void reportError(String msg)
+ throws RDFParseException
+ {
+ reportError(msg, lineNo, -1);
+ }
+
+ /**
+ * Overrides {@link RDFParserBase#reportFatalError(String)}, adding line
+ * number information to the error.
+ */
+ @Override
+ protected void reportFatalError(String msg)
+ throws RDFParseException
+ {
+ reportFatalError(msg, lineNo, -1);
+ }
+
+ /**
+ * Overrides {@link RDFParserBase#reportFatalError(Exception)}, adding line
+ * number information to the error.
+ */
+ @Override
+ protected void reportFatalError(Exception e)
+ throws RDFParseException
+ {
+ reportFatalError(e, lineNo, -1);
+ }
+
+ private void throwEOFException()
+ throws RDFParseException
+ {
+ throw new RDFParseException("Unexpected end of file");
+ }
+}
View
33 src/com/franz/openrdf/rio/nquads/NQuadsParserFactory.java
@@ -0,0 +1,33 @@
+/******************************************************************************
+** Copyright (c) 2008-2011 Franz Inc.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v1.0
+** which accompanies this distribution, and is available at
+** http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************/
+package com.franz.openrdf.rio.nquads;
+
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParser;
+import org.openrdf.rio.RDFParserFactory;
+
+/**
+ * An {@link RDFParserFactory} for N-Quads parsers.
+ *
+ */
+public class NQuadsParserFactory implements RDFParserFactory {
+
+ /**
+ * Returns {@link NQuadsFormat#NQUADS}.
+ */
+ public RDFFormat getRDFFormat() {
+ return NQuadsFormat.NQUADS;
+ }
+
+ /**
+ * Returns a new instance of NQuadsParser.
+ */
+ public RDFParser getParser() {
+ return new NQuadsParser();
+ }
+}
View
197 src/com/franz/openrdf/rio/nquads/NQuadsWriter.java
@@ -0,0 +1,197 @@
+/******************************************************************************
+** Copyright (c) 2008-2011 Franz Inc.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v1.0
+** which accompanies this distribution, and is available at
+** http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************/
+package com.franz.openrdf.rio.nquads;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+import org.openrdf.model.BNode;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFHandlerException;
+import org.openrdf.rio.RDFWriter;
+import org.openrdf.rio.ntriples.NTriplesUtil;
+
+/**
+ * An implementation of the RDFWriter interface that writes RDF documents in
+ * N-Quads format. The N-Quads format is defined
+ * <a href="href="http://sw.deri.org/2008/07/n-quads/">here</a>.
+ */
+public class NQuadsWriter implements RDFWriter {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ private Writer writer;
+
+ private boolean writingStarted;
+
+ /*--------------*
+ * Constructors *
+ *--------------*/
+
+ /**
+ * Creates a new NQuadsWriter that will write to the supplied OutputStream.
+ *
+ * @param out
+ * The OutputStream to write the N-Quads document to.
+ */
+ public NQuadsWriter(OutputStream out) {
+ this(new OutputStreamWriter(out, Charset.forName("US-ASCII")));
+ }
+
+ /**
+ * Creates a new NQuadsWriter that will write to the supplied Writer.
+ *
+ * @param writer
+ * The Writer to write the N-Quads document to.
+ */
+ public NQuadsWriter(Writer writer) {
+ this.writer = writer;
+ writingStarted = false;
+ }
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ public RDFFormat getRDFFormat() {
+ return NQuadsFormat.NQUADS;
+ }
+
+ public void startRDF()
+ throws RDFHandlerException
+ {
+ if (writingStarted) {
+ throw new RuntimeException("Document writing has already started");
+ }
+
+ writingStarted = true;
+ }
+
+ public void endRDF()
+ throws RDFHandlerException
+ {
+ if (!writingStarted) {
+ throw new RuntimeException("Document writing has not yet started");
+ }
+
+ try {
+ writer.flush();
+ }
+ catch (IOException e) {
+ throw new RDFHandlerException(e);
+ }
+ finally {
+ writingStarted = false;
+ }
+ }
+
+ public void handleNamespace(String prefix, String name) {
+ // N-Quads does not support namespace prefixes.
+ }
+
+ public void handleStatement(Statement st)
+ throws RDFHandlerException
+ {
+ if (!writingStarted) {
+ throw new RuntimeException("Document writing has not yet been started");
+ }
+
+ Resource subj = st.getSubject();
+ URI pred = st.getPredicate();
+ Value obj = st.getObject();
+ Resource context = st.getContext();
+
+ try {
+ // SUBJECT
+ writeResource(subj);
+ writer.write(" ");
+
+ // PREDICATE
+ writeURI(pred);
+ writer.write(" ");
+
+ // OBJECT
+ if (obj instanceof Resource) {
+ writeResource((Resource)obj);
+ }
+ else if (obj instanceof Literal) {
+ writeLiteral((Literal)obj);
+ }
+
+ // CONTEXT
+ if (context!=null) {
+ writeResource(context);
+ writer.write(" ");
+ }
+
+ writer.write(" .");
+ writeNewLine();
+ }
+ catch (IOException e) {
+ throw new RDFHandlerException(e);
+ }
+ }
+
+ public void handleComment(String comment)
+ throws RDFHandlerException
+ {
+ try {
+ writer.write("# ");
+ writer.write(comment);
+ writeNewLine();
+ }
+ catch (IOException e) {
+ throw new RDFHandlerException(e);
+ }
+ }
+
+ private void writeResource(Resource res)
+ throws IOException
+ {
+ if (res instanceof BNode) {
+ writeBNode((BNode)res);
+ }
+ else {
+ writeURI((URI)res);
+ }
+ }
+
+ private void writeURI(URI uri)
+ throws IOException
+ {
+ writer.write(NTriplesUtil.toNTriplesString(uri));
+ }
+
+ private void writeBNode(BNode bNode)
+ throws IOException
+ {
+ writer.write(NTriplesUtil.toNTriplesString(bNode));
+ }
+
+ private void writeLiteral(Literal lit)
+ throws IOException
+ {
+ writer.write(NTriplesUtil.toNTriplesString(lit));
+ }
+
+ private void writeNewLine()
+ throws IOException
+ {
+ writer.write("\n");
+ }
+}
View
43 src/com/franz/openrdf/rio/nquads/NQuadsWriterFactory.java
@@ -0,0 +1,43 @@
+/******************************************************************************
+** Copyright (c) 2008-2011 Franz Inc.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v1.0
+** which accompanies this distribution, and is available at
+** http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************/
+package com.franz.openrdf.rio.nquads;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFWriter;
+import org.openrdf.rio.RDFWriterFactory;
+
+/**
+ * An {@link RDFWriterFactory} for N-Quads writers.
+ *
+ */
+public class NQuadsWriterFactory implements RDFWriterFactory {
+
+ /**
+ * Returns {@link NQuadsFormat#NQUADS}.
+ */
+ public RDFFormat getRDFFormat() {
+ return NQuadsFormat.NQUADS;
+ }
+
+ /**
+ * Returns a new instance of {@link NQuadsWriter}.
+ */
+ public RDFWriter getWriter(OutputStream out) {
+ return new NQuadsWriter(out);
+ }
+
+ /**
+ * Returns a new instance of {@link NQuadsWriter}.
+ */
+ public RDFWriter getWriter(Writer writer) {
+ return new NQuadsWriter(writer);
+ }
+}
View
9 src/com/franz/openrdf/rio/nquads/package.html
@@ -0,0 +1,9 @@
+<html>
+<head></head>
+<body>
+Parser and writer for RDF in N-Quads format. The N-Quads format is
+defined <a href="href="http://sw.deri.org/2008/07/n-quads/">here</a>.
+OpenRDF has no N-Quads implementation at the time of writing; this is
+based on org.openrdf.rio.ntriples.
+</body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.