diff --git a/build.gradle.kts b/build.gradle.kts
index 6a08e7797..033c60b50 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -117,7 +117,8 @@ dependencies {
implementation("fr.inria.lille.shexjava:shexjava-core:1.0") // ShEx validation engine
implementation("fr.inria.corese.org.semarglproject:semargl-rdfa:$semargl_version") // RDFa parser (Semargl)
implementation("fr.inria.corese.org.semarglproject:semargl-core:$semargl_version") // Semargl core RDF parser
- implementation("com.github.jsonld-java:jsonld-java:0.13.4") // JSON-LD processing
+ implementation("com.github.jsonld-java:jsonld-java:0.13.6") // Legacy JSON-LD processing
+
// === HTTP and XML ===
implementation("org.glassfish.jersey.core:jersey-client:$jersey_version") // HTTP client (Jersey)
@@ -150,6 +151,7 @@ extraJavaModuleInfo {
automaticModule("commons-lang:commons-lang", "commons.lang") // Module for Commons Lang
automaticModule("fr.inria.lille.shexjava:shexjava-core", "shexjava.core") // Module for ShexJava core
automaticModule("org.eclipse.rdf4j:rdf4j-model", "rdf4j.model") // Module for RDF4J model
+
}
diff --git a/src/main/java/fr/inria/corese/core/next/api/parser/RDFFormat.java b/src/main/java/fr/inria/corese/core/next/api/parser/RDFFormat.java
new file mode 100644
index 000000000..ad7988ad7
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/parser/RDFFormat.java
@@ -0,0 +1,114 @@
+package fr.inria.corese.core.next.api.parser;
+
+import java.nio.charset.Charset;
+import java.util.*;
+import fr.inria.corese.core.next.api.IRI;
+
+public interface RDFFormat {
+
+ /**
+ * Gets the name of this file format.
+ *
+ * @return A human-readable format name, e.g. "PLAIN TEXT".
+ */
+ String getName();
+
+
+ /**
+ * Gets the default MIME type for this file format.
+ *
+ * @return A MIME type string, e.g. "text/plain".
+ */
+ String getDefaultMIMEType() ;
+
+
+ /**
+ * Checks if the specified MIME type matches the FileFormat's default MIME type. The MIME types are compared
+ * ignoring upper/lower-case differences.
+ *
+ * @param mimeType The MIME type to compare to the FileFormat's default MIME type.
+ * @return true if the specified MIME type matches the FileFormat's default MIME type.
+ */
+ boolean hasDefaultMIMEType(String mimeType);
+
+ /**
+ * Gets the file format's MIME types.
+ *
+ * @return An unmodifiable list of MIME type strings, e.g. "text/plain".
+ */
+ List getMIMETypes();
+
+
+
+ /**
+ * Checks if specified MIME type matches one of the FileFormat's MIME types. The MIME types are compared ignoring
+ * upper/lower-case differences.
+ *
+ * @param mimeType The MIME type to compare to the FileFormat's MIME types.
+ * @return true if the specified MIME type matches one of the FileFormat's MIME types.
+ */
+ boolean hasMIMEType(String mimeType);
+
+ /**
+ * Gets the default file name extension for this file format.
+ *
+ * @return A file name extension (excluding the dot), e.g. "txt", or null if there is no common file
+ * extension for the format.
+ */
+ String getDefaultFileExtension();
+
+ /**
+ * Checks if the specified file name extension matches the FileFormat's default file name extension. The file name
+ * extension MIME types are compared ignoring upper/lower-case differences.
+ *
+ * @param extension The file extension to compare to the FileFormat's file extension.
+ * @return true if the file format has a default file name extension and if it matches the specified
+ * extension, false otherwise.
+ */
+ boolean hasDefaultFileExtension(String extension);
+
+ /**
+ * Gets the file format's file extensions.
+ *
+ * @return An unmodifiable list of file extension strings, e.g. "txt".
+ */
+ List getFileExtensions();
+
+ /**
+ * Checks if the FileFormat's file extension is equal to the specified file extension. The file extensions are
+ * compared ignoring upper/lower-case differences.
+ *
+ * @param extension The file extension to compare to the FileFormat's file extension.
+ * @return true if the specified file extension is equal to the FileFormat's file extension.
+ */
+ boolean hasFileExtension(String extension);
+
+ /**
+ * Get the (default) charset for this file format.
+ *
+ * @return the (default) charset for this file format, or null if this format does not have a default charset.
+ */
+ Charset getCharset();
+
+ /**
+ * Checks if the FileFormat has a (default) charset.
+ *
+ * @return true if the FileFormat has a (default) charset.
+ */
+ boolean hasCharset();
+
+ /**
+ * Return true if the RDFFormat supports the encoding of namespace/prefix information.
+ */
+ boolean supportsNamespaces();
+
+ /**
+ * Return true if the RDFFormat supports the encoding of contexts/named graphs.
+ */
+ boolean supportsContexts();
+
+ /**
+ * Return true if the RDFFormat supports the encoding of RDF-star triples natively.
+ */
+ boolean supportsRDFStar();
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/parser/RDFFormats.java b/src/main/java/fr/inria/corese/core/next/api/parser/RDFFormats.java
new file mode 100644
index 000000000..f073fa898
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/parser/RDFFormats.java
@@ -0,0 +1,255 @@
+package fr.inria.corese.core.next.api.parser;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+
+public enum RDFFormats implements RDFFormat {
+
+ TURTLE("Turtle",
+ List.of("text/turtle"),
+ List.of("ttl"),
+ true,
+ false,
+ false),
+ N3("N3",
+ List.of("text/n3"),
+ List.of("n3"),
+ true,
+ false,
+ false),
+ RDF_XML("RDF/XML",
+ List.of("application/rdf+xml"),
+ List.of("rdf", "xml"),
+ true,
+ false,
+ false),
+ JSON_LD("JSON-LD",
+ List.of("application/ld+json"),
+ List.of("jsonld", "json"),
+ true,
+ true,
+ false),
+ N_TRIPLES("N-Triples",
+ List.of("application/n-triples"),
+ List.of("nt"),
+ false,
+ false,
+ false),
+ TRIG("TriG",
+ List.of("application/trig"),
+ List.of("trig"),
+ true,
+ true,
+ false),
+ NQUADS("N-Quads",
+ List.of("application/n-quads"),
+ List.of("nq"),
+ true,
+ true,
+ false);
+
+ private static final boolean DEFAULT_SUPPORTS_NAMESPACES = true;
+ private static final boolean DEFAULT_SUPPORTS_CONTEXTS = true;
+ private static final boolean DEFAULT_SUPPORTS_RDF_STAR = false;
+
+ /**
+ * The file format human-readable name.
+ */
+ private final String name;
+
+ /**
+ * The file format's MIME types. The first item in the list is interpreted as the default MIME type for the format.
+ */
+ private final List mimeTypes;
+
+ /**
+ * The file format's (default) charset.
+ */
+ private final Charset charset;
+
+ /**
+ * The file format's file extensions. The first item in the list is interpreted as the default file extension for
+ * the format.
+ */
+ private final List fileExtensions;
+
+ /**
+ * Flag indicating whether the RDFFormat can encode namespace information.
+ */
+ private final boolean supportsNamespaces;
+
+ /**
+ * Flag indicating whether the RDFFormat can encode context information (ex: Graphs or quads).
+ */
+ private final boolean supportsContexts;
+
+ /**
+ * Flag indicating whether the RDFFormat can encode RDF-star triples natively.
+ */
+ private final boolean supportsRDFStar;
+
+ RDFFormats(String name,
+ List mimeTypes,
+ Charset charset,
+ List fileExtensions,
+ boolean supportsNamespaces,
+ boolean supportsContexts,
+ boolean supportsRDFStar) {
+ this.name = name;
+ this.mimeTypes = mimeTypes;
+ this.charset = charset;
+ this.fileExtensions = fileExtensions;
+ this.supportsNamespaces = supportsNamespaces;
+ this.supportsContexts = supportsContexts;
+ this.supportsRDFStar = supportsRDFStar;
+ }
+
+ RDFFormats(String name,
+ List mimeTypes,
+ Charset charset,
+ List fileExtensions) {
+ this(name, mimeTypes, charset, fileExtensions, DEFAULT_SUPPORTS_NAMESPACES, DEFAULT_SUPPORTS_CONTEXTS, DEFAULT_SUPPORTS_RDF_STAR);
+ }
+
+ RDFFormats(String name,
+ List mimeTypes,
+ List fileExtensions) {
+ this(name, mimeTypes, StandardCharsets.UTF_8, fileExtensions, DEFAULT_SUPPORTS_NAMESPACES, DEFAULT_SUPPORTS_CONTEXTS, DEFAULT_SUPPORTS_RDF_STAR);
+ }
+
+ RDFFormats(String name,
+ List mimeTypes,
+ List fileExtensions,
+ boolean supportsNamespaces,
+ boolean supportsContexts,
+ boolean supportsRDFStar) {
+ this(name, mimeTypes, StandardCharsets.UTF_8, fileExtensions, supportsNamespaces, supportsContexts, supportsRDFStar);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getDefaultMIMEType() {
+ return mimeTypes.get(0);
+ }
+
+ @Override
+ public boolean hasDefaultMIMEType(String mimeType) {
+ return getDefaultMIMEType().equalsIgnoreCase(mimeType);
+ }
+
+ @Override
+ public List getMIMETypes() {
+ return Collections.unmodifiableList(mimeTypes);
+ }
+
+ @Override
+ public boolean hasMIMEType(String mimeType) {
+ if (mimeType == null) {
+ return false;
+ }
+ String type = mimeType;
+ if (mimeType.indexOf(';') > 0) {
+ type = mimeType.substring(0, mimeType.indexOf(';'));
+ }
+ for (String mt : this.mimeTypes) {
+ if (mt.equalsIgnoreCase(mimeType)) {
+ return true;
+ }
+ if (mimeType != type && mt.equalsIgnoreCase(type)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String getDefaultFileExtension() {
+ if (fileExtensions.isEmpty()) {
+ return null;
+ } else {
+ return fileExtensions.get(0);
+ }
+ }
+
+ @Override
+ public boolean hasDefaultFileExtension(String extension) {
+ String ext = getDefaultFileExtension();
+ return ext != null && ext.equalsIgnoreCase(extension);
+ }
+
+ @Override
+ public List getFileExtensions() {
+ return Collections.unmodifiableList(fileExtensions);
+ }
+
+ @Override
+ public boolean hasFileExtension(String extension) {
+ for (String ext : fileExtensions) {
+ if (ext.equalsIgnoreCase(extension)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public Charset getCharset() {
+ return charset;
+ }
+
+ @Override
+ public boolean hasCharset() {
+ return charset != null;
+ }
+
+ @Override
+ public boolean supportsNamespaces() {
+ return supportsNamespaces;
+ }
+
+ @Override
+ public boolean supportsContexts() {
+ return supportsContexts;
+ }
+
+ @Override
+ public boolean supportsRDFStar() {
+ return supportsRDFStar;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(64);
+
+ sb.append(name);
+
+ sb.append(" (mimeTypes=");
+ for (int i = 0; i < mimeTypes.size(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(mimeTypes.get(i));
+ }
+
+ sb.append("; ext=");
+ for (int i = 0; i < fileExtensions.size(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(fileExtensions.get(i));
+ }
+
+ sb.append(")");
+
+ return sb.toString();
+ }
+
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/parser/RDFParser.java b/src/main/java/fr/inria/corese/core/next/api/parser/RDFParser.java
new file mode 100644
index 000000000..2977bf158
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/parser/RDFParser.java
@@ -0,0 +1,42 @@
+package fr.inria.corese.core.next.api.parser;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+public interface RDFParser {
+
+ /**
+ * Gets the RDF format that this parser can parse.
+ */
+ RDFFormat getRDFFormat();
+
+ /**
+ * Parses RDF data from the specified InputStream or Reader and adds it to the model.
+ *
+ * @param in The InputStream to read RDF data from.
+ */
+ void parse(InputStream in);
+
+ /**
+ * Parses RDF data from the specified InputStream or Reader and adds it to the model.
+ *
+ * @param in The InputStream to read RDF data from.
+ * @param baseURI The base URI for resolving relative URIs in the RDF data.
+ */
+ void parse(InputStream in, String baseURI);
+
+ /**
+ * Parses RDF data from the specified InputStream or Reader and adds it to the model.
+ *
+ * @param reader The Reader to read RDF data from.
+ */
+ void parse(Reader reader);
+
+ /**
+ * Parses RDF data from the specified InputStream or Reader and adds it to the model.
+ *
+ * @param reader The Reader to read RDF data from.
+ * @param baseURI The base URI for resolving relative URIs in the RDF data.
+ */
+ void parse(Reader reader, String baseURI);
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/parser/RDFParserFactory.java b/src/main/java/fr/inria/corese/core/next/api/parser/RDFParserFactory.java
new file mode 100644
index 000000000..68f7c16c1
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/parser/RDFParserFactory.java
@@ -0,0 +1,17 @@
+package fr.inria.corese.core.next.api.parser;
+
+import fr.inria.corese.core.next.api.Model;
+import fr.inria.corese.core.next.api.ValueFactory;
+
+public interface RDFParserFactory {
+
+ /**
+ * Creates a new RDF parser for the specified format and model.
+ *
+ * @param format The RDF format to use for parsing.
+ * @param model The model to which the parsed data will be added.
+ * @return A new instance of an RDF parser for the specified format and model.
+ */
+ RDFParser createRDFParser(RDFFormat format, Model model, ValueFactory factory);
+
+}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/exception/ParsingErrorException.java b/src/main/java/fr/inria/corese/core/next/impl/exception/ParsingErrorException.java
new file mode 100644
index 000000000..cc6bf4eee
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/impl/exception/ParsingErrorException.java
@@ -0,0 +1,18 @@
+package fr.inria.corese.core.next.impl.exception;
+
+public class ParsingErrorException extends RuntimeException {
+
+ private static final long serialVersionUID = -2053549958572141648L;
+
+ public ParsingErrorException(String message) {
+ super(message);
+ }
+
+ public ParsingErrorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ParsingErrorException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/exception/UnsupportedFileFormatException.java b/src/main/java/fr/inria/corese/core/next/impl/exception/UnsupportedFileFormatException.java
new file mode 100644
index 000000000..b44687d51
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/impl/exception/UnsupportedFileFormatException.java
@@ -0,0 +1,19 @@
+package fr.inria.corese.core.next.impl.exception;
+
+public class UnsupportedFileFormatException extends Exception {
+
+ private static final long serialVersionUID = 7963163989802143570L;
+
+ public UnsupportedFileFormatException(String message) {
+ super(message);
+ }
+
+ public UnsupportedFileFormatException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnsupportedFileFormatException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParser.java b/src/main/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParser.java
new file mode 100644
index 000000000..e2fb6439a
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParser.java
@@ -0,0 +1,121 @@
+package fr.inria.corese.core.next.impl.parser.jsonld;
+
+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;
+import fr.inria.corese.core.next.api.*;
+import fr.inria.corese.core.next.api.parser.RDFFormat;
+import fr.inria.corese.core.next.api.parser.RDFFormats;
+import fr.inria.corese.core.next.api.parser.RDFParser;
+import fr.inria.corese.core.next.impl.exception.ParsingErrorException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+public class JSONLDParser implements RDFParser {
+
+ private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(JSONLDParser.class);
+
+ private static final String jsonldjavadefaultGraphName = "@default";
+
+ private final Model model;
+ private final ValueFactory valueFactory;
+ private JsonLdOptions commonOptions = new JsonLdOptions();
+
+ public JSONLDParser(Model model, ValueFactory factory) {
+ this.model = model;
+ this.valueFactory = factory;
+ commonOptions.setCompactArrays(false);
+ commonOptions.setBase(null);
+ }
+
+ @Override
+ public RDFFormat getRDFFormat() {
+ return RDFFormats.JSON_LD;
+ }
+
+ private void parseFromJsonInput(Object input, String baseURI) {
+ try {
+ if(baseURI != null) {
+ commonOptions.setBase(baseURI);
+ }
+ RDFDataset output = (RDFDataset)JsonLdProcessor.toRDF(input, this.commonOptions);
+ for(String gName: output.graphNames()) {
+ for(RDFDataset.Quad q : output.getQuads(gName)) {
+ Resource subject = null;
+ if (q.getSubject().isIRI()) {
+ subject = valueFactory.createIRI(q.getSubject().getValue());
+ } else {
+ subject = valueFactory.createBNode(q.getSubject().getValue());
+ }
+
+ IRI predicate = valueFactory.createIRI(q.getPredicate().getValue());
+
+ Value object = null;
+ if (q.getObject().isIRI()) {
+ object = valueFactory.createIRI(q.getObject().getValue());
+ } else if (q.getObject().isBlankNode()) {
+ object = valueFactory.createBNode(q.getObject().getValue());
+ } else if(q.getObject().isLiteral()){
+ String objectDatatype = q.getObject().getDatatype();
+ String objectLanguage = q.getObject().getLanguage();
+ if(objectLanguage != null) {
+ object = valueFactory.createLiteral(q.getObject().getValue(), objectLanguage);
+ } else if(objectDatatype != null) {
+ object = valueFactory.createLiteral(q.getObject().getValue(), valueFactory.createIRI(objectDatatype));
+ } else {
+ object = valueFactory.createLiteral(q.getObject().getValue());
+ }
+ } else {
+ throw new ParsingErrorException("Unknown object type: " + q.getObject());
+ }
+
+ if(gName.equals(jsonldjavadefaultGraphName)) {
+ model.add(subject, predicate, object);
+ } else {
+ IRI graph = valueFactory.createIRI(gName);
+ model.add(subject, predicate, object, graph);
+ }
+ }
+ }
+ if(baseURI != null) {
+ commonOptions.setBase(null);
+ }
+ } catch (JsonLdError e) {
+ throw new ParsingErrorException(e);
+ }
+ }
+
+ @Override
+ public void parse(InputStream in) throws ParsingErrorException {
+ parse(in, null);
+ }
+
+ @Override
+ public void parse(InputStream in, String baseURI) throws ParsingErrorException {
+ try {
+ Object input = JsonUtils.fromInputStream(in);
+ parseFromJsonInput(input, baseURI);
+ } catch (IOException | JsonLdError e) {
+ throw new ParsingErrorException(e);
+ }
+ }
+
+ @Override
+ public void parse(Reader reader) throws ParsingErrorException {
+ parse(reader, null);
+ }
+
+ @Override
+ public void parse(Reader reader, String baseURI) {
+ try {
+ Object input = JsonUtils.fromReader(reader);
+ parseFromJsonInput(input, baseURI);
+ } catch (IOException | JsonLdError e) {
+ throw new ParsingErrorException(e);
+ }
+ }
+}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParserFactory.java b/src/main/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParserFactory.java
new file mode 100644
index 000000000..d7eeae5b8
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParserFactory.java
@@ -0,0 +1,29 @@
+package fr.inria.corese.core.next.impl.parser.jsonld;
+
+import fr.inria.corese.core.next.api.Model;
+import fr.inria.corese.core.next.api.ValueFactory;
+import fr.inria.corese.core.next.api.parser.RDFFormat;
+import fr.inria.corese.core.next.api.parser.RDFFormats;
+import fr.inria.corese.core.next.api.parser.RDFParser;
+import fr.inria.corese.core.next.api.parser.RDFParserFactory;
+
+public class JSONLDParserFactory implements RDFParserFactory {
+
+ private static final JSONLDParserFactory INSTANCE = new JSONLDParserFactory();
+
+ public static JSONLDParserFactory getInstance() {
+ return INSTANCE;
+ }
+
+ private JSONLDParserFactory() {
+
+ }
+
+ @Override
+ public RDFParser createRDFParser(RDFFormat format, Model model, ValueFactory factory) {
+ if(format == RDFFormats.JSON_LD) {
+ return new JSONLDParser(model, factory);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index da52e9920..999115852 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -13,6 +13,8 @@
requires org.json; //
requires org.apache.commons.lang3;
requires org.slf4j;
+ requires jsonld.java;
+
exports fr.inria.corese.core.load;
exports fr.inria.corese.core.load.result;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParserTest.java b/src/test/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParserTest.java
new file mode 100644
index 000000000..42894cc47
--- /dev/null
+++ b/src/test/java/fr/inria/corese/core/next/impl/parser/jsonld/JSONLDParserTest.java
@@ -0,0 +1,288 @@
+package fr.inria.corese.core.next.impl.parser.jsonld;
+
+import fr.inria.corese.core.next.api.BNode;
+import fr.inria.corese.core.next.api.IRI;
+import fr.inria.corese.core.next.api.Literal;
+import fr.inria.corese.core.next.api.Statement;
+import fr.inria.corese.core.next.api.parser.RDFFormats;
+import fr.inria.corese.core.next.api.parser.RDFParser;
+import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
+import fr.inria.corese.core.next.impl.temp.CoreseModel;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JSONLDParserTest {
+
+ @Test
+ void testGetRDFFormat() {
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, new CoreseModel(), new CoreseAdaptedValueFactory());
+ assertEquals(RDFFormats.JSON_LD, parser.getRDFFormat());
+ }
+
+ /**
+ * Test method for {@link JSONLDParser#parse(java.io.InputStream)}. No relative IRIs in this test.
+ */
+ @Test
+ public void testParseInputStream() {
+ // taken from https://www.w3.org/TR/json-ld-api/#object-to-rdf-conversion
+ String sampleJsonLD = """
+ {
+ "@context": {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "knows": "http://xmlns.com/foaf/0.1/knows"
+ },
+ "@id": "http://me.markus-lanthaler.com/",
+ "name": "Markus Lanthaler",
+ "knows": [
+ {
+ "name": "Dave Longley"
+ }
+ ]
+ }
+ """;
+ CoreseModel model = new CoreseModel();
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, model, new CoreseAdaptedValueFactory());
+ parser.parse(new ByteArrayInputStream(sampleJsonLD.getBytes()));
+
+ assertEquals(3, model.size());
+ IRI subject = new CoreseAdaptedValueFactory().createIRI("http://me.markus-lanthaler.com/");
+ IRI namePredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/name");
+ IRI knowsPredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/knows");
+ Literal nameMarkusObject = new CoreseAdaptedValueFactory().createLiteral("Markus Lanthaler");
+ Literal nameDaveObject = new CoreseAdaptedValueFactory().createLiteral("Dave Longley");
+ Statement daveNameStatement = new CoreseAdaptedValueFactory().createStatement(subject, namePredicate, nameMarkusObject);
+
+ assertTrue(model.contains(daveNameStatement));
+ assertTrue(model.contains(subject, knowsPredicate, null));
+ assertTrue(model.contains(null, namePredicate, nameDaveObject));
+ }
+
+ /**
+ * Test method for {@link JSONLDParser#parse(java.io.InputStream, java.lang.String)}. A relative IRI is used in this test.
+ */
+ @Test
+ public void testParseInputStreamString() {
+ // taken from https://www.w3.org/TR/json-ld-api/#object-to-rdf-conversion
+ String sampleJsonLD = """
+ {
+ "@context": {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "knows": "http://xmlns.com/foaf/0.1/knows"
+ },
+ "@id": "",
+ "name": "Markus Lanthaler",
+ "knows": [
+ {
+ "name": "Dave Longley"
+ }
+ ]
+ }
+ """;
+ CoreseModel model = new CoreseModel();
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, model, new CoreseAdaptedValueFactory());
+ parser.parse(new ByteArrayInputStream(sampleJsonLD.getBytes()), "http://me.markus-lanthaler.com/");
+
+ assertEquals(3, model.size());
+ IRI subject = new CoreseAdaptedValueFactory().createIRI("http://me.markus-lanthaler.com/");
+ IRI namePredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/name");
+ IRI knowsPredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/knows");
+ Literal nameMarkusObject = new CoreseAdaptedValueFactory().createLiteral("Markus Lanthaler");
+ Literal nameDaveObject = new CoreseAdaptedValueFactory().createLiteral("Dave Longley");
+ Statement daveNameStatement = new CoreseAdaptedValueFactory().createStatement(subject, namePredicate, nameMarkusObject);
+
+ assertTrue(model.contains(daveNameStatement));
+ assertTrue(model.contains(subject, knowsPredicate, null));
+ assertTrue(model.contains(null, namePredicate, nameDaveObject));
+ }
+
+ /**
+ * Test of {@link JSONLDParser#parse(java.io.Reader, java.lang.String)}, of class JSONLDParser. No relative IRIs are used in this test.
+ */
+ @Test
+ public void testParseReader() {
+ // taken from https://www.w3.org/TR/json-ld-api/#object-to-rdf-conversion
+ String sampleJsonLD = """
+ {
+ "@context": {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "knows": "http://xmlns.com/foaf/0.1/knows"
+ },
+ "@id": "http://me.markus-lanthaler.com/",
+ "name": "Markus Lanthaler",
+ "knows": [
+ {
+ "name": "Dave Longley"
+ }
+ ]
+ }
+ """;
+ CoreseModel model = new CoreseModel();
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, model, new CoreseAdaptedValueFactory());
+ parser.parse(new StringReader(sampleJsonLD));
+
+ assertEquals(3, model.size());
+ IRI subject = new CoreseAdaptedValueFactory().createIRI("http://me.markus-lanthaler.com/");
+ IRI namePredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/name");
+ IRI knowsPredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/knows");
+ Literal nameMarkusObject = new CoreseAdaptedValueFactory().createLiteral("Markus Lanthaler");
+ Literal nameDaveObject = new CoreseAdaptedValueFactory().createLiteral("Dave Longley");
+ Statement daveNameStatement = new CoreseAdaptedValueFactory().createStatement(subject, namePredicate, nameMarkusObject);
+
+ assertTrue(model.contains(daveNameStatement));
+ assertTrue(model.contains(subject, knowsPredicate, null));
+ assertTrue(model.contains(null, namePredicate, nameDaveObject));
+ }
+
+ /**
+ * Test of {@link JSONLDParser#parse(java.io.Reader, java.lang.String)}, of class JSONLDParser. A relative IRI is used in this test.
+ */
+ @Test
+ public void testParseReaderString() {
+ // taken from https://www.w3.org/TR/json-ld-api/#object-to-rdf-conversion
+ String sampleJsonLD = """
+ {
+ "@context": {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "knows": "http://xmlns.com/foaf/0.1/knows"
+ },
+ "@id": "",
+ "name": "Markus Lanthaler",
+ "knows": [
+ {
+ "name": "Dave Longley"
+ }
+ ]
+ }
+ """;
+ CoreseModel model = new CoreseModel();
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, model, new CoreseAdaptedValueFactory());
+ parser.parse(new StringReader(sampleJsonLD), "http://me.markus-lanthaler.com/");
+
+ assertEquals(3, model.size());
+ IRI subject = new CoreseAdaptedValueFactory().createIRI("http://me.markus-lanthaler.com/");
+ IRI namePredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/name");
+ IRI knowsPredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/knows");
+ Literal nameMarkusObject = new CoreseAdaptedValueFactory().createLiteral("Markus Lanthaler");
+ Literal nameDaveObject = new CoreseAdaptedValueFactory().createLiteral("Dave Longley");
+ Statement daveNameStatement = new CoreseAdaptedValueFactory().createStatement(subject, namePredicate, nameMarkusObject);
+
+ assertTrue(model.contains(daveNameStatement));
+ assertTrue(model.contains(subject, knowsPredicate, null));
+ assertTrue(model.contains(null, namePredicate, nameDaveObject));
+ }
+
+ /**
+ * Test parsing JSON-LD with blank nodes.
+ */
+ @Test
+ public void testParseJsonLDWithBlankNodes() {
+ String sampleJsonLD = """
+ {
+ "@context": {
+ "foaf": "http://xmlns.com/foaf/0.1/"
+ },
+
+ "@graph":
+ [
+ {
+ "@id": "_:b0",
+ "foaf:knows": {"@id": "_:b1"}
+ },
+
+ {
+ "@id": "_:b1",
+ "foaf:knows": {"@id": "_:b0"}
+ }
+ ]
+ }
+
+ """;
+ CoreseModel model = new CoreseModel();
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, model, new CoreseAdaptedValueFactory());
+ parser.parse(new StringReader(sampleJsonLD));
+
+ assertEquals(2, model.size());
+ BNode b0 = new CoreseAdaptedValueFactory().createBNode("b0");
+ BNode b1 = new CoreseAdaptedValueFactory().createBNode("b1");
+ IRI knowsPredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/knows");
+ assertTrue(model.contains(b0, knowsPredicate, b1));
+ assertTrue(model.contains(b1, knowsPredicate, b0));
+ }
+
+ @Test
+ public void testParseJSONLDWithGraphs() {
+ // Taken from https://www.w3.org/TR/json-ld11/#named-graphs
+ String sampleJsonLD = """
+ {
+ "@context": {
+ "generatedAt": {
+ "@id": "http://www.w3.org/ns/prov#generatedAtTime"
+ },
+ "Person": "http://xmlns.com/foaf/0.1/Person",
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "knows": {"@id": "http://xmlns.com/foaf/0.1/knows", "@type": "@id"}
+ },
+ "@id": "http://example.org/foaf-graph",
+ "generatedAt": {
+ "@value": "2012-04-09T00:00:00",
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
+ },
+ "@graph": [
+ {
+ "@id": "http://manu.sporny.org/about#manu",
+ "@type": "Person",
+ "name": "Manu Sporny",
+ "knows": "https://greggkellogg.net/foaf#me"
+ }, {
+ "@id": "https://greggkellogg.net/foaf#me",
+ "@type": "Person",
+ "name": "Gregg Kellogg",
+ "knows": "http://manu.sporny.org/about#manu"
+ }
+ ]
+ }
+ """;
+
+ CoreseModel model = new CoreseModel();
+ RDFParser parser = JSONLDParserFactory.getInstance().createRDFParser(RDFFormats.JSON_LD, model, new CoreseAdaptedValueFactory());
+ parser.parse(new StringReader(sampleJsonLD));
+
+ assertEquals(7, model.size());
+ IRI graphIRI = new CoreseAdaptedValueFactory().createIRI("http://example.org/foaf-graph");
+ IRI generatedAt = new CoreseAdaptedValueFactory().createIRI("http://www.w3.org/ns/prov#generatedAtTime");
+ IRI datetimeDatatype = new CoreseAdaptedValueFactory().createIRI("http://www.w3.org/2001/XMLSchema#dateTime");
+ Literal generatedAtValue = new CoreseAdaptedValueFactory().createLiteral("2012-04-09T00:00:00", datetimeDatatype) ;
+ IRI manuIRI = new CoreseAdaptedValueFactory().createIRI("http://manu.sporny.org/about#manu");
+ Literal manuName = new CoreseAdaptedValueFactory().createLiteral("Manu Sporny");
+ IRI greggIRI = new CoreseAdaptedValueFactory().createIRI("https://greggkellogg.net/foaf#me");
+ Literal greggName = new CoreseAdaptedValueFactory().createLiteral("Gregg Kellogg");
+ IRI typeIRI = new CoreseAdaptedValueFactory().createIRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
+ IRI knowsPredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/knows");
+ IRI personType = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/Person");
+ IRI namePredicate = new CoreseAdaptedValueFactory().createIRI("http://xmlns.com/foaf/0.1/name");
+
+
+ // {
+ // a foaf:Person;
+ assertTrue(model.contains(manuIRI, typeIRI, personType, graphIRI));
+ // foaf:name "Manu Sporny";
+ assertTrue(model.contains(manuIRI, namePredicate, manuName, graphIRI));
+ // foaf:knows .
+ assertTrue(model.contains(manuIRI, knowsPredicate, greggIRI, graphIRI));
+ //
+ // a foaf:Person;
+ assertTrue(model.contains(greggIRI, typeIRI, personType, graphIRI));
+ // foaf:name "Gregg Kellogg";
+ assertTrue(model.contains(greggIRI, namePredicate, greggName, graphIRI));
+ // foaf:knows .
+ assertTrue(model.contains(greggIRI, knowsPredicate, manuIRI, graphIRI));
+ //}
+ // prov:generatedAtTime "2012-04-09T00:00:00"^^xsd:dateTime .
+ assertTrue(model.contains(graphIRI, generatedAt, generatedAtValue));
+ }
+}