This is an automated email from the ASF dual-hosted git repository. andy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit 78ec318ff1c5b4ef60c30ab493d0dd8ac6963f98 Author: Andy Seaborne <[email protected]> AuthorDate: Wed Mar 11 17:18:36 2026 +0000 GH-3796: Short blank node labels writer for N-Triples and N-Quads --- .../main/java/org/apache/jena/riot/RDFFormat.java | 52 ++--- .../org/apache/jena/riot/RDFWriterRegistry.java | 239 +++++++++++---------- .../org/apache/jena/riot/writer/NQuadsWriter.java | 33 ++- .../jena/riot/writer/NQuadsWriterPretty.java | 49 +++++ .../apache/jena/riot/writer/NTriplesWriter.java | 52 +++-- .../jena/riot/writer/NTriplesWriterPretty.java | 49 +++++ .../jena/riot/writer/TestRiotWriterGraph.java | 2 + .../src/main/java/arq/cmdline/ModLangOutput.java | 6 + 8 files changed, 323 insertions(+), 159 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFFormat.java b/jena-arq/src/main/java/org/apache/jena/riot/RDFFormat.java index d086bc24e5..35d6ef0ecd 100644 --- a/jena-arq/src/main/java/org/apache/jena/riot/RDFFormat.java +++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFFormat.java @@ -47,49 +47,53 @@ public class RDFFormat { public static final RDFFormatVariant ValueEncoding = new RDFFormatVariant("Value") ; /** Turtle - pretty form */ - public static final RDFFormat TURTLE_PRETTY = new RDFFormat(Lang.TURTLE, PRETTY) ; + public static final RDFFormat TURTLE_PRETTY = new RDFFormat(Lang.TURTLE, PRETTY) ; /** Turtle - default form */ - public static final RDFFormat TURTLE = TURTLE_PRETTY ; + public static final RDFFormat TURTLE = TURTLE_PRETTY ; /** Turtle - short name */ - public static final RDFFormat TTL = TURTLE_PRETTY ; + public static final RDFFormat TTL = TURTLE_PRETTY ; /** Turtle - write in blocks of triples, with same subject, no nested object or RDF lists */ - public static final RDFFormat TURTLE_BLOCKS = new RDFFormat(Lang.TURTLE, BLOCKS) ; + public static final RDFFormat TURTLE_BLOCKS = new RDFFormat(Lang.TURTLE, BLOCKS) ; /** Turtle - one line per triple */ - public static final RDFFormat TURTLE_FLAT = new RDFFormat(Lang.TURTLE, FLAT) ; + public static final RDFFormat TURTLE_FLAT = new RDFFormat(Lang.TURTLE, FLAT) ; /** Turtle - with fixed indentation width and linebreaks after each sequence element */ - public static final RDFFormat TURTLE_LONG = new RDFFormat(Lang.TURTLE, LONG) ; + public static final RDFFormat TURTLE_LONG = new RDFFormat(Lang.TURTLE, LONG) ; /** N-Triples in UTF-8 */ - public static final RDFFormat NTRIPLES_UTF8 = new RDFFormat(Lang.NTRIPLES, UTF8) ; + public static final RDFFormat NTRIPLES_UTF8 = new RDFFormat(Lang.NTRIPLES, UTF8) ; /** N-Triples - RDF 1.1 form - UTF-8 */ - public static final RDFFormat NTRIPLES = NTRIPLES_UTF8 ; + public static final RDFFormat NTRIPLES = NTRIPLES_UTF8 ; /** N-Triples - RDF 1.1 form - UTF-8 */ - public static final RDFFormat NT = NTRIPLES ; + public static final RDFFormat NT = NTRIPLES ; /** N-Triples - Use ASCII */ - public static final RDFFormat NTRIPLES_ASCII = new RDFFormat(Lang.NTRIPLES, ASCII) ; + public static final RDFFormat NTRIPLES_ASCII = new RDFFormat(Lang.NTRIPLES, ASCII) ; + /** N-Triples in UTF-8 with short blank node identifiers */ + public static final RDFFormat NTRIPLES_PRETTY = new RDFFormat(Lang.NTRIPLES, PRETTY) ; /** N-Quads in UTF-8 */ - public static final RDFFormat NQUADS_UTF8 = new RDFFormat(Lang.NQUADS, UTF8) ; + public static final RDFFormat NQUADS_UTF8 = new RDFFormat(Lang.NQUADS, UTF8) ; /** N-Quads - RDF 1.1 form - UTF-8 */ - public static final RDFFormat NQUADS = NQUADS_UTF8 ; + public static final RDFFormat NQUADS = NQUADS_UTF8 ; /** N-Quads - RDF 1.1 form - UTF-8 */ - public static final RDFFormat NQ = NQUADS ; + public static final RDFFormat NQ = NQUADS ; /** N-Quads - Use ASCII */ - public static final RDFFormat NQUADS_ASCII = new RDFFormat(Lang.NQUADS, ASCII) ; + public static final RDFFormat NQUADS_ASCII = new RDFFormat(Lang.NQUADS, ASCII) ; + /** N-Quads in UTF-8 with short blank node identifiers */ + public static final RDFFormat NQUADS_PRETTY = new RDFFormat(Lang.NTRIPLES, PRETTY) ; /** TriG - pretty form */ - public static final RDFFormat TRIG_PRETTY = new RDFFormat(Lang.TRIG, PRETTY) ; + public static final RDFFormat TRIG_PRETTY = new RDFFormat(Lang.TRIG, PRETTY) ; /** TriG - default form */ - public static final RDFFormat TRIG = TRIG_PRETTY ; + public static final RDFFormat TRIG = TRIG_PRETTY ; /** TriG - write in blocks of triples, with same subject, no nested object or RDF lists */ - public static final RDFFormat TRIG_BLOCKS = new RDFFormat(Lang.TRIG, BLOCKS) ; + public static final RDFFormat TRIG_BLOCKS = new RDFFormat(Lang.TRIG, BLOCKS) ; /** TriG - one line per triple */ - public static final RDFFormat TRIG_FLAT = new RDFFormat(Lang.TRIG, FLAT) ; + public static final RDFFormat TRIG_FLAT = new RDFFormat(Lang.TRIG, FLAT) ; /** TriG - with fixed indentation width and linebreaks after each sequence element */ - public static final RDFFormat TRIG_LONG = new RDFFormat(Lang.TRIG, LONG) ; + public static final RDFFormat TRIG_LONG = new RDFFormat(Lang.TRIG, LONG) ; /** SHACL Compact Syntax */ - public static final RDFFormat SHACLC = new RDFFormat(Lang.SHACLC); + public static final RDFFormat SHACLC = new RDFFormat(Lang.SHACLC); // // JSONLD related // @@ -97,13 +101,13 @@ public class RDFFormat { // ---- JSONLD 1.1 / Titanium /** JSON LD 1.1 - multi-line JSON - prefixes and native types. */ - public static RDFFormat JSONLD11_PRETTY = new RDFFormat(Lang.JSONLD11, RDFFormat.PRETTY); + public static final RDFFormat JSONLD11_PRETTY = new RDFFormat(Lang.JSONLD11, RDFFormat.PRETTY); /** JSON LD 1.1 - multi-line JSON */ - public static RDFFormat JSONLD11_PLAIN = new RDFFormat(Lang.JSONLD11, RDFFormat.PLAIN); + public static final RDFFormat JSONLD11_PLAIN = new RDFFormat(Lang.JSONLD11, RDFFormat.PLAIN); /** JSON LD 1.1 - single-line JSON */ - public static RDFFormat JSONLD11_FLAT = new RDFFormat(Lang.JSONLD11, RDFFormat.FLAT); + public static final RDFFormat JSONLD11_FLAT = new RDFFormat(Lang.JSONLD11, RDFFormat.FLAT); /** JSON LD 1.1 default form - multi-line JSON */ - public static RDFFormat JSONLD11 = JSONLD11_PRETTY; + public static final RDFFormat JSONLD11 = JSONLD11_PRETTY; // ---- JSONLD 1.0 / jsonld-java -- support removed in Jena 5 diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterRegistry.java b/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterRegistry.java index 0828bbeb48..1ccbc3d3bb 100644 --- a/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterRegistry.java +++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFWriterRegistry.java @@ -21,17 +21,17 @@ package org.apache.jena.riot; -import java.util.* ; +import java.util.*; -import org.apache.jena.atlas.lib.CharSpace ; +import org.apache.jena.atlas.lib.CharSpace; import org.apache.jena.riot.protobuf.WriterDatasetProtobuf; import org.apache.jena.riot.protobuf.WriterGraphProtobuf; -import org.apache.jena.riot.system.RiotLib ; +import org.apache.jena.riot.system.RiotLib; import org.apache.jena.riot.system.StreamRDFWriter; -import org.apache.jena.riot.thrift.WriterDatasetThrift ; -import org.apache.jena.riot.thrift.WriterGraphThrift ; -import org.apache.jena.riot.writer.* ; -import org.apache.jena.sys.JenaSystem ; +import org.apache.jena.riot.thrift.WriterDatasetThrift; +import org.apache.jena.riot.thrift.WriterGraphThrift; +import org.apache.jena.riot.writer.*; +import org.apache.jena.sys.JenaSystem; /** * Writer registry. This is for writers presenting the functionality to write graphs and datasets, not streams. @@ -51,11 +51,11 @@ public class RDFWriterRegistry // System defaults for JSON-LD writing in init$(). // Also - settings in RDFFormat. - private static Map<RDFFormat, WriterGraphRIOTFactory> registryGraph = new HashMap<>() ; - private static Map<RDFFormat, WriterDatasetRIOTFactory> registryDataset = new HashMap<>() ; - private static Map<Lang, RDFFormat> langToFormat = new HashMap<>() ; + private static Map<RDFFormat, WriterGraphRIOTFactory> registryGraph = new HashMap<>(); + private static Map<RDFFormat, WriterDatasetRIOTFactory> registryDataset = new HashMap<>(); + private static Map<Lang, RDFFormat> langToFormat = new HashMap<>(); - static { JenaSystem.init() ; } + static { JenaSystem.init(); } // WriterDatasetRIOTFactory as graph writer. private static WriterDatasetRIOTFactory wdsfactoryAsGraph = createWriterDatasetFactory(); @@ -66,29 +66,31 @@ public class RDFWriterRegistry return (RDFFormat serialization) -> { // Built-ins if ( Objects.equals(RDFFormat.TURTLE_PRETTY, serialization) ) - return new TurtleWriter() ; + return new TurtleWriter(); if ( Objects.equals(RDFFormat.TURTLE_BLOCKS, serialization) ) - return new TurtleWriterBlocks() ; + return new TurtleWriterBlocks(); if ( Objects.equals(RDFFormat.TURTLE_FLAT, serialization) ) - return new TurtleWriterFlat() ; + return new TurtleWriterFlat(); if ( Objects.equals(RDFFormat.TURTLE_LONG, serialization) ) - return new TurtleWriterLong() ; + return new TurtleWriterLong(); if ( Objects.equals(RDFFormat.NTRIPLES_UTF8, serialization) ) - return new NTriplesWriter() ; + return new NTriplesWriter(); if ( Objects.equals(RDFFormat.NTRIPLES_ASCII, serialization) ) - return new NTriplesWriter(CharSpace.ASCII) ; + return new NTriplesWriter(CharSpace.ASCII); + if ( Objects.equals(RDFFormat.NTRIPLES_PRETTY, serialization) ) + return new NTriplesWriterPretty(); if ( Objects.equals(RDFFormat.RDFJSON, serialization) ) - return new RDFJSONWriter() ; + return new RDFJSONWriter(); if ( Objects.equals(RDFFormat.RDFXML_PRETTY, serialization) ) - return new RDFXMLAbbrevWriter() ; + return new RDFXMLAbbrevWriter(); if ( Objects.equals(RDFFormat.RDFXML_PLAIN, serialization) ) - return new RDFXMLPlainWriter() ; + return new RDFXMLPlainWriter(); - WriterDatasetRIOT dsw = wdsfactoryForGraph().create(serialization) ; + WriterDatasetRIOT dsw = wdsfactoryForGraph().create(serialization); if ( dsw != null ) - return RiotLib.adapter(dsw) ; + return RiotLib.adapter(dsw); return null; }; } @@ -97,25 +99,28 @@ public class RDFWriterRegistry private static WriterDatasetRIOTFactory createWriterDatasetFactory() { return (RDFFormat serialization) -> { if ( Objects.equals(RDFFormat.TRIG_PRETTY, serialization) ) - return new TriGWriter() ; + return new TriGWriter(); if ( Objects.equals(RDFFormat.TRIG_BLOCKS, serialization) ) - return new TriGWriterBlocks() ; + return new TriGWriterBlocks(); if ( Objects.equals(RDFFormat.TRIG_FLAT, serialization) ) - return new TriGWriterFlat() ; + return new TriGWriterFlat(); if ( Objects.equals(RDFFormat.TRIG_LONG, serialization) ) - return new TriGWriterLong() ; + return new TriGWriterLong(); if ( Objects.equals(RDFFormat.NQUADS_UTF8, serialization) ) - return new NQuadsWriter() ; + return new NQuadsWriter(); if ( Objects.equals(RDFFormat.NQUADS_ASCII, serialization) ) - return new NQuadsWriter(CharSpace.ASCII) ; + return new NQuadsWriter(CharSpace.ASCII); + if ( Objects.equals(RDFFormat.NQUADS_PRETTY, serialization) ) + return new NQuadsWriterPretty(); + if ( Objects.equals(RDFFormat.RDFNULL, serialization) ) - return NullWriter.factory.create(RDFFormat.RDFNULL) ; - return null ; - } ; + return NullWriter.factory.create(RDFFormat.RDFNULL); + return null; + }; } public static void init() {} - static { init$() ; } + static { init$(); } private static void init$() { WriterGraphRIOTFactory wgfactory = createWriterGraphFactory(); @@ -129,7 +134,7 @@ public class RDFWriterRegistry WriterGraphRIOTFactory wgThriftFactory = syntaxForm -> new WriterGraphThrift(syntaxForm); WriterDatasetRIOTFactory wdsThriftFactory = syntaxForm -> new WriterDatasetThrift(syntaxForm); WriterGraphRIOTFactory wgTriXFactory = syntaxForm -> new WriterTriX(); - WriterDatasetRIOTFactory wdsTriXFactory = syntaxForm -> new WriterTriX() ; + WriterDatasetRIOTFactory wdsTriXFactory = syntaxForm -> new WriterTriX(); // ==== System defaults for JSON-LD writing. // ** Coordinate with RDFFormat definitions of JSONLD RDFFormats: @@ -141,93 +146,95 @@ public class RDFWriterRegistry // ----------------------- // Language to format. - register(Lang.TURTLE, RDFFormat.TURTLE) ; - register(Lang.N3, RDFFormat.TURTLE) ; - register(Lang.NTRIPLES, RDFFormat.NTRIPLES) ; - register(Lang.RDFXML, RDFFormat.RDFXML) ; + register(Lang.TURTLE, RDFFormat.TURTLE); + register(Lang.N3, RDFFormat.TURTLE); + register(Lang.NTRIPLES, RDFFormat.NTRIPLES); + register(Lang.RDFXML, RDFFormat.RDFXML); - register(Lang.JSONLD, RDFFormat.JSONLD) ; - register(Lang.JSONLD11, RDFFormat.JSONLD11) ; - register(Lang.RDFJSON, RDFFormat.RDFJSON) ; + register(Lang.JSONLD, RDFFormat.JSONLD); + register(Lang.JSONLD11, RDFFormat.JSONLD11); + register(Lang.RDFJSON, RDFFormat.RDFJSON); - register(Lang.TRIG, RDFFormat.TRIG) ; - register(Lang.NQUADS, RDFFormat.NQUADS) ; - register(Lang.RDFNULL, RDFFormat.RDFNULL) ; - register(Lang.RDFPROTO, RDFFormat.RDF_PROTO) ; - register(Lang.RDFTHRIFT, RDFFormat.RDF_THRIFT) ; + register(Lang.TRIG, RDFFormat.TRIG); + register(Lang.NQUADS, RDFFormat.NQUADS); + register(Lang.RDFNULL, RDFFormat.RDFNULL); + register(Lang.RDFPROTO, RDFFormat.RDF_PROTO); + register(Lang.RDFTHRIFT, RDFFormat.RDF_THRIFT); - register(Lang.TRIX, RDFFormat.TRIX) ; + register(Lang.TRIX, RDFFormat.TRIX); // Writer factories - graph. - register(RDFFormat.TURTLE_PRETTY, wgfactory) ; - register(RDFFormat.TURTLE_BLOCKS, wgfactory) ; - register(RDFFormat.TURTLE_FLAT, wgfactory) ; - register(RDFFormat.TURTLE_LONG, wgfactory) ; + register(RDFFormat.TURTLE_PRETTY, wgfactory); + register(RDFFormat.TURTLE_BLOCKS, wgfactory); + register(RDFFormat.TURTLE_FLAT, wgfactory); + register(RDFFormat.TURTLE_LONG, wgfactory); - register(RDFFormat.NTRIPLES, wgfactory) ; - register(RDFFormat.NTRIPLES_ASCII, wgfactory) ; + register(RDFFormat.NTRIPLES, wgfactory); + register(RDFFormat.NTRIPLES_ASCII, wgfactory); + register(RDFFormat.NTRIPLES_PRETTY, wgfactory); // JSON-LD 1.1 - register(RDFFormat.JSONLD11, wgJsonldFactory11) ; - register(RDFFormat.JSONLD11_PRETTY, wgJsonldFactory11) ; - register(RDFFormat.JSONLD11_PLAIN, wgJsonldFactory11) ; - register(RDFFormat.JSONLD11_FLAT, wgJsonldFactory11) ; + register(RDFFormat.JSONLD11, wgJsonldFactory11); + register(RDFFormat.JSONLD11_PRETTY, wgJsonldFactory11); + register(RDFFormat.JSONLD11_PLAIN, wgJsonldFactory11); + register(RDFFormat.JSONLD11_FLAT, wgJsonldFactory11); - register(RDFFormat.JSONLD11, wdsJsonldFactory11) ; - register(RDFFormat.JSONLD11_PRETTY, wdsJsonldFactory11) ; - register(RDFFormat.JSONLD11_PLAIN, wdsJsonldFactory11) ; - register(RDFFormat.JSONLD11_FLAT, wdsJsonldFactory11) ; + register(RDFFormat.JSONLD11, wdsJsonldFactory11); + register(RDFFormat.JSONLD11_PRETTY, wdsJsonldFactory11); + register(RDFFormat.JSONLD11_PLAIN, wdsJsonldFactory11); + register(RDFFormat.JSONLD11_FLAT, wdsJsonldFactory11); // JSON-LD System defaults. - register(RDFFormat.JSONLD, jsonldWriterGraphDefault) ; - register(RDFFormat.JSONLD_PRETTY, jsonldWriterGraphDefault) ; - register(RDFFormat.JSONLD_PLAIN, jsonldWriterGraphDefault) ; - register(RDFFormat.JSONLD_FLAT, jsonldWriterGraphDefault) ; + register(RDFFormat.JSONLD, jsonldWriterGraphDefault); + register(RDFFormat.JSONLD_PRETTY, jsonldWriterGraphDefault); + register(RDFFormat.JSONLD_PLAIN, jsonldWriterGraphDefault); + register(RDFFormat.JSONLD_FLAT, jsonldWriterGraphDefault); - register(RDFFormat.JSONLD, jsonldWriterDatasetDefault) ; - register(RDFFormat.JSONLD_PRETTY, jsonldWriterDatasetDefault) ; - register(RDFFormat.JSONLD_PLAIN, jsonldWriterDatasetDefault) ; - register(RDFFormat.JSONLD_FLAT, jsonldWriterDatasetDefault) ; + register(RDFFormat.JSONLD, jsonldWriterDatasetDefault); + register(RDFFormat.JSONLD_PRETTY, jsonldWriterDatasetDefault); + register(RDFFormat.JSONLD_PLAIN, jsonldWriterDatasetDefault); + register(RDFFormat.JSONLD_FLAT, jsonldWriterDatasetDefault); - register(RDFFormat.RDFJSON, wgfactory) ; + register(RDFFormat.RDFJSON, wgfactory); - register(RDFFormat.RDFXML_PRETTY, wgfactory) ; - register(RDFFormat.RDFXML_PLAIN, wgfactory) ; + register(RDFFormat.RDFXML_PRETTY, wgfactory); + register(RDFFormat.RDFXML_PLAIN, wgfactory); // Graphs in a quad format. - register(RDFFormat.TRIG_PRETTY, wgfactory) ; - register(RDFFormat.TRIG_BLOCKS, wgfactory) ; - register(RDFFormat.TRIG_FLAT, wgfactory) ; - register(RDFFormat.TRIG_LONG, wgfactory) ; + register(RDFFormat.TRIG_PRETTY, wgfactory); + register(RDFFormat.TRIG_BLOCKS, wgfactory); + register(RDFFormat.TRIG_FLAT, wgfactory); + register(RDFFormat.TRIG_LONG, wgfactory); - register(RDFFormat.NQUADS, wgfactory) ; - register(RDFFormat.NQUADS_ASCII, wgfactory) ; - register(RDFFormat.RDFNULL, wgfactory) ; + register(RDFFormat.NQUADS, wgfactory); + register(RDFFormat.NQUADS_ASCII, wgfactory); + register(RDFFormat.NQUADS_PRETTY, wgfactory); + register(RDFFormat.RDFNULL, wgfactory); - register(RDFFormat.RDF_PROTO, wgProtoFactory) ; - register(RDFFormat.RDF_PROTO_VALUES, wgProtoFactory) ; - register(RDFFormat.RDF_THRIFT, wgThriftFactory) ; - register(RDFFormat.RDF_THRIFT_VALUES, wgThriftFactory) ; + register(RDFFormat.RDF_PROTO, wgProtoFactory); + register(RDFFormat.RDF_PROTO_VALUES, wgProtoFactory); + register(RDFFormat.RDF_THRIFT, wgThriftFactory); + register(RDFFormat.RDF_THRIFT_VALUES, wgThriftFactory); - register(RDFFormat.TRIX, wgTriXFactory) ; + register(RDFFormat.TRIX, wgTriXFactory); // Writer factories - datasets. - register(RDFFormat.TRIG_PRETTY, wdsfactory) ; - register(RDFFormat.TRIG_BLOCKS, wdsfactory) ; - register(RDFFormat.TRIG_FLAT, wdsfactory) ; + register(RDFFormat.TRIG_PRETTY, wdsfactory); + register(RDFFormat.TRIG_BLOCKS, wdsfactory); + register(RDFFormat.TRIG_FLAT, wdsfactory); - register(RDFFormat.NQUADS, wdsfactory) ; - register(RDFFormat.NQUADS_ASCII, wdsfactory) ; - register(RDFFormat.RDFNULL, wdsfactory) ; + register(RDFFormat.NQUADS, wdsfactory); + register(RDFFormat.NQUADS_ASCII, wdsfactory); + register(RDFFormat.RDFNULL, wdsfactory); - register(RDFFormat.RDF_PROTO, wdsProtoFactory) ; - register(RDFFormat.RDF_PROTO_VALUES, wdsProtoFactory) ; - register(RDFFormat.RDF_THRIFT, wdsThriftFactory) ; - register(RDFFormat.RDF_THRIFT_VALUES, wdsThriftFactory) ; + register(RDFFormat.RDF_PROTO, wdsProtoFactory); + register(RDFFormat.RDF_PROTO_VALUES, wdsProtoFactory); + register(RDFFormat.RDF_THRIFT, wdsThriftFactory); + register(RDFFormat.RDF_THRIFT_VALUES, wdsThriftFactory); - register(RDFFormat.TRIX, wdsTriXFactory) ; + register(RDFFormat.TRIX, wdsTriXFactory); } // ---- Compatibility @@ -237,7 +244,7 @@ public class RDFWriterRegistry * @param graphWriterFactory Source of writer engines */ public static void register(RDFFormat serialization, WriterGraphRIOTFactory graphWriterFactory) { - registryGraph.put(serialization, graphWriterFactory) ; + registryGraph.put(serialization, graphWriterFactory); } /** Register the serialization for datasets and it's associated factory @@ -263,22 +270,22 @@ public class RDFWriterRegistry * writing. */ public static void register(Lang lang, RDFFormat format) { - register(format) ; - langToFormat.put(lang, format) ; + register(format); + langToFormat.put(lang, format); } /** Return the format registered as the default for the language */ public static RDFFormat defaultSerialization(Lang lang) { - return langToFormat.get(lang) ; + return langToFormat.get(lang); } /** Does the language have a registered output format? */ public static boolean contains(Lang lang) { if ( !langToFormat.containsKey(lang) ) - return false ; + return false; - RDFFormat fmt = langToFormat.get(lang) ; - return contains(fmt) ; + RDFFormat fmt = langToFormat.get(lang); + return contains(fmt); } /** Is the RDFFormat registered for use? */ @@ -289,20 +296,20 @@ public class RDFWriterRegistry /** All registered graph formats */ public static Collection<RDFFormat> registeredGraphFormats() { - return Set.copyOf(registryGraph.keySet()) ; + return Set.copyOf(registryGraph.keySet()); } /** All registered dataset formats */ public static Collection<RDFFormat> registeredDatasetFormats() { - return Set.copyOf(registryDataset.keySet()) ; + return Set.copyOf(registryDataset.keySet()); } /** All registered formats */ public static Collection<RDFFormat> registeredFormats() { - Set<RDFFormat> x = new HashSet<>() ; - x.addAll(registryGraph.keySet()) ; - x.addAll(registryDataset.keySet()) ; - return Set.copyOf(x) ; + Set<RDFFormat> x = new HashSet<>(); + x.addAll(registryGraph.keySet()); + x.addAll(registryDataset.keySet()); + return Set.copyOf(x); } /** All registered languages */ @@ -312,30 +319,30 @@ public class RDFWriterRegistry /** Get the graph writer factory associated with the language */ public static WriterGraphRIOTFactory getWriterGraphFactory(Lang lang) { - RDFFormat serialization = defaultSerialization(lang) ; + RDFFormat serialization = defaultSerialization(lang); if ( serialization == null ) - throw new RiotException("No default serialization for language " + lang) ; - return getWriterGraphFactory(serialization) ; + throw new RiotException("No default serialization for language " + lang); + return getWriterGraphFactory(serialization); } /** Get the graph writer factory associated with the output format */ public static WriterGraphRIOTFactory getWriterGraphFactory(RDFFormat serialization) { - return registryGraph.get(serialization) ; + return registryGraph.get(serialization); } /** Get the dataset writer factory associated with the language */ public static WriterDatasetRIOTFactory getWriterDatasetFactory(Lang lang) { - RDFFormat serialization = defaultSerialization(lang) ; + RDFFormat serialization = defaultSerialization(lang); if ( serialization == null ) - throw new RiotException("No default serialization for language " + lang) ; - return getWriterDatasetFactory(serialization) ; + throw new RiotException("No default serialization for language " + lang); + return getWriterDatasetFactory(serialization); } /** Get the dataset writer factory associated with the output format */ public static WriterDatasetRIOTFactory getWriterDatasetFactory(RDFFormat serialization) { if ( serialization == null ) - return null ; - return registryDataset.get(serialization) ; + return null; + return registryDataset.get(serialization); } } diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java index 275296e61f..bfe85dbb5f 100644 --- a/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java +++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java @@ -25,8 +25,12 @@ import java.io.OutputStream; import java.io.Writer; import java.util.Iterator; +import org.apache.jena.atlas.io.AWriter; +import org.apache.jena.atlas.io.IO; import org.apache.jena.atlas.lib.CharSpace; import org.apache.jena.riot.Lang; +import org.apache.jena.riot.out.NodeFormatter; +import org.apache.jena.riot.out.NodeFormatterNT; import org.apache.jena.riot.system.PrefixMap; import org.apache.jena.riot.system.StreamRDFOps; import org.apache.jena.riot.system.StreamRDF; @@ -36,6 +40,7 @@ import org.apache.jena.sparql.core.Quad; import org.apache.jena.sparql.util.Context; public class NQuadsWriter extends WriterDatasetRIOTBase { + public static void write(OutputStream out, Iterator<Quad> iter) { write(out, iter, CharSpace.UTF8); } @@ -45,10 +50,14 @@ public class NQuadsWriter extends WriterDatasetRIOTBase { write$(s, iter); } + /** @deprecated Use RIOT and language {@link Lang#NQUADS} */ + @Deprecated(forRemoval = true) public static void write(Writer out, Iterator<Quad> iter) { write(out, iter, CharSpace.UTF8); } + /** @deprecated Use RIOT and language {@link Lang#NQUADS} */ + @Deprecated(forRemoval = true) public static void write(Writer out, Iterator<Quad> iter, CharSpace charSpace) { StreamRDF s = StreamRDFLib.writer(out, charSpace); write$(s, iter); @@ -77,11 +86,31 @@ public class NQuadsWriter extends WriterDatasetRIOTBase { @Override public void write(Writer out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context context) { - write(out, dataset.find(null, null, null, null), this.charSpace); + Iterator<Quad> iter = dataset.find(); + NodeFormatter nodeFmt = createNodeFormatter(); + AWriter w = IO.wrap(out); + StreamRDF s = new WriterStreamRDFPlain(IO.wrap(out), nodeFmt); + write$(s, iter); } @Override public void write(OutputStream out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context context) { - write(out, dataset.find(null, null, null, null), this.charSpace); + Iterator<Quad> iter = dataset.find(); + NodeFormatter nodeFmt = createNodeFormatter(); + AWriter w = createAWriter(out); + StreamRDF s = new WriterStreamRDFPlain(w, nodeFmt); + write$(s, iter); + } + + protected NodeFormatter createNodeFormatter() { + NodeFormatter nodeFmt =new NodeFormatterNT(charSpace); + return nodeFmt; + } + + protected AWriter createAWriter(OutputStream out) { + return switch(charSpace) { + case ASCII -> IO.wrapASCII(out); + case UTF8 -> IO.wrapUTF8(out); + }; } } diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriterPretty.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriterPretty.java new file mode 100644 index 0000000000..9711dc70ac --- /dev/null +++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/NQuadsWriterPretty.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 + * + * https://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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.apache.jena.riot.writer; + +import org.apache.jena.atlas.io.AWriter; +import org.apache.jena.graph.Node; +import org.apache.jena.riot.out.NodeFormatter; +import org.apache.jena.riot.out.NodeFormatterNT; +import org.apache.jena.riot.out.NodeToLabel; + +/** + * The only prettiness is that blank nodes are written with short labels. + * <p> + * This means the writer has long-term internal state and may not write very large + * N-triple streams which have very large numbers of blank nodes. + */ +public class NQuadsWriterPretty extends NQuadsWriter { + @Override + protected NodeFormatter createNodeFormatter() { + NodeFormatter nodeFmt = new NodeFormatterNT() { + private final NodeToLabel nodeToLabel = NodeToLabel.createScopeByDocument(); + @Override + public void formatBNode(AWriter w, Node blankNode) { + String x = nodeToLabel.get(null, blankNode); + w.print(x); + } + }; + return nodeFmt; + } +} \ No newline at end of file diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java index 67a6c0a60e..dd93fe6142 100644 --- a/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java +++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java @@ -21,23 +21,29 @@ package org.apache.jena.riot.writer; +import static org.apache.jena.atlas.lib.CharSpace.UTF8; + import java.io.OutputStream; import java.io.Writer; import java.util.Iterator; +import java.util.Objects; +import org.apache.jena.atlas.io.AWriter; import org.apache.jena.atlas.io.IO; import org.apache.jena.atlas.lib.CharSpace; -import static org.apache.jena.atlas.lib.CharSpace.*; import org.apache.jena.graph.Graph; import org.apache.jena.graph.Triple; import org.apache.jena.riot.Lang; +import org.apache.jena.riot.out.NodeFormatter; +import org.apache.jena.riot.out.NodeFormatterNT; import org.apache.jena.riot.system.PrefixMap; -import org.apache.jena.riot.system.StreamRDFOps; import org.apache.jena.riot.system.StreamRDF; import org.apache.jena.riot.system.StreamRDFLib; +import org.apache.jena.riot.system.StreamRDFOps; import org.apache.jena.sparql.util.Context; public class NTriplesWriter extends WriterGraphRIOTBase { + public static void write(OutputStream out, Iterator<Triple> iter) { write(out, iter, CharSpace.UTF8); } @@ -47,10 +53,14 @@ public class NTriplesWriter extends WriterGraphRIOTBase { write$(s, iter); } + /** @deprecated Use RIOT and language {@link Lang#NTRIPLES} */ + @Deprecated(forRemoval = true) public static void write(Writer out, Iterator<Triple> iter) { write(out, iter, CharSpace.UTF8); } + /** @deprecated Use RIOT and language {@link Lang#NTRIPLES} */ + @Deprecated(forRemoval = true) public static void write(Writer out, Iterator<Triple> iter, CharSpace charSpace) { StreamRDF s = StreamRDFLib.writer(out, charSpace); write$(s, iter); @@ -62,13 +72,14 @@ public class NTriplesWriter extends WriterGraphRIOTBase { s.finish(); } - private final CharSpace charSpace; + protected final CharSpace charSpace; public NTriplesWriter() { this(UTF8); } public NTriplesWriter(CharSpace charSpace) { + Objects.requireNonNull(charSpace); this.charSpace = charSpace; } @@ -79,24 +90,31 @@ public class NTriplesWriter extends WriterGraphRIOTBase { @Override public void write(Writer out, Graph graph, PrefixMap prefixMap, String baseURI, Context context) { - Iterator<Triple> iter = graph.find(null, null, null); - if ( charSpace == UTF8 ) - write(out, iter); - else { - StreamRDF s = new WriterStreamRDFPlain(IO.wrap(out), ASCII); - write$(s, iter); - } + Iterator<Triple> iter = graph.find(); + NodeFormatter nodeFmt = createNodeFormatter(); + AWriter w = IO.wrap(out); + StreamRDF s = new WriterStreamRDFPlain(IO.wrap(out), nodeFmt); + write$(s, iter); } @Override public void write(OutputStream out, Graph graph, PrefixMap prefixMap, String baseURI, Context context) { - Iterator<Triple> iter = graph.find(null, null, null); - if ( charSpace == UTF8 ) - write(out, iter); - else { - StreamRDF s = new WriterStreamRDFPlain(IO.wrapASCII(out), ASCII); - write$(s, iter); - } + Iterator<Triple> iter = graph.find(); + NodeFormatter nodeFmt = createNodeFormatter(); + AWriter w = createAWriter(out); + StreamRDF s = new WriterStreamRDFPlain(w, nodeFmt); + write$(s, iter); + } + + protected NodeFormatter createNodeFormatter() { + NodeFormatter nodeFmt =new NodeFormatterNT(charSpace); + return nodeFmt; + } + protected AWriter createAWriter(OutputStream out) { + return switch(charSpace) { + case ASCII -> IO.wrapASCII(out); + case UTF8 -> IO.wrapUTF8(out); + }; } } diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriterPretty.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriterPretty.java new file mode 100644 index 0000000000..d5be5925d3 --- /dev/null +++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/NTriplesWriterPretty.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 + * + * https://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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.apache.jena.riot.writer; + +import org.apache.jena.atlas.io.AWriter; +import org.apache.jena.graph.Node; +import org.apache.jena.riot.out.NodeFormatter; +import org.apache.jena.riot.out.NodeFormatterNT; +import org.apache.jena.riot.out.NodeToLabel; + +/** + * The only prettiness is that blank nodes are written with short labels. + * <p> + * This means the writer has long-term internal state and may not write very large + * N-triple streams which have very large numbers of blank nodes. + */ +public class NTriplesWriterPretty extends NTriplesWriter { + @Override + protected NodeFormatter createNodeFormatter() { + NodeFormatter nodeFmt = new NodeFormatterNT() { + private final NodeToLabel nodeToLabel = NodeToLabel.createScopeByDocument(); + @Override + public void formatBNode(AWriter w, Node blankNode) { + String x = nodeToLabel.get(null, blankNode); + w.print(x); + } + }; + return nodeFmt; + } +} \ No newline at end of file diff --git a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterGraph.java b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterGraph.java index fce4f08b13..6e7be94537 100644 --- a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterGraph.java +++ b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterGraph.java @@ -51,6 +51,7 @@ public class TestRiotWriterGraph extends AbstractWriterTest { Arguments.of(RDFFormat.NTRIPLES_UTF8), Arguments.of(RDFFormat.NTRIPLES_ASCII), + Arguments.of(RDFFormat.NTRIPLES_PRETTY), Arguments.of(RDFFormat.NTRIPLES), Arguments.of(RDFFormat.TURTLE), Arguments.of(RDFFormat.TURTLE_PRETTY), @@ -78,6 +79,7 @@ public class TestRiotWriterGraph extends AbstractWriterTest { Arguments.of(RDFFormat.TRIG_LONG), Arguments.of(RDFFormat.NQUADS_UTF8), Arguments.of(RDFFormat.NQUADS_ASCII), + Arguments.of(RDFFormat.NQUADS_PRETTY), Arguments.of(RDFFormat.NQUADS), Arguments.of(RDFFormat.RDF_PROTO), diff --git a/jena-cmds/src/main/java/arq/cmdline/ModLangOutput.java b/jena-cmds/src/main/java/arq/cmdline/ModLangOutput.java index 5ec1c77969..c73f7627b8 100644 --- a/jena-cmds/src/main/java/arq/cmdline/ModLangOutput.java +++ b/jena-cmds/src/main/java/arq/cmdline/ModLangOutput.java @@ -76,6 +76,12 @@ public class ModLangOutput extends ModBase printRegistered(System.err); throw new CmdException("No output set: '"+langName+"'"); } + + // Formats unused used for "pretty" + if ( Lang.NTRIPLES.equals(formattedOutput.getLang()) ) + formattedOutput = RDFFormat.NTRIPLES_PRETTY; + if ( Lang.NQUADS.equals(formattedOutput.getLang()) ) + formattedOutput = RDFFormat.NQUADS_PRETTY; } if ( cmdLine.contains(argStream) ) {
