Code Monkey home page Code Monkey logo

titanium-json-ld's Introduction

Hi everyone!

titanium-json-ld's People

Contributors

bobeal avatar codacy-badger avatar dependabot[bot] avatar ebremer avatar filip26 avatar jmvanel avatar jtownson avatar kevinpeterson avatar laxystem avatar lolgab avatar magemasher avatar simon-greatrix avatar skodapetr avatar umbreak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

titanium-json-ld's Issues

Parser fails quietly with an @id with no scheme

{
  "@id" : "x.y.z",
  "x:item" : {
    "@value" : "A_Token",
    "@type" : "http://www.w3.org/2001/XMLSchema#token"
  }
}

The above json-ld has an id with a relative (not absolute) URI.
The parser processes this as input without error but emits
no Triples output.
Code:

  try {
      JsonDocument doc = JsonDocument.of(stream);
      ToRdfApi tt = JsonLd.toRdf(doc);
      RdfDataset rdf = tt.get();   
      List<RdfNQuad> list = rdf.toList();
      ....
    } catch (JsonLdError e) {
    ....
    }

The list is empty.

I believe that the parser should either:

  • process the id as-is
  • signal an error in the input format.

NOTE: Change the @id to 'urn:x.y.z' and it works fine.

No setting to Skolemize blank nodes

Describe the bug
Unable to find setting to Skolemize blank nodes as RDF4J parser allows.

To Reproduce
Steps to reproduce the behavior:
This is my input json-ld

 {
   "@context": {
     "@version": 1.1,
     "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
     "xsd": "http://www.w3.org/2001/XMLSchema#",
     "et": "urn:acme:com#",
     "@vocab": "urn:acme:com#",
     "aId": {
       "@id": "@id",
       "@type": "@id"
     },
     "aVId": {
       "@id": "et:aVId",
       "@type": "@id"
     },
     "parts": {
       "@id": "et:parts",
       "@container": "@list",
       "@context": {
         "id": {
           "@id": "@id"
         }
       }
     },
     "id": {
       "@id": "et:id",
       "@type": "xsd:string"
     },
     "title": {
       "@id": "et:title",
       "@language": "en"
     },
     "type": {
       "@id": "et:type",
       "@type": "@vocab"
     },
     "version": {
       "@id": "et:version",
       "@type": "@id"
     }
   },
 
   "type": "Book",
   "title": "Title1",
   "parts": [
     {
       "version": "urn:acme:com:1111",
       "id": "urn:acme:com:2222",
       "type": "chapter",
       "title": "Chapter1"
     }
   ],
   "aId": "urn:acme:com:3333",
   "aVId": "urn:acme:com:4444"
 }

This is the set of triples that gets generated

 <urn:acme:com:2222> <urn:acme:com#title> "Chapter1"@en .
 <urn:acme:com:2222> <urn:acme:com#type> <urn:acme:com#chapter> .
 <urn:acme:com:2222> <urn:acme:com#version> <urn:acme:com:1111> .
 <urn:acme:com:3333> <urn:acme:com#aVId> <urn:acme:com:4444> .
 <urn:acme:com:3333> <urn:acme:com#parts> _:genid5f5f3ab0 .
 _:genid5f5f3ab0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <urn:acme:com:2222> .
 _:genid5f5f3ab0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
 <urn:acme:com:3333> <urn:acme:com#title> "Title1"@en .
 <urn:acme:com:3333> <urn:acme:com#type> <urn:acme:com#Book> .

I cannot find a setting to Skolemize the blank nodes. I want to be able to create RDF4J statements to add these to remote repository using RDF4J Model api and without it I am not able to do so

Expected behavior
There should be an option similar to RDF4J Skolemize
https://rdf4j.org/javadoc/latest/org/eclipse/rdf4j/rio/helpers/BasicParserSettings.html#SKOLEMIZE_ORIGIN

Additional context
Add any other context about the problem here.

JsonLdOptions @base overrides activeContext @base

Input Json: https://w3c.github.io/json-ld-api/tests/compact/0047-in.jsonld
Input context: https://w3c.github.io/json-ld-api/tests/compact/0047-in.jsonld

JsonLdTestCaseOptions options = new JsonLdTestCaseOptions();
options.setBase(URI.create("http://fake.com/"))
JsonLd.compact(input,context).options(options).get();

should still return the expected output https://w3c.github.io/json-ld-api/tests/compact/0047-out.jsonld
since the active @context @base value should override the JsonLDOptions @base

Two @base => JsonValueImpl cannot be cast to class javax.json.JsonStructure

Describe the bug
A @base in @context , and another @base in data block entails a ClassCastException: class javax.json.JsonValueImpl cannot be cast to class javax.json.JsonStructure (javax.json.JsonValueImpl and javax.json.JsonStructure .

To Reproduce
Call
JsonLd.toRdf(JsonDocument . of (is)). get()
where InputStream is reads:

{
  "@context": {
    "@base" : "https://beta.grottocenter.org/api/v1/entrances/"
  } ,
  "@base": "b",
  "@id": "4",
  "urn:name": "Prérouge (Grotte de)"
}

Expected behavior
No exception, of course.
https://json-ld.org/playground/ does not take in account the @base in data block .
Removing it removes the exception.

Additional context
Using latest Titanium 0.8.6 .
The stack is

java.lang.ClassCastException: class javax.json.JsonValueImpl cannot be cast to class javax.json.JsonStructure 
	at com.apicatalog.jsonld.flattening.NodeMapBuilder.build(NodeMapBuilder.java:389)
	at com.apicatalog.jsonld.flattening.NodeMapBuilder.build(NodeMapBuilder.java:122)
	at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:73)

Java 11 api usage prevents titanium being used on android and with Scala

Problem faced using on android
Calls such as com.apicatalog.jsonld.JsonLd.toRdf(...) instantiate a default DocumentLoader which has a dependency on Java 11's java.net.http.HttpClient. If the calling code tries to set options such as JsonLd.toRdf(...).loader(jdk8CompatibleLoader) this fails to circumvent the loading of Java 11 classes (because the default java 11 DocumentLoader instance is created eagerly).

Problem faced using from Scala
Scala projects still commonly use Java 8 as the runtime. The problem above thus causes incompatible class version errors.

Describe the solution you'd like
I recommend you refactor the code so that the core API is compatible with Java 8. For android, it would work if any concrete, default implementations which depend on Java 11 classes are not loaded in the case where the user provides overriding options. For Scala, I think you would have to actually compile under Java 8 (which would require reworking classes such as 'com.apicatalog.jsonld.loader.HttpLoader').

HttpLoader doesn't properly process missing content-type

Describe the bug
If received response doesn't have content-type then an exception is thrown

java.lang.IllegalArgumentException: The provided content type is null.
	at com.apicatalog.jsonld.document.DocumentParser.parse(DocumentParser.java:49)
	at com.apicatalog.jsonld.loader.HttpLoader.createDocument(HttpLoader.java:233)
	at com.apicatalog.jsonld.loader.HttpLoader.loadDocument(HttpLoader.java:193)
	at com.apicatalog.jsonld.loader.SchemeRouter.loadDocument(SchemeRouter.java:62)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:502)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:174)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.initLocalContext(ObjectExpansion.java:202)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:101)
	at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
	at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:124)
	at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:69)
	at com.apicatalog.jsonld.api.impl.ToRdfApi.get(ToRdfApi.java:179)
	at controllers.Json2RDFServiceApp.$anonfun$json2rdf$3(Json2RDFServiceApp.scala:58)
	at scala.util.Try$.apply(Try.scala:213)
	at controllers.Json2RDFServiceApp.$anonfun$json2rdf$1(Json2RDFServiceApp.scala:46)

To Reproduce
Use HttpLoader to load a resource with no content-type header.

Expected behavior
JsonLdError.DOCUMENT_LOADING_ERROR should be thrown.

Additional context
Consider fallback if content-type is missing.

Consideration on performance

This is just informative and for no means with any aim to criticise. I think the code is written very tidily and it is great to have an alternative to Json-LD Java.

I did some benchmarks comparing Json-LD Java with Titanium using the W3C compliance test suite (just the subset that Json-LD Java supported). Please take a look at the results.

I think it is normal performance in Json-LD Java is higher due to the lesser complexity of Json-LD 1.0 spec. Also due to their maturity they had the chance to improve performance. But I'm sure there is a room for performance improvement on this project too.

host Android build on maven central

Is your feature request related to a problem? Please describe.
Java 8/Android compatibility was added with #133, but presently I can't see the jar being hosted anywhere.

I was hoping to raise a PR on https://github.com/decentralized-identity/jsonld-common-java and https://github.com/decentralized-identity/did-common-java to provide Android support and titanium-json-ld is the key transitive dependency.

Describe the solution you'd like
titanium-json-ld uploaded under a separate artifactId to maven central or equivalent.

Describe alternatives you've considered
I've currently used git submodules to achieve the above, but it comes with problems:

  • gradle doesn't have a proxy for maven profiles, so building the maven module from gradle requires a fiddly bit of groovy
  • not sure if individual commits relate 1-1 to maven releases
  • it's ugly

I had a look in your github actions to try and raise a PR, but it didn't seem like the maven-push action actually does a maven push and I assumed you do it manually - I could well be misunderstanding though!

Additional context
Thanks for your work so far!

Cycling JSON->RDF->JSON: dropped data

JSON-RDF-JSON issue

In trying to do the json->rdf->json cycle, the
last entry of the outer list : [7,-7] is lost converting
RDF->JSON

input data:

{
"https://purl.org/geojson/vocab#coordinates": [{
"@list": [
{"@list": [{"@value": 10.0}, {"@value": -10.0}]},
{"@list": [{"@value": 9.0}, {"@value": -9.0}]},
{"@list": [{"@value": 8.0}, {"@value": -8.0}]},
{"@list": [{"@value": 7.0}, {"@value": -7.0}]}
]
}]
}

code:

	String input = 
	"{\n" + 
	"  \"https://purl.org/geojson/vocab#coordinates\": [{\n" + 
	"    \"@list\": [\n" + 
	"      {\"@list\": [{\"@value\": 10.0}, {\"@value\": -10.0}]},\n" + 
	"      {\"@list\": [{\"@value\": 9.0}, {\"@value\": -9.0}]},\n" + 
	"      {\"@list\": [{\"@value\": 8.0}, {\"@value\": -8.0}]},\n" + 
	"      {\"@list\": [{\"@value\": 7.0}, {\"@value\": -7.0}]}\n" + 
	"    ]\n" + 
	"  }]\n" + 
	" }\n" + 
	"";
	
	ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes());

	JsonDocument doc = JsonDocument.of(stream);
	ToRdfApi tt = JsonLd.toRdf(doc);
	RdfDataset rdf = tt.get();
	
	Document rdfDoc = RdfDocument.of(rdf);
	
	FromRdfApi fromRdf = JsonLd.fromRdf(rdfDoc);
	JsonArray array = fromRdf.get();
	System.out.println(array);

Use native types generate an invalid json ld

Describe the bug
Setting use native types to true return an invalid json ld: all string literals are converted to a value with xsd:string attached.

To Reproduce

Steps to reproduce the behavior:

JsonLdOptions  jlo = new JsonLdOptions();
jlo.setUseNativeTypes(true);
JsonArray rdf = JsonLd.fromRdf(RdfDocument.of(streamResult)).options(jlo).get();

The variable streamResult contains the example 1 of rdf nq

<http://one.example/subject1> <http://one.example/predicate1> <http://one.example/object1> <http://example.org/graph3> .
_:subject1 <http://an.example/predicate1> "object1" <http://example.org/graph1> .
_:subject2 <http://an.example/predicate2> 1^^<http://www.w3.org/2001/XMLSchema#integer> <http://example.org/graph5> .

The obtained result is
[{"@id":"http://example.org/graph1","@graph":[{"@id":"_:subject1","http://an.example/predicate1":[{"@value":"object1^^http://www.w3.org/2001/XMLSchema#string"}]}]},{"@id":"http://example.org/graph3","@graph":[{"@id":"http://one.example/subject1","http://one.example/predicate1":[{"@id":"http://one.example/object1"}]}]},{"@id":"http://example.org/graph5","@graph":[{"@id":"_:subject2","http://an.example/predicate2":[{"@value":1}]}]}]

"@value":"object1^^http://www.w3.org/2001/XMLSchema#string" is an invalid format, the correct value would be
{"@value":"object1"} or {"@value":"object1","@type":"http://www.w3.org/2001/XMLSchema#string"}.

Expected behavior
Using useNativeTypes I would expect the object1 that is a string to become a simple {"@value":"object1"} without the type.
With the current example full result:
[{"@id":"http://example.org/graph1","@graph":[{"@id":"_:subject1","http://an.example/predicate1":[{"@value":"object1"}]}]},{"@id":"http://example.org/graph3","@graph":[{"@id":"http://one.example/subject1","http://one.example/predicate1":[{"@id":"http://one.example/object1"}]}]},{"@id":"http://example.org/graph5","@graph":[{"@id":"_:subject2","http://an.example/predicate2":[{"@value":1}]}]}]

CLI support

Add an executable command allowing to perform JSON-LD transformations on a given input

e.g.

> cat input.json | jsonld.sh expand --context context.jsonld > expanded.jsonld

Jena interop

It would be great to implement some conversion from the RdfDatasets of Jena and the ones from this library.

I know this should be implemented in another repo, so this library does not directly depend on Jena.

For your information, I've submitted an issue on the Jena side, and that's their response: https://issues.apache.org/jira/browse/JENA-1948

export plain GeoJSON from GeoJSON-LD: issues RDF lists + key should be unprefixed

With JsonLd.toRdf() and an expandContext, plus my code to convert Titanium Dataset to Jena Dataset,
I was able to get RDF from a plain JSON .
( FYI see code https://github.com/jmvanel/semantic_forms/blob/master/scala/forms_play/app/controllers/Json2RDFServiceApp.scala#L43 )

Now I have the converse requirement. I want to export GeoJSON (being both plain GeoJSON & JSON-LD) from URI's having geographic data in a Jena TDB database.
See code
https://github.com/jmvanel/semantic_forms/blob/master/scala/geo/src/main/scala/jmvanel/GeoJSONexport.scala#L116
The issue is that I get mostly plain JSON with an @context :

    {
      "id": "http://semantic-forms.cc:1952/ldp/1511781044277-27461991065971051",
      "type": "Feature",
      "geometry": {
        "id": "406d4e19-bffb-4a8d-ba3e-2e9e7fadba17",
        "type": "Point",
        "geojson:coordinates": {
          "id": "c8d09a13-8359-49b5-819f-d76cce691faf",
          "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": "4.8193165",
          "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": {
            "id": "0194e207-ce2d-4377-9b33-1f397aa773cf",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": "45.9361934",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": {
              "@list": []
            }
          }
        }
      },
      "properties": {

But there 2 issues:

  1. "geojson:coordinates" instead of "coordinates" ; but maybe the original context from https://geojson.org/geojson-ld/ is wrong here
  2. RDF lists are not output as JSON arrays

cf GeoJSON-LD example https://geojson.org/geojson-ld/
This example works fine with the JSON-LD distiller
http://rdf.greggkellogg.net/distiller?command=compact&format=jsonld&output_format=jsonld&useNativeTypes
that is, the JSON-LD processor outputs is a plain JSON with an @context , and "coordinates" key is correct, and JSON array is present .

Superfluous arrays in Json -> JsonLD expansion

Arrays around single value objects are unnecessary and make reading the expansion result and further processing more awkward:
For example:

[{
  "http://acme.org/feature/structure_comment": [{
    "@value": "A comment"
  }],
  "http://acme.org/feature/structure_type": [{
    "@value": "a bolt"
  }],
  "http://acme.org/feature/load_measurement": [{
    "@value": 45
  }],
  "http://acme.org/feature/structure_id": [{
    "@value": "a.b.111"
  }]
}]

could be validly written as:

{
  "http://acme.org/feature/structure_comment": {
    "@value": "A comment"
  },
  "http://acme.org/feature/structure_type": {
    "@value": "a bolt"
  },
  "http://acme.org/feature/load_measurement": {
    "@value": 45
  },
  "http://acme.org/feature/structure_id": {
    "@value": "a.b.111"
  }
}

I also believe that the use of @value in this example is superfluous, but is less annoying to the eye.

file: URL's are not accepted for context location

To be able to run Titanium with local files , I had to comment out some code :

git diff *
diff --git a/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java b/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java
index edb041c..2a287ca 100644
--- a/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java
+++ b/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java
@@ -71,9 +71,9 @@ public final class ExpansionApi implements CommonApi<ExpansionApi>, LoaderApi<Ex
     public ExpansionApi context(String contextLocation) {
         
         if (contextLocation != null) {
-            if (!UriUtils.isNotURI(contextLocation)) {
-                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
-            }
+//            if (!UriUtils.isNotURI(contextLocation)) {
+//                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
+//            }
             options.setExpandContext(UriUtils.create(contextLocation));
             
         } else {
diff --git a/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java b/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java
index ada138d..a737db2 100644
--- a/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java
+++ b/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java
@@ -72,9 +72,9 @@ public final class ToRdfApi implements CommonApi<ToRdfApi>, LoaderApi<ToRdfApi>,
     public ToRdfApi context(String contextLocation) {
         
         if (contextLocation != null) {
-            if (!UriUtils.isNotURI(contextLocation)) {
-                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
-            }
+//            if (!UriUtils.isNotURI(contextLocation)) {
+//                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
+//            }
             options.setExpandContext(UriUtils.create(contextLocation));
             
         } else {

And now this can run :

JsonLd.toRdf( uri ) . context( context ).get

Blank nodes output as IRI in fromRdf

Describe the bug
After building a single triple RdfDataset from API , and giving it to fromRdf, the blank node "bn1" is output as an IRI :
[{"@id":"urn:s1","urn:p1":[{"@id":"bn1"}]}]

To Reproduce
This is Scala. I can provide a Java code, but I think you can manage that :) .

import com.apicatalog.rdf.impl.DefaultRdfProvider
import com.apicatalog.jsonld.api.impl.FromRdfApi
import com.apicatalog.jsonld.JsonLd
import com.apicatalog.jsonld.document.RdfDocument
import com.apicatalog.rdf.RdfDataset
import javax.json.JsonArray
import java.io.StringWriter
import javax.json.Json

object TestTitaniumBlankNodes extends App {
  val rdfProvider = DefaultRdfProvider.INSTANCE
  val subject = rdfProvider.createIRI("urn:s1")
  val objet = rdfProvider.createBlankNode("bn1")
  val predicate = rdfProvider.createIRI("urn:p1")
  val titaniumDS: RdfDataset = rdfProvider.createDataset()
  val nquad = rdfProvider.createNQuad(subject, predicate, objet, null)
  titaniumDS.add(nquad)

  val fromRdf: FromRdfApi =
      JsonLd.fromRdf(
        RdfDocument.of(titaniumDS) )

  printJsonArray(fromRdf . get) // KO: blank node as IRI !!!!!!!!!!!!!!!!!!!!

  def printJsonArray(jsa: JsonArray) {
    val sw = new StringWriter()
    val jsonWriter = Json.createWriter(sw)
    jsonWriter.writeArray(jsa)
    jsonWriter.close()
    sw.close()
    println(sw.toString())
  }
}

Expected behavior
Real blank node:

[{
"@id":"urn:s1",
"urn:p1": "_:bn1" }]`

Additional context
Distilled from issue #89

java.io.IOException: Too many open files in system when running tests

Hello,

I'm getting the following error when running the tests:

java.lang.InternalError: java.io.IOException: Too many open files in system
	at java.net.http/jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:311)
	at java.net.http/jdk.internal.net.http.HttpClientImpl.create(HttpClientImpl.java:253)
	at java.net.http/jdk.internal.net.http.HttpClientBuilderImpl.build(HttpClientBuilderImpl.java:135)
	at com.apicatalog.jsonld.loader.HttpLoader.<init>(HttpLoader.java:38)
	at com.apicatalog.jsonld.api.JsonLdOptions.<init>(JsonLdOptions.java:88)
	at com.apicatalog.jsonld.suite.JsonLdTestCase.getOptions(JsonLdTestCase.java:154)
	at com.apicatalog.jsonld.JsonLdToRdfTest.testToRdf(JsonLdToRdfTest.java:62)
       .....

I believe com.apicatalog.jsonld.loader.HttpLoader is building a new java.net.http.HttpClient for each instance -- is that necessary, or can one instance of the HttpClient be reused?

Context Builder API

Is your feature request related to a problem? Please describe.
Sometimes a combination of contexts is needed. e.g. a combination of local and remote context.

Describe the solution you'd like
Provide API, a builder, allowing to create combined context.

e.g.

JsonLd.createContext().add(localcontext).add(remotecontext).build()

Describe alternatives you've considered
Now, a user must create a context manually or with JSON-P.

The @base attribute is only used if the remote contexts list is empty.

Describe the bug

The @base attribute is only used if the remote contexts list is empty.

To Reproduce

Populate the @base attribute along with one or more entries in the remote contexts.

For example, I would expect this to result in one triple when going to RDF:

{
  "@id": "1",
  "test": "some-test",
  "@context": [
    "https://fhircat.org/fhir-r5/original/contexts/careplan.context.jsonld",
    {
      "nodeRole": {
        "@type": "@id",
        "@id": "fhir:nodeRole"
      },
      "@base": "http://hl7.org/fhir/",
      "owl:imports": {
        "@type": "@id"
      },
      "owl:versionIRI": {
        "@type": "@id"
      }
    }
  ]
}

Expected behavior

I believe the correct interpretation of this spec is that @base should be considered if the context is not a remote context (not necessarily if the remote contexts list is empty). See linked issue below.

Additional context

w3c/json-ld-api#505

HttpLoader: Suppress HTTP Content-Type validation

Feature request is related to a problem

I'm frustrated when a JSON-LD source has a linked @context whose MIME type is not one of the JSON expected types.
In this case it is a raw github URL, that says test/plain .
This, or a file, is very convenient to develop and debug a new @context .
Moreover, being explicitly loaded as a @context , is is supposed to be application/ld+json .
I deserves a warning for sure, but not a blocking exception.

scala> JsonLd.toRdf("https://geb.ffspeleo.fr/api/api/v2/").get()
com.apicatalog.jsonld.JsonLdError: There was a problem encountered loading a remote context [code=LOADING_REMOTE_CONTEXT_FAILED].
  at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:523)
  at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:173)
  at com.apicatalog.jsonld.expansion.ObjectExpansion.initLocalContext(ObjectExpansion.java:202)
  at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:101)
  at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
  at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:124)
  at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:69)
  at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:58)
  at com.apicatalog.jsonld.api.ToRdfApi.get(ToRdfApi.java:175)
  ... 31 elided
Caused by: com.apicatalog.jsonld.JsonLdError: Unsupported media type 'text/plain'. Supported content types are [application/ld+json, application/json, +json, application/n-quads]
  at com.apicatalog.jsonld.document.DocumentParser.fireUnsupportedMediaType(DocumentParser.java:99)
  at com.apicatalog.jsonld.document.DocumentParser.parse(DocumentParser.java:60)
  at com.apicatalog.jsonld.loader.HttpLoader.createDocument(HttpLoader.java:242)
  at com.apicatalog.jsonld.loader.HttpLoader.loadDocument(HttpLoader.java:202)
  at com.apicatalog.jsonld.loader.SchemeRouter.loadDocument(SchemeRouter.java:62)
  at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:519)
  ... 39 more

Other JSON-LD engines

JENA (with jsonld-java) processes such JSON-LD source well :
$JENA/bin/riot --output=turtle --syntax=jsonld https://geb.ffspeleo.fr/api/api/v2/
The Playground also accepts such input:

{
  "@context": "https://raw.githubusercontent.com/jmvanel/Karstlink-ontology/master/geb.ffspeleo.fr_context.jsonld",
  "@graph": [
    {
      "@id": "321",
      "@type": "UndergroundCavity",
      "name": "Biefs Bousset",
      "latitude": "46.99406",
      "longitude": "6.07472",
      "altitude": "770",
      "locates": [
        {
          "@id": "628",
          "@type": "geo:Point",
          "label": "station_321-590",
          "dwc:Occurrence": [
            {
              "@id": "4278",
              "@type": "dwc:Occurrence",
              "event date": "2010-03-07",
              "associated taxa": "Amilenus aurantiacus",
              "dwci:toTaxon": "http://taxref.mnhn.fr/lod/taxon/337326/13.0"
            }
            ]
        }
      ]
    }
  ]  
}

Question: disabling remote context loading

While it is clearly part of the JSON-LD specification to fetch remote context documents (either via "@context": "https://example.com/context.json" or via @import within an existing @context), is there a mechanism for disabling this feature? It seems that JsonLdOptions.setDocumentLoader(null) may work for that.

The use case I have in mind is an LDP server that accepts JSON-LD documents but which (for security reasons) does not wish to fetch arbitrary remote resources.

add Maven wrapper

add mvnw and mvnw.cmd commands to the root directory to allow building the project without having Maven installed.

integer JSON value should be used for @id

Is feature request related to a problem?
Integer id's are very common in JSON API's. Alas it is explicitly forbidden by JSON-LD, for bad reasons.

Describe the proposed solution

{ "@context": {
  "id": "@id",
  "dwciri": "http://rs.tdwg.org/dwc/iri/",
  "taxonKey":{
    "@context": {
      "@base" : "https://api.gbif.org/v1/species/"
    },
    "@id": "dwciri:toTaxon", "@type": "@id"
  }
},
"id": 123 ,
"taxonKey": 7310533
}

Expected:

<https://json-ld.org/playground/123> <http://rs.tdwg.org/dwc/iri/toTaxon>
  <https://api.gbif.org/v1/species/7310533> .

This is what is obtained in Playground when changing 123 and 7310533 to strings.
@filip26 suggested that "Titanium could support that as an extension. e,g, JsonLdOptions.allowNumericId(boolean). " .
It could be the default, but that is debatable...

Describe alternatives considered
There is no alternative , except pre-processing the JSON, or post-processing with SPARQL.

Additional context
This issue on W3C has got some following:
w3c/json-ld-api#509
See previous issue with example:
json-ld/json-ld.org#742

More meaningful error messages

Except for simple pure JSON syntax errors, there are no meaningful error messages; in many cases all we get is a JsonLdError exception and a stack.

Exemple:
JsonLd.expand( inatdir + "test-jmv.json").context(inatdir + "test.context.jsonld").get com.apicatalog.jsonld.api.JsonLdError at com.apicatalog.jsonld.expansion.ObjectExpansion1314.expand(ObjectExpansion1314.java:170) at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:120) at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:123) at com.apicatalog.jsonld.expansion.ArrayExpansion.expand(ArrayExpansion.java:101) at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:114) at com.apicatalog.jsonld.expansion.ObjectExpansion1314.expand(ObjectExpansion1314.java:339) at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:120) at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:123) at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:140) at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:62) at com.apicatalog.jsonld.api.impl.ExpansionApi.get(ExpansionApi.java:148) ... 36 elided

The JSON data : test-jmv.json

{ "results" : [ {
         "id" : "54141546",
         "place_ids" : [ 97391, 108692 ],
         "map_scale" : null,
         "tags" : [],
         "captive" : false,
         "identifications_some_agree" : false,
         "geoprivacy" : null,
         "uri" : "https://www.inaturalist.org/observations/54141546",
         "quality_grade" : "needs_id",
         "taxon" : null,
         "site_id" : 1,
         "reviewed_by" : [],
         "description" : "Aucune fleur ou fruit, glauque, très drageonnant, pas plus de 40 cm, dans une prairie sèche rarement fauchée",
         "user" : {
            "id" : 3295956,
            "name" : "Jean-Marc Vanel",
            "icon" : "https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662"
         },
         "created_at" : "2020-07-24T12:03:34+02:00",
  "total_results" : 1,
   "per_page" : 1
} ] }

The context: test.context.jsonld

{
"@context": {
  "results" : "@graph" ,
  "id": "@id",
  "uri": "@id"
} }

The URL prefix:

String inatdir = "file:///home/jmv/src/rdf-convert/inaturalist.org/" ;

NOTE: removing in context the line "id": "@id", removes the error .

JsonLd.toRdf takes a long time for a specific example

Describe the bug
I think there may be a performance issue when contexts recurse. I have a small example that does complete, but takes several minutes.

To Reproduce
See the JSONLD content to reproduce is here: https://tinyurl.com/y4jlpkz5

I plug that into JsonLd.toRdf as such:

ToRdfApi rdf = JsonLd.toRdf(stream).options(jsonLdOptions);
RdfDataset dataset = rdf.get();

Expected behavior
I would expect a small example like this to be fairly fast. I suspect there is some looping or something that can be optimized.

Consider to return Optional instead of null

see:

public static JsonValue getValue(JsonValue value) {
return isValueObject(value)
? value.asJsonObject().get(Keywords.VALUE)
: null;
}

public static JsonValue getValue(JsonValue value) {
return JsonUtils.isObject(value) ? value.asJsonObject().get(Keywords.DEFAULT) : null;
}

Nested @embed directive affects processing at a higher level

Describe the bug

When I create a frame with a nested @embed directive, it seems to affect the frame processing at a higher level, which differs from the behavior of the framing processor at the JSON-LD Playground.

To Reproduce

Take for example the following graph:

{
  "@graph": [
    {
      "@id": "http://n2t.net/ark:/39333/ncg/dataset",
      "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag",
      "member": [
        "http://n2t.net/ark:/39333/ncg/place/NCG11248",
        "http://n2t.net/ark:/39333/ncg/place/NCG07554",
        "http://n2t.net/ark:/39333/ncg/place/NCG03755"
      ]
    },
    {
      "@id": "http://n2t.net/ark:/39333/ncg/place/NCG03755",
      "@type": "http://n2t.net/ark:/39333/ncg/type#Mountain",
      "county": "http://n2t.net/ark:/39333/ncg/place/NCG11248",
      "label": "Crawford Mountain"
    },
    {
      "@id": "http://n2t.net/ark:/39333/ncg/place/NCG07554",
      "@type": "http://n2t.net/ark:/39333/ncg/type#Community",
      "county": "http://n2t.net/ark:/39333/ncg/place/NCG11248",
      "label": "Ichley"
    },
    {
      "@id": "http://n2t.net/ark:/39333/ncg/place/NCG11248",
      "@type": "http://n2t.net/ark:/39333/ncg/type#County",
      "label": "Orange County",
      "description": "Not to be confused with Orange County, CA"
    }
  ],
  "@context": {
    "label": {
      "@id": "http://www.w3.org/2004/02/skos/core#label"
    },
    "description": {
      "@id": "http://www.w3.org/2004/02/skos/core#note"
    },
    "county": {
      "@id": "http://n2t.net/ark:/39333/ncg/vocab#county",
      "@type": "@id"
    },
    "member": {
      "@id": "http://www.w3.org/2000/01/rdf-schema#member",
      "@type": "@id"
    }
  }
}

And this frame:

{
  "@context": {
    "@base": "http://n2t.net/ark:/39333/ncg/place/",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "ncv": "http://n2t.net/ark:/39333/ncg/vocab#",
    "nct": "http://n2t.net/ark:/39333/ncg/type#",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "records": {
      "@container": "@set",
      "@type": "@id",
      "@id": "rdfs:member"
    },
    "county": {
      "@container": "@set",
      "@type": "@id",
      "@id": "ncv:county"
    }
  },
  "@type": "rdf:Bag",
  "records": {
    "@id": {},
    "county": {
      "@embed": "@always",
      "@explicit": true,
      "skos:label": {}
    }
  }
}

(See the above on the playground).

Expected behavior

On the JSON-LD Playground, the above graph and frame produce these results, which are what I would expect: county nodes are always embedded and respecting the @explicit directive, but this does not affect the records level.

{
  "@context": {
    "@base": "http://n2t.net/ark:/39333/ncg/place/",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "ncv": "http://n2t.net/ark:/39333/ncg/vocab#",
    "nct": "http://n2t.net/ark:/39333/ncg/type#",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "records": {
      "@container": "@set",
      "@type": "@id",
      "@id": "rdfs:member"
    },
    "county": {
      "@container": "@set",
      "@type": "@id",
      "@id": "ncv:county"
    }
  },
  "@id": "../dataset",
  "@type": "rdf:Bag",
  "records": [
    {
      "@id": "NCG11248",
      "@type": "nct:County",
      "county": [],
      "skos:label": "Orange County",
      "skos:note": "Not to be confused with Orange County, CA"
    },
    {
      "@id": "NCG07554",
      "@type": "nct:Community",
      "county": [
        {
          "@id": "NCG11248",
          "@type": "nct:County",
          "skos:label": "Orange County"
        }
      ],
      "skos:label": "Ichley"
    },
    {
      "@id": "NCG03755",
      "@type": "nct:Mountain",
      "county": [
        {
          "@id": "NCG11248",
          "@type": "nct:County",
          "skos:label": "Orange County"
        }
      ],
      "skos:label": "Crawford Mountain"
    }
  ]
}

However, using Titanium I get the following results:

{
    "@id": "../dataset",
    "@type": "rdf:Bag",
    "records": [
        {
            "@id": "NCG03755",
            "@type": "nct:Mountain",
            "county": [
                {
                    "@id": "NCG11248",
                    "@type": "nct:County",
                    "skos:label": "Orange County"
                }
            ],
            "skos:label": "Crawford Mountain"
        },
        {
            "@id": "NCG07554",
            "@type": "nct:Community",
            "county": [
                {
                    "@id": "NCG11248",
                    "@type": "nct:County",
                    "skos:label": "Orange County"
                }
            ],
            "skos:label": "Ichley"
        },
        "NCG11248"
    ],
    "@context": {
        "@base": "http://n2t.net/ark:/39333/ncg/place/",
        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
        "ncv": "http://n2t.net/ark:/39333/ncg/vocab#",
        "nct": "http://n2t.net/ark:/39333/ncg/type#",
        "skos": "http://www.w3.org/2004/02/skos/core#",
        "records": {
            "@container": "@set",
            "@type": "@id",
            "@id": "rdfs:member"
        },
        "county": {
            "@container": "@set",
            "@type": "@id",
            "@id": "ncv:county"
        }
    }
}

Note that the node for Orange County at the records level is just an @id reference.

Additional context

It seems to me that what is happening is that the records level is being processed with the default "@embed": "@once" directive, but that the embeddings at the county level are being counted as fulfilling that one embedding, so that at the records level Orange County is never embedded.

INVALID_IRI_MAPPING when using specific context in form of an array

When trying to process a JSON-LD 1.1 file using Titanium (e.g. compact, but also other operations), I get the INVALID_IRI_MAPPING exception. The file processed is:

{
    "@context": [
        "https://pod-test.mvcr.gov.cz/otevřené-formální-normy/pracovní-místa/draft/kontexty/pracovní-místo.jsonld",
        {
            "@version": 1.1,
            "@import": "https://ofn.gov.cz/věc/2020-07-01/kontexty/věc.jsonld",
            "@propagate": true,
            "nedefinováno": "https://slovník.gov.cz/nedefinováno/",
            "místa": "https://slovník.gov.cz/generický/pracovní-místa/pojem/",
            "Pracovní místo ve vědě a výzkumu": {
                "@id": "nedefinováno:pracovní-místo-ve-vědě-a-výzkumu",
                "@context": {
                    "pracoviště": {
                        "@id": "místa:má-pracoviště",
                        "@context": "https://pod-test.mvcr.gov.cz/otevřené-formální-normy/věda-a-výzkum/draft/kontexty/věda-a-výzkum.jsonld"
                    }
                }
            }
        }
    ],
    "typ": [
        "Pracovní místo ve vědě a výzkumu"
    ],
    "iri": "https://data.mff.cuni.cz/zdroj/pracovní-místa-mff-uk/202008-AP1-KSI",
    "pracoviště": {
        "typ": "Pracoviště",
        "iri": "https://data.mff.cuni.cz/zdroj/číselník/organizační-struktura/oddělení/204"
    }
}

The weird thing is that when I leave only one of the two items in the @context array, the processing does not fail. It only fails when there are both items.

The exception:

Caused by: com.apicatalog.jsonld.JsonLdError: There was a problem encountered loading a remote context [code=LOADING_REMOTE_CONTEXT_FAILED].
	at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:572)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:173)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.initPropertyContext(ObjectExpansion.java:148)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:99)
	at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
	at com.apicatalog.jsonld.expansion.ObjectExpansion1314.expand(ObjectExpansion1314.java:905)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:120)
	at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
	at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:124)
	at com.apicatalog.jsonld.api.ExpansionApi.get(ExpansionApi.java:142)
	at com.linkedpipes.plugin.transformer.jsonldformattitanium.TitaniumOperator.expand(TitaniumOperator.java:91)
	... 6 common frames omitted
Caused by: com.apicatalog.jsonld.JsonLdError: The local context defined within a term definition is invalid [code=INVALID_SCOPED_CONTEXT].
	at com.apicatalog.jsonld.context.TermDefinitionBuilder.create(TermDefinitionBuilder.java:534)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:451)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:565)
	... 16 common frames omitted
Caused by: com.apicatalog.jsonld.JsonLdError: A local context contains a term that has an invalid or missing IRI mapping [code=INVALID_IRI_MAPPING].
	at com.apicatalog.jsonld.context.TermDefinitionBuilder.create(TermDefinitionBuilder.java:358)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:451)
	at com.apicatalog.jsonld.context.TermDefinitionBuilder.create(TermDefinitionBuilder.java:531)
	... 18 common frames omitted

Note that the referenced external contexts re-use each other, which even forms a cycle, but that should not be an issue, as it holds even when one of the two items in the @context array stays.

triples with aliased @id and @base are missing at root level

Describe the bug
Two triples corresponding to @id "id" : "54141546" at root level in the JSON are lost.
Both @id 's are associated to a @base .
So there is just one triple left, corresponding to the inner JSON block :

<https://www.inaturalist.org/users/3295956>
  <http://xmlns.com/foaf/0.1/img> 
    <https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662>

(works fine with Distiller & JS-LD Playground)

To Reproduce
Prepare files

echo '{
  "uri" : "54141546" ,
  "description" : "Aucune fleur ou fruit, glauque",
  "user" : {
    "id" : "3295956",
    "icon" : "https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662"
  } }' > test-bug-OK.json
echo '{ "@context": {
  "foaf": "http://xmlns.com/foaf/0.1/",
  "rdfs" : "http://www.w3.org/2000/01/rdf-schema#" ,
  "@base" : "https://api.inaturalist.org/v1/observations/" ,  
  "uri": "@id",
  "description" : "rdfs:comment" ,
  "user" : {
     "@id": "foaf:maker",
     "@context": {
      "icon" : { "@id": "foaf:img", "@type": "@id" } ,
      "@base" : "https://www.inaturalist.org/users/" ,
      "id" : "@id"
    }
  }
} }' > test-bug.context-OK.jsonld

Java code

String dir = "file:////home/jmv/test/"
String uri = dir + "test-bug-OK.json";
String context = dir + "test-bug.context-OK.jsonld";
JsonLdOptions options = new JsonLdOptions();
options.setExpandContext(context);
System.println(  JsonLd.toRdf( uri ) . options(options) . get() )

Expected behavior
Like with Distiller:

<https://api.inaturalist.org/v1/observations/54141546> <http://xmlns.com/foaf/0.1/maker> <https://www.inaturalist.org/users/3295956> .
<https://api.inaturalist.org/v1/observations/54141546> <http://www.w3.org/2000/01/rdf-schema#comment> "Aucune fleur ou fruit, glauque" .
<https://www.inaturalist.org/users/3295956> <http://xmlns.com/foaf/0.1/img> <https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662> 

Additional context
NOTE : to be able to test I commented out the faulty Java code that prevents use of file: URL's , see preceding issue .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.