Merge pull request #800 from afs/ttl-base-write
JENA-1968: Relative URIs output, with no BASE
diff --git a/jena-arq/src-examples/arq/examples/riot/ExRIOTw3_AddNewWriter.java b/jena-arq/src-examples/arq/examples/riot/ExRIOT7_AddNewWriter.java
similarity index 98%
rename from jena-arq/src-examples/arq/examples/riot/ExRIOTw3_AddNewWriter.java
rename to jena-arq/src-examples/arq/examples/riot/ExRIOT7_AddNewWriter.java
index ca1b9c4..79cf7b7 100644
--- a/jena-arq/src-examples/arq/examples/riot/ExRIOTw3_AddNewWriter.java
+++ b/jena-arq/src-examples/arq/examples/riot/ExRIOT7_AddNewWriter.java
@@ -34,11 +34,11 @@
import org.apache.jena.sparql.util.Context ;
/** Example of registering a new writer with RIOT */
-public class ExRIOTw3_AddNewWriter
+public class ExRIOT7_AddNewWriter
{
static { LogCtl.setLogging(); }
- // See also ExRIOT6_AddNewLang
+ // See also ExRIOT6_AddReader
public static void main(String[] args)
{
System.out.println("## Example of a registering a new language with RIOT for writing") ;
diff --git a/jena-arq/src-examples/arq/examples/riot/ExRIOT8_RelativeURIs.java b/jena-arq/src-examples/arq/examples/riot/ExRIOT8_RelativeURIs.java
new file mode 100644
index 0000000..bfe12cc
--- /dev/null
+++ b/jena-arq/src-examples/arq/examples/riot/ExRIOT8_RelativeURIs.java
@@ -0,0 +1,71 @@
+/**
+ * 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 arq.examples.riot;
+
+import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.rdf.model.Model ;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFParser;
+import org.apache.jena.riot.RDFWriter;
+import org.apache.jena.riot.RIOT;
+
+/** Example of registering a new writer with RIOT */
+public class ExRIOT8_RelativeURIs
+{
+ static { LogCtl.setLogging(); }
+
+ public static void main(String[] args)
+ {
+ System.out.println("## Example of I/O with relative URIs.") ;
+ System.out.println() ;
+
+ Model model = ModelFactory.createDefaultModel();
+
+ // Read data that has relative URIs, and does not include a BASE directive.
+ // (When reading a URL (including files), the base defaults to the URL.)
+ RDFParser.create()
+ .base("http://theBase/")
+ .source("SomeData.ttl") // Implies "lang(Lang.TTL)"
+ .parse(model);
+
+ // == With BASE URI
+ // Write data, with relative URIs and with BASE.
+ RDFWriter.create()
+ // Cause a BASE to output and URIs to be made relative.
+ .base("http://theBase/")
+ .lang(Lang.TTL)
+ .source(model)
+ .output(System.out);
+
+ // == Without BASE URI
+ // Write data, with relative URIs but no base.
+ // The data is not portable - the exact triples it contains when read back in
+ // will be influenced by the base URI of the parsing step.
+ RDFWriter.create()
+ // Don't print "BASE".
+ .set(RIOT.symTurtleOmitBase, true)
+ // Cause URIs to be made relative using the base.
+ .base("http://theBase/")
+ .lang(Lang.TTL)
+ .source(model)
+ .output(System.out);
+ }
+}
+
diff --git a/jena-arq/src-examples/arq/examples/riot/ExRIOT7_ParserPiped.java b/jena-arq/src-examples/arq/examples/riot/ExRIOT9_ParserPiped.java
similarity index 98%
rename from jena-arq/src-examples/arq/examples/riot/ExRIOT7_ParserPiped.java
rename to jena-arq/src-examples/arq/examples/riot/ExRIOT9_ParserPiped.java
index 0581fed..04aff8c 100644
--- a/jena-arq/src-examples/arq/examples/riot/ExRIOT7_ParserPiped.java
+++ b/jena-arq/src-examples/arq/examples/riot/ExRIOT9_ParserPiped.java
@@ -32,7 +32,7 @@
* {@link PipedRDFStream} and a {@link PipedRDFIterator}
*
*/
-public class ExRIOT7_ParserPiped {
+public class ExRIOT9_ParserPiped {
public static void main(String... argv) {
final String filename = "data.ttl";
diff --git a/jena-arq/src-examples/arq/examples/riot/ExRIOT_RDFXML_ReaderProperties.java b/jena-arq/src-examples/arq/examples/riot/ExRIOT_RDFXML_ReaderProperties.java
index f87a5d0..9a802cf 100644
--- a/jena-arq/src-examples/arq/examples/riot/ExRIOT_RDFXML_ReaderProperties.java
+++ b/jena-arq/src-examples/arq/examples/riot/ExRIOT_RDFXML_ReaderProperties.java
@@ -32,7 +32,7 @@
import org.apache.jena.riot.SysRIOT;
import org.apache.jena.sparql.util.Context;
-/** Set proeprties of the RDF/XML parser (ARP) */
+/** Set properties of the RDF/XML parser (ARP) */
public class ExRIOT_RDFXML_ReaderProperties {
static { LogCtl.setLogging(); }
@@ -42,7 +42,7 @@
("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
,"<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
," xmlns:ex=\"http://examples.org/\">"
- // This rdf:ID startswith a digit which normal causes a warning.
+ // This rdf:ID starts with a digit which normal causes a warning.
," <ex:Type rdf:ID='012345'></ex:Type>"
,"</rdf:RDF>"
);
diff --git a/jena-arq/src-examples/arq/examples/riot/ExRIOTw1_writeModel.java b/jena-arq/src-examples/arq/examples/riot/ExRIOT_writeModel.java
similarity index 97%
rename from jena-arq/src-examples/arq/examples/riot/ExRIOTw1_writeModel.java
rename to jena-arq/src-examples/arq/examples/riot/ExRIOT_writeModel.java
index 405d350..587c155 100644
--- a/jena-arq/src-examples/arq/examples/riot/ExRIOTw1_writeModel.java
+++ b/jena-arq/src-examples/arq/examples/riot/ExRIOT_writeModel.java
@@ -22,7 +22,7 @@
import org.apache.jena.riot.* ;
/** Example writing a model with RIOT */
-public class ExRIOTw1_writeModel
+public class ExRIOT_writeModel
{
public static void main(String[] args)
{
diff --git a/jena-arq/src-examples/arq/examples/riot/ExRIOTw2_writeRDF.java b/jena-arq/src-examples/arq/examples/riot/ExRIOT_writeRDF.java
similarity index 98%
rename from jena-arq/src-examples/arq/examples/riot/ExRIOTw2_writeRDF.java
rename to jena-arq/src-examples/arq/examples/riot/ExRIOT_writeRDF.java
index 69288bd..8a3ffa1 100644
--- a/jena-arq/src-examples/arq/examples/riot/ExRIOTw2_writeRDF.java
+++ b/jena-arq/src-examples/arq/examples/riot/ExRIOT_writeRDF.java
@@ -24,7 +24,7 @@
import org.apache.jena.riot.RDFDataMgr ;
/** Other writer examples */
-public class ExRIOTw2_writeRDF
+public class ExRIOT_writeRDF
{
public static void main(String[] args)
{
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterBuilder.java b/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterBuilder.java
index 2ad010f..2ad2c2a 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterBuilder.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterBuilder.java
@@ -90,8 +90,7 @@
public RDFWriterBuilder source(Dataset dataset) {
return source(dataset.asDatasetGraph());
}
-
-
+
// // Not implemented
// public RDFWriterBuilder labels(NodeToLabel nodeToLabel) { return this; }
//
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RIOT.java b/jena-arq/src/main/java/org/apache/jena/riot/RIOT.java
index 39300ec..7fd7e6f 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/RIOT.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/RIOT.java
@@ -21,9 +21,11 @@
import org.apache.jena.query.ARQ ;
import org.apache.jena.riot.lang.JsonLDReader;
import org.apache.jena.riot.resultset.ResultSetLang;
+import org.apache.jena.riot.system.StreamRDF;
import org.apache.jena.sparql.SystemARQ ;
import org.apache.jena.sparql.mgt.SystemInfo ;
import org.apache.jena.sparql.util.Context ;
+import org.apache.jena.sparql.util.MappingRegistry;
import org.apache.jena.sparql.util.Symbol ;
import org.apache.jena.sys.JenaSystem ;
@@ -76,7 +78,10 @@
RDFParserRegistry.init() ;
RDFWriterRegistry.init() ;
ResultSetLang.init();
-
+
+ MappingRegistry.addPrefixMapping("ttl", TURTLE_SYMBOL_BASE) ;
+ MappingRegistry.addPrefixMapping("trig", TURTLE_SYMBOL_BASE) ;
+
IO_Jena.wireIntoJena() ;
// Don't register JMX info with ARQ as it may not be initialized
@@ -122,6 +127,15 @@
*/
public static final Symbol symTurtleDirectiveStyle = SystemARQ.allocSymbol(TURTLE_SYMBOL_BASE, "directiveStyle");
+ /**
+ * Printing style. Whether to output "BASE"/"@base" (according to
+ * {@link #symTurtleDirectiveStyle} or not. BASE is normally written if there is
+ * a base URI passed to the writer or, for a streaming writer, if
+ * {@link StreamRDF#base} is called. If this context setting is set true, then do
+ * not output BASE even when given.
+ */
+ public static final Symbol symTurtleOmitBase = SystemARQ.allocSymbol(TURTLE_SYMBOL_BASE, "omitBase");
+
/** @deprecated Use {@link #symTurtleDirectiveStyle}. */
@Deprecated
public static final Symbol symTurtlePrefixStyle = SystemARQ.allocSymbol(TURTLE_SYMBOL_BASE, "prefixStyle");
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL.java b/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL.java
index 19f8db8..b0947a3 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL.java
@@ -52,7 +52,7 @@
this.prefixMap = prefixMap ;
this.baseIRI = baseIRI ;
this.iriResolver =
- baseIRI != null ? IRIResolver.iriFactory().construct(baseIRI) : null ;
+ baseIRI != null ? IRIResolver.iriFactory().create(baseIRI) : null ;
}
@Override
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/IRIResolver.java b/jena-arq/src/main/java/org/apache/jena/riot/system/IRIResolver.java
index c46a3e8..dceebd1 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/IRIResolver.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/IRIResolver.java
@@ -66,13 +66,14 @@
setErrorWarning(iriFactoryInst, ViolationCodes.NON_INITIAL_DOT_SEGMENT, false, false);
// Turn off?? (ignored in CheckerIRI.iriViolations anyway).
- // setErrorWarning(iriFactory, ViolationCodes.LOWERCASE_PREFERRED, false, false);
- // setErrorWarning(iriFactory, ViolationCodes.PERCENT_ENCODING_SHOULD_BE_UPPERCASE, false, false);
// setErrorWarning(iriFactory, ViolationCodes.SCHEME_PATTERN_MATCH_FAILED, false, false);
+ // Choices
+ setErrorWarning(iriFactoryInst, ViolationCodes.LOWERCASE_PREFERRED, false, true);
+ //setErrorWarning(iriFactoryInst, ViolationCodes.PERCENT_ENCODING_SHOULD_BE_UPPERCASE, false, true);
+
// NFC tests are not well understood by general developers and these cause confusion.
// See JENA-864
-
// NFC is in RDF 1.1 so do test for that.
// https://www.w3.org/TR/rdf11-concepts/#section-IRIs
// Leave switched on as a warning.
@@ -87,6 +88,7 @@
// The set of legal characters depends on the Java version.
// If not set, this causes test failures in Turtle and Trig eval tests.
setErrorWarning(iriFactoryInst, ViolationCodes.UNASSIGNED_UNICODE_CHARACTER, false, false);
+
if ( ShowResolverSetup ) {
System.out.println("---- After initialization ----");
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java
index 6c591a5..087a484 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java
@@ -51,7 +51,7 @@
private void output$(IndentedWriter iOut, DatasetGraph dsg, PrefixMap prefixMap, String baseURI, Context context) {
if ( baseURI != null )
- baseURI = IRIResolver.resolveString(baseURI) ;
+ baseURI = IRIResolver.resolveStringSilent(baseURI) ;
output(iOut, dsg, prefixMap, baseURI, context) ;
iOut.flush() ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
index deff68b..8da1501 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
@@ -83,7 +83,8 @@
}
protected void writeBase(String base) {
- RiotLib.writeBase(out, base, prefixStyle==DirectiveStyle.SPARQL) ;
+ if ( context == null || ! context.isTrue(RIOT.symTurtleOmitBase) )
+ RiotLib.writeBase(out, base, prefixStyle==DirectiveStyle.SPARQL) ;
}
protected void writePrefixes(PrefixMap prefixMap) {
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java
index 625d92d..30373c2 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java
@@ -50,7 +50,7 @@
private void output$(IndentedWriter iOut, Graph graph, PrefixMap prefixMap, String baseURI, Context context) {
if ( baseURI != null )
- baseURI = IRIResolver.resolveString(baseURI) ;
+ baseURI = IRIResolver.resolveStringSilent(baseURI);
output(iOut, graph, prefixMap, baseURI, context) ;
iOut.flush() ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/WriterStreamRDFBase.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/WriterStreamRDFBase.java
index d1c4d85..7556c10 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/writer/WriterStreamRDFBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/WriterStreamRDFBase.java
@@ -25,6 +25,7 @@
import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.RIOT;
import org.apache.jena.riot.out.NodeFormatterTTL ;
import org.apache.jena.riot.out.NodeToLabel ;
import org.apache.jena.riot.system.PrefixMap ;
@@ -55,117 +56,101 @@
protected NodeFormatterTTL fmt ;
protected final IndentedWriter out ;
protected final DirectiveStyle prefixStyle;
+ protected final boolean printBase;
- public WriterStreamRDFBase(OutputStream output, Context context)
- {
+ public WriterStreamRDFBase(OutputStream output, Context context) {
this(new IndentedWriter(output), context) ;
}
- public WriterStreamRDFBase(Writer output, Context context)
- { this(wrap(output), context) ; }
+ public WriterStreamRDFBase(Writer output, Context context) {
+ this(wrap(output), context);
+ }
-
- public WriterStreamRDFBase(IndentedWriter output, Context context)
- {
+ public WriterStreamRDFBase(IndentedWriter output, Context context) {
out = output ;
- baseURI = null ;
pMap = PrefixMapFactory.create() ;
nodeToLabel = NodeToLabel.createScopeByDocument() ;
+
+ // Stream writing does not take an external base URI from the API "write"
+ // call. The base URI is output if StreamRDF.base() called, which means BASE
+ // was in the data stream.
+ baseURI = null ;
prefixStyle = WriterLib.directiveStyle(context);
+ printBase =
+ ( context == null ) ? true : context.isFalseOrUndef(RIOT.symTurtleOmitBase);
setFormatter() ;
}
- private void setFormatter()
- {
- fmt = new NodeFormatterTTL(baseURI, pMap, nodeToLabel) ;
+ private void setFormatter() {
+ fmt = new NodeFormatterTTL(baseURI, pMap, nodeToLabel);
}
- private static IndentedWriter wrap(Writer output)
- {
- if ( ! ( output instanceof BufferedWriter ) )
- output = new BufferedWriter(output, 32*1024) ;
- return RiotLib.create(output) ;
+ private static IndentedWriter wrap(Writer output) {
+ if ( !(output instanceof BufferedWriter) )
+ output = new BufferedWriter(output, 32 * 1024);
+ return RiotLib.create(output);
}
- private void reset$()
- {
- activeTripleData = false ;
- activeQuadData = false ;
- lastWasDirective = false ;
+ private void reset$() {
+ activeTripleData = false;
+ activeQuadData = false;
+ lastWasDirective = false;
}
@Override
- public final void start()
- {
- reset$() ;
- startData() ;
+ public final void start() {
+ reset$();
+ startData();
}
@Override
- public final void finish()
- {
- endData() ;
- out.flush() ;
+ public final void finish() {
+ endData();
+ out.flush();
}
@Override
- public final void triple(Triple triple)
- {
- print(triple) ;
- activeTripleData = true ;
+ public final void triple(Triple triple) {
+ print(triple);
+ activeTripleData = true;
}
@Override
- public final void quad(Quad quad)
- {
- print(quad) ;
- activeQuadData = true ;
+ public final void quad(Quad quad) {
+ print(quad);
+ activeQuadData = true;
}
@Override
- public final void base(String base)
- {
- baseURI = base ;
- lastWasDirective = true ;
- setFormatter() ;
- RiotLib.writeBase(out, base, prefixStyle==DirectiveStyle.SPARQL) ;
+ public final void base(String base) {
+ baseURI = base;
+ lastWasDirective = true;
+ setFormatter();
+ if ( printBase )
+ RiotLib.writeBase(out, base, prefixStyle == DirectiveStyle.SPARQL);
}
@Override
- public final void prefix(String prefix, String iri)
- {
- endData() ;
- lastWasDirective = true ;
- pMap.add(prefix, iri) ;
- RiotLib.writePrefix(out, prefix, iri, prefixStyle==DirectiveStyle.SPARQL);
+ public final void prefix(String prefix, String iri) {
+ endData();
+ lastWasDirective = true;
+ pMap.add(prefix, iri);
+ RiotLib.writePrefix(out, prefix, iri, prefixStyle == DirectiveStyle.SPARQL);
}
- protected void outputNode(Node n)
- {
- fmt.format(out, n) ;
+ protected void outputNode(Node n) {
+ fmt.format(out, n);
}
// Subclass contract
- protected abstract void startData() ;
+ protected abstract void startData();
- protected abstract void endData() ;
+ protected abstract void endData();
- protected abstract void print(Quad quad) ;
+ protected abstract void print(Quad quad);
- protected abstract void print(Triple triple) ;
+ protected abstract void print(Triple triple);
- protected abstract void reset() ;
-
- protected void DEBUG(String fmt, Object...args)
- {
- int loc = out.getCol() ; // Absolute
- int off = out.getAbsoluteIndent() ;
- out.ensureStartOfLine();
- out.setAbsoluteIndent(0) ;
- out.println(String.format(fmt, args)) ;
- out.setAbsoluteIndent(off) ;
- out.ensureStartOfLine();
- out.pad(loc, true) ;
- }
+ protected abstract void reset();
}
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/TS_RiotGeneral.java b/jena-arq/src/test/java/org/apache/jena/riot/TS_RiotGeneral.java
index 914bb21..5c8c5b7 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/TS_RiotGeneral.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/TS_RiotGeneral.java
@@ -37,6 +37,9 @@
, TestRDFWriter.class
, TestParseURISchemeBases.class
+ , TestTurtleWriter.class
+ , TestTurtleWriterPretty.class
+
, TestJsonLDReader.class
, TestJsonLDWriter.class
})
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/TestRDFWriter.java b/jena-arq/src/test/java/org/apache/jena/riot/TestRDFWriter.java
index c8aeb31..0e6726b 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/TestRDFWriter.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/TestRDFWriter.java
@@ -31,18 +31,18 @@
public class TestRDFWriter {
private static Graph graph = SSE.parseGraph("(graph (:s :p :o))");
-
+
@Test public void rdfwriter_1() {
RDFWriter.create().source(graph).build();
}
-
+
@Test(expected=RiotException.class)
public void rdfwriter_2() {
RDFWriter.create().build();
}
@Test public void rdfwriter_3() {
- String s =
+ String s =
RDFWriter.create()
.source(graph)
.lang(Lang.NT)
@@ -52,13 +52,13 @@
@Test(expected=RiotException.class)
public void rdfwriter_4() {
- String s =
+ String s =
RDFWriter.create()
// No syntax
.source(graph)
.asString();
}
-
+
@Test public void rdfwriter_5() {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
RDFWriter.create()
@@ -68,7 +68,7 @@
String s = StrUtils.fromUTF8bytes(bout.toByteArray());
assertTrue(s.contains("example/s"));
}
-
+
@SuppressWarnings("deprecation")
@Test public void rdfwriter_6() {
Writer w = new CharArrayWriter();
@@ -80,6 +80,4 @@
String s = w.toString();
assertTrue(s.contains("example/s"));
}
-
-
}
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/TestTurtleWriter.java b/jena-arq/src/test/java/org/apache/jena/riot/TestTurtleWriter.java
new file mode 100644
index 0000000..5d9ba40
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/riot/TestTurtleWriter.java
@@ -0,0 +1,100 @@
+/*
+ * 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.riot;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.sparql.graph.GraphFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Tests for Turtle (and Trig) */
+@RunWith(Parameterized.class)
+public class TestTurtleWriter {
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> data() {
+ List<Object[]> x = new ArrayList<>() ;
+ x.add(new Object[]{"Turtle", RDFFormat.TURTLE});
+ x.add(new Object[]{"Turtle/Pretty", RDFFormat.TURTLE_PRETTY});
+ x.add(new Object[]{"Turtle/Blocks", RDFFormat.TURTLE_BLOCKS});
+ x.add(new Object[]{"Turtle/Flat", RDFFormat.TURTLE_FLAT});
+ x.add(new Object[]{"Trig", RDFFormat.TRIG});
+ x.add(new Object[]{"Trig/Pretty", RDFFormat.TRIG_PRETTY});
+ x.add(new Object[]{"Trig/Blocks", RDFFormat.TRIG_BLOCKS});
+ x.add(new Object[]{"Trig/Flat", RDFFormat.TRIG_FLAT});
+ return x ;
+ }
+
+ private static String DIR = "testing/RIOT/Writer/";
+
+ private static String BASE = "http://BASE/";
+
+ private final RDFFormat format;
+
+ private final String filename;
+
+
+ public TestTurtleWriter(String name, RDFFormat format) {
+ this.format = format;
+ if ( format.getLang().equals(Lang.TRIG) )
+ this.filename = DIR+"rdfwriter-02.trig";
+ else
+ this.filename = DIR+"rdfwriter-01.ttl";
+ }
+
+ // read file, with external base URI
+ private static Graph data(String fn, String baseURI) {
+ Graph g1 = GraphFactory.createDefaultGraph();
+ RDFParser.create()
+ .base(BASE)
+ .source(fn)
+ .parse(g1);
+ return g1;
+ }
+
+ // .base() for Turtle.
+ @Test public void writer_parse_base_1() {
+ // This has a relative URI
+ // Not an ideal URI but legal (host is upper case). Allowed.
+ Graph g = data(filename, BASE);
+
+ String written =
+ RDFWriter.create()
+ .base(BASE)
+ .source(g)
+ .set(RIOT.symTurtleDirectiveStyle, "sparql")
+ .format(format)
+ .base(BASE)
+ .asString();
+
+ // Test BASE used.
+ assertTrue(written.contains("<>"));
+ assertTrue(written.contains("BASE"));
+ }
+
+ // Stream writer (BLOCKS and FLAT) don't print a base URI unless explicitly given one in the data.
+ // THis test is in TestTurtleWriterPretty
+ //@Test public void writer_parse_base_2()
+}
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/TestTurtleWriterPretty.java b/jena-arq/src/test/java/org/apache/jena/riot/TestTurtleWriterPretty.java
new file mode 100644
index 0000000..8afce9f
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/riot/TestTurtleWriterPretty.java
@@ -0,0 +1,110 @@
+/*
+ * 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.riot;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.sparql.graph.GraphFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Tests for Turtle and Trig pertty format */
+@RunWith(Parameterized.class)
+public class TestTurtleWriterPretty {
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> data() {
+ List<Object[]> x = new ArrayList<>() ;
+ x.add(new Object[]{"Turtle/Pretty", RDFFormat.TURTLE_PRETTY});
+ x.add(new Object[]{"Trig/Pretty", RDFFormat.TRIG_PRETTY});
+ return x ;
+ }
+
+ private static String DIR = "testing/RIOT/Writer/";
+
+ private static String BASE = "http://BASE/";
+
+ private final RDFFormat format;
+
+ private final String filename;
+
+ public TestTurtleWriterPretty(String name, RDFFormat format) {
+ this.format = format;
+ if ( format.getLang().equals(Lang.TRIG) )
+ this.filename = DIR+"rdfwriter-02.trig";
+ else
+ this.filename = DIR+"rdfwriter-01.ttl";
+ }
+
+ // read file, with external base URI
+ private static Graph data(String fn, String baseURI) {
+ Graph g1 = GraphFactory.createDefaultGraph();
+ RDFParser.create()
+ .base(BASE)
+ .source(fn)
+ .parse(g1);
+ return g1;
+ }
+
+ // Stream writer (BLOCKS and FLAT) don't print a base URI unless explicitly given one in the data.
+
+ @Test public void writer_parse_base_2() {
+ assumeTrue(format.getVariant().equals(RDFFormat.PRETTY));
+
+ Graph g = data(filename, BASE);
+
+ String written =
+ RDFWriter.create()
+ .base(BASE)
+ .source(g)
+ .set(RIOT.symTurtleDirectiveStyle, "sparql")
+ .set(RIOT.symTurtleOmitBase, true)
+ .format(format)
+ .base(BASE)
+ .asString();
+ {
+ // Same base URI => same graph
+ Graph g1 = GraphFactory.createDefaultGraph();
+ RDFParser.create()
+ .base(BASE)
+ .fromString(written)
+ .lang(Lang.TTL)
+ .parse(g1);
+ assertTrue(g.isIsomorphicWith(g1));
+ }
+ {
+ // Different base URI => different graph
+ Graph g2 = GraphFactory.createDefaultGraph();
+ String BASE2 = "http://BASE2/";
+ RDFParser.create()
+ .base(BASE2)
+ .fromString(written)
+ .lang(Lang.TTL)
+ .parse(g2);
+ assertFalse(g.isIsomorphicWith(g2));
+ }
+ }
+}
diff --git a/jena-arq/testing/RIOT/Writer/rdfwriter-01.ttl b/jena-arq/testing/RIOT/Writer/rdfwriter-01.ttl
new file mode 100644
index 0000000..ebaaf1a
--- /dev/null
+++ b/jena-arq/testing/RIOT/Writer/rdfwriter-01.ttl
@@ -0,0 +1,6 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+# test for base URI handling externally.
+PREFIX : <http://example/>
+
+<> :p 123 .
diff --git a/jena-arq/testing/RIOT/Writer/rdfwriter-02.trig b/jena-arq/testing/RIOT/Writer/rdfwriter-02.trig
new file mode 100644
index 0000000..724b1ac
--- /dev/null
+++ b/jena-arq/testing/RIOT/Writer/rdfwriter-02.trig
@@ -0,0 +1,8 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+# test for base URI handling externally.
+PREFIX : <http://example/>
+
+{
+ <> :p 456 .
+}
diff --git a/jena-cmds/src/main/java/arq/cmdline/ModLangParse.java b/jena-cmds/src/main/java/arq/cmdline/ModLangParse.java
index 0b9ee11..6f45653 100644
--- a/jena-cmds/src/main/java/arq/cmdline/ModLangParse.java
+++ b/jena-cmds/src/main/java/arq/cmdline/ModLangParse.java
@@ -114,7 +114,8 @@
if ( cmdLine.contains(argBase) ) {
baseIRI = cmdLine.getValue(argBase) ;
- IRI iri = IRIResolver.resolveIRI(baseIRI) ;
+ IRI iri = IRIResolver.iriFactory().create(baseIRI);
+
if ( iri.hasViolation(false) )
throw new CmdException("Bad base IRI: " + baseIRI) ;
if ( !iri.isAbsolute() )
diff --git a/jena-cmds/src/main/java/riotcmd/CmdLangParse.java b/jena-cmds/src/main/java/riotcmd/CmdLangParse.java
index 88a91f2..49d5af5 100644
--- a/jena-cmds/src/main/java/riotcmd/CmdLangParse.java
+++ b/jena-cmds/src/main/java/riotcmd/CmdLangParse.java
@@ -34,7 +34,6 @@
import jena.cmd.CmdGeneral ;
import org.apache.jena.Jena ;
import org.apache.jena.atlas.io.IO ;
-import org.apache.jena.atlas.lib.InternalErrorException ;
import org.apache.jena.atlas.lib.Pair ;
import org.apache.jena.riot.* ;
import org.apache.jena.riot.lang.LabelToNode ;
@@ -84,8 +83,10 @@
protected List<ParseRecord> outcomes = new ArrayList<>();
- OutputStream outputWrite = System.out ;
- StreamRDF outputStream = null ;
+ protected OutputStream outputWrite = System.out ;
+ protected StreamRDF outputStream = null ;
+ protected String parserBaseIRI = null;
+ protected String writerBaseIRI = null;
@Override
protected void processModulesAndArgs() {
@@ -122,6 +123,10 @@
boolean oldStrictValue = SysRIOT.isStrictMode() ;
if ( modLangParse.strictMode() )
SysRIOT.setStrictMode(true) ;
+
+ parserBaseIRI = modLangParse.getBaseIRI();
+ writerBaseIRI = parserBaseIRI;
+
try { exec$() ; }
finally { SysRIOT.setStrictMode(oldStrictValue) ; }
}
@@ -218,10 +223,10 @@
}
public ParseRecord parseFile(String filename) {
- String baseURI = modLangParse.getBaseIRI() ;
+ String baseParserIRI = this.parserBaseIRI;
RDFParserBuilder builder = RDFParser.create();
- if ( baseURI != null )
- builder.base(baseURI);
+ if ( baseParserIRI != null )
+ builder.base(baseParserIRI);
if ( modLangParse.getLang() != null )
// Always use the command line specified syntax.
builder.forceLang(modLangParse.getLang());
@@ -236,9 +241,9 @@
// Set the source.
if ( filename.equals("-") ) {
- if ( baseURI == null ) {
- baseURI = "http://base/";
- builder.base(baseURI);
+ if ( baseParserIRI == null ) {
+ baseParserIRI = "http://base/";
+ builder.base(baseParserIRI);
}
filename = "stdin";
builder.source(System.in);
@@ -330,23 +335,18 @@
final DatasetGraph dsg = DatasetGraphFactory.create() ;
StreamRDF sink = StreamRDFLib.dataset(dsg) ;
final RDFFormat fmt = modLangOutput.getOutputFormatted() ;
- PostParseHandler handler = new PostParseHandler() {
- @Override
- public void postParse() {
- // Try as dataset, then as graph.
- WriterDatasetRIOTFactory w = RDFWriterRegistry.getWriterDatasetFactory(fmt) ;
- if ( w != null ) {
- RDFDataMgr.write(outputWrite, dsg, fmt) ;
- return ;
- }
- WriterGraphRIOTFactory wg = RDFWriterRegistry.getWriterGraphFactory(fmt) ;
- if ( wg != null ) {
- RDFDataMgr.write(System.out, dsg.getDefaultGraph(), fmt) ;
- return ;
- }
- throw new InternalErrorException("failed to find the writer: "+fmt) ;
- }
- } ;
+ PostParseHandler handler = ()->{
+ RDFWriterBuilder builder = RDFWriter.create();
+ builder.format(fmt);
+ if ( RDFLanguages.isQuads(fmt.getLang()) )
+ builder.source(dsg);
+ else
+ builder.source(dsg.getDefaultGraph());
+ String baseURI = writerBaseIRI;
+ if ( baseURI != null )
+ builder.base(baseURI);
+ builder.output(outputWrite);
+ };
return Pair.create(sink, handler) ;
}