You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2016/10/03 10:35:48 UTC
[16/41] jena git commit: calling the json-ld (0.8.3) method that
assumes no duplicates in dataset (cf.
https://github.com/jsonld-java/jsonld-java/pull/173) Changes following Andy's
comments: RDFFormatVariant, indentation using spaces
calling the json-ld (0.8.3) method that assumes no duplicates in dataset
(cf. https://github.com/jsonld-java/jsonld-java/pull/173)
Changes following Andy's comments: RDFFormatVariant, indentation using
spaces
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/39c881ad
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/39c881ad
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/39c881ad
Branch: refs/heads/master
Commit: 39c881ad8fe599b3e830fef3ced71d3da3b9faf3
Parents: 7f0f061
Author: Franc\u0327ois-Paul Servant <fp...@semanlink.net>
Authored: Sun Aug 28 23:38:01 2016 +0200
Committer: Franc\u0327ois-Paul Servant <fp...@semanlink.net>
Committed: Sun Aug 28 23:38:01 2016 +0200
----------------------------------------------------------------------
.../java/org/apache/jena/riot/RDFFormat.java | 61 +-
.../org/apache/jena/riot/WriterDatasetRIOT.java | 7 +-
.../org/apache/jena/riot/out/JsonLDWriter.java | 328 ++++----
.../jena/riot/writer/TestJsonLDWriter.java | 764 +++++++++----------
4 files changed, 584 insertions(+), 576 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/39c881ad/jena-arq/src/main/java/org/apache/jena/riot/RDFFormat.java
----------------------------------------------------------------------
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 311b21b..c5e1065 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
@@ -40,7 +40,7 @@ public class RDFFormat {
public static final RDFFormatVariant UTF8 = new RDFFormatVariant("utf-8") ;
/** Variant for RDF Thrift using values */
public static final RDFFormatVariant ValueEncoding = new RDFFormatVariant("Value") ;
-
+
/** Turtle - pretty form */
public static final RDFFormat TURTLE_PRETTY = new RDFFormat(Lang.TURTLE, PRETTY) ;
/** Turtle - default form */
@@ -79,19 +79,52 @@ public class RDFFormat {
/** TriG - one line per triple */
public static final RDFFormat TRIG_FLAT = new RDFFormat(Lang.TRIG, FLAT) ;
+ //
+ // JSONLD related
+ //
+
+ public static class JSONLDVariant extends RDFFormatVariant {
+ private static enum JSONLD_FORMAT {
+ COMPACT,
+ FLATTEN,
+ EXPAND,
+ FRAME
+ }
+
+ private JSONLD_FORMAT format ;
+ private boolean prettyJson ;
+
+ JSONLDVariant(String name, boolean prettyJson, JSONLD_FORMAT format) {
+ super(name) ;
+ this.format = format ;
+ this.prettyJson = prettyJson ;
+ }
+
+ public boolean isPretty() { return prettyJson ; }
+
+ private boolean isFormat(JSONLD_FORMAT fmt) {
+ return (fmt == format);
+ }
+
+ public boolean isCompact() { return isFormat(JSONLD_FORMAT.COMPACT); }
+ public boolean isFlatten() { return isFormat(JSONLD_FORMAT.FLATTEN); }
+ public boolean isExpand() { return isFormat(JSONLD_FORMAT.EXPAND); }
+ public boolean isFrame() { return isFormat(JSONLD_FORMAT.FRAME); }
+
+ }
+
// variants for the JsonLD outputs.
- // because of the prexisting JSONLD_PRETTY and JSONLD_FLAT,
+ // because of the preexisting JSONLD_PRETTY and JSONLD_FLAT,
// we're more or less obliged to create all of these
- // (I'd have preferred to use a flag for pretty vs flat)
-
- private static final RDFFormatVariant EXPAND_PRETTY = new RDFFormatVariant("expand pretty") ;
- private static final RDFFormatVariant EXPAND_FLAT = new RDFFormatVariant("expand flat") ;
- private static final RDFFormatVariant COMPACT_PRETTY = new RDFFormatVariant("compact pretty") ;
- private static final RDFFormatVariant COMPACT_FLAT = new RDFFormatVariant("compact flat") ;
- private static final RDFFormatVariant FLATTEN_PRETTY = new RDFFormatVariant("flatten pretty") ;
- private static final RDFFormatVariant FLATTEN_FLAT = new RDFFormatVariant("flatten flat") ;
- private static final RDFFormatVariant FRAME_PRETTY = new RDFFormatVariant("frame pretty") ;
- private static final RDFFormatVariant FRAME_FLAT = new RDFFormatVariant("frame flat") ;
+
+ private static final RDFFormatVariant EXPAND_PRETTY = new JSONLDVariant("expand pretty", true, JSONLDVariant.JSONLD_FORMAT.EXPAND) ;
+ private static final RDFFormatVariant EXPAND_FLAT = new JSONLDVariant("expand flat", false, JSONLDVariant.JSONLD_FORMAT.EXPAND) ;
+ private static final RDFFormatVariant COMPACT_PRETTY = new JSONLDVariant("compact pretty", true, JSONLDVariant.JSONLD_FORMAT.COMPACT) ;
+ private static final RDFFormatVariant COMPACT_FLAT = new JSONLDVariant("compact flat", false, JSONLDVariant.JSONLD_FORMAT.COMPACT) ;
+ private static final RDFFormatVariant FLATTEN_PRETTY = new JSONLDVariant("flatten pretty", true, JSONLDVariant.JSONLD_FORMAT.FLATTEN) ;
+ private static final RDFFormatVariant FLATTEN_FLAT = new JSONLDVariant("flatten flat", false, JSONLDVariant.JSONLD_FORMAT.FLATTEN) ;
+ private static final RDFFormatVariant FRAME_PRETTY = new JSONLDVariant("frame pretty", true, JSONLDVariant.JSONLD_FORMAT.FRAME) ;
+ private static final RDFFormatVariant FRAME_FLAT = new JSONLDVariant("frame flat", false, JSONLDVariant.JSONLD_FORMAT.FRAME) ;
public static final RDFFormat JSONLD_EXPAND_PRETTY = new RDFFormat(Lang.JSONLD, EXPAND_PRETTY) ;
public static final RDFFormat JSONLD_EXPAND_FLAT = new RDFFormat(Lang.JSONLD, EXPAND_FLAT) ;
@@ -102,7 +135,7 @@ public class RDFFormat {
public static final RDFFormat JSONLD_FRAME_PRETTY = new RDFFormat(Lang.JSONLD, FRAME_PRETTY) ;
public static final RDFFormat JSONLD_FRAME_FLAT = new RDFFormat(Lang.JSONLD, FRAME_FLAT) ;
- // redefine following ones in a way that preserve what they were doing in previous version
+ // redefine following ones in a way that preserve what they were doing in previous version
public static final RDFFormat JSONLD_PRETTY = JSONLD_COMPACT_PRETTY ;
public static final RDFFormat JSONLD = JSONLD_COMPACT_PRETTY ;
public static final RDFFormat JSONLD_FLAT = JSONLD_COMPACT_FLAT ;
@@ -127,7 +160,7 @@ public class RDFFormat {
*
* @see #RDF_THRIFT_VALUES
*/
-
+
public static final RDFFormat RDF_THRIFT = new RDFFormat(THRIFT) ;
/**
* A variant of an an RDFFormat that uses value encoding (e.g. integers,
http://git-wip-us.apache.org/repos/asf/jena/blob/39c881ad/jena-arq/src/main/java/org/apache/jena/riot/WriterDatasetRIOT.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/WriterDatasetRIOT.java b/jena-arq/src/main/java/org/apache/jena/riot/WriterDatasetRIOT.java
index f7f21c6..9eb4347 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/WriterDatasetRIOT.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/WriterDatasetRIOT.java
@@ -18,11 +18,12 @@
package org.apache.jena.riot;
-import java.io.OutputStream ;
+import java.io.OutputStream;
import java.io.Writer ;
import org.apache.jena.riot.Lang ;
import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.RiotLib;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.util.Context ;
@@ -47,6 +48,10 @@ public interface WriterDatasetRIOT
* @param context Context (see specific implementation for details)
*/
public void write(OutputStream out, DatasetGraph datasetGraph, PrefixMap prefixMap, String baseURI, Context context) ;
+
+ default public void write(OutputStream out, DatasetGraph datasetGraph, String baseURI, Context context) {
+ write(out, datasetGraph, RiotLib.prefixMap(datasetGraph), baseURI, context);
+ }
// /** Use of Writer is discouraged - let the serializer manage character sets in accordance with the format */
// public void write(Writer out, DatasetGraph datasetGraph) ;
http://git-wip-us.apache.org/repos/asf/jena/blob/39c881ad/jena-arq/src/main/java/org/apache/jena/riot/out/JsonLDWriter.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/out/JsonLDWriter.java b/jena-arq/src/main/java/org/apache/jena/riot/out/JsonLDWriter.java
index 0bbba9f..919e308 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/out/JsonLDWriter.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/out/JsonLDWriter.java
@@ -53,20 +53,24 @@ import org.apache.log4j.Logger;
import com.fasterxml.jackson.core.JsonGenerationException ;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException ;
+import com.github.jsonldjava.core.JsonLdApi;
import com.github.jsonldjava.core.JsonLdError ;
import com.github.jsonldjava.core.JsonLdOptions ;
import com.github.jsonldjava.core.JsonLdProcessor ;
+import com.github.jsonldjava.core.RDFDataset;
import com.github.jsonldjava.utils.JsonUtils ;
/**
* Writer that prints out JSON-LD.
*
- * By default, the output is "compact" (in JSON-LD terminology).
+ * By default, the output is "compact" (in JSON-LD terminology), and the JSON is "pretty" (using line breaks).
* One can choose another form using one of the dedicated RDFFormats (JSONLD_EXPAND_PRETTY, etc.).
+ *
* For formats using a context ("@context" node), (compact and expand), this automatically generates a default one.
* One can pass a jsonld context using the (jena) Context mechanism, defining a (jena) Context
- * (sorry for this clash of contexts), (cf. 4th argument in
+ * (sorry for this clash of contexts), (cf. last argument in
* {@link org.apache.jena.riot.RDFDataMgr#write(OutputStream out, Model model, RDFFormat serialization, Context ctx)})
+ * {@link java.io.OutputStream.WriterDatasetRIOT.write(OutputStream out, DatasetGraph datasetGraph, PrefixMap prefixMap, String baseURI, Context context)})
* with:
* <pre>
* Context jenaContext = new Context()
@@ -74,40 +78,43 @@ import com.github.jsonldjava.utils.JsonUtils ;
* </pre>
* where contextAsJsonString is a JSON string containing the value of the "@context".
*
- * One can also pass a frame with the {@link #JSONLD_FRAME}, or define the options expected
- * by JSONLD-java using {@link #JSONLD_OPTIONS}
+ * It is possible to change the content of the "@context" node in the output using the {@link #JSONLD_CONTEXT_SUBSTITUTION} Symbol.
+ *
+ * For a frame output, one must pass a frame in the jenaContext using the {@link #JSONLD_FRAME} Symbol.
+ *
+ * It is also possible to define the different options supported
+ * by JSONLD-java using the {@link #JSONLD_OPTIONS} Symbol
*
*
*/
public class JsonLDWriter extends WriterDatasetRIOTBase
{
- /** Expected value: the value of the "@context" (a JSON String) */
- public static final Symbol JSONLD_CONTEXT = Symbol.create("JSONLD_CONTEXT");
- /**
- * Expected value: the value of the "@context" to be put in final output (a JSON String)
- * This is NOT the context used to produce the output (given by JSONLD_CONTEXT,
- * or computed from the input RDF. It is something that will replace the @content content
- * This is useful 1) for the cases you want to have a URI as value of @context,
- * without having JSON-LD java to download it and 2) as a trick to
- * change the URIs in your result.
- *
- * Only for compact and flatten formats.
- *
- * Note that it is supposed to be a JSON String: to set the value of @context to a URI,
- * the String to use must be quoted.*/
- public static final Symbol JSONLD_CONTEXT_SUBSTITUTION = Symbol.create("JSONLD_CONTEXT_SUBSTITUTION");
- /** value: the frame object expected by JsonLdProcessor.frame */
- public static final Symbol JSONLD_FRAME = Symbol.create("JSONLD_FRAME");
- /** value: the option object expected by JsonLdProcessor (instance of JsonLdOptions) */
- public static final Symbol JSONLD_OPTIONS = Symbol.create("JSONLD_OPTIONS");
- private static enum JSONLD_FORMAT {
- COMPACT,
- FLATTEN,
- EXPAND,
- FRAME
- }
-
- private final RDFFormat format ;
+ private static final String SYMBOLS_NS = "http://jena.apache.org/riot/jsonld#" ;
+ private static Symbol createSymbol(String localName) {
+ return Symbol.create(SYMBOLS_NS + localName);
+ }
+
+ /** Expected value: the value of the "@context" (a JSON String) */
+ public static final Symbol JSONLD_CONTEXT = createSymbol("JSONLD_CONTEXT");
+ /**
+ * Expected value: the value of the "@context" to be put in final output (a JSON String)
+ * This is NOT the context used to produce the output (given by JSONLD_CONTEXT,
+ * or computed from the input RDF. It is something that will replace the @context content.
+ * This is useful<ol><li>for the cases you want to have a URI as value of @context,
+ * without having JSON-LD java to download it and</li><li>as a trick to
+ * change the URIs in your result.</li></ol>
+ *
+ * Only for compact and flatten formats.
+ *
+ * Note that it is supposed to be a JSON String: to set the value of @context to a URI,
+ * the String must be quoted.*/
+ public static final Symbol JSONLD_CONTEXT_SUBSTITUTION = createSymbol("JSONLD_CONTEXT_SUBSTITUTION");
+ /** value: the frame object expected by JsonLdProcessor.frame */
+ public static final Symbol JSONLD_FRAME = createSymbol("JSONLD_FRAME");
+ /** value: the option object expected by JsonLdProcessor (instance of JsonLdOptions) */
+ public static final Symbol JSONLD_OPTIONS = createSymbol("JSONLD_OPTIONS");
+
+ private final RDFFormat format ;
public JsonLDWriter(RDFFormat syntaxForm) {
format = syntaxForm ;
@@ -130,85 +137,81 @@ public class JsonLDWriter extends WriterDatasetRIOTBase
IO.flush(w) ;
}
- private JSONLD_FORMAT getOutputFormat() {
- if ((RDFFormat.JSONLD_COMPACT_PRETTY.equals(format)) || (RDFFormat.JSONLD_COMPACT_FLAT.equals(format))) return JSONLD_FORMAT.COMPACT;
- if ((RDFFormat.JSONLD_EXPAND_PRETTY.equals(format)) || (RDFFormat.JSONLD_EXPAND_FLAT.equals(format))) return JSONLD_FORMAT.EXPAND;
- if ((RDFFormat.JSONLD_FLATTEN_PRETTY.equals(format)) || (RDFFormat.JSONLD_FLATTEN_FLAT.equals(format))) return JSONLD_FORMAT.FLATTEN;
- if ((RDFFormat.JSONLD_FRAME_PRETTY.equals(format)) || (RDFFormat.JSONLD_FRAME_FLAT.equals(format))) return JSONLD_FORMAT.FRAME;
- throw new RuntimeException("Unexpected output format");
- }
-
- private boolean isPretty() {
- return (((RDFFormat.JSONLD_COMPACT_PRETTY.equals(format))
- || (RDFFormat.JSONLD_FLATTEN_PRETTY.equals(format))
- || (RDFFormat.JSONLD_EXPAND_PRETTY.equals(format)))
- || (RDFFormat.JSONLD_FRAME_PRETTY.equals(format))) ;
+ private RDFFormat.JSONLDVariant getVariant() {
+ return (RDFFormat.JSONLDVariant) format.getVariant();
}
-
+
private JsonLdOptions getJsonLdOptions(String baseURI, Context jenaContext) {
- JsonLdOptions opts = null;
- if (jenaContext != null) {
- opts = (JsonLdOptions) jenaContext.get(JSONLD_OPTIONS);
- }
- if (opts == null) {
- opts = new JsonLdOptions(baseURI);
- opts.useNamespaces = true ;
- //opts.setUseRdfType(true);
- opts.setUseNativeTypes(true);
- opts.setCompactArrays(true);
- }
- return opts;
+ JsonLdOptions opts = null;
+ if (jenaContext != null) {
+ opts = (JsonLdOptions) jenaContext.get(JSONLD_OPTIONS);
+ }
+ if (opts == null) {
+ opts = new JsonLdOptions(baseURI);
+ // maybe we should have used the same defaults as jsonld-java. Too late now
+ opts.useNamespaces = true ;
+ //opts.setUseRdfType(true); // false -> use "@type"
+ opts.setUseNativeTypes(true);
+ opts.setCompactArrays(true);
+ }
+ return opts;
}
+ @SuppressWarnings("deprecation") // JsonLdApi.fromRDF(RDFDataset, boolean) is "experimental" rather than "deprecated", cf. https://github.com/jsonld-java/jsonld-java/pull/173
private void serialize(Writer writer, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context jenaContext) {
try {
- JsonLdOptions opts = getJsonLdOptions(baseURI, jenaContext) ;
-
- Object obj = JsonLdProcessor.fromRDF(dataset, opts, new JenaRDF2JSONLD()) ;
+ JsonLdOptions opts = getJsonLdOptions(baseURI, jenaContext) ;
+
+ // we can benefit from the fact we know that there are no duplicates in the jsonld RDFDataset that we create
+ // cf. cf. https://github.com/jsonld-java/jsonld-java/pull/173
- JSONLD_FORMAT outputForm = getOutputFormat() ;
- if (outputForm == JSONLD_FORMAT.EXPAND) {
- // nothing more to do
-
- } else if (outputForm == JSONLD_FORMAT.FRAME) {
- Object frame = null;
- if (jenaContext != null)
- frame = jenaContext.get(JSONLD_FRAME);
-
- if (frame == null) {
- throw new IllegalArgumentException("No frame object found in context");
- }
- obj = JsonLdProcessor.frame(obj, frame, opts);
-
- } else {
- // we need a (jsonld) context. Get it from jenaContext, or make one:
- Object ctx = getJsonldContext(dataset, prefixMap, jenaContext);
-
- if (outputForm == JSONLD_FORMAT.COMPACT) {
- obj = JsonLdProcessor.compact(obj, ctx, opts);
-
- } else if (outputForm == JSONLD_FORMAT.FLATTEN) {
- obj = JsonLdProcessor.flatten(obj, ctx, opts);
-
- } else {
- throw new IllegalArgumentException("Unexpected output form " + outputForm);
- }
-
- // replace @context in output?
- if (jenaContext != null) {
- Object ctxReplacement = jenaContext.get(JSONLD_CONTEXT_SUBSTITUTION);
- if (ctxReplacement != null) {
- if (obj instanceof Map) {
- Map map = (Map) obj;
- if (map.containsKey("@context")) {
- map.put("@context", JsonUtils.fromString((String) ctxReplacement));
- }
- }
- }
- }
- }
-
- if ( isPretty() )
+ // with this, we cannot call the json-ld fromRDF method that assumes no duplicates in RDFDataset
+ // Object obj = JsonLdProcessor.fromRDF(dataset, opts, new JenaRDF2JSONLD()) ;
+ final RDFDataset jsonldDataset = (new JenaRDF2JSONLD()).parse(dataset);
+ Object obj = (new JsonLdApi(opts)).fromRDF(jsonldDataset, true); // true because we know that we don't have any duplicate in jsonldDataset
+
+ RDFFormat.JSONLDVariant variant = getVariant();
+ if (variant.isExpand()) {
+ // nothing more to do
+
+ } else if (variant.isFrame()) {
+ Object frame = null;
+ if (jenaContext != null) frame = jenaContext.get(JSONLD_FRAME);
+
+ if (frame == null) {
+ throw new IllegalArgumentException("No frame object found in jena Context");
+ }
+ obj = JsonLdProcessor.frame(obj, frame, opts);
+
+ } else { // compact or flatten
+ // we need a (jsonld) context. Get it from jenaContext, or make one:
+ Object ctx = getJsonldContext(dataset, prefixMap, jenaContext);
+
+ if (variant.isCompact()) {
+ obj = JsonLdProcessor.compact(obj, ctx, opts);
+
+ } else if (variant.isFlatten()) {
+ obj = JsonLdProcessor.flatten(obj, ctx, opts);
+
+ } else {
+ throw new IllegalArgumentException("Unexpected " + RDFFormat.JSONLDVariant.class.getName() + ": " + variant);
+ }
+
+ // replace @context in output?
+ if (jenaContext != null) {
+ Object ctxReplacement = jenaContext.get(JSONLD_CONTEXT_SUBSTITUTION);
+ if (ctxReplacement != null) {
+ if (obj instanceof Map) {
+ Map map = (Map) obj;
+ if (map.containsKey("@context")) {
+ map.put("@context", JsonUtils.fromString((String) ctxReplacement));
+ }
+ }
+ }
+ }
+ }
+
+ if ( variant.isPretty() )
JsonUtils.writePrettyPrint(writer, obj) ;
else
JsonUtils.write(writer, obj) ;
@@ -225,72 +228,73 @@ public class JsonLDWriter extends WriterDatasetRIOTBase
//
// getting / creating a (jsonld) context
//
-
+
/** Get the (jsonld) context from the jena context, or create one */
private static Object getJsonldContext(DatasetGraph dataset, PrefixMap prefixMap, Context jenaContext) throws JsonParseException, IOException {
- Object ctx = null;
- boolean isCtxDefined = false; // to allow jenaContext to set ctx to null. Useful?
-
- if (jenaContext != null) {
- if (jenaContext.isDefined(JSONLD_CONTEXT)) {
- isCtxDefined = true;
- Object o = jenaContext.get(JSONLD_CONTEXT);
- if (o != null) {
- // I won't assume it is a string, to leave the possibility to pass
- // the context object expected by JSON-LD JsonLdProcessor.compact and flatten
- // (should not be useful)
- if (o instanceof String) {
- String jsonString = (String) jenaContext.get(JSONLD_CONTEXT);
- if (jsonString != null) ctx = JsonUtils.fromString(jsonString);
- } else {
- Logger.getLogger(JsonLDWriter.class).warn("JSONLD_CONTEXT value is not a String. Assuming a context object expected by JSON-LD JsonLdProcessor.compact or flatten");
- ctx = o;
- }
- }
- }
- }
-
- if (!isCtxDefined) {
- // if no ctx passed via jenaContext, create one in order to have localnames as keys for properties
- ctx = createJsonldContext(dataset.getDefaultGraph(), prefixMap) ;
-
- // I don't think this should be done: the JsonLdProcessor begins
- // by looking whether the argument passed is a map with key "@context" and takes corresponding value
- // Better not to do this: we create a map for nothing, and worse,
- // if the context object has been created by a user and passed through the (jena) context
- // in case he got the same idea, we would end up with 2 levels of maps an it would work
-// Map<String, Object> localCtx = new HashMap<>() ;
-// localCtx.put("@context", ctx) ;
-// obj = JsonLdProcessor.compact(obj, localCtx, opts) ;
- }
- return ctx;
+ Object ctx = null;
+ boolean isCtxDefined = false; // to allow jenaContext to set ctx to null. Useful?
+
+ if (jenaContext != null) {
+ if (jenaContext.isDefined(JSONLD_CONTEXT)) {
+ isCtxDefined = true;
+ Object o = jenaContext.get(JSONLD_CONTEXT);
+ if (o != null) {
+ // I won't assume it is a string, to leave the possibility to pass
+ // the context object expected by JSON-LD JsonLdProcessor.compact and flatten
+ // (should not be useful)
+ if (o instanceof String) {
+ String jsonString = (String) o;
+ if (jsonString != null) ctx = JsonUtils.fromString(jsonString);
+ } else {
+ Logger.getLogger(JsonLDWriter.class).warn("JSONLD_CONTEXT value is not a String. Assuming a context object expected by JSON-LD JsonLdProcessor.compact or flatten");
+ ctx = o;
+ }
+ }
+ }
+ }
+
+ if (!isCtxDefined) {
+ // if no ctx passed via jenaContext, create one in order to have localnames as keys for properties
+ ctx = createJsonldContext(dataset.getDefaultGraph(), prefixMap) ;
+
+ // I don't think this should be done: the JsonLdProcessor begins
+ // by looking whether the argument passed is a map with key "@context" and if so, takes corresponding value
+ // Then, better not to do this: we create a map for nothing, and worse,
+ // if the context object has been created by a user and passed through the (jena) context
+ // in case he got the same idea, we would end up with 2 levels of maps an it would not work
+ // Map<String, Object> localCtx = new HashMap<>() ;
+ // localCtx.put("@context", ctx) ;
+ }
+ return ctx;
}
-
- // useful to help people wanting to create their own context?
+
+ // useful to help people who want to create their own context?
// It is used in TestJsonLDWriter (marginally) (TestJsonLDWriter which happens to be in another package,
- // so either I remove the test, or this has to be public)
- public static Object createJsonldContext(Graph g) {
- return createJsonldContext(g, PrefixMapFactory.create(g.getPrefixMapping()));
- }
-
- private static Object createJsonldContext(Graph g, PrefixMap prefixMap) {
- final Map<String, Object> ctx = new LinkedHashMap<>() ;
- addProperties(ctx, g) ;
- addPrefixes(ctx, prefixMap) ;
- return ctx ;
- }
+ // so either I remove the test in question, or this has to be public)
+ public static Object createJsonldContext(Graph g) {
+ return createJsonldContext(g, PrefixMapFactory.create(g.getPrefixMapping()));
+ }
+
+ private static Object createJsonldContext(Graph g, PrefixMap prefixMap) {
+ final Map<String, Object> ctx = new LinkedHashMap<>() ;
+ addProperties(ctx, g) ;
+ addPrefixes(ctx, prefixMap) ;
+ return ctx ;
+ }
private static void addPrefixes(Map<String, Object> ctx, PrefixMap prefixMap) {
- Map<String, IRI> pmap = prefixMap.getMapping() ;
- for ( Entry<String, IRI> e : pmap.entrySet() ) {
- String key = e.getKey() ;
- if ( key.isEmpty() ) {
- // Prefix "" is not allowed in JSON-LD
- // we could replace "" with "@vocab"
- // key = "@vocab" ;
- continue;
+ if (prefixMap != null) {
+ Map<String, IRI> pmap = prefixMap.getMapping() ;
+ for ( Entry<String, IRI> e : pmap.entrySet() ) {
+ String key = e.getKey() ;
+ if ( key.isEmpty() ) {
+ // Prefix "" is not allowed in JSON-LD
+ // we could replace "" with "@vocab"
+ // key = "@vocab" ;
+ continue;
+ }
+ ctx.put(key, e.getValue().toString()) ;
}
- ctx.put(key, e.getValue().toString()) ;
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/39c881ad/jena-arq/src/test/java/org/apache/jena/riot/writer/TestJsonLDWriter.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestJsonLDWriter.java b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestJsonLDWriter.java
index 440d39a..e79edc2 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestJsonLDWriter.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestJsonLDWriter.java
@@ -23,6 +23,7 @@ import java.io.StringReader;
import org.apache.jena.atlas.json.JsonObject;
import org.apache.jena.atlas.junit.BaseTest;
+import org.apache.jena.query.DatasetFactory;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
@@ -30,7 +31,11 @@ import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.RDFFormat;
+import org.apache.jena.riot.WriterDatasetRIOT;
import org.apache.jena.riot.out.JsonLDWriter;
+import org.apache.jena.riot.system.PrefixMap;
+import org.apache.jena.riot.system.RiotLib;
+import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.util.Context;
import org.apache.jena.vocabulary.RDF;
import org.apache.log4j.Logger;
@@ -41,417 +46,378 @@ import com.github.jsonldjava.utils.JsonUtils;
public class TestJsonLDWriter extends BaseTest {
-/**
- * Checks that JSON-LD RDFFormats supposed to be pretty are pretty
- * and that those supposed to be flat are flat
- */
-@Test public final void prettyIsNotFlat() {
- Model m = simpleModel();
- m.setNsPrefix("ex", "http://www.a.com/foo/");
- String s;
-
- // pretty is pretty
-
- s = toString(m, RDFFormat.JSONLD_EXPAND_PRETTY, null);
- assertTrue(s.trim().indexOf("\n") > -1);
- s = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
- assertTrue(s.trim().indexOf("\n") > -1);
- s = toString(m, RDFFormat.JSONLD_FLATTEN_PRETTY, null);
- assertTrue(s.trim().indexOf("\n") > -1);
-
- // and flat is flat
-
- s = toString(m, RDFFormat.JSONLD_EXPAND_FLAT, null);
- assertTrue(s.trim().indexOf("\n") < 0);
- s = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, null);
- assertTrue(s.trim().indexOf("\n") < 0);
- s = toString(m, RDFFormat.JSONLD_FLATTEN_FLAT, null);
- assertTrue(s.trim().indexOf("\n") < 0);
- assertTrue(s.trim().indexOf("\n") < 0);
- // JSON_LD FRAME case not tested here, but in testFrames
-}
+ /**
+ * Checks that JSON-LD RDFFormats supposed to be pretty are pretty
+ * and that those supposed to be flat are flat
+ */
+ @Test public final void prettyIsNotFlat() {
+ Model m = simpleModel();
+ m.setNsPrefix("ex", "http://www.a.com/foo/");
+ String s;
-/**
- * Checks that JSON-LD RDFFormats that are supposed to return a "@context"
- * actually do so.
- */
-@Test public final void contextOrNot() {
- Model m = simpleModel();
- m.setNsPrefix("ex", "http://www.a.com/foo/");
- String s;
-
- // there's no "@context" in expand
-
- s = toString(m, RDFFormat.JSONLD_EXPAND_PRETTY, null);
- assertTrue(s.indexOf("@context") < 0);
- s = toString(m, RDFFormat.JSONLD_EXPAND_FLAT, null);
- assertTrue(s.indexOf("@context") < 0);
-
- // there's an "@context" in compact and flatten
-
- s = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
- assertTrue(s.indexOf("@context") > -1);
- s = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, null);
- assertTrue(s.indexOf("@context") > -1);
- s = toString(m, RDFFormat.JSONLD_FLATTEN_PRETTY, null);
- assertTrue(s.indexOf("@context") > -1);
- s = toString(m, RDFFormat.JSONLD_FLATTEN_FLAT, null);
- assertTrue(s.indexOf("@context") > -1);
-}
+ // pretty is pretty
-private Model simpleModel() {
- Model m = ModelFactory.createDefaultModel();
- String url = "http://www.a.com/foo/";
- Resource s = m.createResource(url + "s");
- Property p = m.createProperty(url + "p");
- Resource o = m.createResource(url + "o");
- m.add(s,p,o);
- return m;
-}
+ s = toString(m, RDFFormat.JSONLD_EXPAND_PRETTY, null);
+ assertTrue(s.trim().indexOf("\n") > -1);
+ s = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
+ assertTrue(s.trim().indexOf("\n") > -1);
+ s = toString(m, RDFFormat.JSONLD_FLATTEN_PRETTY, null);
+ assertTrue(s.trim().indexOf("\n") > -1);
-/**
- * Write a model and parse it back: you should get the same thing
- * (except with frame)
- */
-@Test public final void roundTrip() {
- Model m = simpleModel();
- m.setNsPrefix("ex", "http://www.a.com/foo/");
- for (RDFFormat f : JSON_LD_FORMATS) {
- if (f.getVariant().toString().indexOf("frame") > -1) continue;
- String s = toString(m, f, null);
- Model m2 = parse(s);
- assertTrue(m2.isIsomorphicWith(m));
- }
-}
+ // and flat is flat
-//@Test public final void supportEmptyNs() {
-// Model m = ModelFactory.createDefaultModel();
-// String ns = "http://www.a.com/foo/";
-// Resource s = m.createResource(ns + "s");
-// Property p = m.createProperty(ns + "p");
-// Resource o = m.createResource(ns + "o");
-// m.add(s,p,o);
-// m.add(m.createResource(ns + "s2"),p,m.createResource(ns + "o2"));
-// m.setNsPrefix("ns", ns);
-// Model m2 = parse(toJsonLDString(m));
-// assertTrue(m2.isIsomorphicWith(m));
-//
-// // RDFDataMgr.write(DevNull.out, m, RDFFormat.JSONLD) ;
-// RDFDataMgr.write(System.out, m2, RDFFormat.TURTLE);
-// RDFDataMgr.write(System.out, m, RDFFormat.JSONLD);
-//}
-
-/** verify that one may pass a context as a JSON string, and that it is actually used in the output */
-@Test public void testSettingContextAsJsonString() {
- // 1) get the context generated by default by jena
- // for a simple model with a prefix declaration
- // 2) remove prefix declaration from model,
- // output as jsonld is different
- // 3) output the model as jsonld using the context:
- // we should get the same output as in 1
- Model m = ModelFactory.createDefaultModel();
- String url = "http://www.semanlink.net/test/";
- Resource s = m.createResource(url + "s");
- Property p = m.createProperty(url + "p");
- Resource o = m.createResource(url + "o");
- m.add(s,p,o);
- m.setNsPrefix("ex", url);
-
- String s1 = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, null);
- // there's a prefix in m, and we find it in the output
- String prefixStringInResult = "\"ex\":\"" + url + "\"";
- assertTrue(s1.indexOf(prefixStringInResult) > 0);
- Model m1 = parse(s1);
-
- // must we pass the json object associated to "@context",
- // or its parent node (that is, with the "@context") ?
- // Actually, we can do both (JSONLD-java's code ensure it)
- // We check it for here
-
- // this is json object associated to "@context" in s1
- // it includes the "ex" prefix
-
- String js = "{\"p\":{\"@id\":\"http://www.semanlink.net/test/p\",\"@type\":\"@id\"},\"ex\":\"http://www.semanlink.net/test/\"}";
-
- // remove the prefix from m
- m.removeNsPrefix("ex"); // RDFDataMgr.write(System.out, m, RDFFormat.JSONLD) ;
- String s2 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
- // model wo prefix -> no more prefix string in result:
- assertTrue(s2.indexOf(prefixStringInResult) < 0);
-
- // the model wo prefix, outputed as jsonld using a context that defines the prefix
- Context jenaCtx = new Context();
- jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT, js);
- String s3 = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, jenaCtx);
-
- assertTrue(s3.length() == s1.length());
- assertTrue(s3.indexOf(prefixStringInResult) > 0);
- Model m3 = parse(s3);
- assertTrue(m3.isIsomorphicWith(m));
- assertTrue(m3.isIsomorphicWith(m1));
-
- // same thing, but passing also the "@context"
- js = "{\"@context\":" + js + "}";
- jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT, js);
- String s4 = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, jenaCtx);
-
- assertTrue(s4.length() == s1.length());
- assertTrue(s4.indexOf(prefixStringInResult) > 0);
- Model m4 = parse(s4);
- assertTrue(m4.isIsomorphicWith(m));
- assertTrue(m4.isIsomorphicWith(m1));
-}
+ s = toString(m, RDFFormat.JSONLD_EXPAND_FLAT, null);
+ assertTrue(s.trim().indexOf("\n") < 0);
+ s = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, null);
+ assertTrue(s.trim().indexOf("\n") < 0);
+ s = toString(m, RDFFormat.JSONLD_FLATTEN_FLAT, null);
+ assertTrue(s.trim().indexOf("\n") < 0);
+ assertTrue(s.trim().indexOf("\n") < 0);
+ // JSON_LD FRAME case not tested here, but in testFrames
+ }
-/**
- * Checks that one can pass a context defined by its URI
- */
-@Test public final void testContextByUri() {
- Model m = ModelFactory.createDefaultModel();
- String ns = "http://schema.org/";
- Resource s = m.createResource();
- m.add(s, m.createProperty(ns + "name"), "Jane Doe");
- m.add(s, m.createProperty(ns + "url"), "http://www.janedoe.com");
- m.add(s, RDF.type, "Person");
-
- // we can pass a uri in the context, as a quoted string (it is a JSON string)
- Context jenaContext = new Context();
- try {
- // jenaContext.set(JsonLDWriter.JSONLD_CONTEXT, "http://schema.org/");
- // beware, it must be quoted, as it is supposed to be a json string
- jenaContext.set(JsonLDWriter.JSONLD_CONTEXT, "\"http://schema.org/\"");
- String jsonld = toString(m, RDFFormat.JSONLD, jenaContext);
- } catch (Throwable e) {
- Logger.getLogger(getClass()).info("Sorry to get this exception",e);
- }
-
- // It seems to work, but there's a problem with httpclient version: the one used by jena
- // is not compatible with the one expected by JSONLD-java API. We get
- /*
-java.lang.NoSuchMethodError: org.apache.http.impl.client.cache.CacheConfig.custom()Lorg/apache/http/impl/client/cache/CacheConfig$Builder;
- at com.github.jsonldjava.utils.JsonUtils.createDefaultHttpClient(JsonUtils.java:333)
- at com.github.jsonldjava.utils.JsonUtils.getDefaultHttpClient(JsonUtils.java:323)
- at com.github.jsonldjava.core.DocumentLoader.getHttpClient(DocumentLoader.java:84)
- at com.github.jsonldjava.core.DocumentLoader.fromURL(DocumentLoader.java:59)
- at com.github.jsonldjava.core.DocumentLoader.loadDocument(DocumentLoader.java:29)
- at com.github.jsonldjava.core.Context.parse(Context.java:169)
- at com.github.jsonldjava.core.Context.parse(Context.java:252)
- at com.github.jsonldjava.core.JsonLdProcessor.compact(JsonLdProcessor.java:57)
- at org.apache.jena.riot.out.JsonLDWriter.serialize(JsonLDWriter.java:179)
- at org.apache.jena.riot.out.JsonLDWriter.write(JsonLDWriter.java:85)
- at org.apache.jena.riot.out.JsonLDWriter.write(JsonLDWriter.java:126)
- at org.apache.jena.riot.system.RiotLib$WriterAdapter.write(RiotLib.java:376)
- at org.apache.jena.riot.RDFDataMgr.write$(RDFDataMgr.java:1235)
- at org.apache.jena.riot.RDFDataMgr.write(RDFDataMgr.java:1026)
- at org.apache.jena.riot.RDFDataMgr.write(RDFDataMgr.java:956)
- at org.apache.jena.riot.out.TestJsonLD.toString(TestJsonLD.java:232)
- at org.apache.jena.riot.out.TestJsonLD.testContextByUri(TestJsonLD.java:186)
- */
- //
- // httpclient-cache 4.2.6 from jena
- // httpclient.version 4.5.1 from jsonld-java
- // No chance to see this solved, as jena parent's pom says:
- /*
- <dependency>
- <groupId>com.github.jsonld-java</groupId>
- <artifactId>jsonld-java</artifactId>
- <version>${ver.jsonldjava}</version>
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- <!-- Exclude so we use our choice of versions -->
- <exclusion>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient-cache</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
- </exclusion>
- */
-
- // But anyway, that's not what we want to do:
- // there's no point in passing the uri of a context to have it dereferenced by jsonld-java
- // (this is for a situation where one would want to parse a jsonld file containing a context defined by a uri)
- // What we want is to pass a context to jsonld-java (in order for json-ld java to produce the correct jsonls output
- // and then we want to replace the @context in the output by "@context":"ourUri"
-
- // How would we do that?
-}
+ /**
+ * Checks that JSON-LD RDFFormats that are supposed to return a "@context" do so.
+ */
+ @Test public final void contextOrNot() {
+ Model m = simpleModel();
+ m.setNsPrefix("ex", "http://www.a.com/foo/");
+ String s;
-/**
- * This generates a waring, but one may pass a context directly as the object
- * used by the JSON-LD java API.
-*/
-@Test public void testSettingContextAsObjectExpectedByJsonldAPI() {
- // 1) get the context generated by default by jena
- // for a simple model with a prefix declaration
- // 2) remove prefix declaration from model,
- // output as jsonld is different
- // 3) output the model as jsonld using the context:
- // we should get the same output as in 1
- Model m = ModelFactory.createDefaultModel();
- String url = "http://www.semanlink.net/test/";
- Resource s = m.createResource(url + "s");
- Property p = m.createProperty(url + "p");
- Resource o = m.createResource(url + "o");
- m.add(s,p,o);
- m.setNsPrefix("ex", url);
-
- String s1 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
- // there's a prefix in m, and we find it in the output
- String prefixStringInResult = "\"ex\" : \"" + url + "\"";
- assertTrue(s1.indexOf(prefixStringInResult) > 0);
- Model m1 = parse(s1);
-
- // the context used in this case, created automatically by jena as none is set
- // it includes one prefix
- Object ctx = JsonLDWriter.createJsonldContext(m.getGraph());
-
- // remove the prefix from m
- m.removeNsPrefix("ex"); // RDFDataMgr.write(System.out, m, RDFFormat.JSONLD) ;
- String s2 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
- // model wo prefix -> no more prefix string in result:
- assertTrue(s2.indexOf(prefixStringInResult) < 0);
-
- // the model wo prefix, outputed as jsonld using a context that defines the prefix
- Context jenaCtx = new Context();
- jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT, ctx);
- String s3 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, jenaCtx);
-
- assertTrue(s3.length() == s1.length());
- assertTrue(s3.indexOf(prefixStringInResult) > 0);
- Model m3 = parse(s3);
- assertTrue(m3.isIsomorphicWith(m));
- assertTrue(m3.isIsomorphicWith(m1));
+ // there's no "@context" in expand
-}
+ s = toString(m, RDFFormat.JSONLD_EXPAND_PRETTY, null);
+ assertTrue(s.indexOf("@context") < 0);
+ s = toString(m, RDFFormat.JSONLD_EXPAND_FLAT, null);
+ assertTrue(s.indexOf("@context") < 0);
-/**
- * Test using a context to compute the output, and replacing the @context with a given value
- */
-@Test public void testSubstitutingContext() {
- Model m = ModelFactory.createDefaultModel();
- String ns = "http://schema.org/";
- Resource person = m.createResource(ns + "Person");
- Resource s = m.createResource();
- m.add(s, m.createProperty(ns + "name"), "Jane Doe");
- m.add(s, m.createProperty(ns + "url"), "http://www.janedoe.com");
- m.add(s, m.createProperty(ns + "jobTitle"), "Professor");
- m.add(s, RDF.type, person);
-
- Context jenaCtx = new Context();
- jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT_SUBSTITUTION, "\"" + ns + "\"");
-
- String jsonld = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, jenaCtx);
- String c = "\"@context\":\"http://schema.org/\"";
- assertTrue(jsonld.indexOf(c) > -1);
-}
+ // there's an "@context" in compact and flatten
+ s = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
+ assertTrue(s.indexOf("@context") > -1);
+ s = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, null);
+ assertTrue(s.indexOf("@context") > -1);
+ s = toString(m, RDFFormat.JSONLD_FLATTEN_PRETTY, null);
+ assertTrue(s.indexOf("@context") > -1);
+ s = toString(m, RDFFormat.JSONLD_FLATTEN_FLAT, null);
+ assertTrue(s.indexOf("@context") > -1);
+ }
-/**
- * Checking frames
- */
-@Test public final void testFrames() throws JsonParseException, IOException {
- Model m = ModelFactory.createDefaultModel();
- String ns = "http://schema.org/";
- Resource person = m.createResource(ns + "Person");
- Resource s = m.createResource();
- m.add(s, m.createProperty(ns + "name"), "Jane Doe");
- m.add(s, m.createProperty(ns + "url"), "http://www.janedoe.com");
- m.add(s, m.createProperty(ns + "jobTitle"), "Professor");
- m.add(s, RDF.type, person);
- s = m.createResource();
- m.add(s, m.createProperty(ns + "name"), "Gado Salamatou");
- m.add(s, m.createProperty(ns + "url"), "http://www.salamatou.com");
- m.add(s, RDF.type, person);
- s = m.createResource();
- m.add(s, m.createProperty(ns + "name"), "Not a person");
- m.add(s, RDF.type, m.createResource(ns + "Event"));
-
- Context jenaCtx = new Context();
- JsonObject frame = new JsonObject();
-
- // only ouput the persons using a frame
-
- frame.put("@type", ns +"Person");
- jenaCtx.set(JsonLDWriter.JSONLD_FRAME, JsonUtils.fromString(frame.toString()));
- String jsonld = toString(m, RDFFormat.JSONLD_FRAME_PRETTY, jenaCtx);
- Model m2 = parse(jsonld);
- // 2 subjects with a type in m2
- assertTrue(m2.listStatements((Resource) null, RDF.type, (RDFNode) null).toList().size() == 2);
- // 2 persons in m2
- assertTrue(m2.listStatements((Resource) null, RDF.type, person).toList().size() == 2);
- // something we hadn't tested in prettyIsNotFlat
- assertTrue(jsonld.trim().indexOf("\n") > -1);
-
- // only output the subjects which have a jobTitle
-
- frame = new JsonObject();
- frame.put("http://schema.org/jobTitle", new JsonObject());
- jenaCtx.set(JsonLDWriter.JSONLD_FRAME, JsonUtils.fromString(frame.toString()));
- jsonld = toString(m, RDFFormat.JSONLD_FRAME_FLAT, jenaCtx);
- m2 = parse(jsonld);
- // 1 subject with a type in m2
- assertTrue(m2.listStatements((Resource) null, RDF.type, (RDFNode) null).toList().size() == 1);
- // 1 subject with a jobTitle in m2
- assertTrue(m2.listStatements((Resource) null, m.createProperty(ns + "jobTitle"), (RDFNode) null).toList().size() == 1);
- // something we hadn't tested in prettyIsNotFlat
- assertTrue(jsonld.trim().indexOf("\n") < 0);
-}
+ private Model simpleModel() {
+ Model m = ModelFactory.createDefaultModel();
+ String url = "http://www.a.com/foo/";
+ Resource s = m.createResource(url + "s");
+ Property p = m.createProperty(url + "p");
+ Resource o = m.createResource(url + "o");
+ m.add(s,p,o);
+ return m;
+ }
-/**
- * There was a problem with props taking a string as value.
- * cf https://mail-archives.apache.org/mod_mbox/jena-users/201604.mbox/%3c218AC4A3-030B-4248-A7DA-2B2597328242@gmail.com%3e
- */
-@Test public final void testStringPropsInContext() {
- Model m = ModelFactory.createDefaultModel();
- String ns = "http://www.a.com/foo/";
- Resource s = m.createResource(ns + "s");
- m.add(s,m.createProperty(ns + "plangstring"),"a langstring","fr");
- m.add(s, m.createProperty(ns + "pint"), m.createTypedLiteral(42));
- m.add(s, m.createProperty(ns + "pfloat"), m.createTypedLiteral((float) 1789.14));
- m.add(s, m.createProperty(ns + "pstring"), m.createTypedLiteral("a TypedLiteral atring"));
-
- String jsonld = toString(m, RDFFormat.JSONLD_FLAT, null);
-
- // without following line in JsonLDWriter, the test fails
- // if (! isLangString(o) && ! isSimpleString(o) )
- String vv = "\"plangstring\":{\"@language\":\"fr\",\"@value\":\"a langstring\"}";
- assertTrue(jsonld.indexOf(vv) > -1);
-}
+ /**
+ * Write a model and parse it back: you should get the same thing
+ * (except with frame)
+ */
+ @Test public final void roundTrip() {
+ Model m = simpleModel();
+ m.setNsPrefix("ex", "http://www.a.com/foo/");
+ for (RDFFormat f : JSON_LD_FORMATS) {
+ if (((RDFFormat.JSONLDVariant) f.getVariant()).isFrame()) continue;
+ String s = toString(m, f, null);
+ Model m2 = parse(s);
+ assertTrue(m2.isIsomorphicWith(m));
+ }
+ }
-//
-// some utilities
-//
-
-private String toString(Model m, RDFFormat f, Context jenaContext) {
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- RDFDataMgr.write(out, m, f, jenaContext) ;
- out.flush();
- String x = out.toString("UTF-8");
- out.close();
- return x;
- } catch (IOException e) { throw new RuntimeException(e); }
-}
+ //@Test public final void supportEmptyNs() {
+ // Model m = ModelFactory.createDefaultModel();
+ // String ns = "http://www.a.com/foo/";
+ // Resource s = m.createResource(ns + "s");
+ // Property p = m.createProperty(ns + "p");
+ // Resource o = m.createResource(ns + "o");
+ // m.add(s,p,o);
+ // m.add(m.createResource(ns + "s2"),p,m.createResource(ns + "o2"));
+ // m.setNsPrefix("ns", ns);
+ // Model m2 = parse(toJsonLDString(m));
+ // assertTrue(m2.isIsomorphicWith(m));
+ //
+ // // RDFDataMgr.write(DevNull.out, m, RDFFormat.JSONLD) ;
+ // RDFDataMgr.write(System.out, m2, RDFFormat.TURTLE);
+ // RDFDataMgr.write(System.out, m, RDFFormat.JSONLD);
+ //}
-private Model parse(String jsonld) {
- Model m = ModelFactory.createDefaultModel();
- StringReader reader = new StringReader(jsonld);
- m.read(reader, null, "JSON-LD");
- return m;
-}
+ /** verify that one may pass a context as a JSON string, and that it is actually used in the output */
+ @Test public void testSettingContextAsJsonString() {
+ // 1) get the context generated by default by jena
+ // for a simple model with a prefix declaration
+ // 2) remove prefix declaration from model,
+ // output as jsonld is different
+ // 3) output the model as jsonld using the context:
+ // we should get the same output as in 1
+ Model m = ModelFactory.createDefaultModel();
+ String url = "http://www.semanlink.net/test/";
+ Resource s = m.createResource(url + "s");
+ Property p = m.createProperty(url + "p");
+ Resource o = m.createResource(url + "o");
+ m.add(s,p,o);
+ m.setNsPrefix("ex", url);
+
+ String s1 = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, null);
+ // there's a prefix in m, and we find it in the output
+ String prefixStringInResult = "\"ex\":\"" + url + "\"";
+ assertTrue(s1.indexOf(prefixStringInResult) > 0);
+ Model m1 = parse(s1);
+
+ // must we pass the json object associated to "@context",
+ // or its parent node (that is, with the "@context") ?
+ // Actually, we can do both (JSONLD-java's code ensure it)
+ // We check it for here
+
+ // this is json object associated to "@context" in s1
+ // it includes the "ex" prefix
+
+ String js = "{\"p\":{\"@id\":\"http://www.semanlink.net/test/p\",\"@type\":\"@id\"},\"ex\":\"http://www.semanlink.net/test/\"}";
+
+ // remove the prefix from m
+ m.removeNsPrefix("ex"); // RDFDataMgr.write(System.out, m, RDFFormat.JSONLD) ;
+ String s2 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
+ // model wo prefix -> no more prefix string in result:
+ assertTrue(s2.indexOf(prefixStringInResult) < 0);
+
+ // the model wo prefix, outputed as jsonld using a context that defines the prefix
+ Context jenaCtx = new Context();
+ jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT, js);
+ String s3 = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, jenaCtx);
+
+ assertTrue(s3.length() == s1.length());
+ assertTrue(s3.indexOf(prefixStringInResult) > 0);
+ Model m3 = parse(s3);
+ assertTrue(m3.isIsomorphicWith(m));
+ assertTrue(m3.isIsomorphicWith(m1));
+
+ // same thing, but passing also the "@context"
+ js = "{\"@context\":" + js + "}";
+ jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT, js);
+ String s4 = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, jenaCtx);
+
+ assertTrue(s4.length() == s1.length());
+ assertTrue(s4.indexOf(prefixStringInResult) > 0);
+ Model m4 = parse(s4);
+ assertTrue(m4.isIsomorphicWith(m));
+ assertTrue(m4.isIsomorphicWith(m1));
+ }
+
+ /**
+ * Checks that one can pass a context defined by its URI
+ */
+ @Test public final void testContextByUri() {
+ Model m = ModelFactory.createDefaultModel();
+ String ns = "http://schema.org/";
+ Resource s = m.createResource();
+ m.add(s, m.createProperty(ns + "name"), "Jane Doe");
+ m.add(s, m.createProperty(ns + "url"), "http://www.janedoe.com");
+ m.add(s, RDF.type, "Person");
+
+ // we can pass a uri in the context, as a quoted string (it is a JSON string)
+ Context jenaContext = new Context();
+ try {
+ // jenaContext.set(JsonLDWriter.JSONLD_CONTEXT, "http://schema.org/");
+ // beware, it must be quoted, as it is supposed to be a json string
+ jenaContext.set(JsonLDWriter.JSONLD_CONTEXT, "\"http://schema.org/\"");
+ String jsonld = toString(m, RDFFormat.JSONLD, jenaContext);
+ } catch (Throwable e) {
+ Logger.getLogger(getClass()).info("Sorry to get this exception",e);
+ }
+
+ // But anyway, that's not what we want to do:
+ // there's no point in passing the uri of a context to have it dereferenced by jsonld-java
+ // (this is for a situation where one would want to parse a jsonld file containing a context defined by a uri)
+ // What we want is to pass a context to jsonld-java (in order for json-ld java to produce the correct jsonls output
+ // and then we want to replace the @context in the output by "@context":"ourUri"
+
+ // How would we do that? see testSubstitutingContext()
+ }
+
+ /**
+ * This generates a warning, but one may pass a context directly as the object
+ * used by the JSON-LD java API.
+ */
+ @Test public void testSettingContextAsObjectExpectedByJsonldAPI() {
+ // 1) get the context generated by default by jena
+ // for a simple model with a prefix declaration
+ // 2) remove prefix declaration from model,
+ // output as jsonld is different
+ // 3) output the model as jsonld using the context:
+ // we should get the same output as in 1
+ Model m = ModelFactory.createDefaultModel();
+ String url = "http://www.semanlink.net/test/";
+ Resource s = m.createResource(url + "s");
+ Property p = m.createProperty(url + "p");
+ Resource o = m.createResource(url + "o");
+ m.add(s,p,o);
+ m.setNsPrefix("ex", url);
+
+ String s1 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
+ // there's a prefix in m, and we find it in the output
+ String prefixStringInResult = "\"ex\" : \"" + url + "\"";
+ assertTrue(s1.indexOf(prefixStringInResult) > 0);
+ Model m1 = parse(s1);
+
+ // the context used in this case, created automatically by jena as none is set
+ // it includes one prefix
+ Object ctx = JsonLDWriter.createJsonldContext(m.getGraph());
+
+ // remove the prefix from m
+ m.removeNsPrefix("ex"); // RDFDataMgr.write(System.out, m, RDFFormat.JSONLD) ;
+ String s2 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, null);
+ // model wo prefix -> no more prefix string in result:
+ assertTrue(s2.indexOf(prefixStringInResult) < 0);
+
+ // the model wo prefix, output as jsonld using a context that defines the prefix
+ Context jenaCtx = new Context();
+ jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT, ctx);
+ String s3 = toString(m, RDFFormat.JSONLD_COMPACT_PRETTY, jenaCtx);
+
+ assertTrue(s3.length() == s1.length());
+ assertTrue(s3.indexOf(prefixStringInResult) > 0);
+ Model m3 = parse(s3);
+ assertTrue(m3.isIsomorphicWith(m));
+ assertTrue(m3.isIsomorphicWith(m1));
+
+ }
+
+ /**
+ * Test using a context to compute the output, and replacing the @context with a given value
+ */
+ @Test public void testSubstitutingContext() {
+ Model m = ModelFactory.createDefaultModel();
+ String ns = "http://schema.org/";
+ Resource person = m.createResource(ns + "Person");
+ Resource s = m.createResource();
+ m.add(s, m.createProperty(ns + "name"), "Jane Doe");
+ m.add(s, m.createProperty(ns + "url"), "http://www.janedoe.com");
+ m.add(s, m.createProperty(ns + "jobTitle"), "Professor");
+ m.add(s, RDF.type, person);
+
+ Context jenaCtx = new Context();
+ jenaCtx.set(JsonLDWriter.JSONLD_CONTEXT_SUBSTITUTION, "\"" + ns + "\"");
+
+ String jsonld = toString(m, RDFFormat.JSONLD_COMPACT_FLAT, jenaCtx);
+ String c = "\"@context\":\"http://schema.org/\"";
+ assertTrue(jsonld.indexOf(c) > -1);
+ }
+
+
+ /**
+ * Checking frames
+ */
+ @Test public final void testFrames() throws JsonParseException, IOException {
+ Model m = ModelFactory.createDefaultModel();
+ String ns = "http://schema.org/";
+ Resource person = m.createResource(ns + "Person");
+ Resource s = m.createResource();
+ m.add(s, m.createProperty(ns + "name"), "Jane Doe");
+ m.add(s, m.createProperty(ns + "url"), "http://www.janedoe.com");
+ m.add(s, m.createProperty(ns + "jobTitle"), "Professor");
+ m.add(s, RDF.type, person);
+ s = m.createResource();
+ m.add(s, m.createProperty(ns + "name"), "Gado Salamatou");
+ m.add(s, m.createProperty(ns + "url"), "http://www.salamatou.com");
+ m.add(s, RDF.type, person);
+ s = m.createResource();
+ m.add(s, m.createProperty(ns + "name"), "Not a person");
+ m.add(s, RDF.type, m.createResource(ns + "Event"));
+
+ Context jenaCtx = new Context();
+ JsonObject frame = new JsonObject();
+
+ // only output the persons using a frame
+
+ frame.put("@type", ns +"Person");
+ jenaCtx.set(JsonLDWriter.JSONLD_FRAME, JsonUtils.fromString(frame.toString()));
+ String jsonld = toString(m, RDFFormat.JSONLD_FRAME_PRETTY, jenaCtx);
+ Model m2 = parse(jsonld);
+ // 2 subjects with a type in m2
+ assertTrue(m2.listStatements((Resource) null, RDF.type, (RDFNode) null).toList().size() == 2);
+ // 2 persons in m2
+ assertTrue(m2.listStatements((Resource) null, RDF.type, person).toList().size() == 2);
+ // something we hadn't tested in prettyIsNotFlat
+ assertTrue(jsonld.trim().indexOf("\n") > -1);
+
+ // only output the subjects which have a jobTitle
+
+ frame = new JsonObject();
+ frame.put("http://schema.org/jobTitle", new JsonObject());
+ jenaCtx.set(JsonLDWriter.JSONLD_FRAME, JsonUtils.fromString(frame.toString()));
+ jsonld = toString(m, RDFFormat.JSONLD_FRAME_FLAT, jenaCtx);
+ m2 = parse(jsonld);
+ // 1 subject with a type in m2
+ assertTrue(m2.listStatements((Resource) null, RDF.type, (RDFNode) null).toList().size() == 1);
+ // 1 subject with a jobTitle in m2
+ assertTrue(m2.listStatements((Resource) null, m.createProperty(ns + "jobTitle"), (RDFNode) null).toList().size() == 1);
+ // something we hadn't tested in prettyIsNotFlat
+ assertTrue(jsonld.trim().indexOf("\n") < 0);
+ }
+
+ /**
+ * There was a problem with props taking a string as value.
+ * cf https://mail-archives.apache.org/mod_mbox/jena-users/201604.mbox/%3c218AC4A3-030B-4248-A7DA-2B2597328242@gmail.com%3e
+ */
+ @Test public final void testStringPropsInContext() {
+ Model m = ModelFactory.createDefaultModel();
+ String ns = "http://www.a.com/foo/";
+ Resource s = m.createResource(ns + "s");
+ m.add(s,m.createProperty(ns + "plangstring"),"a langstring","fr");
+ m.add(s, m.createProperty(ns + "pint"), m.createTypedLiteral(42));
+ m.add(s, m.createProperty(ns + "pfloat"), m.createTypedLiteral((float) 1789.14));
+ m.add(s, m.createProperty(ns + "pstring"), m.createTypedLiteral("a TypedLiteral atring"));
+
+ String jsonld = toString(m, RDFFormat.JSONLD_FLAT, null);
+
+ // without following line in JsonLDWriter, the test fails
+ // if (! isLangString(o) && ! isSimpleString(o) )
+ String vv = "\"plangstring\":{\"@language\":\"fr\",\"@value\":\"a langstring\"}";
+ assertTrue(jsonld.indexOf(vv) > -1);
+ }
+
+ //
+ // some utilities
+ //
+
+ private String toString(Model m, RDFFormat f, Context jenaContext) {
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ // RDFDataMgr.write(out, m, f, jenaContext) ;
+
+
+ WriterDatasetRIOT w = RDFDataMgr.createDatasetWriter(f) ;
+ DatasetGraph g = DatasetFactory.create(m).asDatasetGraph();
+ PrefixMap pm = RiotLib.prefixMap(g);
+ String base = null;
+ w.write(out, g, pm, base, jenaContext) ;
+
+
+ out.flush();
+ String x = out.toString("UTF-8");
+ out.close();
+ return x;
+ } catch (IOException e) { throw new RuntimeException(e); }
+ }
+
+ private Model parse(String jsonld) {
+ Model m = ModelFactory.createDefaultModel();
+ StringReader reader = new StringReader(jsonld);
+ m.read(reader, null, "JSON-LD");
+ return m;
+ }
-private static RDFFormat[] JSON_LD_FORMATS = {
- RDFFormat.JSONLD_COMPACT_PRETTY,
- RDFFormat.JSONLD_FLATTEN_PRETTY,
- RDFFormat.JSONLD_EXPAND_PRETTY,
- RDFFormat.JSONLD_FRAME_PRETTY,
- RDFFormat.JSONLD_COMPACT_FLAT,
- RDFFormat.JSONLD_FLATTEN_FLAT,
- RDFFormat.JSONLD_EXPAND_FLAT,
- RDFFormat.JSONLD_FRAME_FLAT,
-};
+ private static RDFFormat[] JSON_LD_FORMATS = {
+ RDFFormat.JSONLD_COMPACT_PRETTY,
+ RDFFormat.JSONLD_FLATTEN_PRETTY,
+ RDFFormat.JSONLD_EXPAND_PRETTY,
+ RDFFormat.JSONLD_FRAME_PRETTY,
+ RDFFormat.JSONLD_COMPACT_FLAT,
+ RDFFormat.JSONLD_FLATTEN_FLAT,
+ RDFFormat.JSONLD_EXPAND_FLAT,
+ RDFFormat.JSONLD_FRAME_FLAT,
+ };
}