From 894fa5675871073ff7959c36155dc92a49bd0bd6 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Fri, 14 Mar 2014 15:39:25 +0100 Subject: [PATCH 001/440] Avoid exception on @context with default @language and unmapped key Fix NullPointerException occurring when compacting a document using a @context with a default @language that does not explicitly map a key that appears in the document (see included test case). --- .../src/main/java/com/github/jsonldjava/core/Context.java | 3 ++- .../resources/json-ld.org/compact-0072-context.jsonld | 5 +++++ .../src/test/resources/json-ld.org/compact-0072-in.jsonld | 3 +++ .../test/resources/json-ld.org/compact-0072-out.jsonld | 8 ++++++++ .../test/resources/json-ld.org/compact-manifest.jsonld | 8 ++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/json-ld.org/compact-0072-context.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0072-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0072-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 29fe39dc..5c4251e3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -111,7 +111,8 @@ public Object compactValue(String activeProperty, Map value) { } // 7) if (numberMembers == 1 - && (!(valueValue instanceof String) || !this.containsKey("@language") || (getTermDefinition( + && (!(valueValue instanceof String) || !this.containsKey("@language") || + (termDefinitions.containsKey(activeProperty) && getTermDefinition( activeProperty).containsKey("@language") && languageMapping == null))) { return valueValue; } diff --git a/core/src/test/resources/json-ld.org/compact-0072-context.jsonld b/core/src/test/resources/json-ld.org/compact-0072-context.jsonld new file mode 100644 index 00000000..0026dacf --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0072-context.jsonld @@ -0,0 +1,5 @@ +{ + "@context": { + "@language": "en" + } +} diff --git a/core/src/test/resources/json-ld.org/compact-0072-in.jsonld b/core/src/test/resources/json-ld.org/compact-0072-in.jsonld new file mode 100644 index 00000000..35f7cdd3 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0072-in.jsonld @@ -0,0 +1,3 @@ +{ + "http://example.com/foo": "foo-value" +} diff --git a/core/src/test/resources/json-ld.org/compact-0072-out.jsonld b/core/src/test/resources/json-ld.org/compact-0072-out.jsonld new file mode 100644 index 00000000..298459cf --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0072-out.jsonld @@ -0,0 +1,8 @@ +{ + "http://example.com/foo": { + "@value": "foo-value" + }, + "@context": { + "@language": "en" + } +} diff --git a/core/src/test/resources/json-ld.org/compact-manifest.jsonld b/core/src/test/resources/json-ld.org/compact-manifest.jsonld index e882e34a..ebf65343 100644 --- a/core/src/test/resources/json-ld.org/compact-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/compact-manifest.jsonld @@ -577,6 +577,14 @@ "input": "compact-0071-in.jsonld", "context": "compact-0071-context.jsonld", "expect": "compact-0071-out.jsonld" + }, { + "@id": "#t0072", + "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], + "name": "@context has default @language", + "purpose": "Default @language in @context also works when a key is not explicitly mapped in the @context", + "input": "compact-0072-in.jsonld", + "context": "compact-0072-context.jsonld", + "expect": "compact-0072-out.jsonld" } ] } From 33b86a777e98edd802f01a142ffe9e854ffa078e Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Mon, 17 Mar 2014 12:06:36 +0100 Subject: [PATCH 002/440] Update test manifest to conform to upstream test suite See https://github.com/json-ld/json-ld.org/pull/335 --- core/src/test/resources/json-ld.org/compact-manifest.jsonld | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/test/resources/json-ld.org/compact-manifest.jsonld b/core/src/test/resources/json-ld.org/compact-manifest.jsonld index ebf65343..cddd412e 100644 --- a/core/src/test/resources/json-ld.org/compact-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/compact-manifest.jsonld @@ -572,7 +572,7 @@ }, { "@id": "#t0071", "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], - "name": "input has multiple @contexts, output has one", + "name": "Input has multiple @contexts, output has one", "purpose": "Expanding input with multiple @contexts and compacting with just one doesn't output undefined properties", "input": "compact-0071-in.jsonld", "context": "compact-0071-context.jsonld", @@ -580,8 +580,8 @@ }, { "@id": "#t0072", "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], - "name": "@context has default @language", - "purpose": "Default @language in @context also works when a key is not explicitly mapped in the @context", + "name": "Default language and unmapped properties", + "purpose": "Ensure that the default language is handled correctly for unmapped properties", "input": "compact-0072-in.jsonld", "context": "compact-0072-context.jsonld", "expect": "compact-0072-out.jsonld" From 4bf95d796d00421d803a8cb4a4cef63b5117a08e Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 14:05:14 +0000 Subject: [PATCH 003/440] JsonUtils.fromURL() delegates to DocumentLoader.fromURL() --- .../github/jsonldjava/utils/JsonUtils.java | 91 +------------------ 1 file changed, 3 insertions(+), 88 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 5cdb1bc3..32643da6 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -11,16 +11,7 @@ import java.util.List; import java.util.Map; -import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.RequestAcceptEncoding; -import org.apache.http.client.protocol.ResponseContentEncoding; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.client.SystemDefaultHttpClient; -import org.apache.http.impl.client.cache.CacheConfig; -import org.apache.http.impl.client.cache.CachingHttpClient; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerationException; @@ -29,6 +20,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.jsonldjava.core.DocumentLoader; import com.github.jsonldjava.core.JsonLdApi; import com.github.jsonldjava.core.JsonLdProcessor; @@ -46,6 +38,7 @@ public class JsonUtils { protected static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); private static final JsonFactory JSON_FACTORY = new JsonFactory(JSON_MAPPER); + private static DocumentLoader DOCUMENT_LOADER = new DocumentLoader(); static { // Disable default Jackson behaviour to close @@ -58,8 +51,6 @@ public class JsonUtils { JSON_FACTORY.disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES); } - private static volatile HttpClient httpClient; - /** * Parses a JSON-LD document from the given {@link InputStream} to an object * that can be used as input for the {@link JsonLdApi} and @@ -167,83 +158,7 @@ public static Object fromString(String jsonString) throws JsonParseException, IO * If there was an IO error during parsing. */ public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { - - InputStream in = null; - try { - in = openStreamFromURL(url); - return fromInputStream(in); - } finally { - if (in != null) { - in.close(); - } - } - } - - /** - * Returns the internal {@link HttpClient} object used to resolve URLs. - * - * @return The {@link HttpClient} we use to resolve URLs. - */ - protected static HttpClient getHttpClient() { - if (httpClient == null) { - synchronized (JsonUtils.class) { - if (httpClient == null) { - // Uses Apache SystemDefaultHttpClient rather than - // DefaultHttpClient, thus the normal proxy settings for the - // JVM will be used - - final DefaultHttpClient client = new SystemDefaultHttpClient(); - // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 - client.addRequestInterceptor(new RequestAcceptEncoding()); - client.addResponseInterceptor(new ResponseContentEncoding()); - final CacheConfig cacheConfig = new CacheConfig(); - cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB - cacheConfig.setMaxCacheEntries(1000); - // and allow caching - httpClient = new CachingHttpClient(client, cacheConfig); - } - } - } - return httpClient; - } - - /** - * Opens an {@link InputStream} for the given {@link JsonLdUrl}, including - * support for http and https URLs that are requested using Content - * Negotiation with application/ld+json as the preferred content type. - * - * @param url - * The JsonLdUrl identifying the source. - * @return An InputStream containing the contents of the source. - * @throws IOException - * If there was an error resolving the JsonLdUrl. - */ - protected static InputStream openStreamFromURL(java.net.URL url) throws IOException { - final String protocol = url.getProtocol(); - if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { - // Can't use the HTTP client for those! - // Fallback to Java's built-in JsonLdUrl handler. No need for - // Accept headers as it's likely to be file: or jar: - return url.openStream(); - } - final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to application/json - // or whatever is available - request.addHeader("Accept", ACCEPT_HEADER); - - final HttpResponse response = getHttpClient().execute(request); - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - return response.getEntity().getContent(); - } - - protected static void setHttpClient(HttpClient nextHttpClient) { - synchronized (JsonUtils.class) { - httpClient = nextHttpClient; - } + return DOCUMENT_LOADER.fromURL(url); } /** From 5fdb60ce6c01d7e2bd70a59dc8739e1081c8a574 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 14:05:36 +0000 Subject: [PATCH 004/440] unused private method resolve() removed --- .../github/jsonldjava/core/JsonLdUtils.java | 79 ------------------- 1 file changed, 79 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 33c3686c..4150a721 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -761,85 +761,6 @@ static boolean isBlankNode(Object v) { return false; } - /** - * Resolves external @context URLs using the given JsonLdUrl resolver. Each - * instance of @context in the input that refers to a JsonLdUrl will be - * replaced with the JSON @context found at that JsonLdUrl. - * - * @param input - * the JSON-LD input with possible contexts. - * @param resolver - * (url, callback(err, jsonCtx)) the JsonLdUrl resolver to use. - * @param callback - * (err, input) called once the operation completes. - * @throws JsonLdError - */ - static void resolveContextUrls(Object input) throws JsonLdError { - resolve(input, new LinkedHashMap()); - } - - private static void resolve(Object input, Map cycles) throws JsonLdError { - final Pattern regex = Pattern - .compile("(http|https)://(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(/|/([\\w#!:.?+=&%@!\\-/]))?"); - - if (cycles.size() > MAX_CONTEXT_URLS) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); - } - - // for tracking the URLs to resolve - final Map urls = new LinkedHashMap(); - - // find all URLs in the given input - if (!findContextUrls(input, urls, false)) { - // finished - findContextUrls(input, urls, true); - } - - // queue all unresolved URLs - final List queue = new ArrayList(); - for (final String url : urls.keySet()) { - if (Boolean.FALSE.equals(urls.get(url))) { - // validate JsonLdUrl - if (!regex.matcher(url).matches()) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); - } - queue.add(url); - } - } - - // resolve URLs in queue - int count = queue.size(); - for (final String url : queue) { - // check for context JsonLdUrl cycle - if (cycles.containsKey(url)) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); - } - final Map _cycles = (Map) clone(cycles); - _cycles.put(url, Boolean.TRUE); - - try { - Map ctx = (Map) DocumentLoader - .fromURL(new java.net.URL(url)); - if (!ctx.containsKey("@context")) { - ctx = new LinkedHashMap(); - ctx.put("@context", new LinkedHashMap()); - } - resolve(ctx, _cycles); - urls.put(url, ctx.get("@context")); - count -= 1; - if (count == 0) { - findContextUrls(input, urls, true); - } - } catch (final JsonParseException e) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); - } catch (final MalformedURLException e) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); - } catch (final IOException e) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); - } - } - - } /** * Finds all @context URLs in the given JSON-LD input. From 734327fc392faf4fa9e3a982f8ac387a83c42b1b Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 14:06:57 +0000 Subject: [PATCH 005/440] DocumentLoader methods made non-static .. so that it makes sense to provide a DocumentLoader to JsonLdOptions - e.g. one can customize http client just for one parsing session. WARNIG: This will break backwards-compatibility with v0.3 --- .../jsonldjava/core/DocumentLoader.java | 37 +++++++++---------- .../jsonldjava/utils/JsonUtilsTest.java | 22 ++++++----- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index cfe6557d..28aa5ebe 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -1,10 +1,11 @@ package com.github.jsonldjava.core; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.MappingJsonFactory; -import com.github.jsonldjava.utils.JsonUtils; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.Map; + import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; @@ -16,11 +17,10 @@ import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClient; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.List; -import java.util.Map; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; public class DocumentLoader { @@ -38,7 +38,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { * An HTTP Accept header that prefers JSONLD. */ public static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; - private static volatile HttpClient httpClient; + private volatile HttpClient httpClient; /** * Returns a Map, List, or String containing the contents of the JSON @@ -53,7 +53,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { * @throws IOException * If there was an error resolving the resource. */ - public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { + public Object fromURL(java.net.URL url) throws JsonParseException, IOException { final MappingJsonFactory jsonFactory = new MappingJsonFactory(); final InputStream in = openStreamFromURL(url); @@ -90,7 +90,7 @@ public static Object fromURL(java.net.URL url) throws JsonParseException, IOExce * @throws IOException * If there was an error resolving the {@link java.net.URL}. */ - public static InputStream openStreamFromURL(java.net.URL url) throws IOException { + public InputStream openStreamFromURL(java.net.URL url) throws IOException { final String protocol = url.getProtocol(); if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { // Can't use the HTTP client for those! @@ -111,10 +111,10 @@ public static InputStream openStreamFromURL(java.net.URL url) throws IOException return response.getEntity().getContent(); } - public static HttpClient getHttpClient() { + public HttpClient getHttpClient() { HttpClient result = httpClient; if (result == null) { - synchronized (JsonUtils.class) { + synchronized (this) { result = httpClient; if (result == null) { // Uses Apache SystemDefaultHttpClient rather than @@ -131,6 +131,7 @@ public static HttpClient getHttpClient() { cacheConfig.setMaxCacheEntries(1000); // and allow caching httpClient = new CachingHttpClient(client, cacheConfig); + result = httpClient; } } @@ -138,9 +139,7 @@ public static HttpClient getHttpClient() { return result; } - public static void setHttpClient(HttpClient nextHttpClient) { - synchronized (JsonUtils.class) { - httpClient = nextHttpClient; - } + public synchronized void setHttpClient(HttpClient nextHttpClient) { + httpClient = nextHttpClient; } } diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 50d7fe9a..bce18d4c 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -35,6 +35,8 @@ import com.github.jsonldjava.core.DocumentLoader; public class JsonUtilsTest { + + DocumentLoader documentLoader = new DocumentLoader(); @SuppressWarnings("unchecked") @Test @@ -65,7 +67,7 @@ public void fromStringTest() { public void fromURLTest0001() throws Exception { final URL contexttest = getClass().getResource("/custom/contexttest-0001.jsonld"); assertNotNull(contexttest); - final Object context = DocumentLoader.fromURL(contexttest); + final Object context = documentLoader.fromURL(contexttest); assertTrue(context instanceof Map); final Map contextMap = (Map) context; assertEquals(1, contextMap.size()); @@ -81,7 +83,7 @@ public void fromURLTest0001() throws Exception { public void fromURLTest0002() throws Exception { final URL contexttest = getClass().getResource("/custom/contexttest-0002.jsonld"); assertNotNull(contexttest); - final Object context = DocumentLoader.fromURL(contexttest); + final Object context = documentLoader.fromURL(contexttest); assertTrue(context instanceof List); final List> contextList = (List>) context; @@ -105,7 +107,7 @@ public void fromURLTest0002() throws Exception { @Test public void fromURLredirectHTTPSToHTTP() throws Exception { final URL url = new URL("https://w3id.org/bundle/context"); - final Object context = DocumentLoader.fromURL(url); + final Object context = documentLoader.fromURL(url); // Should not fail because of // http://stackoverflow.com/questions/1884230/java-doesnt-follow-redirect-in-urlconnection // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571 @@ -117,7 +119,7 @@ public void fromURLredirectHTTPSToHTTP() throws Exception { @Test public void fromURLredirect() throws Exception { final URL url = new URL("http://purl.org/wf4ever/ro-bundle/context.json"); - final Object context = DocumentLoader.fromURL(url); + final Object context = documentLoader.fromURL(url); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); } @@ -125,11 +127,11 @@ public void fromURLredirect() throws Exception { @Test public void fromURLCache() throws Exception { final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); - DocumentLoader.fromURL(url); + documentLoader.fromURL(url); // Now try to get it again and ensure it is // cached - final HttpClient client = new CachingHttpClient(DocumentLoader.getHttpClient()); + final HttpClient client = new CachingHttpClient(documentLoader.getHttpClient()); final HttpUriRequest get = new HttpGet(url.toURI()); get.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); final HttpContext localContext = new BasicHttpContext(); @@ -165,7 +167,7 @@ public InputStream getInputStream() throws IOException { }; final URL url = new URL(null, "jsonldtest:context", handler); assertEquals(0, requests.get()); - final Object context = DocumentLoader.fromURL(url); + final Object context = documentLoader.fromURL(url); assertEquals(1, requests.get()); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); @@ -192,12 +194,12 @@ public void fromURLAcceptHeaders() throws Exception { final URL url = new URL("http://example.com/fake-jsonld-test"); final ArgumentCaptor httpRequest = ArgumentCaptor .forClass(HttpUriRequest.class); - DocumentLoader.setHttpClient(fakeHttpClient(httpRequest)); + documentLoader.setHttpClient(fakeHttpClient(httpRequest)); try { - final Object context = DocumentLoader.fromURL(url); + final Object context = documentLoader.fromURL(url); assertTrue(context instanceof Map); } finally { - DocumentLoader.setHttpClient(null); + documentLoader.setHttpClient(null); } assertEquals(1, httpRequest.getAllValues().size()); final HttpUriRequest req = httpRequest.getValue(); From e78bbb518908a4aa8969fd2bde5d7d91b8e43b2f Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 14:11:36 +0000 Subject: [PATCH 006/440] Moved out DocumentLoaderTests from JsonUtilsTest --- .../jsonldjava/core/DocumentLoaderTest.java | 213 ++++++++++++++++++ .../jsonldjava/utils/JsonUtilsTest.java | 204 ----------------- 2 files changed, 213 insertions(+), 204 deletions(-) create mode 100644 core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java new file mode 100644 index 00000000..182e837c --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -0,0 +1,213 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.cache.CacheResponseStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.cache.CachingHttpClient; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.EntityUtils; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +public class DocumentLoaderTest { + + DocumentLoader documentLoader = new DocumentLoader(); + + @SuppressWarnings("unchecked") + @Test + public void fromURLTest0001() throws Exception { + final URL contexttest = getClass().getResource("/custom/contexttest-0001.jsonld"); + assertNotNull(contexttest); + final Object context = documentLoader.fromURL(contexttest); + assertTrue(context instanceof Map); + final Map contextMap = (Map) context; + assertEquals(1, contextMap.size()); + final Map cont = (Map) contextMap.get("@context"); + assertEquals(3, cont.size()); + assertEquals("http://example.org/", cont.get("ex")); + final Map term1 = (Map) cont.get("term1"); + assertEquals("ex:term1", term1.get("@id")); + } + + @SuppressWarnings("unchecked") + @Test + public void fromURLTest0002() throws Exception { + final URL contexttest = getClass().getResource("/custom/contexttest-0002.jsonld"); + assertNotNull(contexttest); + final Object context = documentLoader.fromURL(contexttest); + assertTrue(context instanceof List); + final List> contextList = (List>) context; + + final Map contextMap1 = contextList.get(0); + assertEquals(1, contextMap1.size()); + final Map cont1 = (Map) contextMap1.get("@context"); + assertEquals(2, cont1.size()); + assertEquals("http://example.org/", cont1.get("ex")); + final Map term1 = (Map) cont1.get("term1"); + assertEquals("ex:term1", term1.get("@id")); + + final Map contextMap2 = contextList.get(1); + assertEquals(1, contextMap2.size()); + final Map cont2 = (Map) contextMap2.get("@context"); + assertEquals(1, cont2.size()); + final Map term2 = (Map) cont2.get("term2"); + assertEquals("ex:term2", term2.get("@id")); + } + + // @Ignore("Integration test") + @Test + public void fromURLredirectHTTPSToHTTP() throws Exception { + final URL url = new URL("https://w3id.org/bundle/context"); + final Object context = documentLoader.fromURL(url); + // Should not fail because of + // http://stackoverflow.com/questions/1884230/java-doesnt-follow-redirect-in-urlconnection + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571 + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + + // @Ignore("Integration test") + @Test + public void fromURLredirect() throws Exception { + final URL url = new URL("http://purl.org/wf4ever/ro-bundle/context.json"); + final Object context = documentLoader.fromURL(url); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + + @Test + public void fromURLCache() throws Exception { + final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); + documentLoader.fromURL(url); + + // Now try to get it again and ensure it is + // cached + final HttpClient client = new CachingHttpClient(documentLoader.getHttpClient()); + final HttpUriRequest get = new HttpGet(url.toURI()); + get.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); + final HttpContext localContext = new BasicHttpContext(); + final HttpResponse respo = client.execute(get, localContext); + EntityUtils.consume(respo.getEntity()); + + // Check cache status + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/caching.html + final CacheResponseStatus responseStatus = (CacheResponseStatus) localContext + .getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS); + assertFalse(CacheResponseStatus.CACHE_MISS.equals(responseStatus)); + } + + @Test + public void fromURLCustomHandler() throws Exception { + final AtomicInteger requests = new AtomicInteger(); + final URLStreamHandler handler = new URLStreamHandler() { + @Override + protected URLConnection openConnection(URL u) throws IOException { + return new URLConnection(u) { + @Override + public void connect() throws IOException { + return; + } + + @Override + public InputStream getInputStream() throws IOException { + requests.incrementAndGet(); + return getClass().getResourceAsStream("/custom/contexttest-0001.jsonld"); + } + }; + } + }; + final URL url = new URL(null, "jsonldtest:context", handler); + assertEquals(0, requests.get()); + final Object context = documentLoader.fromURL(url); + assertEquals(1, requests.get()); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + + protected HttpClient fakeHttpClient(ArgumentCaptor httpRequest) + throws IllegalStateException, IOException { + final HttpClient httpClient = mock(HttpClient.class); + final HttpResponse fakeResponse = mock(HttpResponse.class); + final StatusLine statusCode = mock(StatusLine.class); + when(statusCode.getStatusCode()).thenReturn(200); + when(fakeResponse.getStatusLine()).thenReturn(statusCode); + final HttpEntity entity = mock(HttpEntity.class); + when(entity.getContent()).thenReturn( + DocumentLoaderTest.class.getResourceAsStream("/custom/contexttest-0001.jsonld")); + when(fakeResponse.getEntity()).thenReturn(entity); + when(httpClient.execute(httpRequest.capture())).thenReturn(fakeResponse); + return httpClient; + } + + @Test + public void fromURLAcceptHeaders() throws Exception { + + final URL url = new URL("http://example.com/fake-jsonld-test"); + final ArgumentCaptor httpRequest = ArgumentCaptor + .forClass(HttpUriRequest.class); + documentLoader.setHttpClient(fakeHttpClient(httpRequest)); + try { + final Object context = documentLoader.fromURL(url); + assertTrue(context instanceof Map); + } finally { + documentLoader.setHttpClient(null); + } + assertEquals(1, httpRequest.getAllValues().size()); + final HttpUriRequest req = httpRequest.getValue(); + assertEquals(url.toURI(), req.getURI()); + + final Header[] accept = req.getHeaders("Accept"); + assertEquals(1, accept.length); + assertEquals(DocumentLoader.ACCEPT_HEADER, accept[0].getValue()); + // Test that this header parses correctly + final HeaderElement[] elems = accept[0].getElements(); + assertEquals("application/ld+json", elems[0].getName()); + assertEquals(0, elems[0].getParameterCount()); + + assertEquals("application/json", elems[1].getName()); + assertEquals(1, elems[1].getParameterCount()); + assertEquals("0.9", elems[1].getParameterByName("q").getValue()); + + assertEquals("application/javascript", elems[2].getName()); + assertEquals(1, elems[2].getParameterCount()); + assertEquals("0.5", elems[2].getParameterByName("q").getValue()); + + assertEquals("text/javascript", elems[3].getName()); + assertEquals(1, elems[3].getParameterCount()); + assertEquals("0.5", elems[3].getParameterByName("q").getValue()); + + assertEquals("text/plain", elems[4].getName()); + assertEquals(1, elems[4].getParameterCount()); + assertEquals("0.2", elems[4].getParameterByName("q").getValue()); + + assertEquals("*/*", elems[5].getName()); + assertEquals(1, elems[5].getParameterCount()); + assertEquals("0.1", elems[5].getParameterByName("q").getValue()); + + assertEquals(6, elems.length); + } + +} diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index bce18d4c..ade23660 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -1,43 +1,13 @@ package com.github.jsonldjava.utils; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.StatusLine; -import org.apache.http.client.HttpClient; -import org.apache.http.client.cache.CacheResponseStatus; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.cache.CachingHttpClient; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; -import org.apache.http.util.EntityUtils; import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import com.github.jsonldjava.core.DocumentLoader; public class JsonUtilsTest { - DocumentLoader documentLoader = new DocumentLoader(); - @SuppressWarnings("unchecked") @Test public void fromStringTest() { @@ -62,178 +32,4 @@ public void fromStringTest() { } } - @SuppressWarnings("unchecked") - @Test - public void fromURLTest0001() throws Exception { - final URL contexttest = getClass().getResource("/custom/contexttest-0001.jsonld"); - assertNotNull(contexttest); - final Object context = documentLoader.fromURL(contexttest); - assertTrue(context instanceof Map); - final Map contextMap = (Map) context; - assertEquals(1, contextMap.size()); - final Map cont = (Map) contextMap.get("@context"); - assertEquals(3, cont.size()); - assertEquals("http://example.org/", cont.get("ex")); - final Map term1 = (Map) cont.get("term1"); - assertEquals("ex:term1", term1.get("@id")); - } - - @SuppressWarnings("unchecked") - @Test - public void fromURLTest0002() throws Exception { - final URL contexttest = getClass().getResource("/custom/contexttest-0002.jsonld"); - assertNotNull(contexttest); - final Object context = documentLoader.fromURL(contexttest); - assertTrue(context instanceof List); - final List> contextList = (List>) context; - - final Map contextMap1 = contextList.get(0); - assertEquals(1, contextMap1.size()); - final Map cont1 = (Map) contextMap1.get("@context"); - assertEquals(2, cont1.size()); - assertEquals("http://example.org/", cont1.get("ex")); - final Map term1 = (Map) cont1.get("term1"); - assertEquals("ex:term1", term1.get("@id")); - - final Map contextMap2 = contextList.get(1); - assertEquals(1, contextMap2.size()); - final Map cont2 = (Map) contextMap2.get("@context"); - assertEquals(1, cont2.size()); - final Map term2 = (Map) cont2.get("term2"); - assertEquals("ex:term2", term2.get("@id")); - } - - // @Ignore("Integration test") - @Test - public void fromURLredirectHTTPSToHTTP() throws Exception { - final URL url = new URL("https://w3id.org/bundle/context"); - final Object context = documentLoader.fromURL(url); - // Should not fail because of - // http://stackoverflow.com/questions/1884230/java-doesnt-follow-redirect-in-urlconnection - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571 - assertTrue(context instanceof Map); - assertFalse(((Map) context).isEmpty()); - } - - // @Ignore("Integration test") - @Test - public void fromURLredirect() throws Exception { - final URL url = new URL("http://purl.org/wf4ever/ro-bundle/context.json"); - final Object context = documentLoader.fromURL(url); - assertTrue(context instanceof Map); - assertFalse(((Map) context).isEmpty()); - } - - @Test - public void fromURLCache() throws Exception { - final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); - documentLoader.fromURL(url); - - // Now try to get it again and ensure it is - // cached - final HttpClient client = new CachingHttpClient(documentLoader.getHttpClient()); - final HttpUriRequest get = new HttpGet(url.toURI()); - get.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); - final HttpContext localContext = new BasicHttpContext(); - final HttpResponse respo = client.execute(get, localContext); - EntityUtils.consume(respo.getEntity()); - - // Check cache status - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/caching.html - final CacheResponseStatus responseStatus = (CacheResponseStatus) localContext - .getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS); - assertFalse(CacheResponseStatus.CACHE_MISS.equals(responseStatus)); - } - - @Test - public void fromURLCustomHandler() throws Exception { - final AtomicInteger requests = new AtomicInteger(); - final URLStreamHandler handler = new URLStreamHandler() { - @Override - protected URLConnection openConnection(URL u) throws IOException { - return new URLConnection(u) { - @Override - public void connect() throws IOException { - return; - } - - @Override - public InputStream getInputStream() throws IOException { - requests.incrementAndGet(); - return getClass().getResourceAsStream("/custom/contexttest-0001.jsonld"); - } - }; - } - }; - final URL url = new URL(null, "jsonldtest:context", handler); - assertEquals(0, requests.get()); - final Object context = documentLoader.fromURL(url); - assertEquals(1, requests.get()); - assertTrue(context instanceof Map); - assertFalse(((Map) context).isEmpty()); - } - - protected HttpClient fakeHttpClient(ArgumentCaptor httpRequest) - throws IllegalStateException, IOException { - final HttpClient httpClient = mock(HttpClient.class); - final HttpResponse fakeResponse = mock(HttpResponse.class); - final StatusLine statusCode = mock(StatusLine.class); - when(statusCode.getStatusCode()).thenReturn(200); - when(fakeResponse.getStatusLine()).thenReturn(statusCode); - final HttpEntity entity = mock(HttpEntity.class); - when(entity.getContent()).thenReturn( - JsonUtilsTest.class.getResourceAsStream("/custom/contexttest-0001.jsonld")); - when(fakeResponse.getEntity()).thenReturn(entity); - when(httpClient.execute(httpRequest.capture())).thenReturn(fakeResponse); - return httpClient; - } - - @Test - public void fromURLAcceptHeaders() throws Exception { - - final URL url = new URL("http://example.com/fake-jsonld-test"); - final ArgumentCaptor httpRequest = ArgumentCaptor - .forClass(HttpUriRequest.class); - documentLoader.setHttpClient(fakeHttpClient(httpRequest)); - try { - final Object context = documentLoader.fromURL(url); - assertTrue(context instanceof Map); - } finally { - documentLoader.setHttpClient(null); - } - assertEquals(1, httpRequest.getAllValues().size()); - final HttpUriRequest req = httpRequest.getValue(); - assertEquals(url.toURI(), req.getURI()); - - final Header[] accept = req.getHeaders("Accept"); - assertEquals(1, accept.length); - assertEquals(DocumentLoader.ACCEPT_HEADER, accept[0].getValue()); - // Test that this header parses correctly - final HeaderElement[] elems = accept[0].getElements(); - assertEquals("application/ld+json", elems[0].getName()); - assertEquals(0, elems[0].getParameterCount()); - - assertEquals("application/json", elems[1].getName()); - assertEquals(1, elems[1].getParameterCount()); - assertEquals("0.9", elems[1].getParameterByName("q").getValue()); - - assertEquals("application/javascript", elems[2].getName()); - assertEquals(1, elems[2].getParameterCount()); - assertEquals("0.5", elems[2].getParameterByName("q").getValue()); - - assertEquals("text/javascript", elems[3].getName()); - assertEquals(1, elems[3].getParameterCount()); - assertEquals("0.5", elems[3].getParameterByName("q").getValue()); - - assertEquals("text/plain", elems[4].getName()); - assertEquals(1, elems[4].getParameterCount()); - assertEquals("0.2", elems[4].getParameterByName("q").getValue()); - - assertEquals("*/*", elems[5].getName()); - assertEquals(1, elems[5].getParameterCount()); - assertEquals("0.1", elems[5].getParameterByName("q").getValue()); - - assertEquals(6, elems.length); - } - } From 72af0597a3385ddd04323ac4c4ff4a3fe3ddbc55 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 14:12:58 +0000 Subject: [PATCH 007/440] Use JAR cache --- core/pom.xml | 5 ++++ .../jsonldjava/core/DocumentLoader.java | 25 ++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 7447c84c..7bed4494 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -57,6 +57,11 @@ sesame-rio-nquads test + + uk.org.taverna.httpclientjarcache + httpclient-jarcache + 0.0.2-SNAPSHOT + diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 28aa5ebe..0d6461ca 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -1,10 +1,10 @@ package com.github.jsonldjava.core; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.List; -import java.util.Map; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; +import com.github.jsonldjava.utils.JsonUtils; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; @@ -17,10 +17,13 @@ import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClient; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.MappingJsonFactory; +import uk.org.taverna.httpclient.jarcache.JarCacheStorage; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.Map; public class DocumentLoader { @@ -132,6 +135,10 @@ public HttpClient getHttpClient() { // and allow caching httpClient = new CachingHttpClient(client, cacheConfig); + // Wrap with JAR cache + JarCacheStorage jarCache = new JarCacheStorage(); + httpClient = new CachingHttpClient(httpClient, jarCache, jarCache.getCacheConfig()); + result = httpClient; } } From 5843fe11a3fb2a090e12881c96a99a129d68058e Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 15:02:58 +0000 Subject: [PATCH 008/440] test jarcache, through thread contextloader --- .../jsonldjava/core/DocumentLoader.java | 25 ++++---- .../jsonldjava/core/DocumentLoaderTest.java | 60 ++++++++++++++++-- core/src/test/resources/jarcache.json | 8 +++ core/src/test/resources/nested.jar | Bin 0 -> 862 bytes 4 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 core/src/test/resources/jarcache.json create mode 100644 core/src/test/resources/nested.jar diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 0d6461ca..f89e0563 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -1,10 +1,10 @@ package com.github.jsonldjava.core; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.MappingJsonFactory; -import com.github.jsonldjava.utils.JsonUtils; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.Map; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; @@ -19,11 +19,10 @@ import uk.org.taverna.httpclient.jarcache.JarCacheStorage; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.List; -import java.util.Map; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; public class DocumentLoader { @@ -133,11 +132,11 @@ public HttpClient getHttpClient() { cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB cacheConfig.setMaxCacheEntries(1000); // and allow caching - httpClient = new CachingHttpClient(client, cacheConfig); + CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); - // Wrap with JAR cache + // Wrap again with JAR cache JarCacheStorage jarCache = new JarCacheStorage(); - httpClient = new CachingHttpClient(httpClient, jarCache, jarCache.getCacheConfig()); + httpClient = new CachingHttpClient(cachingClient, jarCache, jarCache.getCacheConfig()); result = httpClient; } diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 182e837c..32bd672a 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -1,21 +1,20 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.net.URLClassLoader; import java.net.URLConnection; import java.net.URLStreamHandler; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; @@ -25,13 +24,17 @@ import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.impl.client.cache.CachingHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; +import org.junit.After; import org.junit.Test; import org.mockito.ArgumentCaptor; +import uk.org.taverna.httpclient.jarcache.JarCacheStorage; + public class DocumentLoaderTest { DocumentLoader documentLoader = new DocumentLoader(); @@ -209,5 +212,54 @@ public void fromURLAcceptHeaders() throws Exception { assertEquals(6, elems.length); } + + @Test + public void jarCacheHit() throws Exception { + // If no cache, should fail-fast as nonexisting.example.com is not in DNS + Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/context")); + assertTrue(context instanceof Map); + assertTrue(((Map)context).containsKey("@context")); + } + + + @Test(expected=IOException.class) + public void jarCacheMiss404() throws Exception { + // Should fail-fast as nonexisting.example.com is not in DNS + Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/miss")); + } + + + @After + public void setContextClassLoader() { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + } + + @Test(expected=IOException.class) + public void jarCacheMissThreadCtx() throws Exception { + URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); + Thread.currentThread().setContextClassLoader(findNothingCL); + Object context = documentLoader.fromURL(new URL( + "http://nonexisting.example.com/context")); + } + @Test + public void jarCacheHitThreadCtx() throws Exception { + URL url = new URL( + "http://nonexisting.example.com/nested/hello"); + URL nestedJar = getClass().getResource("/nested.jar"); + try { + Object hello = documentLoader.fromURL(url); + fail("Should not be able to find nested/hello yet"); + } catch (IOException ex) { + // expected + } + + ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + Thread.currentThread().setContextClassLoader(cl); + Object hello = documentLoader.fromURL(url); + assertTrue(hello instanceof Map); + assertEquals("World!", ((Map)hello).get("Hello")); + + } + } diff --git a/core/src/test/resources/jarcache.json b/core/src/test/resources/jarcache.json new file mode 100644 index 00000000..42f3769f --- /dev/null +++ b/core/src/test/resources/jarcache.json @@ -0,0 +1,8 @@ +[ + { + "Content-Location": "http://nonexisting.example.com/context", + "X-Classpath": "custom/contexttest-0001.jsonld", + "Content-Type": "application/ld+json" + } +] + diff --git a/core/src/test/resources/nested.jar b/core/src/test/resources/nested.jar new file mode 100644 index 0000000000000000000000000000000000000000..0c585a6d571fa1d4a1c1fd5716413544a5ccf599 GIT binary patch literal 862 zcmWIWW@Zs#VBp|jsIE_UVE_Uq5CH_73@i-3t|5-Po_=on|4uP5Ff#<8DDIr@z~~HA z2+{>K0-@N~(a+P(H8@1i*X^_KnbSVrx_TFRy>+$DojJcb$l!|cgQrD$UcNe>z86bZ zv2f0KEqP?Nlvc(MaaFbFOSCMWi;F%HSDnT%HTzT1$0A0srCdN4GB6}TT?n)b4A_BW zacNRYW|2O^Wyed3Tzrn1rq==`7XUFYgA7AfVo`Epaz?6NR&jn_Xb2|*b7+)Ca2ODm zR&X;gvbHXu@Cn(4J>PJ zPyW7JGP}N1{kpK$f^F$ii_)B~M@|pf$<4@_cy5v8e7R>9g^czWL+k0K#bgs8&$&04Y?mQcw!dFUm<#R8pwr3h-uR5&=aO zj@SlSjQ}WdkFFIx?h)E_flRnoq?7v}k69L^E2@fZQR+j4PaxjqC=Rj3v~8#$pNa0B=?{kaJjpFb1gc4aivx0I-eG AY5)KL literal 0 HcmV?d00001 From db6130746f12a2a0126bc6c52b6cca35feb1d24d Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 15:20:17 +0000 Subject: [PATCH 009/440] Test to verify that toRDF() on array contexts fail --- .../core/ArrayContextToRDFTest.java | 39 +++++++++++++++++++ .../resources/custom/array-context.jsonld | 8 ++++ 2 files changed, 47 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java create mode 100644 core/src/test/resources/custom/array-context.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java new file mode 100644 index 00000000..86db2c88 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -0,0 +1,39 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertNotNull; + +import java.net.URL; + +import org.junit.Test; + +import com.github.jsonldjava.utils.JsonUtils; + +public class ArrayContextToRDFTest { + @Test + public void toRdfWithNamespace() throws Exception { + + URL contextUrl = getClass().getResource("/custom/contexttest-0001.jsonld"); + assertNotNull(contextUrl); + final Object context = JsonUtils.fromURL(contextUrl); + assertNotNull(context); + + URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); + assertNotNull(arrayContextUrl); + Object arrayContext = JsonUtils.fromURL(arrayContextUrl); + assertNotNull(arrayContext); + JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + // Fake document loader that always returns the imported context + // from classpath + DocumentLoader documentLoader = new DocumentLoader() { + @Override + public RemoteDocument loadDocument(String url) throws JsonLdError { + return new RemoteDocument("http://nonexisting.example.com/context", + context); + } + }; + options.setDocumentLoader(documentLoader); + JsonLdProcessor.toRDF(arrayContext, options); + + } +} diff --git a/core/src/test/resources/custom/array-context.jsonld b/core/src/test/resources/custom/array-context.jsonld new file mode 100644 index 00000000..5473b990 --- /dev/null +++ b/core/src/test/resources/custom/array-context.jsonld @@ -0,0 +1,8 @@ +{ + "@context": [ + "http://nonexisting.example.com/context", + { "ex2": "http://example.com/2/" } + ], + "@id": "ex2:a", + "ex:term2": "ex2:b" +} \ No newline at end of file From e1f237fd146b22b1b9b6d7114abbbea2cc4acf1d Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 15:28:03 +0000 Subject: [PATCH 010/440] Test with term2, not ex:term2 (to get @type:@id) --- core/src/test/resources/custom/array-context.jsonld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/resources/custom/array-context.jsonld b/core/src/test/resources/custom/array-context.jsonld index 5473b990..d461ab6f 100644 --- a/core/src/test/resources/custom/array-context.jsonld +++ b/core/src/test/resources/custom/array-context.jsonld @@ -4,5 +4,5 @@ { "ex2": "http://example.com/2/" } ], "@id": "ex2:a", - "ex:term2": "ex2:b" + "term2": "ex2:b" } \ No newline at end of file From 77b30a0258cc24327780f5046c40f54f6cc999da Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 15:33:09 +0000 Subject: [PATCH 011/440] Don't assume @context are Map - also handle List TODO: Also handle String (e.g. external) --- .../jsonldjava/core/JsonLdProcessor.java | 2 +- .../github/jsonldjava/core/RDFDataset.java | 20 +++++++++++++++++-- .../core/ArrayContextToRDFTest.java | 3 ++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 324876d2..fedf2fe2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -482,7 +482,7 @@ public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOp } for (final Map e : _input) { if (e.containsKey("@context")) { - dataset.parseContext((Map) e.get("@context")); + dataset.parseContext(e.get("@context")); } } } diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 6a90bbe3..22cde3fa 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -395,7 +395,23 @@ public Map getContext() { * @param context * The context to parse */ - public void parseContext(Map context) { + public void parseContext(Object contextLike) { + Map context; + + if (contextLike instanceof Map) { + context = (Map) contextLike; + } else if (contextLike instanceof List) { + for (Object cntx : (List)contextLike) { + parseContext(cntx); + } + return; + } else if (contextLike instanceof String) { + // FIXME: Ignore external contexts for now + return; + } else { + throw new RuntimeException("Can't handle context of type " + contextLike.getClass()); + } + for (final String key : context.keySet()) { final Object val = context.get(key); if ("@vocab".equals(key)) { @@ -407,7 +423,7 @@ public void parseContext(Map context) { } } else if ("@context".equals(key)) { // go deeper! - parseContext((Map) context.get("@context")); + parseContext(context.get("@context")); } else if (!isKeyword(key)) { // TODO: should we make sure val is a valid URI prefix (i.e. it // ends with /# or ?) diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index 86db2c88..bf89d924 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -33,7 +33,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { } }; options.setDocumentLoader(documentLoader); - JsonLdProcessor.toRDF(arrayContext, options); + Object rdf = JsonLdProcessor.toRDF(arrayContext, options); + System.out.println(rdf); } } From 67cdb6f4fc0834b91ffb8d9d92814e9f619fa8a1 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 16:58:08 +0000 Subject: [PATCH 012/440] Add getPrefixes() to expose term definitions to RDFDataset --- .../com/github/jsonldjava/core/Context.java | 2223 +++++++++-------- 1 file changed, 1171 insertions(+), 1052 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 29fe39dc..69a2e089 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -22,1057 +23,1175 @@ */ public class Context extends LinkedHashMap { - private JsonLdOptions options; - private Map termDefinitions; - public Map inverse = null; - - public Context() { - this(new JsonLdOptions()); - } - - public Context(JsonLdOptions opts) { - super(); - init(opts); - } - - public Context(Map map, JsonLdOptions opts) { - super(map); - init(opts); - } - - public Context(Map map) { - super(map); - init(new JsonLdOptions()); - } - - public Context(Object context, JsonLdOptions opts) { - // TODO: load remote context - super(context instanceof Map ? (Map) context : null); - init(opts); - } - - private void init(JsonLdOptions options) { - this.options = options; - if (options.getBase() != null) { - this.put("@base", options.getBase()); - } - this.termDefinitions = new LinkedHashMap(); - } - - /** - * Value Compaction Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#value-compaction - * - * @param activeProperty - * The Active Property - * @param value - * The value to compact - * @return The compacted value - */ - public Object compactValue(String activeProperty, Map value) { - // 1) - int numberMembers = value.size(); - // 2) - if (value.containsKey("@index") && "@index".equals(this.getContainer(activeProperty))) { - numberMembers--; - } - // 3) - if (numberMembers > 2) { - return value; - } - // 4) - final String typeMapping = getTypeMapping(activeProperty); - final String languageMapping = getLanguageMapping(activeProperty); - if (value.containsKey("@id")) { - // 4.1) - if (numberMembers == 1 && "@id".equals(typeMapping)) { - return compactIri((String) value.get("@id")); - } - // 4.2) - if (numberMembers == 1 && "@vocab".equals(typeMapping)) { - return compactIri((String) value.get("@id"), true); - } - // 4.3) - return value; - } - final Object valueValue = value.get("@value"); - // 5) - if (value.containsKey("@type") && Obj.equals(value.get("@type"), typeMapping)) { - return valueValue; - } - // 6) - if (value.containsKey("@language")) { - // TODO: SPEC: doesn't specify to check default language as well - if (Obj.equals(value.get("@language"), languageMapping) - || Obj.equals(value.get("@language"), this.get("@language"))) { - return valueValue; - } - } - // 7) - if (numberMembers == 1 - && (!(valueValue instanceof String) || !this.containsKey("@language") || (getTermDefinition( - activeProperty).containsKey("@language") && languageMapping == null))) { - return valueValue; - } - // 8) - return value; - } - - /** - * Context Processing Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms - * - * @param localContext - * The Local Context object. - * @param remoteContexts - * The list of Strings denoting the remote Context URLs. - * @return The parsed and merged Context. - * @throws JsonLdError - * If there is an error parsing the contexts. - */ - public Context parse(Object localContext, List remoteContexts) throws JsonLdError { - if (remoteContexts == null) { - remoteContexts = new ArrayList(); - } - // 1. Initialize result to the result of cloning active context. - Context result = this.clone(); // TODO: clone? - // 2) - if (!(localContext instanceof List)) { - final Object temp = localContext; - localContext = new ArrayList(); - ((List) localContext).add(temp); - } - // 3) - for (Object context : ((List) localContext)) { - // 3.1) - if (context == null) { - result = new Context(this.options); - continue; - } else if (context instanceof Context) { - result = ((Context) context).clone(); - } - // 3.2) - else if (context instanceof String) { - String uri = (String) result.get("@base"); - uri = JsonLdUrl.resolve(uri, (String) context); - // 3.2.2 - if (remoteContexts.contains(uri)) { - throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, uri); - } - remoteContexts.add(uri); - - // 3.2.3: Dereference context - final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); - final Object remoteContext = rd.document; - if (!(remoteContext instanceof Map) - || !((Map) remoteContext).containsKey("@context")) { - // If the dereferenced document has no top-level JSON object - // with an @context member - throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); - } - context = ((Map) remoteContext).get("@context"); - - // 3.2.4 - result = result.parse(context, remoteContexts); - // 3.2.5 - continue; - } else if (!(context instanceof Map)) { - // 3.3 - throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); - } - - // 3.4 - if (remoteContexts.isEmpty() && ((Map) context).containsKey("@base")) { - final Object value = ((Map) context).get("@base"); - if (value == null) { - result.remove("@base"); - } else if (value instanceof String) { - if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@base", value); - } else { - final String baseUri = (String) result.get("@base"); - if (!JsonLdUtils.isAbsoluteIri(baseUri)) { - throw new JsonLdError(Error.INVALID_BASE_IRI, baseUri); - } - result.put("@base", JsonLdUrl.resolve(baseUri, (String) value)); - } - } else { - throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, - "@base must be a string"); - } - } - - // 3.5 - if (((Map) context).containsKey("@vocab")) { - final Object value = ((Map) context).get("@vocab"); - if (value == null) { - result.remove("@vocab"); - } else if (value instanceof String) { - if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@vocab", value); - } else { - throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, - "@value must be an absolute IRI"); - } - } else { - throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, - "@vocab must be a string or null"); - } - } - - // 3.6 - if (((Map) context).containsKey("@language")) { - final Object value = ((Map) context).get("@language"); - if (value == null) { - result.remove("@language"); - } else if (value instanceof String) { - result.put("@language", ((String) value).toLowerCase()); - } else { - throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); - } - } - - // 3.7 - final Map defined = new LinkedHashMap(); - for (final String key : ((Map) context).keySet()) { - if ("@base".equals(key) || "@vocab".equals(key) || "@language".equals(key)) { - continue; - } - result.createTermDefinition((Map) context, key, defined); - } - } - return result; - } - - public Context parse(Object localContext) throws JsonLdError { - return this.parse(localContext, new ArrayList()); - } - - /** - * Create Term Definition Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition - * - * @param result - * @param context - * @param key - * @param defined - * @throws JsonLdError - */ - private void createTermDefinition(Map context, String term, - Map defined) throws JsonLdError { - if (defined.containsKey(term)) { - if (Boolean.TRUE.equals(defined.get(term))) { - return; - } - throw new JsonLdError(Error.CYCLIC_IRI_MAPPING, term); - } - - defined.put(term, false); - - if (JsonLdUtils.isKeyword(term)) { - throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); - } - - this.termDefinitions.remove(term); - Object value = context.get(term); - if (value == null - || (value instanceof Map && ((Map) value).containsKey("@id") && ((Map) value) - .get("@id") == null)) { - this.termDefinitions.put(term, null); - defined.put(term, true); - return; - } - - if (value instanceof String) { - final Map tmp = new LinkedHashMap(); - tmp.put("@id", value); - value = tmp; - } - - if (!(value instanceof Map)) { - throw new JsonLdError(Error.INVALID_TERM_DEFINITION, value); - } - - // casting the value so it doesn't have to be done below everytime - final Map val = (Map) value; - - // 9) create a new term definition - final Map definition = new LinkedHashMap(); - - // 10) - if (val.containsKey("@type")) { - if (!(val.get("@type") instanceof String)) { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, val.get("@type")); - } - String type = (String) val.get("@type"); - try { - type = this.expandIri((String) val.get("@type"), false, true, context, defined); - } catch (final JsonLdError error) { - if (error.getType() != Error.INVALID_IRI_MAPPING) { - throw error; - } - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); - } - // TODO: fix check for absoluteIri (blank nodes shouldn't count, at - // least not here!) - if ("@id".equals(type) || "@vocab".equals(type) - || (!type.startsWith("_:") && JsonLdUtils.isAbsoluteIri(type))) { - definition.put("@type", type); - } else { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); - } - } - - // 11) - if (val.containsKey("@reverse")) { - if (val.containsKey("@id")) { - throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); - } - if (!(val.get("@reverse") instanceof String)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "Expected String for @reverse value. got " - + (val.get("@reverse") == null ? "null" : val.get("@reverse") - .getClass())); - } - final String reverse = this.expandIri((String) val.get("@reverse"), false, true, - context, defined); - if (!JsonLdUtils.isAbsoluteIri(reverse)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Non-absolute @reverse IRI: " - + reverse); - } - definition.put("@id", reverse); - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (container == null || "@set".equals(container) || "@index".equals(container)) { - definition.put("@container", container); - } else { - throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, - "reverse properties only support set- and index-containers"); - } - } - definition.put("@reverse", true); - this.termDefinitions.put(term, definition); - defined.put(term, true); - return; - } - - // 12) - definition.put("@reverse", false); - - // 13) - if (val.get("@id") != null && !term.equals(val.get("@id"))) { - if (!(val.get("@id") instanceof String)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "expected value of @id to be a string"); - } - - final String res = this.expandIri((String) val.get("@id"), false, true, context, - defined); - if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { - if ("@context".equals(res)) { - throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, "cannot alias @context"); - } - definition.put("@id", res); - } else { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "resulting IRI mapping should be a keyword, absolute IRI or blank node"); - } - } - - // 14) - else if (term.indexOf(":") >= 0) { - final int colIndex = term.indexOf(":"); - final String prefix = term.substring(0, colIndex); - final String suffix = term.substring(colIndex + 1); - if (context.containsKey(prefix)) { - this.createTermDefinition(context, prefix, defined); - } - if (termDefinitions.containsKey(prefix)) { - definition.put("@id", - ((Map) termDefinitions.get(prefix)).get("@id") + suffix); - } else { - definition.put("@id", term); - } - // 15) - } else if (this.containsKey("@vocab")) { - definition.put("@id", this.get("@vocab") + term); - } else { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "relative term definition without vocab mapping"); - } - - // 16) - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (!"@list".equals(container) && !"@set".equals(container) - && !"@index".equals(container) && !"@language".equals(container)) { - throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, - "@container must be either @list, @set, @index, or @language"); - } - definition.put("@container", container); - } - - // 17) - if (val.containsKey("@language") && !val.containsKey("@type")) { - if (val.get("@language") == null || val.get("@language") instanceof String) { - final String language = (String) val.get("@language"); - definition.put("@language", language != null ? language.toLowerCase() : null); - } else { - throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, - "@language must be a string or null"); - } - } - - // 18) - this.termDefinitions.put(term, definition); - defined.put(term, true); - } - - /** - * IRI Expansion Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion - * - * @param value - * @param relative - * @param vocab - * @param context - * @param defined - * @return - * @throws JsonLdError - */ - String expandIri(String value, boolean relative, boolean vocab, Map context, - Map defined) throws JsonLdError { - // 1) - if (value == null || JsonLdUtils.isKeyword(value)) { - return value; - } - // 2) - if (context != null && context.containsKey(value) - && !Boolean.TRUE.equals(defined.get(value))) { - this.createTermDefinition(context, value, defined); - } - // 3) - if (vocab && this.termDefinitions.containsKey(value)) { - final Map td = (LinkedHashMap) this.termDefinitions - .get(value); - if (td != null) { - return (String) td.get("@id"); - } else { - return null; - } - } - // 4) - final int colIndex = value.indexOf(":"); - if (colIndex >= 0) { - // 4.1) - final String prefix = value.substring(0, colIndex); - final String suffix = value.substring(colIndex + 1); - // 4.2) - if ("_".equals(prefix) || suffix.startsWith("//")) { - return value; - } - // 4.3) - if (context != null && context.containsKey(prefix) - && (!defined.containsKey(prefix) || defined.get(prefix) == false)) { - this.createTermDefinition(context, prefix, defined); - } - // 4.4) - if (this.termDefinitions.containsKey(prefix)) { - return (String) ((LinkedHashMap) this.termDefinitions.get(prefix)) - .get("@id") + suffix; - } - // 4.5) - return value; - } - // 5) - if (vocab && this.containsKey("@vocab")) { - return this.get("@vocab") + value; - } - // 6) - else if (relative) { - return JsonLdUrl.resolve((String) this.get("@base"), value); - } else if (context != null && JsonLdUtils.isRelativeIri(value)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, "not an absolute IRI: " + value); - } - // 7) - return value; - } - - /** - * IRI Compaction Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction - * - * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI - * has an associated value it may be passed. - * - * @param iri - * the IRI to compact. - * @param value - * the value to check or null. - * @param relativeTo - * options for how to compact IRIs: vocab: true to split after - * @vocab, false not to. - * @param reverse - * true if a reverse property is being compacted, false if not. - * - * @return the compacted term, prefix, keyword alias, or the original IRI. - */ - String compactIri(String iri, Object value, boolean relativeToVocab, boolean reverse) { - // 1) - if (iri == null) { - return null; - } - - // 2) - if (relativeToVocab && getInverse().containsKey(iri)) { - // 2.1) - String defaultLanguage = (String) this.get("@language"); - if (defaultLanguage == null) { - defaultLanguage = "@none"; - } - - // 2.2) - final List containers = new ArrayList(); - // 2.3) - String typeLanguage = "@language"; - String typeLanguageValue = "@null"; - - // 2.4) - if (value instanceof Map && ((Map) value).containsKey("@index")) { - containers.add("@index"); - } - - // 2.5) - if (reverse) { - typeLanguage = "@type"; - typeLanguageValue = "@reverse"; - containers.add("@set"); - } - // 2.6) - else if (value instanceof Map && ((Map) value).containsKey("@list")) { - // 2.6.1) - if (!((Map) value).containsKey("@index")) { - containers.add("@list"); - } - // 2.6.2) - final List list = (List) ((Map) value).get("@list"); - // 2.6.3) - String commonLanguage = (list.size() == 0) ? defaultLanguage : null; - String commonType = null; - // 2.6.4) - for (final Object item : list) { - // 2.6.4.1) - String itemLanguage = "@none"; - String itemType = "@none"; - // 2.6.4.2) - if (JsonLdUtils.isValue(item)) { - // 2.6.4.2.1) - if (((Map) item).containsKey("@language")) { - itemLanguage = (String) ((Map) item).get("@language"); - } - // 2.6.4.2.2) - else if (((Map) item).containsKey("@type")) { - itemType = (String) ((Map) item).get("@type"); - } - // 2.6.4.2.3) - else { - itemLanguage = "@null"; - } - } - // 2.6.4.3) - else { - itemType = "@id"; - } - // 2.6.4.4) - if (commonLanguage == null) { - commonLanguage = itemLanguage; - } - // 2.6.4.5) - else if (!commonLanguage.equals(itemLanguage) && JsonLdUtils.isValue(item)) { - commonLanguage = "@none"; - } - // 2.6.4.6) - if (commonType == null) { - commonType = itemType; - } - // 2.6.4.7) - else if (!commonType.equals(itemType)) { - commonType = "@none"; - } - // 2.6.4.8) - if ("@none".equals(commonLanguage) && "@none".equals(commonType)) { - break; - } - } - // 2.6.5) - commonLanguage = (commonLanguage != null) ? commonLanguage : "@none"; - // 2.6.6) - commonType = (commonType != null) ? commonType : "@none"; - // 2.6.7) - if (!"@none".equals(commonType)) { - typeLanguage = "@type"; - typeLanguageValue = commonType; - } - // 2.6.8) - else { - typeLanguageValue = commonLanguage; - } - } - // 2.7) - else { - // 2.7.1) - if (value instanceof Map && ((Map) value).containsKey("@value")) { - // 2.7.1.1) - if (((Map) value).containsKey("@language") - && !((Map) value).containsKey("@index")) { - containers.add("@language"); - typeLanguageValue = (String) ((Map) value).get("@language"); - } - // 2.7.1.2) - else if (((Map) value).containsKey("@type")) { - typeLanguage = "@type"; - typeLanguageValue = (String) ((Map) value).get("@type"); - } - } - // 2.7.2) - else { - typeLanguage = "@type"; - typeLanguageValue = "@id"; - } - // 2.7.3) - containers.add("@set"); - } - - // 2.8) - containers.add("@none"); - // 2.9) - if (typeLanguageValue == null) { - typeLanguageValue = "@null"; - } - // 2.10) - final List preferredValues = new ArrayList(); - // 2.11) - if ("@reverse".equals(typeLanguageValue)) { - preferredValues.add("@reverse"); - } - // 2.12) - if (("@reverse".equals(typeLanguageValue) || "@id".equals(typeLanguageValue)) - && (value instanceof Map) && ((Map) value).containsKey("@id")) { - // 2.12.1) - final String result = this.compactIri( - (String) ((Map) value).get("@id"), null, true, true); - if (termDefinitions.containsKey(result) - && ((Map) termDefinitions.get(result)).containsKey("@id") - && ((Map) value).get("@id").equals( - ((Map) termDefinitions.get(result)).get("@id"))) { - preferredValues.add("@vocab"); - preferredValues.add("@id"); - } - // 2.12.2) - else { - preferredValues.add("@id"); - preferredValues.add("@vocab"); - } - } - // 2.13) - else { - preferredValues.add(typeLanguageValue); - } - preferredValues.add("@none"); - - // 2.14) - final String term = selectTerm(iri, containers, typeLanguage, preferredValues); - // 2.15) - if (term != null) { - return term; - } - } - - // 3) - if (relativeToVocab && this.containsKey("@vocab")) { - // determine if vocab is a prefix of the iri - final String vocab = (String) this.get("@vocab"); - // 3.1) - if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { - // use suffix as relative iri if it is not a term in the - // active context - final String suffix = iri.substring(vocab.length()); - if (!termDefinitions.containsKey(suffix)) { - return suffix; - } - } - } - - // 4) - String compactIRI = null; - // 5) - for (final String term : termDefinitions.keySet()) { - final Map termDefinition = (Map) termDefinitions - .get(term); - // 5.1) - if (term.contains(":")) { - continue; - } - // 5.2) - if (termDefinition == null || iri.equals(termDefinition.get("@id")) - || !iri.startsWith((String) termDefinition.get("@id"))) { - continue; - } - - // 5.3) - final String candidate = term + ":" - + iri.substring(((String) termDefinition.get("@id")).length()); - // 5.4) - if ((compactIRI == null || compareShortestLeast(candidate, compactIRI) < 0) - && (!termDefinitions.containsKey(candidate) || (iri - .equals(((Map) termDefinitions.get(candidate)) - .get("@id")) && value == null))) { - compactIRI = candidate; - } - - } - - // 6) - if (compactIRI != null) { - return compactIRI; - } - - // 7) - if (!relativeToVocab) { - return JsonLdUrl.removeBase(this.get("@base"), iri); - } - - // 8) - return iri; - } - - String compactIri(String iri, boolean relativeToVocab) { - return compactIri(iri, null, relativeToVocab, false); - } - - String compactIri(String iri) { - return compactIri(iri, null, false, false); - } - - @Override - public Context clone() { - final Context rval = (Context) super.clone(); - // TODO: is this shallow copy enough? probably not, but it passes all - // the tests! - rval.termDefinitions = new LinkedHashMap(this.termDefinitions); - return rval; - } - - /** - * Inverse Context Creation - * - * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation - * - * Generates an inverse context for use in the compaction algorithm, if not - * already generated for the given active context. - * - * @return the inverse context. - */ - public Map getInverse() { - - // lazily create inverse - if (inverse != null) { - return inverse; - } - - // 1) - inverse = new LinkedHashMap(); - - // 2) - String defaultLanguage = (String) this.get("@language"); - if (defaultLanguage == null) { - defaultLanguage = "@none"; - } - - // create term selections for each mapping in the context, ordererd by - // shortest and then lexicographically least - final List terms = new ArrayList(termDefinitions.keySet()); - Collections.sort(terms, new Comparator() { - @Override - public int compare(String a, String b) { - return compareShortestLeast(a, b); - } - }); - - for (final String term : terms) { - final Map definition = (Map) termDefinitions.get(term); - // 3.1) - if (definition == null) { - continue; - } - - // 3.2) - String container = (String) definition.get("@container"); - if (container == null) { - container = "@none"; - } - - // 3.3) - final String iri = (String) definition.get("@id"); - - // 3.4 + 3.5) - Map containerMap = (Map) inverse.get(iri); - if (containerMap == null) { - containerMap = new LinkedHashMap(); - inverse.put(iri, containerMap); - } - - // 3.6 + 3.7) - Map typeLanguageMap = (Map) containerMap.get(container); - if (typeLanguageMap == null) { - typeLanguageMap = new LinkedHashMap(); - typeLanguageMap.put("@language", new LinkedHashMap()); - typeLanguageMap.put("@type", new LinkedHashMap()); - containerMap.put(container, typeLanguageMap); - } - - // 3.8) - if (Boolean.TRUE.equals(definition.get("@reverse"))) { - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey("@reverse")) { - typeMap.put("@reverse", term); - } - // 3.9) - } else if (definition.containsKey("@type")) { - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey(definition.get("@type"))) { - typeMap.put((String) definition.get("@type"), term); - } - // 3.10) - } else if (definition.containsKey("@language")) { - final Map languageMap = (Map) typeLanguageMap - .get("@language"); - String language = (String) definition.get("@language"); - if (language == null) { - language = "@null"; - } - if (!languageMap.containsKey(language)) { - languageMap.put(language, term); - } - // 3.11) - } else { - // 3.11.1) - final Map languageMap = (Map) typeLanguageMap - .get("@language"); - // 3.11.2) - if (!languageMap.containsKey("@language")) { - languageMap.put("@language", term); - } - // 3.11.3) - if (!languageMap.containsKey("@none")) { - languageMap.put("@none", term); - } - // 3.11.4) - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - // 3.11.5) - if (!typeMap.containsKey("@none")) { - typeMap.put("@none", term); - } - } - } - // 4) - return inverse; - } - - /** - * Term Selection - * - * http://json-ld.org/spec/latest/json-ld-api/#term-selection - * - * This algorithm, invoked via the IRI Compaction algorithm, makes use of an - * active context's inverse context to find the term that is best used to - * compact an IRI. Other information about a value associated with the IRI - * is given, including which container mappings and which type mapping or - * language mapping would be best used to express the value. - * - * @return the selected term. - */ - private String selectTerm(String iri, List containers, String typeLanguage, - List preferredValues) { - final Map inv = getInverse(); - // 1) - final Map containerMap = (Map) inv.get(iri); - // 2) - for (final String container : containers) { - // 2.1) - if (!containerMap.containsKey(container)) { - continue; - } - // 2.2) - final Map typeLanguageMap = (Map) containerMap - .get(container); - // 2.3) - final Map valueMap = (Map) typeLanguageMap - .get(typeLanguage); - // 2.4 ) - for (final String item : preferredValues) { - // 2.4.1 - if (!valueMap.containsKey(item)) { - continue; - } - // 2.4.2 - return (String) valueMap.get(item); - } - } - // 3) - return null; - } - - /** - * Retrieve container mapping. - * - * @param property - * The Property to get a container mapping for. - * @return The container mapping - */ - public String getContainer(String property) { - if ("@graph".equals(property)) { - return "@set"; - } - if (JsonLdUtils.isKeyword(property)) { - return property; - } - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return null; - } - return (String) td.get("@container"); - } - - public Boolean isReverseProperty(String property) { - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return false; - } - final Object reverse = td.get("@reverse"); - return reverse != null && (Boolean) reverse; - } - - private String getTypeMapping(String property) { - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return null; - } - return (String) td.get("@type"); - } - - private String getLanguageMapping(String property) { - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return null; - } - return (String) td.get("@language"); - } - - Map getTermDefinition(String key) { - return ((Map) termDefinitions.get(key)); - } - - public Object expandValue(String activeProperty, Object value) throws JsonLdError { - final Map rval = new LinkedHashMap(); - final Map td = getTermDefinition(activeProperty); - // 1) - if (td != null && "@id".equals(td.get("@type"))) { - // TODO: i'm pretty sure value should be a string if the @type is - // @id - rval.put("@id", expandIri(value.toString(), true, false, null, null)); - return rval; - } - // 2) - if (td != null && "@vocab".equals(td.get("@type"))) { - // TODO: same as above - rval.put("@id", expandIri(value.toString(), true, true, null, null)); - return rval; - } - // 3) - rval.put("@value", value); - // 4) - if (td != null && td.containsKey("@type")) { - rval.put("@type", td.get("@type")); - } - // 5) - else if (value instanceof String) { - // 5.1) - if (td != null && td.containsKey("@language")) { - final String lang = (String) td.get("@language"); - if (lang != null) { - rval.put("@language", lang); - } - } - // 5.2) - else if (this.get("@language") != null) { - rval.put("@language", this.get("@language")); - } - } - return rval; - } - - public Object getContextValue(String activeProperty, String string) throws JsonLdError { - throw new JsonLdError(Error.NOT_IMPLEMENTED, - "getContextValue is only used by old code so far and thus isn't implemented"); - } - - public Map serialize() { - final Map ctx = new LinkedHashMap(); - if (this.get("@base") != null && !this.get("@base").equals(options.getBase())) { - ctx.put("@base", this.get("@base")); - } - if (this.get("@language") != null) { - ctx.put("@language", this.get("@language")); - } - if (this.get("@vocab") != null) { - ctx.put("@vocab", this.get("@vocab")); - } - for (final String term : termDefinitions.keySet()) { - final Map definition = (Map) termDefinitions.get(term); - if (definition.get("@language") == null - && definition.get("@container") == null - && definition.get("@type") == null - && (definition.get("@reverse") == null || Boolean.FALSE.equals(definition - .get("@reverse")))) { - final String cid = this.compactIri((String) definition.get("@id")); - ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); - } else { - final Map defn = new LinkedHashMap(); - final String cid = this.compactIri((String) definition.get("@id")); - final Boolean reverseProperty = Boolean.TRUE.equals(definition.get("@reverse")); - if (!(term.equals(cid) && !reverseProperty)) { - defn.put(reverseProperty ? "@reverse" : "@id", cid); - } - final String typeMapping = (String) definition.get("@type"); - if (typeMapping != null) { - defn.put("@type", JsonLdUtils.isKeyword(typeMapping) ? typeMapping - : compactIri(typeMapping, true)); - } - if (definition.get("@container") != null) { - defn.put("@container", definition.get("@container")); - } - final Object lang = definition.get("@language"); - if (definition.get("@language") != null) { - defn.put("@language", Boolean.FALSE.equals(lang) ? null : lang); - } - ctx.put(term, defn); - } - } - - final Map rval = new LinkedHashMap(); - if (!(ctx == null || ctx.isEmpty())) { - rval.put("@context", ctx); - } - return rval; - } + private JsonLdOptions options; + private Map termDefinitions; + public Map inverse = null; + + public Context() { + this(new JsonLdOptions()); + } + + public Context(JsonLdOptions opts) { + super(); + init(opts); + } + + public Context(Map map, JsonLdOptions opts) { + super(map); + init(opts); + } + + public Context(Map map) { + super(map); + init(new JsonLdOptions()); + } + + public Context(Object context, JsonLdOptions opts) { + // TODO: load remote context + super(context instanceof Map ? (Map) context : null); + init(opts); + } + + private void init(JsonLdOptions options) { + this.options = options; + if (options.getBase() != null) { + this.put("@base", options.getBase()); + } + this.termDefinitions = new LinkedHashMap(); + } + + /** + * Value Compaction Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#value-compaction + * + * @param activeProperty + * The Active Property + * @param value + * The value to compact + * @return The compacted value + */ + public Object compactValue(String activeProperty, Map value) { + // 1) + int numberMembers = value.size(); + // 2) + if (value.containsKey("@index") + && "@index".equals(this.getContainer(activeProperty))) { + numberMembers--; + } + // 3) + if (numberMembers > 2) { + return value; + } + // 4) + final String typeMapping = getTypeMapping(activeProperty); + final String languageMapping = getLanguageMapping(activeProperty); + if (value.containsKey("@id")) { + // 4.1) + if (numberMembers == 1 && "@id".equals(typeMapping)) { + return compactIri((String) value.get("@id")); + } + // 4.2) + if (numberMembers == 1 && "@vocab".equals(typeMapping)) { + return compactIri((String) value.get("@id"), true); + } + // 4.3) + return value; + } + final Object valueValue = value.get("@value"); + // 5) + if (value.containsKey("@type") + && Obj.equals(value.get("@type"), typeMapping)) { + return valueValue; + } + // 6) + if (value.containsKey("@language")) { + // TODO: SPEC: doesn't specify to check default language as well + if (Obj.equals(value.get("@language"), languageMapping) + || Obj.equals(value.get("@language"), this.get("@language"))) { + return valueValue; + } + } + // 7) + if (numberMembers == 1 + && (!(valueValue instanceof String) + || !this.containsKey("@language") || (getTermDefinition( + activeProperty).containsKey("@language") && languageMapping == null))) { + return valueValue; + } + // 8) + return value; + } + + /** + * Context Processing Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms + * + * @param localContext + * The Local Context object. + * @param remoteContexts + * The list of Strings denoting the remote Context URLs. + * @return The parsed and merged Context. + * @throws JsonLdError + * If there is an error parsing the contexts. + */ + public Context parse(Object localContext, List remoteContexts) + throws JsonLdError { + if (remoteContexts == null) { + remoteContexts = new ArrayList(); + } + // 1. Initialize result to the result of cloning active context. + Context result = this.clone(); // TODO: clone? + // 2) + if (!(localContext instanceof List)) { + final Object temp = localContext; + localContext = new ArrayList(); + ((List) localContext).add(temp); + } + // 3) + for (Object context : ((List) localContext)) { + // 3.1) + if (context == null) { + result = new Context(this.options); + continue; + } else if (context instanceof Context) { + result = ((Context) context).clone(); + } + // 3.2) + else if (context instanceof String) { + String uri = (String) result.get("@base"); + uri = JsonLdUrl.resolve(uri, (String) context); + // 3.2.2 + if (remoteContexts.contains(uri)) { + throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, + uri); + } + remoteContexts.add(uri); + + // 3.2.3: Dereference context + final RemoteDocument rd = this.options.getDocumentLoader() + .loadDocument(uri); + final Object remoteContext = rd.document; + if (!(remoteContext instanceof Map) + || !((Map) remoteContext) + .containsKey("@context")) { + // If the dereferenced document has no top-level JSON object + // with an @context member + throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); + } + context = ((Map) remoteContext).get("@context"); + + // 3.2.4 + result = result.parse(context, remoteContexts); + // 3.2.5 + continue; + } else if (!(context instanceof Map)) { + // 3.3 + throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); + } + + // 3.4 + if (remoteContexts.isEmpty() + && ((Map) context).containsKey("@base")) { + final Object value = ((Map) context) + .get("@base"); + if (value == null) { + result.remove("@base"); + } else if (value instanceof String) { + if (JsonLdUtils.isAbsoluteIri((String) value)) { + result.put("@base", value); + } else { + final String baseUri = (String) result.get("@base"); + if (!JsonLdUtils.isAbsoluteIri(baseUri)) { + throw new JsonLdError(Error.INVALID_BASE_IRI, + baseUri); + } + result.put("@base", + JsonLdUrl.resolve(baseUri, (String) value)); + } + } else { + throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, + "@base must be a string"); + } + } + + // 3.5 + if (((Map) context).containsKey("@vocab")) { + final Object value = ((Map) context) + .get("@vocab"); + if (value == null) { + result.remove("@vocab"); + } else if (value instanceof String) { + if (JsonLdUtils.isAbsoluteIri((String) value)) { + result.put("@vocab", value); + } else { + throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, + "@value must be an absolute IRI"); + } + } else { + throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, + "@vocab must be a string or null"); + } + } + + // 3.6 + if (((Map) context).containsKey("@language")) { + final Object value = ((Map) context) + .get("@language"); + if (value == null) { + result.remove("@language"); + } else if (value instanceof String) { + result.put("@language", ((String) value).toLowerCase()); + } else { + throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); + } + } + + // 3.7 + final Map defined = new LinkedHashMap(); + for (final String key : ((Map) context).keySet()) { + if ("@base".equals(key) || "@vocab".equals(key) + || "@language".equals(key)) { + continue; + } + result.createTermDefinition((Map) context, key, + defined); + } + } + return result; + } + + public Context parse(Object localContext) throws JsonLdError { + return this.parse(localContext, new ArrayList()); + } + + /** + * Create Term Definition Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition + * + * @param result + * @param context + * @param key + * @param defined + * @throws JsonLdError + */ + private void createTermDefinition(Map context, String term, + Map defined) throws JsonLdError { + if (defined.containsKey(term)) { + if (Boolean.TRUE.equals(defined.get(term))) { + return; + } + throw new JsonLdError(Error.CYCLIC_IRI_MAPPING, term); + } + + defined.put(term, false); + + if (JsonLdUtils.isKeyword(term)) { + throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); + } + + this.termDefinitions.remove(term); + Object value = context.get(term); + if (value == null + || (value instanceof Map + && ((Map) value).containsKey("@id") && ((Map) value) + .get("@id") == null)) { + this.termDefinitions.put(term, null); + defined.put(term, true); + return; + } + + if (value instanceof String) { + final Map tmp = new LinkedHashMap(); + tmp.put("@id", value); + value = tmp; + } + + if (!(value instanceof Map)) { + throw new JsonLdError(Error.INVALID_TERM_DEFINITION, value); + } + + // casting the value so it doesn't have to be done below everytime + final Map val = (Map) value; + + // 9) create a new term definition + final Map definition = new LinkedHashMap(); + + // 10) + if (val.containsKey("@type")) { + if (!(val.get("@type") instanceof String)) { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, + val.get("@type")); + } + String type = (String) val.get("@type"); + try { + type = this.expandIri((String) val.get("@type"), false, true, + context, defined); + } catch (final JsonLdError error) { + if (error.getType() != Error.INVALID_IRI_MAPPING) { + throw error; + } + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + } + // TODO: fix check for absoluteIri (blank nodes shouldn't count, at + // least not here!) + if ("@id".equals(type) + || "@vocab".equals(type) + || (!type.startsWith("_:") && JsonLdUtils + .isAbsoluteIri(type))) { + definition.put("@type", type); + } else { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + } + } + + // 11) + if (val.containsKey("@reverse")) { + if (val.containsKey("@id")) { + throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); + } + if (!(val.get("@reverse") instanceof String)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "Expected String for @reverse value. got " + + (val.get("@reverse") == null ? "null" : val + .get("@reverse").getClass())); + } + final String reverse = this.expandIri((String) val.get("@reverse"), + false, true, context, defined); + if (!JsonLdUtils.isAbsoluteIri(reverse)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "Non-absolute @reverse IRI: " + reverse); + } + definition.put("@id", reverse); + if (val.containsKey("@container")) { + final String container = (String) val.get("@container"); + if (container == null || "@set".equals(container) + || "@index".equals(container)) { + definition.put("@container", container); + } else { + throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, + "reverse properties only support set- and index-containers"); + } + } + definition.put("@reverse", true); + this.termDefinitions.put(term, definition); + defined.put(term, true); + return; + } + + // 12) + definition.put("@reverse", false); + + // 13) + if (val.get("@id") != null && !term.equals(val.get("@id"))) { + if (!(val.get("@id") instanceof String)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "expected value of @id to be a string"); + } + + final String res = this.expandIri((String) val.get("@id"), false, + true, context, defined); + if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { + if ("@context".equals(res)) { + throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, + "cannot alias @context"); + } + definition.put("@id", res); + } else { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "resulting IRI mapping should be a keyword, absolute IRI or blank node"); + } + } + + // 14) + else if (term.indexOf(":") >= 0) { + final int colIndex = term.indexOf(":"); + final String prefix = term.substring(0, colIndex); + final String suffix = term.substring(colIndex + 1); + if (context.containsKey(prefix)) { + this.createTermDefinition(context, prefix, defined); + } + if (termDefinitions.containsKey(prefix)) { + definition.put( + "@id", + ((Map) termDefinitions.get(prefix)) + .get("@id") + suffix); + } else { + definition.put("@id", term); + } + // 15) + } else if (this.containsKey("@vocab")) { + definition.put("@id", this.get("@vocab") + term); + } else { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "relative term definition without vocab mapping"); + } + + // 16) + if (val.containsKey("@container")) { + final String container = (String) val.get("@container"); + if (!"@list".equals(container) && !"@set".equals(container) + && !"@index".equals(container) + && !"@language".equals(container)) { + throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, + "@container must be either @list, @set, @index, or @language"); + } + definition.put("@container", container); + } + + // 17) + if (val.containsKey("@language") && !val.containsKey("@type")) { + if (val.get("@language") == null + || val.get("@language") instanceof String) { + final String language = (String) val.get("@language"); + definition.put("@language", + language != null ? language.toLowerCase() : null); + } else { + throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, + "@language must be a string or null"); + } + } + + // 18) + this.termDefinitions.put(term, definition); + defined.put(term, true); + } + + /** + * IRI Expansion Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion + * + * @param value + * @param relative + * @param vocab + * @param context + * @param defined + * @return + * @throws JsonLdError + */ + String expandIri(String value, boolean relative, boolean vocab, + Map context, Map defined) + throws JsonLdError { + // 1) + if (value == null || JsonLdUtils.isKeyword(value)) { + return value; + } + // 2) + if (context != null && context.containsKey(value) + && !Boolean.TRUE.equals(defined.get(value))) { + this.createTermDefinition(context, value, defined); + } + // 3) + if (vocab && this.termDefinitions.containsKey(value)) { + final Map td = (LinkedHashMap) this.termDefinitions + .get(value); + if (td != null) { + return (String) td.get("@id"); + } else { + return null; + } + } + // 4) + final int colIndex = value.indexOf(":"); + if (colIndex >= 0) { + // 4.1) + final String prefix = value.substring(0, colIndex); + final String suffix = value.substring(colIndex + 1); + // 4.2) + if ("_".equals(prefix) || suffix.startsWith("//")) { + return value; + } + // 4.3) + if (context != null + && context.containsKey(prefix) + && (!defined.containsKey(prefix) || defined.get(prefix) == false)) { + this.createTermDefinition(context, prefix, defined); + } + // 4.4) + if (this.termDefinitions.containsKey(prefix)) { + return (String) ((LinkedHashMap) this.termDefinitions + .get(prefix)).get("@id") + suffix; + } + // 4.5) + return value; + } + // 5) + if (vocab && this.containsKey("@vocab")) { + return this.get("@vocab") + value; + } + // 6) + else if (relative) { + return JsonLdUrl.resolve((String) this.get("@base"), value); + } else if (context != null && JsonLdUtils.isRelativeIri(value)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "not an absolute IRI: " + value); + } + // 7) + return value; + } + + /** + * IRI Compaction Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction + * + * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI + * has an associated value it may be passed. + * + * @param iri + * the IRI to compact. + * @param value + * the value to check or null. + * @param relativeTo + * options for how to compact IRIs: vocab: true to split after + * @vocab, false not to. + * @param reverse + * true if a reverse property is being compacted, false if not. + * + * @return the compacted term, prefix, keyword alias, or the original IRI. + */ + String compactIri(String iri, Object value, boolean relativeToVocab, + boolean reverse) { + // 1) + if (iri == null) { + return null; + } + + // 2) + if (relativeToVocab && getInverse().containsKey(iri)) { + // 2.1) + String defaultLanguage = (String) this.get("@language"); + if (defaultLanguage == null) { + defaultLanguage = "@none"; + } + + // 2.2) + final List containers = new ArrayList(); + // 2.3) + String typeLanguage = "@language"; + String typeLanguageValue = "@null"; + + // 2.4) + if (value instanceof Map + && ((Map) value).containsKey("@index")) { + containers.add("@index"); + } + + // 2.5) + if (reverse) { + typeLanguage = "@type"; + typeLanguageValue = "@reverse"; + containers.add("@set"); + } + // 2.6) + else if (value instanceof Map + && ((Map) value).containsKey("@list")) { + // 2.6.1) + if (!((Map) value).containsKey("@index")) { + containers.add("@list"); + } + // 2.6.2) + final List list = (List) ((Map) value) + .get("@list"); + // 2.6.3) + String commonLanguage = (list.size() == 0) ? defaultLanguage + : null; + String commonType = null; + // 2.6.4) + for (final Object item : list) { + // 2.6.4.1) + String itemLanguage = "@none"; + String itemType = "@none"; + // 2.6.4.2) + if (JsonLdUtils.isValue(item)) { + // 2.6.4.2.1) + if (((Map) item) + .containsKey("@language")) { + itemLanguage = (String) ((Map) item) + .get("@language"); + } + // 2.6.4.2.2) + else if (((Map) item) + .containsKey("@type")) { + itemType = (String) ((Map) item) + .get("@type"); + } + // 2.6.4.2.3) + else { + itemLanguage = "@null"; + } + } + // 2.6.4.3) + else { + itemType = "@id"; + } + // 2.6.4.4) + if (commonLanguage == null) { + commonLanguage = itemLanguage; + } + // 2.6.4.5) + else if (!commonLanguage.equals(itemLanguage) + && JsonLdUtils.isValue(item)) { + commonLanguage = "@none"; + } + // 2.6.4.6) + if (commonType == null) { + commonType = itemType; + } + // 2.6.4.7) + else if (!commonType.equals(itemType)) { + commonType = "@none"; + } + // 2.6.4.8) + if ("@none".equals(commonLanguage) + && "@none".equals(commonType)) { + break; + } + } + // 2.6.5) + commonLanguage = (commonLanguage != null) ? commonLanguage + : "@none"; + // 2.6.6) + commonType = (commonType != null) ? commonType : "@none"; + // 2.6.7) + if (!"@none".equals(commonType)) { + typeLanguage = "@type"; + typeLanguageValue = commonType; + } + // 2.6.8) + else { + typeLanguageValue = commonLanguage; + } + } + // 2.7) + else { + // 2.7.1) + if (value instanceof Map + && ((Map) value).containsKey("@value")) { + // 2.7.1.1) + if (((Map) value).containsKey("@language") + && !((Map) value) + .containsKey("@index")) { + containers.add("@language"); + typeLanguageValue = (String) ((Map) value) + .get("@language"); + } + // 2.7.1.2) + else if (((Map) value).containsKey("@type")) { + typeLanguage = "@type"; + typeLanguageValue = (String) ((Map) value) + .get("@type"); + } + } + // 2.7.2) + else { + typeLanguage = "@type"; + typeLanguageValue = "@id"; + } + // 2.7.3) + containers.add("@set"); + } + + // 2.8) + containers.add("@none"); + // 2.9) + if (typeLanguageValue == null) { + typeLanguageValue = "@null"; + } + // 2.10) + final List preferredValues = new ArrayList(); + // 2.11) + if ("@reverse".equals(typeLanguageValue)) { + preferredValues.add("@reverse"); + } + // 2.12) + if (("@reverse".equals(typeLanguageValue) || "@id" + .equals(typeLanguageValue)) + && (value instanceof Map) + && ((Map) value).containsKey("@id")) { + // 2.12.1) + final String result = this.compactIri( + (String) ((Map) value).get("@id"), + null, true, true); + if (termDefinitions.containsKey(result) + && ((Map) termDefinitions.get(result)) + .containsKey("@id") + && ((Map) value).get("@id").equals( + ((Map) termDefinitions + .get(result)).get("@id"))) { + preferredValues.add("@vocab"); + preferredValues.add("@id"); + } + // 2.12.2) + else { + preferredValues.add("@id"); + preferredValues.add("@vocab"); + } + } + // 2.13) + else { + preferredValues.add(typeLanguageValue); + } + preferredValues.add("@none"); + + // 2.14) + final String term = selectTerm(iri, containers, typeLanguage, + preferredValues); + // 2.15) + if (term != null) { + return term; + } + } + + // 3) + if (relativeToVocab && this.containsKey("@vocab")) { + // determine if vocab is a prefix of the iri + final String vocab = (String) this.get("@vocab"); + // 3.1) + if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { + // use suffix as relative iri if it is not a term in the + // active context + final String suffix = iri.substring(vocab.length()); + if (!termDefinitions.containsKey(suffix)) { + return suffix; + } + } + } + + // 4) + String compactIRI = null; + // 5) + for (final String term : termDefinitions.keySet()) { + final Map termDefinition = (Map) termDefinitions + .get(term); + // 5.1) + if (term.contains(":")) { + continue; + } + // 5.2) + if (termDefinition == null || iri.equals(termDefinition.get("@id")) + || !iri.startsWith((String) termDefinition.get("@id"))) { + continue; + } + + // 5.3) + final String candidate = term + + ":" + + iri.substring(((String) termDefinition.get("@id")) + .length()); + // 5.4) + if ((compactIRI == null || compareShortestLeast(candidate, + compactIRI) < 0) + && (!termDefinitions.containsKey(candidate) || (iri + .equals(((Map) termDefinitions + .get(candidate)).get("@id")) && value == null))) { + compactIRI = candidate; + } + + } + + // 6) + if (compactIRI != null) { + return compactIRI; + } + + // 7) + if (!relativeToVocab) { + return JsonLdUrl.removeBase(this.get("@base"), iri); + } + + // 8) + return iri; + } + + /** + * Return a map of potential RDF prefixes based on the JSON-LD Term + * Definitions in this context. + *

+ * No guarantees of the prefixes are given, + * beyond that it will not contain ":". + * + * @param onlyCommonPrefixes + * If true, the result will not include + * "not so useful" prefixes, such as "term1": + * "http://example.com/term1", e.g. all IRIs will + * end with "/" or "#". If false, all + * potential prefixes are returned. + * + * @return A map from prefix string to IRI string + */ + public Map getPrefixes(boolean onlyCommonPrefixes) { + Map prefixes = new LinkedHashMap(); + for (final String term : termDefinitions.keySet()) { + if (term.contains(":")) { + continue; + } + Map termDefinition = (Map) termDefinitions + .get(term); + if (termDefinition == null) { + continue; + } + String id = (String) termDefinition.get("@id"); + if (id == null) { + continue; + } + if (term.startsWith("@") || id.startsWith("@")) { + continue; + } + if (! onlyCommonPrefixes || id.endsWith("/") || id.endsWith("#")) { + prefixes.put(term, id); + } + } + return prefixes; + } + + String compactIri(String iri, boolean relativeToVocab) { + return compactIri(iri, null, relativeToVocab, false); + } + + String compactIri(String iri) { + return compactIri(iri, null, false, false); + } + + @Override + public Context clone() { + final Context rval = (Context) super.clone(); + // TODO: is this shallow copy enough? probably not, but it passes all + // the tests! + rval.termDefinitions = new LinkedHashMap( + this.termDefinitions); + return rval; + } + + /** + * Inverse Context Creation + * + * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation + * + * Generates an inverse context for use in the compaction algorithm, if not + * already generated for the given active context. + * + * @return the inverse context. + */ + public Map getInverse() { + + // lazily create inverse + if (inverse != null) { + return inverse; + } + + // 1) + inverse = new LinkedHashMap(); + + // 2) + String defaultLanguage = (String) this.get("@language"); + if (defaultLanguage == null) { + defaultLanguage = "@none"; + } + + // create term selections for each mapping in the context, ordererd by + // shortest and then lexicographically least + final List terms = new ArrayList( + termDefinitions.keySet()); + Collections.sort(terms, new Comparator() { + @Override + public int compare(String a, String b) { + return compareShortestLeast(a, b); + } + }); + + for (final String term : terms) { + final Map definition = (Map) termDefinitions + .get(term); + // 3.1) + if (definition == null) { + continue; + } + + // 3.2) + String container = (String) definition.get("@container"); + if (container == null) { + container = "@none"; + } + + // 3.3) + final String iri = (String) definition.get("@id"); + + // 3.4 + 3.5) + Map containerMap = (Map) inverse + .get(iri); + if (containerMap == null) { + containerMap = new LinkedHashMap(); + inverse.put(iri, containerMap); + } + + // 3.6 + 3.7) + Map typeLanguageMap = (Map) containerMap + .get(container); + if (typeLanguageMap == null) { + typeLanguageMap = new LinkedHashMap(); + typeLanguageMap.put("@language", + new LinkedHashMap()); + typeLanguageMap.put("@type", + new LinkedHashMap()); + containerMap.put(container, typeLanguageMap); + } + + // 3.8) + if (Boolean.TRUE.equals(definition.get("@reverse"))) { + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + if (!typeMap.containsKey("@reverse")) { + typeMap.put("@reverse", term); + } + // 3.9) + } else if (definition.containsKey("@type")) { + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + if (!typeMap.containsKey(definition.get("@type"))) { + typeMap.put((String) definition.get("@type"), term); + } + // 3.10) + } else if (definition.containsKey("@language")) { + final Map languageMap = (Map) typeLanguageMap + .get("@language"); + String language = (String) definition.get("@language"); + if (language == null) { + language = "@null"; + } + if (!languageMap.containsKey(language)) { + languageMap.put(language, term); + } + // 3.11) + } else { + // 3.11.1) + final Map languageMap = (Map) typeLanguageMap + .get("@language"); + // 3.11.2) + if (!languageMap.containsKey("@language")) { + languageMap.put("@language", term); + } + // 3.11.3) + if (!languageMap.containsKey("@none")) { + languageMap.put("@none", term); + } + // 3.11.4) + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + // 3.11.5) + if (!typeMap.containsKey("@none")) { + typeMap.put("@none", term); + } + } + } + // 4) + return inverse; + } + + /** + * Term Selection + * + * http://json-ld.org/spec/latest/json-ld-api/#term-selection + * + * This algorithm, invoked via the IRI Compaction algorithm, makes use of an + * active context's inverse context to find the term that is best used to + * compact an IRI. Other information about a value associated with the IRI + * is given, including which container mappings and which type mapping or + * language mapping would be best used to express the value. + * + * @return the selected term. + */ + private String selectTerm(String iri, List containers, + String typeLanguage, List preferredValues) { + final Map inv = getInverse(); + // 1) + final Map containerMap = (Map) inv + .get(iri); + // 2) + for (final String container : containers) { + // 2.1) + if (!containerMap.containsKey(container)) { + continue; + } + // 2.2) + final Map typeLanguageMap = (Map) containerMap + .get(container); + // 2.3) + final Map valueMap = (Map) typeLanguageMap + .get(typeLanguage); + // 2.4 ) + for (final String item : preferredValues) { + // 2.4.1 + if (!valueMap.containsKey(item)) { + continue; + } + // 2.4.2 + return (String) valueMap.get(item); + } + } + // 3) + return null; + } + + /** + * Retrieve container mapping. + * + * @param property + * The Property to get a container mapping for. + * @return The container mapping + */ + public String getContainer(String property) { + if ("@graph".equals(property)) { + return "@set"; + } + if (JsonLdUtils.isKeyword(property)) { + return property; + } + final Map td = (Map) termDefinitions + .get(property); + if (td == null) { + return null; + } + return (String) td.get("@container"); + } + + public Boolean isReverseProperty(String property) { + final Map td = (Map) termDefinitions + .get(property); + if (td == null) { + return false; + } + final Object reverse = td.get("@reverse"); + return reverse != null && (Boolean) reverse; + } + + private String getTypeMapping(String property) { + final Map td = (Map) termDefinitions + .get(property); + if (td == null) { + return null; + } + return (String) td.get("@type"); + } + + private String getLanguageMapping(String property) { + final Map td = (Map) termDefinitions + .get(property); + if (td == null) { + return null; + } + return (String) td.get("@language"); + } + + Map getTermDefinition(String key) { + return ((Map) termDefinitions.get(key)); + } + + public Object expandValue(String activeProperty, Object value) + throws JsonLdError { + final Map rval = new LinkedHashMap(); + final Map td = getTermDefinition(activeProperty); + // 1) + if (td != null && "@id".equals(td.get("@type"))) { + // TODO: i'm pretty sure value should be a string if the @type is + // @id + rval.put("@id", + expandIri(value.toString(), true, false, null, null)); + return rval; + } + // 2) + if (td != null && "@vocab".equals(td.get("@type"))) { + // TODO: same as above + rval.put("@id", expandIri(value.toString(), true, true, null, null)); + return rval; + } + // 3) + rval.put("@value", value); + // 4) + if (td != null && td.containsKey("@type")) { + rval.put("@type", td.get("@type")); + } + // 5) + else if (value instanceof String) { + // 5.1) + if (td != null && td.containsKey("@language")) { + final String lang = (String) td.get("@language"); + if (lang != null) { + rval.put("@language", lang); + } + } + // 5.2) + else if (this.get("@language") != null) { + rval.put("@language", this.get("@language")); + } + } + return rval; + } + + public Object getContextValue(String activeProperty, String string) + throws JsonLdError { + throw new JsonLdError(Error.NOT_IMPLEMENTED, + "getContextValue is only used by old code so far and thus isn't implemented"); + } + + public Map serialize() { + final Map ctx = new LinkedHashMap(); + if (this.get("@base") != null + && !this.get("@base").equals(options.getBase())) { + ctx.put("@base", this.get("@base")); + } + if (this.get("@language") != null) { + ctx.put("@language", this.get("@language")); + } + if (this.get("@vocab") != null) { + ctx.put("@vocab", this.get("@vocab")); + } + for (final String term : termDefinitions.keySet()) { + final Map definition = (Map) termDefinitions + .get(term); + if (definition.get("@language") == null + && definition.get("@container") == null + && definition.get("@type") == null + && (definition.get("@reverse") == null || Boolean.FALSE + .equals(definition.get("@reverse")))) { + final String cid = this.compactIri((String) definition + .get("@id")); + ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); + } else { + final Map defn = new LinkedHashMap(); + final String cid = this.compactIri((String) definition + .get("@id")); + final Boolean reverseProperty = Boolean.TRUE.equals(definition + .get("@reverse")); + if (!(term.equals(cid) && !reverseProperty)) { + defn.put(reverseProperty ? "@reverse" : "@id", cid); + } + final String typeMapping = (String) definition.get("@type"); + if (typeMapping != null) { + defn.put("@type", + JsonLdUtils.isKeyword(typeMapping) ? typeMapping + : compactIri(typeMapping, true)); + } + if (definition.get("@container") != null) { + defn.put("@container", definition.get("@container")); + } + final Object lang = definition.get("@language"); + if (definition.get("@language") != null) { + defn.put("@language", Boolean.FALSE.equals(lang) ? null + : lang); + } + ctx.put(term, defn); + } + } + + final Map rval = new LinkedHashMap(); + if (!(ctx == null || ctx.isEmpty())) { + rval.put("@context", ctx); + } + return rval; + } } \ No newline at end of file From d3d0027152ed43678043bd82d304485beeb37430 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 16:59:06 +0000 Subject: [PATCH 013/440] Use Context to parse contexts and find prefixes --- .../github/jsonldjava/core/RDFDataset.java | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 22cde3fa..939033b5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -15,6 +15,8 @@ import static com.github.jsonldjava.core.JsonLdUtils.isString; import static com.github.jsonldjava.core.JsonLdUtils.isValue; +import java.io.IOException; +import java.net.URL; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; @@ -25,6 +27,8 @@ import java.util.Set; import java.util.regex.Pattern; +import com.fasterxml.jackson.core.JsonParseException; + /** * Starting to migrate away from using plain java Maps as the internal RDF * dataset store. Currently each item just wraps a Map based on the old format @@ -359,8 +363,8 @@ public void setNamespace(String ns, String prefix) { context.put(ns, prefix); } - public void getNamespace(String ns) { - context.get(ns); + public String getNamespace(String ns) { + return context.get(ns); } /** @@ -394,45 +398,32 @@ public Map getContext() { * * @param context * The context to parse + * @throws JsonLdError If the context can't be parsed */ - public void parseContext(Object contextLike) { - Map context; - - if (contextLike instanceof Map) { - context = (Map) contextLike; - } else if (contextLike instanceof List) { - for (Object cntx : (List)contextLike) { - parseContext(cntx); - } - return; - } else if (contextLike instanceof String) { - // FIXME: Ignore external contexts for now - return; + public void parseContext(Object contextLike) throws JsonLdError { + Context context; + if (api != null) { + context = new Context(api.opts); } else { - throw new RuntimeException("Can't handle context of type " + contextLike.getClass()); + context = new Context(); } + // Context will do our recursive parsing and initial IRI resolution + context = context.parse(contextLike); + // And then leak to us the potential 'prefixes' + Map prefixes = context.getPrefixes(false); - for (final String key : context.keySet()) { - final Object val = context.get(key); + for (final String key : prefixes.keySet()) { + final String val = prefixes.get(key); if ("@vocab".equals(key)) { if (val == null || isString(val)) { setNamespace("", (String) val); } else { - // TODO: the context is actually invalid, should we throw an - // exception? } - } else if ("@context".equals(key)) { - // go deeper! - parseContext(context.get("@context")); } else if (!isKeyword(key)) { + setNamespace(key, val); // TODO: should we make sure val is a valid URI prefix (i.e. it // ends with /# or ?) // or is it ok that full URIs for terms are used? - if (val instanceof String) { - setNamespace(key, (String) context.get(key)); - } else if (isObject(val) && ((HashMap) val).containsKey("@id")) { - setNamespace(key, (String) ((HashMap) val).get("@id")); - } } } } From 275dd69655def6913eef121d513cdb31f730df6a Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 17:00:22 +0000 Subject: [PATCH 014/440] assert returned namespaces --- .../github/jsonldjava/core/ArrayContextToRDFTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index bf89d924..5f647d18 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -1,5 +1,6 @@ package com.github.jsonldjava.core; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.net.URL; @@ -33,8 +34,14 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { } }; options.setDocumentLoader(documentLoader); - Object rdf = JsonLdProcessor.toRDF(arrayContext, options); - System.out.println(rdf); + RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(arrayContext, options); + System.out.println(rdf.getNamespaces()); + assertEquals("http://example.org/", rdf.getNamespace("ex")); + assertEquals("http://example.com/2/", rdf.getNamespace("ex2")); + // FIXME: Should this also be included? + assertEquals("http://example.org/term1", rdf.getNamespace("term1")); +// assertFalse(rdf.getNamespaces().containsKey("term1")); + } } From 163bf3774eba0e8a7a6a7089a64429c9c13d9c95 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 17:01:13 +0000 Subject: [PATCH 015/440] Only 'common' prefixes returned - not every term --- .../main/java/com/github/jsonldjava/core/RDFDataset.java | 2 +- .../com/github/jsonldjava/core/ArrayContextToRDFTest.java | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 939033b5..a81b163a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -410,7 +410,7 @@ public void parseContext(Object contextLike) throws JsonLdError { // Context will do our recursive parsing and initial IRI resolution context = context.parse(contextLike); // And then leak to us the potential 'prefixes' - Map prefixes = context.getPrefixes(false); + Map prefixes = context.getPrefixes(true); for (final String key : prefixes.keySet()) { final String val = prefixes.get(key); diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index 5f647d18..e47031c9 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -1,7 +1,6 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; import java.net.URL; @@ -38,9 +37,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { System.out.println(rdf.getNamespaces()); assertEquals("http://example.org/", rdf.getNamespace("ex")); assertEquals("http://example.com/2/", rdf.getNamespace("ex2")); - // FIXME: Should this also be included? - assertEquals("http://example.org/term1", rdf.getNamespace("term1")); -// assertFalse(rdf.getNamespaces().containsKey("term1")); + // Only 'proper' prefixes returned + assertFalse(rdf.getNamespaces().containsKey("term1")); } From 09095fb6b1079fd3434484f2e0d97149401c2eae Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 17:03:31 +0000 Subject: [PATCH 016/440] Ignore purl.org test as purl.org is unstable (again) --- .../test/java/com/github/jsonldjava/utils/JsonUtilsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 50d7fe9a..c1092db8 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -29,6 +29,7 @@ import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; +import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -113,7 +114,7 @@ public void fromURLredirectHTTPSToHTTP() throws Exception { assertFalse(((Map) context).isEmpty()); } - // @Ignore("Integration test") + @Ignore("Integration test, purl.org is unstable") @Test public void fromURLredirect() throws Exception { final URL url = new URL("http://purl.org/wf4ever/ro-bundle/context.json"); From f80d91cb99e7ab2058f9df7da996f3a7e477b8b1 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 18 Mar 2014 17:46:37 +0000 Subject: [PATCH 017/440] Embedding JarCacheStorage Originally conceived at https://github.com/myGrid/httpclient-jarcache by Stian Soiland-Reyes (me) --- core/pom.xml | 5 - .../jsonldjava/core/DocumentLoader.java | 3 +- .../jsonldjava/utils/JarCacheResource.java | 42 ++++ .../jsonldjava/utils/JarCacheStorage.java | 209 ++++++++++++++++++ .../jsonldjava/core/DocumentLoaderTest.java | 10 +- 5 files changed, 257 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java create mode 100644 core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java diff --git a/core/pom.xml b/core/pom.xml index 7bed4494..7447c84c 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -57,11 +57,6 @@ sesame-rio-nquads test - - uk.org.taverna.httpclientjarcache - httpclient-jarcache - 0.0.2-SNAPSHOT - diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index f89e0563..9eb2fdfe 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -17,12 +17,11 @@ import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClient; -import uk.org.taverna.httpclient.jarcache.JarCacheStorage; - import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.MappingJsonFactory; +import com.github.jsonldjava.utils.JarCacheStorage; public class DocumentLoader { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java new file mode 100644 index 00000000..075a7083 --- /dev/null +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -0,0 +1,42 @@ +package com.github.jsonldjava.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.client.cache.Resource; + +public class JarCacheResource implements Resource { + + private static final long serialVersionUID = -7101296464577357444L; + + private final Log log = LogFactory.getLog(getClass()); + + private URLConnection connection; + + public JarCacheResource(URL classpath) throws IOException { + this.connection = classpath.openConnection(); + } + + @Override + public long length() { + return connection.getContentLengthLong(); + } + + @Override + public InputStream getInputStream() throws IOException { + return connection.getInputStream(); + } + + @Override + public void dispose() { + try { + connection.getInputStream().close(); + } catch (IOException e) { + log.error("Can't close JarCacheResource input stream", e); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java new file mode 100644 index 00000000..ddb2f100 --- /dev/null +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -0,0 +1,209 @@ +package com.github.jsonldjava.utils; + +import java.io.IOException; +import java.lang.ref.SoftReference; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpVersion; +import org.apache.http.client.cache.HeaderConstants; +import org.apache.http.client.cache.HttpCacheEntry; +import org.apache.http.client.cache.HttpCacheStorage; +import org.apache.http.client.cache.HttpCacheUpdateCallback; +import org.apache.http.client.cache.HttpCacheUpdateException; +import org.apache.http.client.cache.Resource; +import org.apache.http.impl.client.cache.CacheConfig; +import org.apache.http.impl.cookie.DateUtils; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.apache.http.protocol.HTTP; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JarCacheStorage implements HttpCacheStorage { + + private static final String JARCACHE_JSON = "jarcache.json"; + + private final Log log = LogFactory.getLog(getClass()); + + private CacheConfig cacheConfig = new CacheConfig(); + private ClassLoader classLoader; + + public ClassLoader getClassLoader() { + if (classLoader != null) { + return classLoader; + } + return Thread.currentThread().getContextClassLoader(); + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public JarCacheStorage() { + this(null); + } + + public JarCacheStorage(ClassLoader classLoader) { + setClassLoader(classLoader); + cacheConfig.setMaxObjectSize(0); + cacheConfig.setMaxCacheEntries(0); + cacheConfig.setMaxUpdateRetries(0); + cacheConfig.getMaxCacheEntries(); + } + + @Override + public void putEntry(String key, HttpCacheEntry entry) throws IOException { + // ignored + + } + + ObjectMapper mapper = new ObjectMapper(); + + @Override + public HttpCacheEntry getEntry(String key) throws IOException { + log.trace("Requesting " + key); + URI requestedUri; + try { + requestedUri = new URI(key); + } catch (URISyntaxException e) { + return null; + } + if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) + || (requestedUri.getScheme().equals("https") && requestedUri + .getPort() == 443)) { + // Strip away default http ports + try { + requestedUri = new URI(requestedUri.getScheme(), + requestedUri.getHost(), requestedUri.getPath(), + requestedUri.getFragment()); + } catch (URISyntaxException e) { + } + } + + Enumeration jarcaches = getResources(); + while (jarcaches.hasMoreElements()) { + URL url = jarcaches.nextElement(); + + JsonNode tree = getJarCache(url); + // TODO: Cache tree per URL + for (JsonNode node : tree) { + URI uri = URI.create(node.get("Content-Location").asText()); + if (uri.equals(requestedUri)) { + return cacheEntry(requestedUri, url, node); + + } + } + } + return null; + } + + private Enumeration getResources() throws IOException { + ClassLoader cl = getClassLoader(); + if (cl != null) { + return cl.getResources(JARCACHE_JSON); + } else { + return ClassLoader.getSystemResources(JARCACHE_JSON); + } + } + + /** Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) + * to a SoftReference to its content as JsonNode. + * + * @see #getJarCache(URL) + */ + protected Map> jarCaches = new ConcurrentHashMap(new HashMap>()); + + protected JsonNode getJarCache(URL url) throws IOException, + JsonProcessingException { + + URI uri; + try { + uri = url.toURI(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid jarCache URI " + url, e); + } + + // Check if we have one from before - we'll use SoftReference so that + // + SoftReference jarCacheRef = jarCaches.get(uri); + if (jarCacheRef != null) { + JsonNode jarCache = jarCacheRef.get(); + if (jarCache != null) { + return jarCache; + } else { + jarCaches.remove(uri); + } + } + + JsonNode tree = mapper.readTree(url); + jarCaches.put(uri, new SoftReference(tree)); + return tree; + } + + protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cacheNode) + throws MalformedURLException, IOException { + final URL classpath = new URL(baseURL, cacheNode.get("X-Classpath") + .asText()); + log.debug("Cache hit for " + requestedUri); + log.trace(cacheNode); + + List

responseHeaders = new ArrayList
(); + if (!cacheNode.has(HTTP.DATE_HEADER)) { + responseHeaders.add(new BasicHeader(HTTP.DATE_HEADER, + DateUtils.formatDate(new Date()))); + } + if (!cacheNode.has(HeaderConstants.CACHE_CONTROL)) { + responseHeaders.add(new BasicHeader( + HeaderConstants.CACHE_CONTROL, + HeaderConstants.CACHE_CONTROL_MAX_AGE + "=" + + Integer.MAX_VALUE)); + } + Resource resource = new JarCacheResource(classpath); + Iterator fieldNames = cacheNode.fieldNames(); + while (fieldNames.hasNext()) { + String headerName = fieldNames.next(); + JsonNode header = cacheNode.get(headerName); + // TODO: Support multiple headers with [] + responseHeaders.add(new BasicHeader(headerName, header + .asText())); + } + + return new HttpCacheEntry( + new Date(), + new Date(), + new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"), + responseHeaders.toArray(new Header[0]), resource); + } + + @Override + public void removeEntry(String key) throws IOException { + // Ignored + } + + @Override + public void updateEntry(String key, HttpCacheUpdateCallback callback) + throws IOException, HttpCacheUpdateException { + // ignored + } + + public CacheConfig getCacheConfig() { + return cacheConfig; + } + +} diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 32bd672a..57cdd491 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -1,6 +1,10 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -14,7 +18,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; @@ -24,7 +27,6 @@ import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.impl.client.cache.CachingHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; @@ -33,8 +35,6 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; -import uk.org.taverna.httpclient.jarcache.JarCacheStorage; - public class DocumentLoaderTest { DocumentLoader documentLoader = new DocumentLoader(); From f8e7db7be04e8db7ad43b99d5fd72d7e20c1fbfc Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 19 Mar 2014 12:23:07 +0000 Subject: [PATCH 018/440] Test JarCacheStorage --- .../github/jsonldjava/utils/TestJarCache.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java diff --git a/core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java b/core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java new file mode 100644 index 00000000..f6c3fcc4 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java @@ -0,0 +1,113 @@ +package com.github.jsonldjava.utils; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.SystemDefaultHttpClient; +import org.apache.http.impl.client.cache.CachingHttpClient; +import org.junit.After; +import org.junit.Test; + +public class TestJarCache { + + @Test + public void cacheHit() throws Exception { + JarCacheStorage storage = new JarCacheStorage(); + HttpClient httpClient = new CachingHttpClient( + new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + HttpResponse resp = httpClient.execute(get); + + assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); + String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + assertTrue(str.contains("ex:datatype")); + } + + + @Test(expected=IOException.class) + public void cacheMiss() throws Exception { + JarCacheStorage storage = new JarCacheStorage(); + HttpClient httpClient = new CachingHttpClient( + new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/notfound"); + // Should throw an IOException as the DNS name + // nonexisting.example.com does not exist + HttpResponse resp = httpClient.execute(get); + } + + + @Test + public void doubleLoad() throws Exception { + JarCacheStorage storage = new JarCacheStorage(); + HttpClient httpClient = new CachingHttpClient( + new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + HttpResponse resp = httpClient.execute(get); + resp = httpClient.execute(get); + // Ensure second load through the cached jarcache list works + assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); + } + + @Test + public void customClassPath() throws Exception { + URL nestedJar = getClass().getResource("/nested.jar"); + ClassLoader cl = new URLClassLoader(new URL[]{ nestedJar } ); + JarCacheStorage storage = new JarCacheStorage(cl); + + HttpClient httpClient = new CachingHttpClient( + new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); + HttpResponse resp = httpClient.execute(get); + + assertEquals("application/json", resp.getEntity().getContentType().getValue()); + String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + assertEquals("{ \"Hello\": \"World!\" }", str.trim()); + } + + @Test + public void contextClassLoader() throws Exception { + URL nestedJar = getClass().getResource("/nested.jar"); + assertNotNull(nestedJar); + ClassLoader cl = new URLClassLoader(new URL[]{ nestedJar } ); + + JarCacheStorage storage = new JarCacheStorage(); + Thread.currentThread().setContextClassLoader(cl); + + HttpClient httpClient = new CachingHttpClient( + new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); + HttpResponse resp = httpClient.execute(get); + + assertEquals("application/json", resp.getEntity().getContentType().getValue()); + String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + assertEquals("{ \"Hello\": \"World!\" }", str.trim()); + } + + @After + public void setContextClassLoader() { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + } + + @Test + public void systemClassLoader() throws Exception { + URL nestedJar = getClass().getResource("/nested.jar"); + assertNotNull(nestedJar); + ClassLoader cl = new URLClassLoader(new URL[]{ nestedJar } ); + JarCacheStorage storage = new JarCacheStorage(null); + + HttpClient httpClient = new CachingHttpClient( + new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + HttpResponse resp = httpClient.execute(get); + assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); + } + + +} From f803172da4ed192b68fccd7fb2f834f09370016b Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 19 Mar 2014 12:33:29 +0000 Subject: [PATCH 019/440] Use shared httpClient unless explicitly set --- .../jsonldjava/core/DocumentLoader.java | 68 +++++++++++-------- .../jsonldjava/core/DocumentLoaderTest.java | 31 ++++++--- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 9eb2fdfe..5c8d3d24 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -25,7 +25,8 @@ public class DocumentLoader { - public RemoteDocument loadDocument(String url) throws JsonLdError { + + public RemoteDocument loadDocument(String url) throws JsonLdError { RemoteDocument doc = new RemoteDocument(url, null); try { doc.setDocument(fromURL(new URL(url))); @@ -39,6 +40,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { * An HTTP Accept header that prefers JSONLD. */ public static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; + + protected static volatile CachingHttpClient defaultHttpClient; private volatile HttpClient httpClient; /** @@ -111,40 +114,45 @@ public InputStream openStreamFromURL(java.net.URL url) throws IOException { } return response.getEntity().getContent(); } + + protected static HttpClient getDefaultHttpClient() { + HttpClient result = defaultHttpClient; + if (result != null) { + return result; + } + synchronized (DocumentLoader.class) { + if (defaultHttpClient == null) { + // Uses Apache SystemDefaultHttpClient rather than + // DefaultHttpClient, thus the normal proxy settings for the + // JVM will be used - public HttpClient getHttpClient() { - HttpClient result = httpClient; - if (result == null) { - synchronized (this) { - result = httpClient; - if (result == null) { - // Uses Apache SystemDefaultHttpClient rather than - // DefaultHttpClient, thus the normal proxy settings for the - // JVM will be used - - final DefaultHttpClient client = new SystemDefaultHttpClient(); - // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 - client.addRequestInterceptor(new RequestAcceptEncoding()); - client.addResponseInterceptor(new ResponseContentEncoding()); - final CacheConfig cacheConfig = new CacheConfig(); - cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB - cacheConfig.setMaxCacheEntries(1000); - // and allow caching - CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); - - // Wrap again with JAR cache - JarCacheStorage jarCache = new JarCacheStorage(); - httpClient = new CachingHttpClient(cachingClient, jarCache, jarCache.getCacheConfig()); - - result = httpClient; - } + final DefaultHttpClient client = new SystemDefaultHttpClient(); + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + client.addRequestInterceptor(new RequestAcceptEncoding()); + client.addResponseInterceptor(new ResponseContentEncoding()); + final CacheConfig cacheConfig = new CacheConfig(); + cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB + cacheConfig.setMaxCacheEntries(1000); + // and allow caching + CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); + + // Wrap again with JAR cache + JarCacheStorage jarCache = new JarCacheStorage(); + defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, jarCache.getCacheConfig()); } + return defaultHttpClient; } - return result; } - public synchronized void setHttpClient(HttpClient nextHttpClient) { + public HttpClient getHttpClient() { + if (httpClient == null) { + return getDefaultHttpClient(); + } + return httpClient; + } + + public void setHttpClient(HttpClient nextHttpClient) { httpClient = nextHttpClient; } } diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 57cdd491..29fc77e7 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -1,10 +1,6 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -27,6 +23,7 @@ import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.impl.client.cache.CachingHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; @@ -258,8 +255,26 @@ public void jarCacheHitThreadCtx() throws Exception { Thread.currentThread().setContextClassLoader(cl); Object hello = documentLoader.fromURL(url); assertTrue(hello instanceof Map); - assertEquals("World!", ((Map)hello).get("Hello")); - + assertEquals("World!", ((Map)hello).get("Hello")); } - + + @Test + public void sharedHttpClient() throws Exception { + // Should be the same instance unless explicitly set + assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + } + + + @Test + public void differentHttpClient() throws Exception { + // Custom http client + documentLoader.setHttpClient(new SystemDefaultHttpClient()); + assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + + // Use default again + documentLoader.setHttpClient(null); + assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + } + + } From 43ee6f1e7ced1790ad1b3c0935a82b2056dd8158 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 19 Mar 2014 13:40:19 +0000 Subject: [PATCH 020/440] README about HTTP client and JAR cache --- README.md | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 041d40c6..8e4e9691 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Note: this is the documentation for the current unstable development branch. [Fo JSONLD-JAVA =========== -This is a Java implementation of the JSON-LD specification (http://json-ld.org/). +This is a Java implementation of the [JSON-LD specification](http://json-ld.org/). USAGE ===== @@ -38,9 +38,129 @@ Code example Processor options ----------------- - +A The Options specified by the [JSON-LD API Specification](http://json-ld.org/spec/latest/json-ld-api/#jsonldoptions) are accessible via the `com.github.jsonldjava.core.JsonLdOptions` class, and each `JsonLdProcessor.*` function has an optional input to take an instance of this class. + +Controlling network traffic +--------------------------- + +Parsing JSON-LD will normally follow any external `@context` declarations. +Loading these contexts from the network may in some cases not be desirable, or +might require additional proxy configuration or authentication. + +JSONLD-Java uses the [Apache HTTPComponents Client](https://hc.apache.org/httpcomponents-client-ga/index.html) for these network connections, +based on the [SystemDefaultHttpClient](http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/SystemDefaultHttpClient.html) which reads +standard Java properties like `http.proxyHost`. + +The default HTTP Client is wrapped with a +[CachingHttpClient](https://hc.apache.org/httpcomponents-client-ga/httpclient-cache/apidocs/org/apache/http/impl/client/cache/CachingHttpClient.html) to provide a +small memory-based cache (1000 objects, max 128 kB each) of regularly accessed contexts. + + +### Loading contexts from classpath/JAR + +Your application might be parsing JSONLD documents which always use the same +external `@context` IRIs. Although the default HTTP cache (see above) will +avoid repeated downloading of the same contexts, your application would still +initially be vulnerable to network connectivity. + +To bypass this issue, and even facilitate parsing of such documents in an +offline state, it is possible to provide a 'warmed' cache populated +from the classpath, e.g. loaded from a JAR. + +In your application, simply add a resource `jarcache.json` to the root of your +classpath together with the JSON-LD contexts to embed. (Note that you might +have to recursively embed any nested contexts). + +The syntax of `jarcache.json` is best explained by example: + + [ + { + "Content-Location": "http://www.example.com/context", + "X-Classpath": "contexts/example.jsonld", + "Content-Type": "application/ld+json" + }, + { + "Content-Location": "http://data.example.net/other", + "X-Classpath": "contexts/other.jsonld", + "Content-Type": "application/ld+json" + } + ] + +This will mean that any JSON-LD document trying to import the `@context` +`http://www.example.com/context` will instead be given +`contexts/example.jsonld` loaded as a classpath resource. + +The `X-Classpath` location is an IRI reference resolved relative to the +location of the `jarcache.json` - so if you have multiple JARs with a +`jarcache.json` each, then the `X-Classpath` will be resolved within the +corresponding JAR (minimizing any conclicts). + +Additional HTTP headers (such as `Content-Type` above) can be included, +although these are generally ignored by JSONLD-Java. + +Unless overridden, this `Cache-Control` header is injected, meaning that the +resource loaded from the JAR will never expire (the real IRI will never be +consulted by the Apache HTTP client): + + Date: Wed, 19 Mar 2014 13:25:08 GMT + Cache-Control: max-age=2147483647 + +The mechanism for loading `jarcache.json` relies on +[Thread.currentThread().getContextClassLoader()](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getContextClassLoader%28%29) +to locate resources from the classpath - if you are running on a command line, +within a framework (e.g. OSGi) or Servlet container this should normally be +set correctly. If not, try: + + ClassLoader oldContextCL = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + JsonLdProcessor.expand(input); // or any other JsonLd operation + } finally { + Thread.currentThread().setContextClassLoader(oldContextCL); + } + + + +### Customizing the Apache HttpClient + +To customize the HTTP behaviour (e.g. to disable the cache or provide +authentication credentials), you may want to create and configure your +own `HttpClient` instance, which can be passed to a `DocumentLoader` instance using +`setHttpClient()`. This document loader can then be inserted into +`JsonLdOptions` using `setDocumentLoader()` and passed as an argument to +`JsonLdProcessor` arguments. + +Example of inserting a credential provider (e.g. to load a `@context` protected +by HTTP Basic Auth): + + Object input = JsonUtils.fromInputStream(..); + DocumentLoader documentLoader = new DocumentLoader(); + + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope("localhost", 443), + new UsernamePasswordCredentials("username", "password")); + + DefaultHttpClient httpClient = new SystemDefaultHttpClient(); + httpClient.setCredentialsProvider(credsProvider); + + documentLoader.setHttpClient(httpClient); + + JsonLdOptions options = new JsonLdOptions(); + options.setDocumentLoader(documentLoader); + // .. and any other options + Object rdf = JsonLdProcessor.toRDF(input, options); + +Note that if you override the DocumentLoader HTTP Client, this would also +disable the JAR Cache (see above), unless reinitiated: + + JarCacheStorage jarCache = new JarCacheStorage(); + httpClient = new CachingHttpClient(httpClient, jarCache, jarCache.getCacheConfig()); + documentLoader.setHttpClient(httpClient); + + RDF implementation specific code -------------------------------- From e6a6781bf1afbf0f08bf5f8c143c7cf6d3ba1d8f Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 19 Mar 2014 13:47:20 +0000 Subject: [PATCH 021/440] README typos --- README.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8e4e9691..918bca8e 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,8 @@ The syntax of `jarcache.json` is best explained by example: } ] +(See also [core/src/test/resources/jarcache.json](core/src/test/resources/jarcache.json)). + This will mean that any JSON-LD document trying to import the `@context` `http://www.example.com/context` will instead be given `contexts/example.jsonld` loaded as a classpath resource. @@ -95,14 +97,15 @@ This will mean that any JSON-LD document trying to import the `@context` The `X-Classpath` location is an IRI reference resolved relative to the location of the `jarcache.json` - so if you have multiple JARs with a `jarcache.json` each, then the `X-Classpath` will be resolved within the -corresponding JAR (minimizing any conclicts). +corresponding JAR (minimizing any conflicts). Additional HTTP headers (such as `Content-Type` above) can be included, although these are generally ignored by JSONLD-Java. -Unless overridden, this `Cache-Control` header is injected, meaning that the -resource loaded from the JAR will never expire (the real IRI will never be -consulted by the Apache HTTP client): +Unless overridden in `jarcache.json`, this `Cache-Control` header is +autoamtically injected together with the current `Date`, meaning that the +resource loaded from the JAR will effectively never expire (the real HTTP +server will never be consulted by the Apache HTTP client): Date: Wed, 19 Mar 2014 13:25:08 GMT Cache-Control: max-age=2147483647 @@ -110,14 +113,16 @@ consulted by the Apache HTTP client): The mechanism for loading `jarcache.json` relies on [Thread.currentThread().getContextClassLoader()](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getContextClassLoader%28%29) to locate resources from the classpath - if you are running on a command line, -within a framework (e.g. OSGi) or Servlet container this should normally be -set correctly. If not, try: +within a framework (e.g. OSGi) or Servlet container (e.g. Tomcat) this should +normally be set correctly. If not, try: ClassLoader oldContextCL = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); JsonLdProcessor.expand(input); // or any other JsonLd operation } finally { + // Restore, in case the current thread was doing something else + // with the context classloader before calling our method Thread.currentThread().setContextClassLoader(oldContextCL); } @@ -126,11 +131,12 @@ set correctly. If not, try: ### Customizing the Apache HttpClient To customize the HTTP behaviour (e.g. to disable the cache or provide -authentication credentials), you may want to create and configure your -own `HttpClient` instance, which can be passed to a `DocumentLoader` instance using -`setHttpClient()`. This document loader can then be inserted into -`JsonLdOptions` using `setDocumentLoader()` and passed as an argument to -`JsonLdProcessor` arguments. +[authentication +credentials)](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html), +you may want to create and configure your own `HttpClient` instance, which can +be passed to a `DocumentLoader` instance using `setHttpClient()`. This document +loader can then be inserted into `JsonLdOptions` using `setDocumentLoader()` +and passed as an argument to `JsonLdProcessor` arguments. Example of inserting a credential provider (e.g. to load a `@context` protected by HTTP Basic Auth): From 8313298e8321b8a4985fddeb74fa5def265aafd8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 12:18:14 +1100 Subject: [PATCH 022/440] Reformat to use our style --- .../com/github/jsonldjava/core/Context.java | 2262 ++++++++--------- .../github/jsonldjava/core/RDFDataset.java | 27 +- .../core/ArrayContextToRDFTest.java | 64 +- 3 files changed, 1137 insertions(+), 1216 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 69a2e089..f234f472 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -23,1175 +23,1097 @@ */ public class Context extends LinkedHashMap { - private JsonLdOptions options; - private Map termDefinitions; - public Map inverse = null; - - public Context() { - this(new JsonLdOptions()); - } - - public Context(JsonLdOptions opts) { - super(); - init(opts); - } - - public Context(Map map, JsonLdOptions opts) { - super(map); - init(opts); - } - - public Context(Map map) { - super(map); - init(new JsonLdOptions()); - } - - public Context(Object context, JsonLdOptions opts) { - // TODO: load remote context - super(context instanceof Map ? (Map) context : null); - init(opts); - } - - private void init(JsonLdOptions options) { - this.options = options; - if (options.getBase() != null) { - this.put("@base", options.getBase()); - } - this.termDefinitions = new LinkedHashMap(); - } - - /** - * Value Compaction Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#value-compaction - * - * @param activeProperty - * The Active Property - * @param value - * The value to compact - * @return The compacted value - */ - public Object compactValue(String activeProperty, Map value) { - // 1) - int numberMembers = value.size(); - // 2) - if (value.containsKey("@index") - && "@index".equals(this.getContainer(activeProperty))) { - numberMembers--; - } - // 3) - if (numberMembers > 2) { - return value; - } - // 4) - final String typeMapping = getTypeMapping(activeProperty); - final String languageMapping = getLanguageMapping(activeProperty); - if (value.containsKey("@id")) { - // 4.1) - if (numberMembers == 1 && "@id".equals(typeMapping)) { - return compactIri((String) value.get("@id")); - } - // 4.2) - if (numberMembers == 1 && "@vocab".equals(typeMapping)) { - return compactIri((String) value.get("@id"), true); - } - // 4.3) - return value; - } - final Object valueValue = value.get("@value"); - // 5) - if (value.containsKey("@type") - && Obj.equals(value.get("@type"), typeMapping)) { - return valueValue; - } - // 6) - if (value.containsKey("@language")) { - // TODO: SPEC: doesn't specify to check default language as well - if (Obj.equals(value.get("@language"), languageMapping) - || Obj.equals(value.get("@language"), this.get("@language"))) { - return valueValue; - } - } - // 7) - if (numberMembers == 1 - && (!(valueValue instanceof String) - || !this.containsKey("@language") || (getTermDefinition( - activeProperty).containsKey("@language") && languageMapping == null))) { - return valueValue; - } - // 8) - return value; - } - - /** - * Context Processing Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms - * - * @param localContext - * The Local Context object. - * @param remoteContexts - * The list of Strings denoting the remote Context URLs. - * @return The parsed and merged Context. - * @throws JsonLdError - * If there is an error parsing the contexts. - */ - public Context parse(Object localContext, List remoteContexts) - throws JsonLdError { - if (remoteContexts == null) { - remoteContexts = new ArrayList(); - } - // 1. Initialize result to the result of cloning active context. - Context result = this.clone(); // TODO: clone? - // 2) - if (!(localContext instanceof List)) { - final Object temp = localContext; - localContext = new ArrayList(); - ((List) localContext).add(temp); - } - // 3) - for (Object context : ((List) localContext)) { - // 3.1) - if (context == null) { - result = new Context(this.options); - continue; - } else if (context instanceof Context) { - result = ((Context) context).clone(); - } - // 3.2) - else if (context instanceof String) { - String uri = (String) result.get("@base"); - uri = JsonLdUrl.resolve(uri, (String) context); - // 3.2.2 - if (remoteContexts.contains(uri)) { - throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, - uri); - } - remoteContexts.add(uri); - - // 3.2.3: Dereference context - final RemoteDocument rd = this.options.getDocumentLoader() - .loadDocument(uri); - final Object remoteContext = rd.document; - if (!(remoteContext instanceof Map) - || !((Map) remoteContext) - .containsKey("@context")) { - // If the dereferenced document has no top-level JSON object - // with an @context member - throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); - } - context = ((Map) remoteContext).get("@context"); - - // 3.2.4 - result = result.parse(context, remoteContexts); - // 3.2.5 - continue; - } else if (!(context instanceof Map)) { - // 3.3 - throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); - } - - // 3.4 - if (remoteContexts.isEmpty() - && ((Map) context).containsKey("@base")) { - final Object value = ((Map) context) - .get("@base"); - if (value == null) { - result.remove("@base"); - } else if (value instanceof String) { - if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@base", value); - } else { - final String baseUri = (String) result.get("@base"); - if (!JsonLdUtils.isAbsoluteIri(baseUri)) { - throw new JsonLdError(Error.INVALID_BASE_IRI, - baseUri); - } - result.put("@base", - JsonLdUrl.resolve(baseUri, (String) value)); - } - } else { - throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, - "@base must be a string"); - } - } - - // 3.5 - if (((Map) context).containsKey("@vocab")) { - final Object value = ((Map) context) - .get("@vocab"); - if (value == null) { - result.remove("@vocab"); - } else if (value instanceof String) { - if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@vocab", value); - } else { - throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, - "@value must be an absolute IRI"); - } - } else { - throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, - "@vocab must be a string or null"); - } - } - - // 3.6 - if (((Map) context).containsKey("@language")) { - final Object value = ((Map) context) - .get("@language"); - if (value == null) { - result.remove("@language"); - } else if (value instanceof String) { - result.put("@language", ((String) value).toLowerCase()); - } else { - throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); - } - } - - // 3.7 - final Map defined = new LinkedHashMap(); - for (final String key : ((Map) context).keySet()) { - if ("@base".equals(key) || "@vocab".equals(key) - || "@language".equals(key)) { - continue; - } - result.createTermDefinition((Map) context, key, - defined); - } - } - return result; - } - - public Context parse(Object localContext) throws JsonLdError { - return this.parse(localContext, new ArrayList()); - } - - /** - * Create Term Definition Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition - * - * @param result - * @param context - * @param key - * @param defined - * @throws JsonLdError - */ - private void createTermDefinition(Map context, String term, - Map defined) throws JsonLdError { - if (defined.containsKey(term)) { - if (Boolean.TRUE.equals(defined.get(term))) { - return; - } - throw new JsonLdError(Error.CYCLIC_IRI_MAPPING, term); - } - - defined.put(term, false); - - if (JsonLdUtils.isKeyword(term)) { - throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); - } - - this.termDefinitions.remove(term); - Object value = context.get(term); - if (value == null - || (value instanceof Map - && ((Map) value).containsKey("@id") && ((Map) value) - .get("@id") == null)) { - this.termDefinitions.put(term, null); - defined.put(term, true); - return; - } - - if (value instanceof String) { - final Map tmp = new LinkedHashMap(); - tmp.put("@id", value); - value = tmp; - } - - if (!(value instanceof Map)) { - throw new JsonLdError(Error.INVALID_TERM_DEFINITION, value); - } - - // casting the value so it doesn't have to be done below everytime - final Map val = (Map) value; - - // 9) create a new term definition - final Map definition = new LinkedHashMap(); - - // 10) - if (val.containsKey("@type")) { - if (!(val.get("@type") instanceof String)) { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, - val.get("@type")); - } - String type = (String) val.get("@type"); - try { - type = this.expandIri((String) val.get("@type"), false, true, - context, defined); - } catch (final JsonLdError error) { - if (error.getType() != Error.INVALID_IRI_MAPPING) { - throw error; - } - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); - } - // TODO: fix check for absoluteIri (blank nodes shouldn't count, at - // least not here!) - if ("@id".equals(type) - || "@vocab".equals(type) - || (!type.startsWith("_:") && JsonLdUtils - .isAbsoluteIri(type))) { - definition.put("@type", type); - } else { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); - } - } - - // 11) - if (val.containsKey("@reverse")) { - if (val.containsKey("@id")) { - throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); - } - if (!(val.get("@reverse") instanceof String)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "Expected String for @reverse value. got " - + (val.get("@reverse") == null ? "null" : val - .get("@reverse").getClass())); - } - final String reverse = this.expandIri((String) val.get("@reverse"), - false, true, context, defined); - if (!JsonLdUtils.isAbsoluteIri(reverse)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "Non-absolute @reverse IRI: " + reverse); - } - definition.put("@id", reverse); - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (container == null || "@set".equals(container) - || "@index".equals(container)) { - definition.put("@container", container); - } else { - throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, - "reverse properties only support set- and index-containers"); - } - } - definition.put("@reverse", true); - this.termDefinitions.put(term, definition); - defined.put(term, true); - return; - } - - // 12) - definition.put("@reverse", false); - - // 13) - if (val.get("@id") != null && !term.equals(val.get("@id"))) { - if (!(val.get("@id") instanceof String)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "expected value of @id to be a string"); - } - - final String res = this.expandIri((String) val.get("@id"), false, - true, context, defined); - if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { - if ("@context".equals(res)) { - throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, - "cannot alias @context"); - } - definition.put("@id", res); - } else { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "resulting IRI mapping should be a keyword, absolute IRI or blank node"); - } - } - - // 14) - else if (term.indexOf(":") >= 0) { - final int colIndex = term.indexOf(":"); - final String prefix = term.substring(0, colIndex); - final String suffix = term.substring(colIndex + 1); - if (context.containsKey(prefix)) { - this.createTermDefinition(context, prefix, defined); - } - if (termDefinitions.containsKey(prefix)) { - definition.put( - "@id", - ((Map) termDefinitions.get(prefix)) - .get("@id") + suffix); - } else { - definition.put("@id", term); - } - // 15) - } else if (this.containsKey("@vocab")) { - definition.put("@id", this.get("@vocab") + term); - } else { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "relative term definition without vocab mapping"); - } - - // 16) - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (!"@list".equals(container) && !"@set".equals(container) - && !"@index".equals(container) - && !"@language".equals(container)) { - throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, - "@container must be either @list, @set, @index, or @language"); - } - definition.put("@container", container); - } - - // 17) - if (val.containsKey("@language") && !val.containsKey("@type")) { - if (val.get("@language") == null - || val.get("@language") instanceof String) { - final String language = (String) val.get("@language"); - definition.put("@language", - language != null ? language.toLowerCase() : null); - } else { - throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, - "@language must be a string or null"); - } - } - - // 18) - this.termDefinitions.put(term, definition); - defined.put(term, true); - } - - /** - * IRI Expansion Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion - * - * @param value - * @param relative - * @param vocab - * @param context - * @param defined - * @return - * @throws JsonLdError - */ - String expandIri(String value, boolean relative, boolean vocab, - Map context, Map defined) - throws JsonLdError { - // 1) - if (value == null || JsonLdUtils.isKeyword(value)) { - return value; - } - // 2) - if (context != null && context.containsKey(value) - && !Boolean.TRUE.equals(defined.get(value))) { - this.createTermDefinition(context, value, defined); - } - // 3) - if (vocab && this.termDefinitions.containsKey(value)) { - final Map td = (LinkedHashMap) this.termDefinitions - .get(value); - if (td != null) { - return (String) td.get("@id"); - } else { - return null; - } - } - // 4) - final int colIndex = value.indexOf(":"); - if (colIndex >= 0) { - // 4.1) - final String prefix = value.substring(0, colIndex); - final String suffix = value.substring(colIndex + 1); - // 4.2) - if ("_".equals(prefix) || suffix.startsWith("//")) { - return value; - } - // 4.3) - if (context != null - && context.containsKey(prefix) - && (!defined.containsKey(prefix) || defined.get(prefix) == false)) { - this.createTermDefinition(context, prefix, defined); - } - // 4.4) - if (this.termDefinitions.containsKey(prefix)) { - return (String) ((LinkedHashMap) this.termDefinitions - .get(prefix)).get("@id") + suffix; - } - // 4.5) - return value; - } - // 5) - if (vocab && this.containsKey("@vocab")) { - return this.get("@vocab") + value; - } - // 6) - else if (relative) { - return JsonLdUrl.resolve((String) this.get("@base"), value); - } else if (context != null && JsonLdUtils.isRelativeIri(value)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "not an absolute IRI: " + value); - } - // 7) - return value; - } - - /** - * IRI Compaction Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction - * - * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI - * has an associated value it may be passed. - * - * @param iri - * the IRI to compact. - * @param value - * the value to check or null. - * @param relativeTo - * options for how to compact IRIs: vocab: true to split after - * @vocab, false not to. - * @param reverse - * true if a reverse property is being compacted, false if not. - * - * @return the compacted term, prefix, keyword alias, or the original IRI. - */ - String compactIri(String iri, Object value, boolean relativeToVocab, - boolean reverse) { - // 1) - if (iri == null) { - return null; - } - - // 2) - if (relativeToVocab && getInverse().containsKey(iri)) { - // 2.1) - String defaultLanguage = (String) this.get("@language"); - if (defaultLanguage == null) { - defaultLanguage = "@none"; - } - - // 2.2) - final List containers = new ArrayList(); - // 2.3) - String typeLanguage = "@language"; - String typeLanguageValue = "@null"; - - // 2.4) - if (value instanceof Map - && ((Map) value).containsKey("@index")) { - containers.add("@index"); - } - - // 2.5) - if (reverse) { - typeLanguage = "@type"; - typeLanguageValue = "@reverse"; - containers.add("@set"); - } - // 2.6) - else if (value instanceof Map - && ((Map) value).containsKey("@list")) { - // 2.6.1) - if (!((Map) value).containsKey("@index")) { - containers.add("@list"); - } - // 2.6.2) - final List list = (List) ((Map) value) - .get("@list"); - // 2.6.3) - String commonLanguage = (list.size() == 0) ? defaultLanguage - : null; - String commonType = null; - // 2.6.4) - for (final Object item : list) { - // 2.6.4.1) - String itemLanguage = "@none"; - String itemType = "@none"; - // 2.6.4.2) - if (JsonLdUtils.isValue(item)) { - // 2.6.4.2.1) - if (((Map) item) - .containsKey("@language")) { - itemLanguage = (String) ((Map) item) - .get("@language"); - } - // 2.6.4.2.2) - else if (((Map) item) - .containsKey("@type")) { - itemType = (String) ((Map) item) - .get("@type"); - } - // 2.6.4.2.3) - else { - itemLanguage = "@null"; - } - } - // 2.6.4.3) - else { - itemType = "@id"; - } - // 2.6.4.4) - if (commonLanguage == null) { - commonLanguage = itemLanguage; - } - // 2.6.4.5) - else if (!commonLanguage.equals(itemLanguage) - && JsonLdUtils.isValue(item)) { - commonLanguage = "@none"; - } - // 2.6.4.6) - if (commonType == null) { - commonType = itemType; - } - // 2.6.4.7) - else if (!commonType.equals(itemType)) { - commonType = "@none"; - } - // 2.6.4.8) - if ("@none".equals(commonLanguage) - && "@none".equals(commonType)) { - break; - } - } - // 2.6.5) - commonLanguage = (commonLanguage != null) ? commonLanguage - : "@none"; - // 2.6.6) - commonType = (commonType != null) ? commonType : "@none"; - // 2.6.7) - if (!"@none".equals(commonType)) { - typeLanguage = "@type"; - typeLanguageValue = commonType; - } - // 2.6.8) - else { - typeLanguageValue = commonLanguage; - } - } - // 2.7) - else { - // 2.7.1) - if (value instanceof Map - && ((Map) value).containsKey("@value")) { - // 2.7.1.1) - if (((Map) value).containsKey("@language") - && !((Map) value) - .containsKey("@index")) { - containers.add("@language"); - typeLanguageValue = (String) ((Map) value) - .get("@language"); - } - // 2.7.1.2) - else if (((Map) value).containsKey("@type")) { - typeLanguage = "@type"; - typeLanguageValue = (String) ((Map) value) - .get("@type"); - } - } - // 2.7.2) - else { - typeLanguage = "@type"; - typeLanguageValue = "@id"; - } - // 2.7.3) - containers.add("@set"); - } - - // 2.8) - containers.add("@none"); - // 2.9) - if (typeLanguageValue == null) { - typeLanguageValue = "@null"; - } - // 2.10) - final List preferredValues = new ArrayList(); - // 2.11) - if ("@reverse".equals(typeLanguageValue)) { - preferredValues.add("@reverse"); - } - // 2.12) - if (("@reverse".equals(typeLanguageValue) || "@id" - .equals(typeLanguageValue)) - && (value instanceof Map) - && ((Map) value).containsKey("@id")) { - // 2.12.1) - final String result = this.compactIri( - (String) ((Map) value).get("@id"), - null, true, true); - if (termDefinitions.containsKey(result) - && ((Map) termDefinitions.get(result)) - .containsKey("@id") - && ((Map) value).get("@id").equals( - ((Map) termDefinitions - .get(result)).get("@id"))) { - preferredValues.add("@vocab"); - preferredValues.add("@id"); - } - // 2.12.2) - else { - preferredValues.add("@id"); - preferredValues.add("@vocab"); - } - } - // 2.13) - else { - preferredValues.add(typeLanguageValue); - } - preferredValues.add("@none"); - - // 2.14) - final String term = selectTerm(iri, containers, typeLanguage, - preferredValues); - // 2.15) - if (term != null) { - return term; - } - } - - // 3) - if (relativeToVocab && this.containsKey("@vocab")) { - // determine if vocab is a prefix of the iri - final String vocab = (String) this.get("@vocab"); - // 3.1) - if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { - // use suffix as relative iri if it is not a term in the - // active context - final String suffix = iri.substring(vocab.length()); - if (!termDefinitions.containsKey(suffix)) { - return suffix; - } - } - } - - // 4) - String compactIRI = null; - // 5) - for (final String term : termDefinitions.keySet()) { - final Map termDefinition = (Map) termDefinitions - .get(term); - // 5.1) - if (term.contains(":")) { - continue; - } - // 5.2) - if (termDefinition == null || iri.equals(termDefinition.get("@id")) - || !iri.startsWith((String) termDefinition.get("@id"))) { - continue; - } - - // 5.3) - final String candidate = term - + ":" - + iri.substring(((String) termDefinition.get("@id")) - .length()); - // 5.4) - if ((compactIRI == null || compareShortestLeast(candidate, - compactIRI) < 0) - && (!termDefinitions.containsKey(candidate) || (iri - .equals(((Map) termDefinitions - .get(candidate)).get("@id")) && value == null))) { - compactIRI = candidate; - } - - } - - // 6) - if (compactIRI != null) { - return compactIRI; - } - - // 7) - if (!relativeToVocab) { - return JsonLdUrl.removeBase(this.get("@base"), iri); - } - - // 8) - return iri; - } - - /** - * Return a map of potential RDF prefixes based on the JSON-LD Term - * Definitions in this context. - *

- * No guarantees of the prefixes are given, - * beyond that it will not contain ":". - * - * @param onlyCommonPrefixes - * If true, the result will not include - * "not so useful" prefixes, such as "term1": - * "http://example.com/term1", e.g. all IRIs will - * end with "/" or "#". If false, all - * potential prefixes are returned. - * - * @return A map from prefix string to IRI string - */ - public Map getPrefixes(boolean onlyCommonPrefixes) { - Map prefixes = new LinkedHashMap(); - for (final String term : termDefinitions.keySet()) { - if (term.contains(":")) { - continue; - } - Map termDefinition = (Map) termDefinitions - .get(term); - if (termDefinition == null) { - continue; - } - String id = (String) termDefinition.get("@id"); - if (id == null) { - continue; - } - if (term.startsWith("@") || id.startsWith("@")) { - continue; - } - if (! onlyCommonPrefixes || id.endsWith("/") || id.endsWith("#")) { - prefixes.put(term, id); - } - } - return prefixes; - } - - String compactIri(String iri, boolean relativeToVocab) { - return compactIri(iri, null, relativeToVocab, false); - } - - String compactIri(String iri) { - return compactIri(iri, null, false, false); - } - - @Override - public Context clone() { - final Context rval = (Context) super.clone(); - // TODO: is this shallow copy enough? probably not, but it passes all - // the tests! - rval.termDefinitions = new LinkedHashMap( - this.termDefinitions); - return rval; - } - - /** - * Inverse Context Creation - * - * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation - * - * Generates an inverse context for use in the compaction algorithm, if not - * already generated for the given active context. - * - * @return the inverse context. - */ - public Map getInverse() { - - // lazily create inverse - if (inverse != null) { - return inverse; - } - - // 1) - inverse = new LinkedHashMap(); - - // 2) - String defaultLanguage = (String) this.get("@language"); - if (defaultLanguage == null) { - defaultLanguage = "@none"; - } - - // create term selections for each mapping in the context, ordererd by - // shortest and then lexicographically least - final List terms = new ArrayList( - termDefinitions.keySet()); - Collections.sort(terms, new Comparator() { - @Override - public int compare(String a, String b) { - return compareShortestLeast(a, b); - } - }); - - for (final String term : terms) { - final Map definition = (Map) termDefinitions - .get(term); - // 3.1) - if (definition == null) { - continue; - } - - // 3.2) - String container = (String) definition.get("@container"); - if (container == null) { - container = "@none"; - } - - // 3.3) - final String iri = (String) definition.get("@id"); - - // 3.4 + 3.5) - Map containerMap = (Map) inverse - .get(iri); - if (containerMap == null) { - containerMap = new LinkedHashMap(); - inverse.put(iri, containerMap); - } - - // 3.6 + 3.7) - Map typeLanguageMap = (Map) containerMap - .get(container); - if (typeLanguageMap == null) { - typeLanguageMap = new LinkedHashMap(); - typeLanguageMap.put("@language", - new LinkedHashMap()); - typeLanguageMap.put("@type", - new LinkedHashMap()); - containerMap.put(container, typeLanguageMap); - } - - // 3.8) - if (Boolean.TRUE.equals(definition.get("@reverse"))) { - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey("@reverse")) { - typeMap.put("@reverse", term); - } - // 3.9) - } else if (definition.containsKey("@type")) { - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey(definition.get("@type"))) { - typeMap.put((String) definition.get("@type"), term); - } - // 3.10) - } else if (definition.containsKey("@language")) { - final Map languageMap = (Map) typeLanguageMap - .get("@language"); - String language = (String) definition.get("@language"); - if (language == null) { - language = "@null"; - } - if (!languageMap.containsKey(language)) { - languageMap.put(language, term); - } - // 3.11) - } else { - // 3.11.1) - final Map languageMap = (Map) typeLanguageMap - .get("@language"); - // 3.11.2) - if (!languageMap.containsKey("@language")) { - languageMap.put("@language", term); - } - // 3.11.3) - if (!languageMap.containsKey("@none")) { - languageMap.put("@none", term); - } - // 3.11.4) - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - // 3.11.5) - if (!typeMap.containsKey("@none")) { - typeMap.put("@none", term); - } - } - } - // 4) - return inverse; - } - - /** - * Term Selection - * - * http://json-ld.org/spec/latest/json-ld-api/#term-selection - * - * This algorithm, invoked via the IRI Compaction algorithm, makes use of an - * active context's inverse context to find the term that is best used to - * compact an IRI. Other information about a value associated with the IRI - * is given, including which container mappings and which type mapping or - * language mapping would be best used to express the value. - * - * @return the selected term. - */ - private String selectTerm(String iri, List containers, - String typeLanguage, List preferredValues) { - final Map inv = getInverse(); - // 1) - final Map containerMap = (Map) inv - .get(iri); - // 2) - for (final String container : containers) { - // 2.1) - if (!containerMap.containsKey(container)) { - continue; - } - // 2.2) - final Map typeLanguageMap = (Map) containerMap - .get(container); - // 2.3) - final Map valueMap = (Map) typeLanguageMap - .get(typeLanguage); - // 2.4 ) - for (final String item : preferredValues) { - // 2.4.1 - if (!valueMap.containsKey(item)) { - continue; - } - // 2.4.2 - return (String) valueMap.get(item); - } - } - // 3) - return null; - } - - /** - * Retrieve container mapping. - * - * @param property - * The Property to get a container mapping for. - * @return The container mapping - */ - public String getContainer(String property) { - if ("@graph".equals(property)) { - return "@set"; - } - if (JsonLdUtils.isKeyword(property)) { - return property; - } - final Map td = (Map) termDefinitions - .get(property); - if (td == null) { - return null; - } - return (String) td.get("@container"); - } - - public Boolean isReverseProperty(String property) { - final Map td = (Map) termDefinitions - .get(property); - if (td == null) { - return false; - } - final Object reverse = td.get("@reverse"); - return reverse != null && (Boolean) reverse; - } - - private String getTypeMapping(String property) { - final Map td = (Map) termDefinitions - .get(property); - if (td == null) { - return null; - } - return (String) td.get("@type"); - } - - private String getLanguageMapping(String property) { - final Map td = (Map) termDefinitions - .get(property); - if (td == null) { - return null; - } - return (String) td.get("@language"); - } - - Map getTermDefinition(String key) { - return ((Map) termDefinitions.get(key)); - } - - public Object expandValue(String activeProperty, Object value) - throws JsonLdError { - final Map rval = new LinkedHashMap(); - final Map td = getTermDefinition(activeProperty); - // 1) - if (td != null && "@id".equals(td.get("@type"))) { - // TODO: i'm pretty sure value should be a string if the @type is - // @id - rval.put("@id", - expandIri(value.toString(), true, false, null, null)); - return rval; - } - // 2) - if (td != null && "@vocab".equals(td.get("@type"))) { - // TODO: same as above - rval.put("@id", expandIri(value.toString(), true, true, null, null)); - return rval; - } - // 3) - rval.put("@value", value); - // 4) - if (td != null && td.containsKey("@type")) { - rval.put("@type", td.get("@type")); - } - // 5) - else if (value instanceof String) { - // 5.1) - if (td != null && td.containsKey("@language")) { - final String lang = (String) td.get("@language"); - if (lang != null) { - rval.put("@language", lang); - } - } - // 5.2) - else if (this.get("@language") != null) { - rval.put("@language", this.get("@language")); - } - } - return rval; - } - - public Object getContextValue(String activeProperty, String string) - throws JsonLdError { - throw new JsonLdError(Error.NOT_IMPLEMENTED, - "getContextValue is only used by old code so far and thus isn't implemented"); - } - - public Map serialize() { - final Map ctx = new LinkedHashMap(); - if (this.get("@base") != null - && !this.get("@base").equals(options.getBase())) { - ctx.put("@base", this.get("@base")); - } - if (this.get("@language") != null) { - ctx.put("@language", this.get("@language")); - } - if (this.get("@vocab") != null) { - ctx.put("@vocab", this.get("@vocab")); - } - for (final String term : termDefinitions.keySet()) { - final Map definition = (Map) termDefinitions - .get(term); - if (definition.get("@language") == null - && definition.get("@container") == null - && definition.get("@type") == null - && (definition.get("@reverse") == null || Boolean.FALSE - .equals(definition.get("@reverse")))) { - final String cid = this.compactIri((String) definition - .get("@id")); - ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); - } else { - final Map defn = new LinkedHashMap(); - final String cid = this.compactIri((String) definition - .get("@id")); - final Boolean reverseProperty = Boolean.TRUE.equals(definition - .get("@reverse")); - if (!(term.equals(cid) && !reverseProperty)) { - defn.put(reverseProperty ? "@reverse" : "@id", cid); - } - final String typeMapping = (String) definition.get("@type"); - if (typeMapping != null) { - defn.put("@type", - JsonLdUtils.isKeyword(typeMapping) ? typeMapping - : compactIri(typeMapping, true)); - } - if (definition.get("@container") != null) { - defn.put("@container", definition.get("@container")); - } - final Object lang = definition.get("@language"); - if (definition.get("@language") != null) { - defn.put("@language", Boolean.FALSE.equals(lang) ? null - : lang); - } - ctx.put(term, defn); - } - } - - final Map rval = new LinkedHashMap(); - if (!(ctx == null || ctx.isEmpty())) { - rval.put("@context", ctx); - } - return rval; - } + private JsonLdOptions options; + private Map termDefinitions; + public Map inverse = null; + + public Context() { + this(new JsonLdOptions()); + } + + public Context(JsonLdOptions opts) { + super(); + init(opts); + } + + public Context(Map map, JsonLdOptions opts) { + super(map); + init(opts); + } + + public Context(Map map) { + super(map); + init(new JsonLdOptions()); + } + + public Context(Object context, JsonLdOptions opts) { + // TODO: load remote context + super(context instanceof Map ? (Map) context : null); + init(opts); + } + + private void init(JsonLdOptions options) { + this.options = options; + if (options.getBase() != null) { + this.put("@base", options.getBase()); + } + this.termDefinitions = new LinkedHashMap(); + } + + /** + * Value Compaction Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#value-compaction + * + * @param activeProperty + * The Active Property + * @param value + * The value to compact + * @return The compacted value + */ + public Object compactValue(String activeProperty, Map value) { + // 1) + int numberMembers = value.size(); + // 2) + if (value.containsKey("@index") && "@index".equals(this.getContainer(activeProperty))) { + numberMembers--; + } + // 3) + if (numberMembers > 2) { + return value; + } + // 4) + final String typeMapping = getTypeMapping(activeProperty); + final String languageMapping = getLanguageMapping(activeProperty); + if (value.containsKey("@id")) { + // 4.1) + if (numberMembers == 1 && "@id".equals(typeMapping)) { + return compactIri((String) value.get("@id")); + } + // 4.2) + if (numberMembers == 1 && "@vocab".equals(typeMapping)) { + return compactIri((String) value.get("@id"), true); + } + // 4.3) + return value; + } + final Object valueValue = value.get("@value"); + // 5) + if (value.containsKey("@type") && Obj.equals(value.get("@type"), typeMapping)) { + return valueValue; + } + // 6) + if (value.containsKey("@language")) { + // TODO: SPEC: doesn't specify to check default language as well + if (Obj.equals(value.get("@language"), languageMapping) + || Obj.equals(value.get("@language"), this.get("@language"))) { + return valueValue; + } + } + // 7) + if (numberMembers == 1 + && (!(valueValue instanceof String) || !this.containsKey("@language") || (getTermDefinition( + activeProperty).containsKey("@language") && languageMapping == null))) { + return valueValue; + } + // 8) + return value; + } + + /** + * Context Processing Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms + * + * @param localContext + * The Local Context object. + * @param remoteContexts + * The list of Strings denoting the remote Context URLs. + * @return The parsed and merged Context. + * @throws JsonLdError + * If there is an error parsing the contexts. + */ + public Context parse(Object localContext, List remoteContexts) throws JsonLdError { + if (remoteContexts == null) { + remoteContexts = new ArrayList(); + } + // 1. Initialize result to the result of cloning active context. + Context result = this.clone(); // TODO: clone? + // 2) + if (!(localContext instanceof List)) { + final Object temp = localContext; + localContext = new ArrayList(); + ((List) localContext).add(temp); + } + // 3) + for (Object context : ((List) localContext)) { + // 3.1) + if (context == null) { + result = new Context(this.options); + continue; + } else if (context instanceof Context) { + result = ((Context) context).clone(); + } + // 3.2) + else if (context instanceof String) { + String uri = (String) result.get("@base"); + uri = JsonLdUrl.resolve(uri, (String) context); + // 3.2.2 + if (remoteContexts.contains(uri)) { + throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, uri); + } + remoteContexts.add(uri); + + // 3.2.3: Dereference context + final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); + final Object remoteContext = rd.document; + if (!(remoteContext instanceof Map) + || !((Map) remoteContext).containsKey("@context")) { + // If the dereferenced document has no top-level JSON object + // with an @context member + throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); + } + context = ((Map) remoteContext).get("@context"); + + // 3.2.4 + result = result.parse(context, remoteContexts); + // 3.2.5 + continue; + } else if (!(context instanceof Map)) { + // 3.3 + throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); + } + + // 3.4 + if (remoteContexts.isEmpty() && ((Map) context).containsKey("@base")) { + final Object value = ((Map) context).get("@base"); + if (value == null) { + result.remove("@base"); + } else if (value instanceof String) { + if (JsonLdUtils.isAbsoluteIri((String) value)) { + result.put("@base", value); + } else { + final String baseUri = (String) result.get("@base"); + if (!JsonLdUtils.isAbsoluteIri(baseUri)) { + throw new JsonLdError(Error.INVALID_BASE_IRI, baseUri); + } + result.put("@base", JsonLdUrl.resolve(baseUri, (String) value)); + } + } else { + throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, + "@base must be a string"); + } + } + + // 3.5 + if (((Map) context).containsKey("@vocab")) { + final Object value = ((Map) context).get("@vocab"); + if (value == null) { + result.remove("@vocab"); + } else if (value instanceof String) { + if (JsonLdUtils.isAbsoluteIri((String) value)) { + result.put("@vocab", value); + } else { + throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, + "@value must be an absolute IRI"); + } + } else { + throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, + "@vocab must be a string or null"); + } + } + + // 3.6 + if (((Map) context).containsKey("@language")) { + final Object value = ((Map) context).get("@language"); + if (value == null) { + result.remove("@language"); + } else if (value instanceof String) { + result.put("@language", ((String) value).toLowerCase()); + } else { + throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); + } + } + + // 3.7 + final Map defined = new LinkedHashMap(); + for (final String key : ((Map) context).keySet()) { + if ("@base".equals(key) || "@vocab".equals(key) || "@language".equals(key)) { + continue; + } + result.createTermDefinition((Map) context, key, defined); + } + } + return result; + } + + public Context parse(Object localContext) throws JsonLdError { + return this.parse(localContext, new ArrayList()); + } + + /** + * Create Term Definition Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition + * + * @param result + * @param context + * @param key + * @param defined + * @throws JsonLdError + */ + private void createTermDefinition(Map context, String term, + Map defined) throws JsonLdError { + if (defined.containsKey(term)) { + if (Boolean.TRUE.equals(defined.get(term))) { + return; + } + throw new JsonLdError(Error.CYCLIC_IRI_MAPPING, term); + } + + defined.put(term, false); + + if (JsonLdUtils.isKeyword(term)) { + throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); + } + + this.termDefinitions.remove(term); + Object value = context.get(term); + if (value == null + || (value instanceof Map && ((Map) value).containsKey("@id") && ((Map) value) + .get("@id") == null)) { + this.termDefinitions.put(term, null); + defined.put(term, true); + return; + } + + if (value instanceof String) { + final Map tmp = new LinkedHashMap(); + tmp.put("@id", value); + value = tmp; + } + + if (!(value instanceof Map)) { + throw new JsonLdError(Error.INVALID_TERM_DEFINITION, value); + } + + // casting the value so it doesn't have to be done below everytime + final Map val = (Map) value; + + // 9) create a new term definition + final Map definition = new LinkedHashMap(); + + // 10) + if (val.containsKey("@type")) { + if (!(val.get("@type") instanceof String)) { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, val.get("@type")); + } + String type = (String) val.get("@type"); + try { + type = this.expandIri((String) val.get("@type"), false, true, context, defined); + } catch (final JsonLdError error) { + if (error.getType() != Error.INVALID_IRI_MAPPING) { + throw error; + } + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + } + // TODO: fix check for absoluteIri (blank nodes shouldn't count, at + // least not here!) + if ("@id".equals(type) || "@vocab".equals(type) + || (!type.startsWith("_:") && JsonLdUtils.isAbsoluteIri(type))) { + definition.put("@type", type); + } else { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + } + } + + // 11) + if (val.containsKey("@reverse")) { + if (val.containsKey("@id")) { + throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); + } + if (!(val.get("@reverse") instanceof String)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "Expected String for @reverse value. got " + + (val.get("@reverse") == null ? "null" : val.get("@reverse") + .getClass())); + } + final String reverse = this.expandIri((String) val.get("@reverse"), false, true, + context, defined); + if (!JsonLdUtils.isAbsoluteIri(reverse)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Non-absolute @reverse IRI: " + + reverse); + } + definition.put("@id", reverse); + if (val.containsKey("@container")) { + final String container = (String) val.get("@container"); + if (container == null || "@set".equals(container) || "@index".equals(container)) { + definition.put("@container", container); + } else { + throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, + "reverse properties only support set- and index-containers"); + } + } + definition.put("@reverse", true); + this.termDefinitions.put(term, definition); + defined.put(term, true); + return; + } + + // 12) + definition.put("@reverse", false); + + // 13) + if (val.get("@id") != null && !term.equals(val.get("@id"))) { + if (!(val.get("@id") instanceof String)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "expected value of @id to be a string"); + } + + final String res = this.expandIri((String) val.get("@id"), false, true, context, + defined); + if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { + if ("@context".equals(res)) { + throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, "cannot alias @context"); + } + definition.put("@id", res); + } else { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "resulting IRI mapping should be a keyword, absolute IRI or blank node"); + } + } + + // 14) + else if (term.indexOf(":") >= 0) { + final int colIndex = term.indexOf(":"); + final String prefix = term.substring(0, colIndex); + final String suffix = term.substring(colIndex + 1); + if (context.containsKey(prefix)) { + this.createTermDefinition(context, prefix, defined); + } + if (termDefinitions.containsKey(prefix)) { + definition.put("@id", + ((Map) termDefinitions.get(prefix)).get("@id") + suffix); + } else { + definition.put("@id", term); + } + // 15) + } else if (this.containsKey("@vocab")) { + definition.put("@id", this.get("@vocab") + term); + } else { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "relative term definition without vocab mapping"); + } + + // 16) + if (val.containsKey("@container")) { + final String container = (String) val.get("@container"); + if (!"@list".equals(container) && !"@set".equals(container) + && !"@index".equals(container) && !"@language".equals(container)) { + throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, + "@container must be either @list, @set, @index, or @language"); + } + definition.put("@container", container); + } + + // 17) + if (val.containsKey("@language") && !val.containsKey("@type")) { + if (val.get("@language") == null || val.get("@language") instanceof String) { + final String language = (String) val.get("@language"); + definition.put("@language", language != null ? language.toLowerCase() : null); + } else { + throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, + "@language must be a string or null"); + } + } + + // 18) + this.termDefinitions.put(term, definition); + defined.put(term, true); + } + + /** + * IRI Expansion Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion + * + * @param value + * @param relative + * @param vocab + * @param context + * @param defined + * @return + * @throws JsonLdError + */ + String expandIri(String value, boolean relative, boolean vocab, Map context, + Map defined) throws JsonLdError { + // 1) + if (value == null || JsonLdUtils.isKeyword(value)) { + return value; + } + // 2) + if (context != null && context.containsKey(value) + && !Boolean.TRUE.equals(defined.get(value))) { + this.createTermDefinition(context, value, defined); + } + // 3) + if (vocab && this.termDefinitions.containsKey(value)) { + final Map td = (LinkedHashMap) this.termDefinitions + .get(value); + if (td != null) { + return (String) td.get("@id"); + } else { + return null; + } + } + // 4) + final int colIndex = value.indexOf(":"); + if (colIndex >= 0) { + // 4.1) + final String prefix = value.substring(0, colIndex); + final String suffix = value.substring(colIndex + 1); + // 4.2) + if ("_".equals(prefix) || suffix.startsWith("//")) { + return value; + } + // 4.3) + if (context != null && context.containsKey(prefix) + && (!defined.containsKey(prefix) || defined.get(prefix) == false)) { + this.createTermDefinition(context, prefix, defined); + } + // 4.4) + if (this.termDefinitions.containsKey(prefix)) { + return (String) ((LinkedHashMap) this.termDefinitions.get(prefix)) + .get("@id") + suffix; + } + // 4.5) + return value; + } + // 5) + if (vocab && this.containsKey("@vocab")) { + return this.get("@vocab") + value; + } + // 6) + else if (relative) { + return JsonLdUrl.resolve((String) this.get("@base"), value); + } else if (context != null && JsonLdUtils.isRelativeIri(value)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, "not an absolute IRI: " + value); + } + // 7) + return value; + } + + /** + * IRI Compaction Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction + * + * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI + * has an associated value it may be passed. + * + * @param iri + * the IRI to compact. + * @param value + * the value to check or null. + * @param relativeTo + * options for how to compact IRIs: vocab: true to split after + * @vocab, false not to. + * @param reverse + * true if a reverse property is being compacted, false if not. + * + * @return the compacted term, prefix, keyword alias, or the original IRI. + */ + String compactIri(String iri, Object value, boolean relativeToVocab, boolean reverse) { + // 1) + if (iri == null) { + return null; + } + + // 2) + if (relativeToVocab && getInverse().containsKey(iri)) { + // 2.1) + String defaultLanguage = (String) this.get("@language"); + if (defaultLanguage == null) { + defaultLanguage = "@none"; + } + + // 2.2) + final List containers = new ArrayList(); + // 2.3) + String typeLanguage = "@language"; + String typeLanguageValue = "@null"; + + // 2.4) + if (value instanceof Map && ((Map) value).containsKey("@index")) { + containers.add("@index"); + } + + // 2.5) + if (reverse) { + typeLanguage = "@type"; + typeLanguageValue = "@reverse"; + containers.add("@set"); + } + // 2.6) + else if (value instanceof Map && ((Map) value).containsKey("@list")) { + // 2.6.1) + if (!((Map) value).containsKey("@index")) { + containers.add("@list"); + } + // 2.6.2) + final List list = (List) ((Map) value).get("@list"); + // 2.6.3) + String commonLanguage = (list.size() == 0) ? defaultLanguage : null; + String commonType = null; + // 2.6.4) + for (final Object item : list) { + // 2.6.4.1) + String itemLanguage = "@none"; + String itemType = "@none"; + // 2.6.4.2) + if (JsonLdUtils.isValue(item)) { + // 2.6.4.2.1) + if (((Map) item).containsKey("@language")) { + itemLanguage = (String) ((Map) item).get("@language"); + } + // 2.6.4.2.2) + else if (((Map) item).containsKey("@type")) { + itemType = (String) ((Map) item).get("@type"); + } + // 2.6.4.2.3) + else { + itemLanguage = "@null"; + } + } + // 2.6.4.3) + else { + itemType = "@id"; + } + // 2.6.4.4) + if (commonLanguage == null) { + commonLanguage = itemLanguage; + } + // 2.6.4.5) + else if (!commonLanguage.equals(itemLanguage) && JsonLdUtils.isValue(item)) { + commonLanguage = "@none"; + } + // 2.6.4.6) + if (commonType == null) { + commonType = itemType; + } + // 2.6.4.7) + else if (!commonType.equals(itemType)) { + commonType = "@none"; + } + // 2.6.4.8) + if ("@none".equals(commonLanguage) && "@none".equals(commonType)) { + break; + } + } + // 2.6.5) + commonLanguage = (commonLanguage != null) ? commonLanguage : "@none"; + // 2.6.6) + commonType = (commonType != null) ? commonType : "@none"; + // 2.6.7) + if (!"@none".equals(commonType)) { + typeLanguage = "@type"; + typeLanguageValue = commonType; + } + // 2.6.8) + else { + typeLanguageValue = commonLanguage; + } + } + // 2.7) + else { + // 2.7.1) + if (value instanceof Map && ((Map) value).containsKey("@value")) { + // 2.7.1.1) + if (((Map) value).containsKey("@language") + && !((Map) value).containsKey("@index")) { + containers.add("@language"); + typeLanguageValue = (String) ((Map) value).get("@language"); + } + // 2.7.1.2) + else if (((Map) value).containsKey("@type")) { + typeLanguage = "@type"; + typeLanguageValue = (String) ((Map) value).get("@type"); + } + } + // 2.7.2) + else { + typeLanguage = "@type"; + typeLanguageValue = "@id"; + } + // 2.7.3) + containers.add("@set"); + } + + // 2.8) + containers.add("@none"); + // 2.9) + if (typeLanguageValue == null) { + typeLanguageValue = "@null"; + } + // 2.10) + final List preferredValues = new ArrayList(); + // 2.11) + if ("@reverse".equals(typeLanguageValue)) { + preferredValues.add("@reverse"); + } + // 2.12) + if (("@reverse".equals(typeLanguageValue) || "@id".equals(typeLanguageValue)) + && (value instanceof Map) && ((Map) value).containsKey("@id")) { + // 2.12.1) + final String result = this.compactIri( + (String) ((Map) value).get("@id"), null, true, true); + if (termDefinitions.containsKey(result) + && ((Map) termDefinitions.get(result)).containsKey("@id") + && ((Map) value).get("@id").equals( + ((Map) termDefinitions.get(result)).get("@id"))) { + preferredValues.add("@vocab"); + preferredValues.add("@id"); + } + // 2.12.2) + else { + preferredValues.add("@id"); + preferredValues.add("@vocab"); + } + } + // 2.13) + else { + preferredValues.add(typeLanguageValue); + } + preferredValues.add("@none"); + + // 2.14) + final String term = selectTerm(iri, containers, typeLanguage, preferredValues); + // 2.15) + if (term != null) { + return term; + } + } + + // 3) + if (relativeToVocab && this.containsKey("@vocab")) { + // determine if vocab is a prefix of the iri + final String vocab = (String) this.get("@vocab"); + // 3.1) + if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { + // use suffix as relative iri if it is not a term in the + // active context + final String suffix = iri.substring(vocab.length()); + if (!termDefinitions.containsKey(suffix)) { + return suffix; + } + } + } + + // 4) + String compactIRI = null; + // 5) + for (final String term : termDefinitions.keySet()) { + final Map termDefinition = (Map) termDefinitions + .get(term); + // 5.1) + if (term.contains(":")) { + continue; + } + // 5.2) + if (termDefinition == null || iri.equals(termDefinition.get("@id")) + || !iri.startsWith((String) termDefinition.get("@id"))) { + continue; + } + + // 5.3) + final String candidate = term + ":" + + iri.substring(((String) termDefinition.get("@id")).length()); + // 5.4) + if ((compactIRI == null || compareShortestLeast(candidate, compactIRI) < 0) + && (!termDefinitions.containsKey(candidate) || (iri + .equals(((Map) termDefinitions.get(candidate)) + .get("@id")) && value == null))) { + compactIRI = candidate; + } + + } + + // 6) + if (compactIRI != null) { + return compactIRI; + } + + // 7) + if (!relativeToVocab) { + return JsonLdUrl.removeBase(this.get("@base"), iri); + } + + // 8) + return iri; + } + + /** + * Return a map of potential RDF prefixes based on the JSON-LD Term + * Definitions in this context. + *

+ * No guarantees of the prefixes are given, beyond that it will not contain + * ":". + * + * @param onlyCommonPrefixes + * If true, the result will not include + * "not so useful" prefixes, such as "term1": + * "http://example.com/term1", e.g. all IRIs will end with "/" or + * "#". If false, all potential prefixes are + * returned. + * + * @return A map from prefix string to IRI string + */ + public Map getPrefixes(boolean onlyCommonPrefixes) { + Map prefixes = new LinkedHashMap(); + for (final String term : termDefinitions.keySet()) { + if (term.contains(":")) { + continue; + } + Map termDefinition = (Map) termDefinitions.get(term); + if (termDefinition == null) { + continue; + } + String id = (String) termDefinition.get("@id"); + if (id == null) { + continue; + } + if (term.startsWith("@") || id.startsWith("@")) { + continue; + } + if (!onlyCommonPrefixes || id.endsWith("/") || id.endsWith("#")) { + prefixes.put(term, id); + } + } + return prefixes; + } + + String compactIri(String iri, boolean relativeToVocab) { + return compactIri(iri, null, relativeToVocab, false); + } + + String compactIri(String iri) { + return compactIri(iri, null, false, false); + } + + @Override + public Context clone() { + final Context rval = (Context) super.clone(); + // TODO: is this shallow copy enough? probably not, but it passes all + // the tests! + rval.termDefinitions = new LinkedHashMap(this.termDefinitions); + return rval; + } + + /** + * Inverse Context Creation + * + * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation + * + * Generates an inverse context for use in the compaction algorithm, if not + * already generated for the given active context. + * + * @return the inverse context. + */ + public Map getInverse() { + + // lazily create inverse + if (inverse != null) { + return inverse; + } + + // 1) + inverse = new LinkedHashMap(); + + // 2) + String defaultLanguage = (String) this.get("@language"); + if (defaultLanguage == null) { + defaultLanguage = "@none"; + } + + // create term selections for each mapping in the context, ordererd by + // shortest and then lexicographically least + final List terms = new ArrayList(termDefinitions.keySet()); + Collections.sort(terms, new Comparator() { + @Override + public int compare(String a, String b) { + return compareShortestLeast(a, b); + } + }); + + for (final String term : terms) { + final Map definition = (Map) termDefinitions.get(term); + // 3.1) + if (definition == null) { + continue; + } + + // 3.2) + String container = (String) definition.get("@container"); + if (container == null) { + container = "@none"; + } + + // 3.3) + final String iri = (String) definition.get("@id"); + + // 3.4 + 3.5) + Map containerMap = (Map) inverse.get(iri); + if (containerMap == null) { + containerMap = new LinkedHashMap(); + inverse.put(iri, containerMap); + } + + // 3.6 + 3.7) + Map typeLanguageMap = (Map) containerMap.get(container); + if (typeLanguageMap == null) { + typeLanguageMap = new LinkedHashMap(); + typeLanguageMap.put("@language", new LinkedHashMap()); + typeLanguageMap.put("@type", new LinkedHashMap()); + containerMap.put(container, typeLanguageMap); + } + + // 3.8) + if (Boolean.TRUE.equals(definition.get("@reverse"))) { + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + if (!typeMap.containsKey("@reverse")) { + typeMap.put("@reverse", term); + } + // 3.9) + } else if (definition.containsKey("@type")) { + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + if (!typeMap.containsKey(definition.get("@type"))) { + typeMap.put((String) definition.get("@type"), term); + } + // 3.10) + } else if (definition.containsKey("@language")) { + final Map languageMap = (Map) typeLanguageMap + .get("@language"); + String language = (String) definition.get("@language"); + if (language == null) { + language = "@null"; + } + if (!languageMap.containsKey(language)) { + languageMap.put(language, term); + } + // 3.11) + } else { + // 3.11.1) + final Map languageMap = (Map) typeLanguageMap + .get("@language"); + // 3.11.2) + if (!languageMap.containsKey("@language")) { + languageMap.put("@language", term); + } + // 3.11.3) + if (!languageMap.containsKey("@none")) { + languageMap.put("@none", term); + } + // 3.11.4) + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + // 3.11.5) + if (!typeMap.containsKey("@none")) { + typeMap.put("@none", term); + } + } + } + // 4) + return inverse; + } + + /** + * Term Selection + * + * http://json-ld.org/spec/latest/json-ld-api/#term-selection + * + * This algorithm, invoked via the IRI Compaction algorithm, makes use of an + * active context's inverse context to find the term that is best used to + * compact an IRI. Other information about a value associated with the IRI + * is given, including which container mappings and which type mapping or + * language mapping would be best used to express the value. + * + * @return the selected term. + */ + private String selectTerm(String iri, List containers, String typeLanguage, + List preferredValues) { + final Map inv = getInverse(); + // 1) + final Map containerMap = (Map) inv.get(iri); + // 2) + for (final String container : containers) { + // 2.1) + if (!containerMap.containsKey(container)) { + continue; + } + // 2.2) + final Map typeLanguageMap = (Map) containerMap + .get(container); + // 2.3) + final Map valueMap = (Map) typeLanguageMap + .get(typeLanguage); + // 2.4 ) + for (final String item : preferredValues) { + // 2.4.1 + if (!valueMap.containsKey(item)) { + continue; + } + // 2.4.2 + return (String) valueMap.get(item); + } + } + // 3) + return null; + } + + /** + * Retrieve container mapping. + * + * @param property + * The Property to get a container mapping for. + * @return The container mapping + */ + public String getContainer(String property) { + if ("@graph".equals(property)) { + return "@set"; + } + if (JsonLdUtils.isKeyword(property)) { + return property; + } + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return null; + } + return (String) td.get("@container"); + } + + public Boolean isReverseProperty(String property) { + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return false; + } + final Object reverse = td.get("@reverse"); + return reverse != null && (Boolean) reverse; + } + + private String getTypeMapping(String property) { + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return null; + } + return (String) td.get("@type"); + } + + private String getLanguageMapping(String property) { + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return null; + } + return (String) td.get("@language"); + } + + Map getTermDefinition(String key) { + return ((Map) termDefinitions.get(key)); + } + + public Object expandValue(String activeProperty, Object value) throws JsonLdError { + final Map rval = new LinkedHashMap(); + final Map td = getTermDefinition(activeProperty); + // 1) + if (td != null && "@id".equals(td.get("@type"))) { + // TODO: i'm pretty sure value should be a string if the @type is + // @id + rval.put("@id", expandIri(value.toString(), true, false, null, null)); + return rval; + } + // 2) + if (td != null && "@vocab".equals(td.get("@type"))) { + // TODO: same as above + rval.put("@id", expandIri(value.toString(), true, true, null, null)); + return rval; + } + // 3) + rval.put("@value", value); + // 4) + if (td != null && td.containsKey("@type")) { + rval.put("@type", td.get("@type")); + } + // 5) + else if (value instanceof String) { + // 5.1) + if (td != null && td.containsKey("@language")) { + final String lang = (String) td.get("@language"); + if (lang != null) { + rval.put("@language", lang); + } + } + // 5.2) + else if (this.get("@language") != null) { + rval.put("@language", this.get("@language")); + } + } + return rval; + } + + public Object getContextValue(String activeProperty, String string) throws JsonLdError { + throw new JsonLdError(Error.NOT_IMPLEMENTED, + "getContextValue is only used by old code so far and thus isn't implemented"); + } + + public Map serialize() { + final Map ctx = new LinkedHashMap(); + if (this.get("@base") != null && !this.get("@base").equals(options.getBase())) { + ctx.put("@base", this.get("@base")); + } + if (this.get("@language") != null) { + ctx.put("@language", this.get("@language")); + } + if (this.get("@vocab") != null) { + ctx.put("@vocab", this.get("@vocab")); + } + for (final String term : termDefinitions.keySet()) { + final Map definition = (Map) termDefinitions.get(term); + if (definition.get("@language") == null + && definition.get("@container") == null + && definition.get("@type") == null + && (definition.get("@reverse") == null || Boolean.FALSE.equals(definition + .get("@reverse")))) { + final String cid = this.compactIri((String) definition.get("@id")); + ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); + } else { + final Map defn = new LinkedHashMap(); + final String cid = this.compactIri((String) definition.get("@id")); + final Boolean reverseProperty = Boolean.TRUE.equals(definition.get("@reverse")); + if (!(term.equals(cid) && !reverseProperty)) { + defn.put(reverseProperty ? "@reverse" : "@id", cid); + } + final String typeMapping = (String) definition.get("@type"); + if (typeMapping != null) { + defn.put("@type", JsonLdUtils.isKeyword(typeMapping) ? typeMapping + : compactIri(typeMapping, true)); + } + if (definition.get("@container") != null) { + defn.put("@container", definition.get("@container")); + } + final Object lang = definition.get("@language"); + if (definition.get("@language") != null) { + defn.put("@language", Boolean.FALSE.equals(lang) ? null : lang); + } + ctx.put(term, defn); + } + } + + final Map rval = new LinkedHashMap(); + if (!(ctx == null || ctx.isEmpty())) { + rval.put("@context", ctx); + } + return rval; + } } \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index a81b163a..06f318b3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -398,20 +398,21 @@ public Map getContext() { * * @param context * The context to parse - * @throws JsonLdError If the context can't be parsed + * @throws JsonLdError + * If the context can't be parsed */ public void parseContext(Object contextLike) throws JsonLdError { - Context context; - if (api != null) { - context = new Context(api.opts); - } else { - context = new Context(); - } - // Context will do our recursive parsing and initial IRI resolution - context = context.parse(contextLike); - // And then leak to us the potential 'prefixes' - Map prefixes = context.getPrefixes(true); - + Context context; + if (api != null) { + context = new Context(api.opts); + } else { + context = new Context(); + } + // Context will do our recursive parsing and initial IRI resolution + context = context.parse(contextLike); + // And then leak to us the potential 'prefixes' + Map prefixes = context.getPrefixes(true); + for (final String key : prefixes.keySet()) { final String val = prefixes.get(key); if ("@vocab".equals(key)) { @@ -420,7 +421,7 @@ public void parseContext(Object contextLike) throws JsonLdError { } else { } } else if (!isKeyword(key)) { - setNamespace(key, val); + setNamespace(key, val); // TODO: should we make sure val is a valid URI prefix (i.e. it // ends with /# or ?) // or is it ok that full URIs for terms are used? diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index e47031c9..a5e9d71b 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -9,37 +9,35 @@ import com.github.jsonldjava.utils.JsonUtils; public class ArrayContextToRDFTest { - @Test - public void toRdfWithNamespace() throws Exception { - - URL contextUrl = getClass().getResource("/custom/contexttest-0001.jsonld"); - assertNotNull(contextUrl); - final Object context = JsonUtils.fromURL(contextUrl); - assertNotNull(context); - - URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); - assertNotNull(arrayContextUrl); - Object arrayContext = JsonUtils.fromURL(arrayContextUrl); - assertNotNull(arrayContext); - JsonLdOptions options = new JsonLdOptions(); - options.useNamespaces = true; - // Fake document loader that always returns the imported context - // from classpath - DocumentLoader documentLoader = new DocumentLoader() { - @Override - public RemoteDocument loadDocument(String url) throws JsonLdError { - return new RemoteDocument("http://nonexisting.example.com/context", - context); - } - }; - options.setDocumentLoader(documentLoader); - RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(arrayContext, options); - System.out.println(rdf.getNamespaces()); - assertEquals("http://example.org/", rdf.getNamespace("ex")); - assertEquals("http://example.com/2/", rdf.getNamespace("ex2")); - // Only 'proper' prefixes returned - assertFalse(rdf.getNamespaces().containsKey("term1")); - - - } + @Test + public void toRdfWithNamespace() throws Exception { + + URL contextUrl = getClass().getResource("/custom/contexttest-0001.jsonld"); + assertNotNull(contextUrl); + final Object context = JsonUtils.fromURL(contextUrl); + assertNotNull(context); + + URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); + assertNotNull(arrayContextUrl); + Object arrayContext = JsonUtils.fromURL(arrayContextUrl); + assertNotNull(arrayContext); + JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + // Fake document loader that always returns the imported context + // from classpath + DocumentLoader documentLoader = new DocumentLoader() { + @Override + public RemoteDocument loadDocument(String url) throws JsonLdError { + return new RemoteDocument("http://nonexisting.example.com/context", context); + } + }; + options.setDocumentLoader(documentLoader); + RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(arrayContext, options); + System.out.println(rdf.getNamespaces()); + assertEquals("http://example.org/", rdf.getNamespace("ex")); + assertEquals("http://example.com/2/", rdf.getNamespace("ex2")); + // Only 'proper' prefixes returned + assertFalse(rdf.getNamespaces().containsKey("term1")); + + } } From 3ad6d67d5bad7b5ae0747970842395aa90ed8eaf Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 12:38:56 +1100 Subject: [PATCH 023/440] Reformat to our style Also rename TestJarCache to JarCacheTest for consistency --- .../jsonldjava/core/DocumentLoader.java | 22 +- .../jsonldjava/utils/JarCacheResource.java | 56 +-- .../jsonldjava/utils/JarCacheStorage.java | 342 +++++++++--------- .../github/jsonldjava/utils/JsonUtils.java | 2 +- .../jsonldjava/core/DocumentLoaderTest.java | 133 ++++--- .../github/jsonldjava/utils/JarCacheTest.java | 109 ++++++ .../jsonldjava/utils/JsonUtilsTest.java | 2 +- .../github/jsonldjava/utils/TestJarCache.java | 113 ------ 8 files changed, 388 insertions(+), 391 deletions(-) create mode 100644 core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java delete mode 100644 core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 5c8d3d24..ac4f0ac7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -25,8 +25,7 @@ public class DocumentLoader { - - public RemoteDocument loadDocument(String url) throws JsonLdError { + public RemoteDocument loadDocument(String url) throws JsonLdError { RemoteDocument doc = new RemoteDocument(url, null); try { doc.setDocument(fromURL(new URL(url))); @@ -114,11 +113,11 @@ public InputStream openStreamFromURL(java.net.URL url) throws IOException { } return response.getEntity().getContent(); } - + protected static HttpClient getDefaultHttpClient() { HttpClient result = defaultHttpClient; if (result != null) { - return result; + return result; } synchronized (DocumentLoader.class) { if (defaultHttpClient == null) { @@ -136,23 +135,24 @@ protected static HttpClient getDefaultHttpClient() { cacheConfig.setMaxCacheEntries(1000); // and allow caching CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); - + // Wrap again with JAR cache JarCacheStorage jarCache = new JarCacheStorage(); - defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, jarCache.getCacheConfig()); + defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, + jarCache.getCacheConfig()); } return defaultHttpClient; } } public HttpClient getHttpClient() { - if (httpClient == null) { - return getDefaultHttpClient(); - } - return httpClient; + if (httpClient == null) { + return getDefaultHttpClient(); + } + return httpClient; } public void setHttpClient(HttpClient nextHttpClient) { - httpClient = nextHttpClient; + httpClient = nextHttpClient; } } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java index 075a7083..4a6e5d7c 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -11,32 +11,32 @@ public class JarCacheResource implements Resource { - private static final long serialVersionUID = -7101296464577357444L; - - private final Log log = LogFactory.getLog(getClass()); - - private URLConnection connection; - - public JarCacheResource(URL classpath) throws IOException { - this.connection = classpath.openConnection(); - } - - @Override - public long length() { - return connection.getContentLengthLong(); - } - - @Override - public InputStream getInputStream() throws IOException { - return connection.getInputStream(); - } - - @Override - public void dispose() { - try { - connection.getInputStream().close(); - } catch (IOException e) { - log.error("Can't close JarCacheResource input stream", e); - } - } + private static final long serialVersionUID = -7101296464577357444L; + + private final Log log = LogFactory.getLog(getClass()); + + private URLConnection connection; + + public JarCacheResource(URL classpath) throws IOException { + this.connection = classpath.openConnection(); + } + + @Override + public long length() { + return connection.getContentLengthLong(); + } + + @Override + public InputStream getInputStream() throws IOException { + return connection.getInputStream(); + } + + @Override + public void dispose() { + try { + connection.getInputStream().close(); + } catch (IOException e) { + log.error("Can't close JarCacheResource input stream", e); + } + } } \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index ddb2f100..0435bf95 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,173 +38,178 @@ public class JarCacheStorage implements HttpCacheStorage { - private static final String JARCACHE_JSON = "jarcache.json"; - - private final Log log = LogFactory.getLog(getClass()); - - private CacheConfig cacheConfig = new CacheConfig(); - private ClassLoader classLoader; - - public ClassLoader getClassLoader() { - if (classLoader != null) { - return classLoader; - } - return Thread.currentThread().getContextClassLoader(); - } - - public void setClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - public JarCacheStorage() { - this(null); - } - - public JarCacheStorage(ClassLoader classLoader) { - setClassLoader(classLoader); - cacheConfig.setMaxObjectSize(0); - cacheConfig.setMaxCacheEntries(0); - cacheConfig.setMaxUpdateRetries(0); - cacheConfig.getMaxCacheEntries(); - } - - @Override - public void putEntry(String key, HttpCacheEntry entry) throws IOException { - // ignored - - } - - ObjectMapper mapper = new ObjectMapper(); - - @Override - public HttpCacheEntry getEntry(String key) throws IOException { - log.trace("Requesting " + key); - URI requestedUri; - try { - requestedUri = new URI(key); - } catch (URISyntaxException e) { - return null; - } - if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) - || (requestedUri.getScheme().equals("https") && requestedUri - .getPort() == 443)) { - // Strip away default http ports - try { - requestedUri = new URI(requestedUri.getScheme(), - requestedUri.getHost(), requestedUri.getPath(), - requestedUri.getFragment()); - } catch (URISyntaxException e) { - } - } - - Enumeration jarcaches = getResources(); - while (jarcaches.hasMoreElements()) { - URL url = jarcaches.nextElement(); - - JsonNode tree = getJarCache(url); - // TODO: Cache tree per URL - for (JsonNode node : tree) { - URI uri = URI.create(node.get("Content-Location").asText()); - if (uri.equals(requestedUri)) { - return cacheEntry(requestedUri, url, node); - - } - } - } - return null; - } - - private Enumeration getResources() throws IOException { - ClassLoader cl = getClassLoader(); - if (cl != null) { - return cl.getResources(JARCACHE_JSON); - } else { - return ClassLoader.getSystemResources(JARCACHE_JSON); - } - } - - /** Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) - * to a SoftReference to its content as JsonNode. - * - * @see #getJarCache(URL) - */ - protected Map> jarCaches = new ConcurrentHashMap(new HashMap>()); - - protected JsonNode getJarCache(URL url) throws IOException, - JsonProcessingException { - - URI uri; - try { - uri = url.toURI(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid jarCache URI " + url, e); - } - - // Check if we have one from before - we'll use SoftReference so that - // - SoftReference jarCacheRef = jarCaches.get(uri); - if (jarCacheRef != null) { - JsonNode jarCache = jarCacheRef.get(); - if (jarCache != null) { - return jarCache; - } else { - jarCaches.remove(uri); - } - } - - JsonNode tree = mapper.readTree(url); - jarCaches.put(uri, new SoftReference(tree)); - return tree; - } - - protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cacheNode) - throws MalformedURLException, IOException { - final URL classpath = new URL(baseURL, cacheNode.get("X-Classpath") - .asText()); - log.debug("Cache hit for " + requestedUri); - log.trace(cacheNode); - - List

responseHeaders = new ArrayList
(); - if (!cacheNode.has(HTTP.DATE_HEADER)) { - responseHeaders.add(new BasicHeader(HTTP.DATE_HEADER, - DateUtils.formatDate(new Date()))); - } - if (!cacheNode.has(HeaderConstants.CACHE_CONTROL)) { - responseHeaders.add(new BasicHeader( - HeaderConstants.CACHE_CONTROL, - HeaderConstants.CACHE_CONTROL_MAX_AGE + "=" - + Integer.MAX_VALUE)); - } - Resource resource = new JarCacheResource(classpath); - Iterator fieldNames = cacheNode.fieldNames(); - while (fieldNames.hasNext()) { - String headerName = fieldNames.next(); - JsonNode header = cacheNode.get(headerName); - // TODO: Support multiple headers with [] - responseHeaders.add(new BasicHeader(headerName, header - .asText())); - } - - return new HttpCacheEntry( - new Date(), - new Date(), - new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"), - responseHeaders.toArray(new Header[0]), resource); - } - - @Override - public void removeEntry(String key) throws IOException { - // Ignored - } - - @Override - public void updateEntry(String key, HttpCacheUpdateCallback callback) - throws IOException, HttpCacheUpdateException { - // ignored - } - - public CacheConfig getCacheConfig() { - return cacheConfig; - } + private static final String JARCACHE_JSON = "jarcache.json"; + + private final Log log = LogFactory.getLog(getClass()); + + private CacheConfig cacheConfig = new CacheConfig(); + private ClassLoader classLoader; + + public ClassLoader getClassLoader() { + if (classLoader != null) { + return classLoader; + } + return Thread.currentThread().getContextClassLoader(); + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public JarCacheStorage() { + this(null); + } + + public JarCacheStorage(ClassLoader classLoader) { + setClassLoader(classLoader); + cacheConfig.setMaxObjectSize(0); + cacheConfig.setMaxCacheEntries(0); + cacheConfig.setMaxUpdateRetries(0); + cacheConfig.getMaxCacheEntries(); + } + + @Override + public void putEntry(String key, HttpCacheEntry entry) throws IOException { + // ignored + + } + + ObjectMapper mapper = new ObjectMapper(); + + @Override + public HttpCacheEntry getEntry(String key) throws IOException { + log.trace("Requesting " + key); + URI requestedUri; + try { + requestedUri = new URI(key); + } catch (URISyntaxException e) { + return null; + } + if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) + || (requestedUri.getScheme().equals("https") && requestedUri.getPort() == 443)) { + // Strip away default http ports + try { + requestedUri = new URI(requestedUri.getScheme(), requestedUri.getHost(), + requestedUri.getPath(), requestedUri.getFragment()); + } catch (URISyntaxException e) { + } + } + + Enumeration jarcaches = getResources(); + while (jarcaches.hasMoreElements()) { + URL url = jarcaches.nextElement(); + + JsonNode tree = getJarCache(url); + // TODO: Cache tree per URL + for (JsonNode node : tree) { + URI uri = URI.create(node.get("Content-Location").asText()); + if (uri.equals(requestedUri)) { + return cacheEntry(requestedUri, url, node); + + } + } + } + return null; + } + + private Enumeration getResources() throws IOException { + ClassLoader cl = getClassLoader(); + if (cl != null) { + return cl.getResources(JARCACHE_JSON); + } else { + return ClassLoader.getSystemResources(JARCACHE_JSON); + } + } + + /** + * Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) to a + * SoftReference to its content as JsonNode. + * + * @see #getJarCache(URL) + */ + protected ConcurrentMap> jarCaches = new ConcurrentHashMap>(); + + protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingException { + + URI uri; + try { + uri = url.toURI(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid jarCache URI " + url, e); + } + + // Check if we have one from before - we'll use SoftReference so that + // the maps reference is not counted for garbage collection purposes + SoftReference jarCacheRef = jarCaches.get(uri); + if (jarCacheRef != null) { + JsonNode jarCache = jarCacheRef.get(); + if (jarCache != null) { + return jarCache; + } else { + jarCaches.remove(uri); + } + } + + // Only parse again if the optimistic get failed + JsonNode tree = mapper.readTree(url); + // Use putIfAbsent to ensure concurrent reads do not return different + // JsonNode objects, for memory management purposes + SoftReference putIfAbsent = jarCaches.putIfAbsent(uri, + new SoftReference(tree)); + if (putIfAbsent != null) { + JsonNode returnValue = putIfAbsent.get(); + if (returnValue != null) { + return returnValue; + } else { + // Force update the reference if the existing reference had + // been garbage collected + jarCaches.put(uri, new SoftReference(tree)); + } + } + return tree; + } + + protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cacheNode) + throws MalformedURLException, IOException { + final URL classpath = new URL(baseURL, cacheNode.get("X-Classpath").asText()); + log.debug("Cache hit for " + requestedUri); + log.trace(cacheNode); + + List
responseHeaders = new ArrayList
(); + if (!cacheNode.has(HTTP.DATE_HEADER)) { + responseHeaders + .add(new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()))); + } + if (!cacheNode.has(HeaderConstants.CACHE_CONTROL)) { + responseHeaders.add(new BasicHeader(HeaderConstants.CACHE_CONTROL, + HeaderConstants.CACHE_CONTROL_MAX_AGE + "=" + Integer.MAX_VALUE)); + } + Resource resource = new JarCacheResource(classpath); + Iterator fieldNames = cacheNode.fieldNames(); + while (fieldNames.hasNext()) { + String headerName = fieldNames.next(); + JsonNode header = cacheNode.get(headerName); + // TODO: Support multiple headers with [] + responseHeaders.add(new BasicHeader(headerName, header.asText())); + } + + return new HttpCacheEntry(new Date(), new Date(), new BasicStatusLine(HttpVersion.HTTP_1_1, + 200, "OK"), responseHeaders.toArray(new Header[0]), resource); + } + + @Override + public void removeEntry(String key) throws IOException { + // Ignored + } + + @Override + public void updateEntry(String key, HttpCacheUpdateCallback callback) throws IOException, + HttpCacheUpdateException { + // ignored + } + + public CacheConfig getCacheConfig() { + return cacheConfig; + } } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 32643da6..ab707634 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -158,7 +158,7 @@ public static Object fromString(String jsonString) throws JsonParseException, IO * If there was an IO error during parsing. */ public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { - return DOCUMENT_LOADER.fromURL(url); + return DOCUMENT_LOADER.fromURL(url); } /** diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 29fc77e7..eba491de 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -33,8 +33,8 @@ import org.mockito.ArgumentCaptor; public class DocumentLoaderTest { - - DocumentLoader documentLoader = new DocumentLoader(); + + DocumentLoader documentLoader = new DocumentLoader(); @SuppressWarnings("unchecked") @Test @@ -209,72 +209,67 @@ public void fromURLAcceptHeaders() throws Exception { assertEquals(6, elems.length); } - + + @Test + public void jarCacheHit() throws Exception { + // If no cache, should fail-fast as nonexisting.example.com is not in + // DNS + Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/context")); + assertTrue(context instanceof Map); + assertTrue(((Map) context).containsKey("@context")); + } + + @Test(expected = IOException.class) + public void jarCacheMiss404() throws Exception { + // Should fail-fast as nonexisting.example.com is not in DNS + Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/miss")); + } + + @After + public void setContextClassLoader() { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + } + + @Test(expected = IOException.class) + public void jarCacheMissThreadCtx() throws Exception { + URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); + Thread.currentThread().setContextClassLoader(findNothingCL); + Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/context")); + } + + @Test + public void jarCacheHitThreadCtx() throws Exception { + URL url = new URL("http://nonexisting.example.com/nested/hello"); + URL nestedJar = getClass().getResource("/nested.jar"); + try { + Object hello = documentLoader.fromURL(url); + fail("Should not be able to find nested/hello yet"); + } catch (IOException ex) { + // expected + } + + ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + Thread.currentThread().setContextClassLoader(cl); + Object hello = documentLoader.fromURL(url); + assertTrue(hello instanceof Map); + assertEquals("World!", ((Map) hello).get("Hello")); + } + + @Test + public void sharedHttpClient() throws Exception { + // Should be the same instance unless explicitly set + assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + } + @Test - public void jarCacheHit() throws Exception { - // If no cache, should fail-fast as nonexisting.example.com is not in DNS - Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/context")); - assertTrue(context instanceof Map); - assertTrue(((Map)context).containsKey("@context")); - } - - - @Test(expected=IOException.class) - public void jarCacheMiss404() throws Exception { - // Should fail-fast as nonexisting.example.com is not in DNS - Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/miss")); - } - - - @After - public void setContextClassLoader() { - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - } - - @Test(expected=IOException.class) - public void jarCacheMissThreadCtx() throws Exception { - URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); - Thread.currentThread().setContextClassLoader(findNothingCL); - Object context = documentLoader.fromURL(new URL( - "http://nonexisting.example.com/context")); - } - - @Test - public void jarCacheHitThreadCtx() throws Exception { - URL url = new URL( - "http://nonexisting.example.com/nested/hello"); - URL nestedJar = getClass().getResource("/nested.jar"); - try { - Object hello = documentLoader.fromURL(url); - fail("Should not be able to find nested/hello yet"); - } catch (IOException ex) { - // expected - } - - ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); - Thread.currentThread().setContextClassLoader(cl); - Object hello = documentLoader.fromURL(url); - assertTrue(hello instanceof Map); - assertEquals("World!", ((Map)hello).get("Hello")); - } - - @Test - public void sharedHttpClient() throws Exception { - // Should be the same instance unless explicitly set - assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); - } - - - @Test - public void differentHttpClient() throws Exception { - // Custom http client - documentLoader.setHttpClient(new SystemDefaultHttpClient()); - assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); - - // Use default again - documentLoader.setHttpClient(null); - assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); - } - - + public void differentHttpClient() throws Exception { + // Custom http client + documentLoader.setHttpClient(new SystemDefaultHttpClient()); + assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + + // Use default again + documentLoader.setHttpClient(null); + assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + } + } diff --git a/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java b/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java new file mode 100644 index 00000000..fb1f21ad --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java @@ -0,0 +1,109 @@ +package com.github.jsonldjava.utils; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.SystemDefaultHttpClient; +import org.apache.http.impl.client.cache.CachingHttpClient; +import org.junit.After; +import org.junit.Test; + +public class JarCacheTest { + + @Test + public void cacheHit() throws Exception { + JarCacheStorage storage = new JarCacheStorage(); + HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + HttpResponse resp = httpClient.execute(get); + + assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); + String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + assertTrue(str.contains("ex:datatype")); + } + + @Test(expected = IOException.class) + public void cacheMiss() throws Exception { + JarCacheStorage storage = new JarCacheStorage(); + HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/notfound"); + // Should throw an IOException as the DNS name + // nonexisting.example.com does not exist + HttpResponse resp = httpClient.execute(get); + } + + @Test + public void doubleLoad() throws Exception { + JarCacheStorage storage = new JarCacheStorage(); + HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + HttpResponse resp = httpClient.execute(get); + resp = httpClient.execute(get); + // Ensure second load through the cached jarcache list works + assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); + } + + @Test + public void customClassPath() throws Exception { + URL nestedJar = getClass().getResource("/nested.jar"); + ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + JarCacheStorage storage = new JarCacheStorage(cl); + + HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); + HttpResponse resp = httpClient.execute(get); + + assertEquals("application/json", resp.getEntity().getContentType().getValue()); + String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + assertEquals("{ \"Hello\": \"World!\" }", str.trim()); + } + + @Test + public void contextClassLoader() throws Exception { + URL nestedJar = getClass().getResource("/nested.jar"); + assertNotNull(nestedJar); + ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + + JarCacheStorage storage = new JarCacheStorage(); + Thread.currentThread().setContextClassLoader(cl); + + HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); + HttpResponse resp = httpClient.execute(get); + + assertEquals("application/json", resp.getEntity().getContentType().getValue()); + String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + assertEquals("{ \"Hello\": \"World!\" }", str.trim()); + } + + @After + public void setContextClassLoader() { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + } + + @Test + public void systemClassLoader() throws Exception { + URL nestedJar = getClass().getResource("/nested.jar"); + assertNotNull(nestedJar); + JarCacheStorage storage = new JarCacheStorage(null); + + HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + storage.getCacheConfig()); + HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + HttpResponse resp = httpClient.execute(get); + assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); + } + +} diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index ade23660..a72e2df8 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -7,7 +7,7 @@ import org.junit.Test; public class JsonUtilsTest { - + @SuppressWarnings("unchecked") @Test public void fromStringTest() { diff --git a/core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java b/core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java deleted file mode 100644 index f6c3fcc4..00000000 --- a/core/src/test/java/com/github/jsonldjava/utils/TestJarCache.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.github.jsonldjava.utils; - -import static org.junit.Assert.*; - -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; - -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.SystemDefaultHttpClient; -import org.apache.http.impl.client.cache.CachingHttpClient; -import org.junit.After; -import org.junit.Test; - -public class TestJarCache { - - @Test - public void cacheHit() throws Exception { - JarCacheStorage storage = new JarCacheStorage(); - HttpClient httpClient = new CachingHttpClient( - new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/context"); - HttpResponse resp = httpClient.execute(get); - - assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); - String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); - assertTrue(str.contains("ex:datatype")); - } - - - @Test(expected=IOException.class) - public void cacheMiss() throws Exception { - JarCacheStorage storage = new JarCacheStorage(); - HttpClient httpClient = new CachingHttpClient( - new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/notfound"); - // Should throw an IOException as the DNS name - // nonexisting.example.com does not exist - HttpResponse resp = httpClient.execute(get); - } - - - @Test - public void doubleLoad() throws Exception { - JarCacheStorage storage = new JarCacheStorage(); - HttpClient httpClient = new CachingHttpClient( - new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/context"); - HttpResponse resp = httpClient.execute(get); - resp = httpClient.execute(get); - // Ensure second load through the cached jarcache list works - assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); - } - - @Test - public void customClassPath() throws Exception { - URL nestedJar = getClass().getResource("/nested.jar"); - ClassLoader cl = new URLClassLoader(new URL[]{ nestedJar } ); - JarCacheStorage storage = new JarCacheStorage(cl); - - HttpClient httpClient = new CachingHttpClient( - new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); - HttpResponse resp = httpClient.execute(get); - - assertEquals("application/json", resp.getEntity().getContentType().getValue()); - String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); - assertEquals("{ \"Hello\": \"World!\" }", str.trim()); - } - - @Test - public void contextClassLoader() throws Exception { - URL nestedJar = getClass().getResource("/nested.jar"); - assertNotNull(nestedJar); - ClassLoader cl = new URLClassLoader(new URL[]{ nestedJar } ); - - JarCacheStorage storage = new JarCacheStorage(); - Thread.currentThread().setContextClassLoader(cl); - - HttpClient httpClient = new CachingHttpClient( - new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); - HttpResponse resp = httpClient.execute(get); - - assertEquals("application/json", resp.getEntity().getContentType().getValue()); - String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); - assertEquals("{ \"Hello\": \"World!\" }", str.trim()); - } - - @After - public void setContextClassLoader() { - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - } - - @Test - public void systemClassLoader() throws Exception { - URL nestedJar = getClass().getResource("/nested.jar"); - assertNotNull(nestedJar); - ClassLoader cl = new URLClassLoader(new URL[]{ nestedJar } ); - JarCacheStorage storage = new JarCacheStorage(null); - - HttpClient httpClient = new CachingHttpClient( - new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/context"); - HttpResponse resp = httpClient.execute(get); - assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); - } - - -} From 319e0f65436e5dea52cd55eca6fa8f246f41b682 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 12:47:40 +1100 Subject: [PATCH 024/440] Update readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 918bca8e..a30e0a95 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,11 @@ Current possible values for `` include JSON-LD (`application/ld+json` or CHANGELOG ========= +### 2014-03-24 +* Allow loading remote @context from bundled JAR cache +* Support JSON array in @context with toRDF +* Avoid exception on @context with default @language and unmapped key + ### 2014-02-24 * Javadoc some core classes, JsonLdProcessor, JsonLdApi, and JsonUtils * Rename some core classes for consistency, particularly JSONUtils to JsonUtils and JsonLdTripleCallback From c87103839cadf6597dc07d2affbe714b48639b7f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 12:49:25 +1100 Subject: [PATCH 025/440] Automated cleanup, mostly final variables and unused imports --- .../com/github/jsonldjava/core/Context.java | 16 ++--- .../jsonldjava/core/DocumentLoader.java | 10 +-- .../github/jsonldjava/core/JsonLdUtils.java | 7 +- .../github/jsonldjava/core/RDFDataset.java | 9 +-- .../github/jsonldjava/core/UniqueNamer.java | 3 +- .../jsonldjava/utils/JarCacheResource.java | 4 +- .../jsonldjava/utils/JarCacheStorage.java | 42 ++++++------ .../github/jsonldjava/utils/JsonUtils.java | 2 - .../core/ArrayContextToRDFTest.java | 16 +++-- .../jsonldjava/core/DocumentLoaderTest.java | 31 +++++---- .../core/JsonLdPerformanceTest.java | 21 ++---- .../jsonldjava/core/JsonLdProcessorTest.java | 11 ++-- .../github/jsonldjava/utils/JarCacheTest.java | 66 ++++++++++--------- .../github/jsonldjava/utils/TestUtils.java | 6 +- 14 files changed, 118 insertions(+), 126 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 3c6eb732..3d8a8730 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -5,14 +5,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.github.jsonldjava.core.JsonLdError.Error; -import com.github.jsonldjava.utils.Obj; import com.github.jsonldjava.utils.JsonLdUrl; +import com.github.jsonldjava.utils.Obj; /** * A helper class which still stores all the values in a map but gives member @@ -112,9 +111,9 @@ public Object compactValue(String activeProperty, Map value) { } // 7) if (numberMembers == 1 - && (!(valueValue instanceof String) || !this.containsKey("@language") || - (termDefinitions.containsKey(activeProperty) && getTermDefinition( - activeProperty).containsKey("@language") && languageMapping == null))) { + && (!(valueValue instanceof String) || !this.containsKey("@language") || (termDefinitions + .containsKey(activeProperty) + && getTermDefinition(activeProperty).containsKey("@language") && languageMapping == null))) { return valueValue; } // 8) @@ -770,16 +769,17 @@ else if (((Map) value).containsKey("@type")) { * @return A map from prefix string to IRI string */ public Map getPrefixes(boolean onlyCommonPrefixes) { - Map prefixes = new LinkedHashMap(); + final Map prefixes = new LinkedHashMap(); for (final String term : termDefinitions.keySet()) { if (term.contains(":")) { continue; } - Map termDefinition = (Map) termDefinitions.get(term); + final Map termDefinition = (Map) termDefinitions + .get(term); if (termDefinition == null) { continue; } - String id = (String) termDefinition.get("@id"); + final String id = (String) termDefinition.get("@id"); if (id == null) { continue; } diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index ac4f0ac7..528e72e7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -26,10 +26,10 @@ public class DocumentLoader { public RemoteDocument loadDocument(String url) throws JsonLdError { - RemoteDocument doc = new RemoteDocument(url, null); + final RemoteDocument doc = new RemoteDocument(url, null); try { doc.setDocument(fromURL(new URL(url))); - } catch (Exception e) { + } catch (final Exception e) { new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); } return doc; @@ -115,7 +115,7 @@ public InputStream openStreamFromURL(java.net.URL url) throws IOException { } protected static HttpClient getDefaultHttpClient() { - HttpClient result = defaultHttpClient; + final HttpClient result = defaultHttpClient; if (result != null) { return result; } @@ -134,10 +134,10 @@ protected static HttpClient getDefaultHttpClient() { cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB cacheConfig.setMaxCacheEntries(1000); // and allow caching - CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); + final CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); // Wrap again with JAR cache - JarCacheStorage jarCache = new JarCacheStorage(); + final JarCacheStorage jarCache = new JarCacheStorage(); defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, jarCache.getCacheConfig()); } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 4150a721..8aba7ecf 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -1,7 +1,5 @@ package com.github.jsonldjava.core; -import java.io.IOException; -import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -9,11 +7,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; -import com.fasterxml.jackson.core.JsonParseException; -import com.github.jsonldjava.utils.Obj; import com.github.jsonldjava.utils.JsonLdUrl; +import com.github.jsonldjava.utils.Obj; public class JsonLdUtils { @@ -761,7 +757,6 @@ static boolean isBlankNode(Object v) { return false; } - /** * Finds all @context URLs in the given JSON-LD input. * diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 06f318b3..422b61b6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -15,20 +15,15 @@ import static com.github.jsonldjava.core.JsonLdUtils.isString; import static com.github.jsonldjava.core.JsonLdUtils.isValue; -import java.io.IOException; -import java.net.URL; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; -import com.fasterxml.jackson.core.JsonParseException; - /** * Starting to migrate away from using plain java Maps as the internal RDF * dataset store. Currently each item just wraps a Map based on the old format @@ -411,13 +406,13 @@ public void parseContext(Object contextLike) throws JsonLdError { // Context will do our recursive parsing and initial IRI resolution context = context.parse(contextLike); // And then leak to us the potential 'prefixes' - Map prefixes = context.getPrefixes(true); + final Map prefixes = context.getPrefixes(true); for (final String key : prefixes.keySet()) { final String val = prefixes.get(key); if ("@vocab".equals(key)) { if (val == null || isString(val)) { - setNamespace("", (String) val); + setNamespace("", val); } else { } } else if (!isKeyword(key)) { diff --git a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java index eca90038..46fc7c81 100644 --- a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java +++ b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java @@ -38,7 +38,8 @@ public UniqueNamer clone() { * Gets the new name for the given old name, where if no old name is given a * new name will be generated. * - * @param oldName the old name to get the new name for. + * @param oldName + * the old name to get the new name for. * * @return the new name. */ diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java index 4a6e5d7c..92063838 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -15,7 +15,7 @@ public class JarCacheResource implements Resource { private final Log log = LogFactory.getLog(getClass()); - private URLConnection connection; + private final URLConnection connection; public JarCacheResource(URL classpath) throws IOException { this.connection = classpath.openConnection(); @@ -35,7 +35,7 @@ public InputStream getInputStream() throws IOException { public void dispose() { try { connection.getInputStream().close(); - } catch (IOException e) { + } catch (final IOException e) { log.error("Can't close JarCacheResource input stream", e); } } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 0435bf95..9c629f12 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -9,10 +9,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -42,7 +40,7 @@ public class JarCacheStorage implements HttpCacheStorage { private final Log log = LogFactory.getLog(getClass()); - private CacheConfig cacheConfig = new CacheConfig(); + private final CacheConfig cacheConfig = new CacheConfig(); private ClassLoader classLoader; public ClassLoader getClassLoader() { @@ -82,7 +80,7 @@ public HttpCacheEntry getEntry(String key) throws IOException { URI requestedUri; try { requestedUri = new URI(key); - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { return null; } if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) @@ -91,18 +89,18 @@ public HttpCacheEntry getEntry(String key) throws IOException { try { requestedUri = new URI(requestedUri.getScheme(), requestedUri.getHost(), requestedUri.getPath(), requestedUri.getFragment()); - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { } } - Enumeration jarcaches = getResources(); + final Enumeration jarcaches = getResources(); while (jarcaches.hasMoreElements()) { - URL url = jarcaches.nextElement(); + final URL url = jarcaches.nextElement(); - JsonNode tree = getJarCache(url); + final JsonNode tree = getJarCache(url); // TODO: Cache tree per URL - for (JsonNode node : tree) { - URI uri = URI.create(node.get("Content-Location").asText()); + for (final JsonNode node : tree) { + final URI uri = URI.create(node.get("Content-Location").asText()); if (uri.equals(requestedUri)) { return cacheEntry(requestedUri, url, node); @@ -113,7 +111,7 @@ public HttpCacheEntry getEntry(String key) throws IOException { } private Enumeration getResources() throws IOException { - ClassLoader cl = getClassLoader(); + final ClassLoader cl = getClassLoader(); if (cl != null) { return cl.getResources(JARCACHE_JSON); } else { @@ -134,15 +132,15 @@ protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingExcept URI uri; try { uri = url.toURI(); - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { throw new IllegalArgumentException("Invalid jarCache URI " + url, e); } // Check if we have one from before - we'll use SoftReference so that // the maps reference is not counted for garbage collection purposes - SoftReference jarCacheRef = jarCaches.get(uri); + final SoftReference jarCacheRef = jarCaches.get(uri); if (jarCacheRef != null) { - JsonNode jarCache = jarCacheRef.get(); + final JsonNode jarCache = jarCacheRef.get(); if (jarCache != null) { return jarCache; } else { @@ -151,13 +149,13 @@ protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingExcept } // Only parse again if the optimistic get failed - JsonNode tree = mapper.readTree(url); + final JsonNode tree = mapper.readTree(url); // Use putIfAbsent to ensure concurrent reads do not return different // JsonNode objects, for memory management purposes - SoftReference putIfAbsent = jarCaches.putIfAbsent(uri, + final SoftReference putIfAbsent = jarCaches.putIfAbsent(uri, new SoftReference(tree)); if (putIfAbsent != null) { - JsonNode returnValue = putIfAbsent.get(); + final JsonNode returnValue = putIfAbsent.get(); if (returnValue != null) { return returnValue; } else { @@ -175,7 +173,7 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach log.debug("Cache hit for " + requestedUri); log.trace(cacheNode); - List
responseHeaders = new ArrayList
(); + final List
responseHeaders = new ArrayList
(); if (!cacheNode.has(HTTP.DATE_HEADER)) { responseHeaders .add(new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()))); @@ -184,11 +182,11 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach responseHeaders.add(new BasicHeader(HeaderConstants.CACHE_CONTROL, HeaderConstants.CACHE_CONTROL_MAX_AGE + "=" + Integer.MAX_VALUE)); } - Resource resource = new JarCacheResource(classpath); - Iterator fieldNames = cacheNode.fieldNames(); + final Resource resource = new JarCacheResource(classpath); + final Iterator fieldNames = cacheNode.fieldNames(); while (fieldNames.hasNext()) { - String headerName = fieldNames.next(); - JsonNode header = cacheNode.get(headerName); + final String headerName = fieldNames.next(); + final JsonNode header = cacheNode.get(headerName); // TODO: Support multiple headers with [] responseHeaders.add(new BasicHeader(headerName, header.asText())); } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index ab707634..8b9dfa41 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -11,8 +11,6 @@ import java.util.List; import java.util.Map; -import org.apache.http.client.HttpClient; - import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index a5e9d71b..8c287a6c 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -1,6 +1,8 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import java.net.URL; @@ -12,27 +14,27 @@ public class ArrayContextToRDFTest { @Test public void toRdfWithNamespace() throws Exception { - URL contextUrl = getClass().getResource("/custom/contexttest-0001.jsonld"); + final URL contextUrl = getClass().getResource("/custom/contexttest-0001.jsonld"); assertNotNull(contextUrl); final Object context = JsonUtils.fromURL(contextUrl); assertNotNull(context); - URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); + final URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); assertNotNull(arrayContextUrl); - Object arrayContext = JsonUtils.fromURL(arrayContextUrl); + final Object arrayContext = JsonUtils.fromURL(arrayContextUrl); assertNotNull(arrayContext); - JsonLdOptions options = new JsonLdOptions(); + final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; // Fake document loader that always returns the imported context // from classpath - DocumentLoader documentLoader = new DocumentLoader() { + final DocumentLoader documentLoader = new DocumentLoader() { @Override public RemoteDocument loadDocument(String url) throws JsonLdError { return new RemoteDocument("http://nonexisting.example.com/context", context); } }; options.setDocumentLoader(documentLoader); - RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(arrayContext, options); + final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(arrayContext, options); System.out.println(rdf.getNamespaces()); assertEquals("http://example.org/", rdf.getNamespace("ex")); assertEquals("http://example.com/2/", rdf.getNamespace("ex2")); diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index eba491de..23f99997 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -1,6 +1,12 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -214,7 +220,8 @@ public void fromURLAcceptHeaders() throws Exception { public void jarCacheHit() throws Exception { // If no cache, should fail-fast as nonexisting.example.com is not in // DNS - Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/context")); + final Object context = documentLoader.fromURL(new URL( + "http://nonexisting.example.com/context")); assertTrue(context instanceof Map); assertTrue(((Map) context).containsKey("@context")); } @@ -222,7 +229,8 @@ public void jarCacheHit() throws Exception { @Test(expected = IOException.class) public void jarCacheMiss404() throws Exception { // Should fail-fast as nonexisting.example.com is not in DNS - Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/miss")); + final Object context = documentLoader + .fromURL(new URL("http://nonexisting.example.com/miss")); } @After @@ -232,25 +240,26 @@ public void setContextClassLoader() { @Test(expected = IOException.class) public void jarCacheMissThreadCtx() throws Exception { - URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); + final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); Thread.currentThread().setContextClassLoader(findNothingCL); - Object context = documentLoader.fromURL(new URL("http://nonexisting.example.com/context")); + final Object context = documentLoader.fromURL(new URL( + "http://nonexisting.example.com/context")); } @Test public void jarCacheHitThreadCtx() throws Exception { - URL url = new URL("http://nonexisting.example.com/nested/hello"); - URL nestedJar = getClass().getResource("/nested.jar"); + final URL url = new URL("http://nonexisting.example.com/nested/hello"); + final URL nestedJar = getClass().getResource("/nested.jar"); try { - Object hello = documentLoader.fromURL(url); + final Object hello = documentLoader.fromURL(url); fail("Should not be able to find nested/hello yet"); - } catch (IOException ex) { + } catch (final IOException ex) { // expected } - ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); Thread.currentThread().setContextClassLoader(cl); - Object hello = documentLoader.fromURL(url); + final Object hello = documentLoader.fromURL(url); assertTrue(hello instanceof Map); assertEquals("World!", ((Map) hello).get("Hello")); } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index a07080d4..667f5d57 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -3,17 +3,10 @@ */ package com.github.jsonldjava.core; -import static org.junit.Assert.*; - import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; import java.util.zip.GZIPInputStream; -import org.junit.After; -import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -35,16 +28,16 @@ public class JsonLdPerformanceTest { @Ignore("Enable as necessary for manual testing, particularly to test that it fails due to irregular URIs") @Test public final void test() throws Exception { - long parseStart = System.currentTimeMillis(); - Object inputObject = JsonUtils.fromInputStream(new GZIPInputStream(new FileInputStream( - new File("/home/ans025/Downloads/2000007922.jsonld.gz")))); - long parseEnd = System.currentTimeMillis(); + final long parseStart = System.currentTimeMillis(); + final Object inputObject = JsonUtils.fromInputStream(new GZIPInputStream( + new FileInputStream(new File("/home/ans025/Downloads/2000007922.jsonld.gz")))); + final long parseEnd = System.currentTimeMillis(); System.out.printf("Parse time: %d", (parseEnd - parseStart)); - JsonLdOptions opts = new JsonLdOptions("urn:test:"); + final JsonLdOptions opts = new JsonLdOptions("urn:test:"); - long compactStart = System.currentTimeMillis(); + final long compactStart = System.currentTimeMillis(); JsonLdProcessor.compact(inputObject, null, opts); - long compactEnd = System.currentTimeMillis(); + final long compactEnd = System.currentTimeMillis(); System.out.printf("Compaction time: %d", (compactEnd - compactStart)); } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index a7717973..4a16a93e 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -31,7 +31,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.junit.rules.Timeout; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @@ -282,7 +281,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { if (url.contains(":")) { // check if the url is relative to the test base if (url.startsWith(this.base)) { - String classpath = url.substring(this.base.length()); + final String classpath = url.substring(this.base.length()); final ClassLoader cl = Thread.currentThread().getContextClassLoader(); final InputStream inputStream = cl.getResourceAsStream(TEST_DIR + "/" + classpath); @@ -318,8 +317,8 @@ public void addHttpLink(String nextLink) { } } - //@Rule - //public Timeout timeout = new Timeout(10000); + // @Rule + // public Timeout timeout = new Timeout(10000); @Rule public TemporaryFolder tempDir = new TemporaryFolder(); @@ -427,7 +426,7 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { // OPTIONS SETUP final JsonLdOptions options = new JsonLdOptions("http://json-ld.org/test-suite/tests/" + test.get("input")); - TestDocumentLoader testLoader = new TestDocumentLoader( + final TestDocumentLoader testLoader = new TestDocumentLoader( "http://json-ld.org/test-suite/tests/"); options.setDocumentLoader(testLoader); if (test.containsKey("option")) { @@ -463,7 +462,7 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { } if (test_opts.containsKey("httpLink")) { if (test_opts.get("httpLink") instanceof List) { - for (String nextLink : (List) test_opts.get("httpLink")) { + for (final String nextLink : (List) test_opts.get("httpLink")) { testLoader.addHttpLink(nextLink); } } else { diff --git a/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java b/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java index fb1f21ad..4dca5951 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java @@ -1,6 +1,8 @@ package com.github.jsonldjava.utils; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.net.URL; @@ -19,34 +21,34 @@ public class JarCacheTest { @Test public void cacheHit() throws Exception { - JarCacheStorage storage = new JarCacheStorage(); - HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + final JarCacheStorage storage = new JarCacheStorage(); + final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/context"); - HttpResponse resp = httpClient.execute(get); + final HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + final HttpResponse resp = httpClient.execute(get); assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); - String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + final String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); assertTrue(str.contains("ex:datatype")); } @Test(expected = IOException.class) public void cacheMiss() throws Exception { - JarCacheStorage storage = new JarCacheStorage(); - HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + final JarCacheStorage storage = new JarCacheStorage(); + final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/notfound"); + final HttpGet get = new HttpGet("http://nonexisting.example.com/notfound"); // Should throw an IOException as the DNS name // nonexisting.example.com does not exist - HttpResponse resp = httpClient.execute(get); + final HttpResponse resp = httpClient.execute(get); } @Test public void doubleLoad() throws Exception { - JarCacheStorage storage = new JarCacheStorage(); - HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + final JarCacheStorage storage = new JarCacheStorage(); + final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + final HttpGet get = new HttpGet("http://nonexisting.example.com/context"); HttpResponse resp = httpClient.execute(get); resp = httpClient.execute(get); // Ensure second load through the cached jarcache list works @@ -55,36 +57,36 @@ public void doubleLoad() throws Exception { @Test public void customClassPath() throws Exception { - URL nestedJar = getClass().getResource("/nested.jar"); - ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); - JarCacheStorage storage = new JarCacheStorage(cl); + final URL nestedJar = getClass().getResource("/nested.jar"); + final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + final JarCacheStorage storage = new JarCacheStorage(cl); - HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); - HttpResponse resp = httpClient.execute(get); + final HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); + final HttpResponse resp = httpClient.execute(get); assertEquals("application/json", resp.getEntity().getContentType().getValue()); - String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + final String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); assertEquals("{ \"Hello\": \"World!\" }", str.trim()); } @Test public void contextClassLoader() throws Exception { - URL nestedJar = getClass().getResource("/nested.jar"); + final URL nestedJar = getClass().getResource("/nested.jar"); assertNotNull(nestedJar); - ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); + final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); - JarCacheStorage storage = new JarCacheStorage(); + final JarCacheStorage storage = new JarCacheStorage(); Thread.currentThread().setContextClassLoader(cl); - HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); - HttpResponse resp = httpClient.execute(get); + final HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); + final HttpResponse resp = httpClient.execute(get); assertEquals("application/json", resp.getEntity().getContentType().getValue()); - String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); + final String str = IOUtils.toString(resp.getEntity().getContent(), "UTF-8"); assertEquals("{ \"Hello\": \"World!\" }", str.trim()); } @@ -95,14 +97,14 @@ public void setContextClassLoader() { @Test public void systemClassLoader() throws Exception { - URL nestedJar = getClass().getResource("/nested.jar"); + final URL nestedJar = getClass().getResource("/nested.jar"); assertNotNull(nestedJar); - JarCacheStorage storage = new JarCacheStorage(null); + final JarCacheStorage storage = new JarCacheStorage(null); - HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, + final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, storage.getCacheConfig()); - HttpGet get = new HttpGet("http://nonexisting.example.com/context"); - HttpResponse resp = httpClient.execute(get); + final HttpGet get = new HttpGet("http://nonexisting.example.com/context"); + final HttpResponse resp = httpClient.execute(get); assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); } diff --git a/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java b/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java index 11df67a5..f73d26bc 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java +++ b/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java @@ -32,12 +32,12 @@ public static String copyResourceToFile(File testDir, String resource) throws Ex filename = resource.substring(resource.lastIndexOf('/')); directory = resource.substring(0, resource.lastIndexOf('/')); } - File nextDirectory = new File(testDir, directory); + final File nextDirectory = new File(testDir, directory); nextDirectory.mkdirs(); - File nextFile = new File(nextDirectory, filename); + final File nextFile = new File(nextDirectory, filename); nextFile.createNewFile(); - InputStream inputStream = TestUtils.class.getResourceAsStream(resource); + final InputStream inputStream = TestUtils.class.getResourceAsStream(resource); assertNotNull("Missing test resource: " + resource, inputStream); IOUtils.copy(inputStream, new FileOutputStream(nextFile)); From ae4dc68a3b21bfe818db75f573c11d5a289fb646 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 12:50:14 +1100 Subject: [PATCH 026/440] Automated cleanup, mostly final variables and unused imports --- .../com/github/jsonldjava/jena/JenaRDFParser.java | 12 ++++++------ .../com/github/jsonldjava/jena/JsonLDReader.java | 5 ++--- .../github/jsonldjava/jena/JenaJSONReaderTest.java | 1 - .../github/jsonldjava/jena/JenaJSONWriterTest.java | 1 - .../github/jsonldjava/jena/JenaRDFParserTest.java | 1 - .../jsonldjava/jena/JenaRiotReadWriteTest.java | 2 -- .../jsonldjava/jena/JenaTripleCallbackTest.java | 7 +++---- .../github/jsonldjava/rdf2go/RDF2GoRDFParser.java | 3 --- .../jsonldjava/rdf2go/RDF2GoTripleCallback.java | 1 - .../jsonldjava/rdf2go/RDF2GoRDFParserTest.java | 2 -- .../github/jsonldjava/sesame/SesameJSONLDParser.java | 11 ++++++----- .../github/jsonldjava/sesame/SesameJSONLDWriter.java | 1 - .../jsonldjava/sesame/SesameTripleCallback.java | 4 ++-- .../sesame/SesameJSONLDParserHandlerTest.java | 3 --- .../jsonldjava/sesame/SesameJSONLDWriterTest.java | 3 --- .../jsonldjava/sesame/SesameTripleCallbackTest.java | 1 - 16 files changed, 19 insertions(+), 39 deletions(-) diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java index b68ac797..c109839c 100644 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java +++ b/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java @@ -123,9 +123,9 @@ public void importResource(RDFDataset result, Resource subject) { } private void importGraph(RDFDataset result, Graph graph, String graphName) { - ExtendedIterator triples = graph.find(null, null, null); + final ExtendedIterator triples = graph.find(null, null, null); while (triples.hasNext()) { - Triple t = triples.next(); + final Triple t = triples.next(); final String subj = getID(t.getSubject()); final String prop = t.getPredicate().getURI(); if (t.getObject().isLiteral()) { @@ -146,11 +146,11 @@ private void importDatasetGraph(RDFDataset result, DatasetGraph input) { importGraph(result, input.getDefaultGraph(), "@default"); - Iterator graphNodes = input.listGraphNodes(); + final Iterator graphNodes = input.listGraphNodes(); while (graphNodes.hasNext()) { - Node n = graphNodes.next(); - Graph graph = input.getGraph(n); - String graphName = n.getURI(); + final Node n = graphNodes.next(); + final Graph graph = input.getGraph(n); + final String graphName = n.getURI(); importGraph(result, graph, graphName); } diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java index a074fd01..7de5dd26 100644 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java +++ b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java @@ -31,11 +31,10 @@ import org.apache.jena.riot.system.StreamRDF; import org.apache.jena.riot.system.SyntaxLabels; -import com.github.jsonldjava.core.JsonLdTripleCallback; -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.JsonLdTripleCallback; import com.github.jsonldjava.core.RDFDataset; import com.github.jsonldjava.utils.JsonUtils; import com.hp.hpl.jena.datatypes.RDFDatatype; @@ -84,7 +83,7 @@ public Object call(RDFDataset dataset) { return null; } }; - JsonLdOptions options = new JsonLdOptions(baseURI); + final JsonLdOptions options = new JsonLdOptions(baseURI); options.useNamespaces = true; JsonLdProcessor.toRDF(JsonUtils.fromInputStream(in), callback, options); } catch (final IOException e) { diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java index ac639359..810b29fb 100644 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java +++ b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java @@ -6,7 +6,6 @@ import java.io.InputStream; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import com.hp.hpl.jena.rdf.model.Model; diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java index 03b811da..fb73eeeb 100644 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java +++ b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java @@ -6,7 +6,6 @@ import java.io.StringWriter; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import com.hp.hpl.jena.rdf.model.Model; diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java index 28e6d766..640a1283 100644 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java +++ b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java @@ -14,7 +14,6 @@ import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.jena.JenaRDFParser; import com.github.jsonldjava.utils.Obj; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java index d74d6793..06078471 100644 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java +++ b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java @@ -27,12 +27,10 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; -import java.net.URL; import org.apache.jena.riot.RDFDataMgr; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java index d934f2b4..e06bcce8 100644 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java +++ b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java @@ -14,10 +14,9 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; -import com.github.jsonldjava.core.JsonLdTripleCallback; import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.jena.JenaTripleCallback; +import com.github.jsonldjava.core.JsonLdTripleCallback; import com.github.jsonldjava.utils.Obj; import com.hp.hpl.jena.rdf.model.Model; @@ -75,8 +74,8 @@ public void triplesTest() throws JsonParseException, JsonMappingException, JsonL final List result = new ArrayList(Arrays.asList(w.getBuffer().toString() .split("\n"))); Collections.sort(result); -// System.out.println(expected); -// System.out.println(result); + // System.out.println(expected); + // System.out.println(result); assertTrue(Obj.equals(expected, result)); } diff --git a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java index 7e9e9727..89fc4c08 100644 --- a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java +++ b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java @@ -1,6 +1,5 @@ package com.github.jsonldjava.rdf2go; - import java.util.Map; import org.ontoware.aifbcommons.collection.ClosableIterator; @@ -19,8 +18,6 @@ import com.github.jsonldjava.core.RDFDataset; import com.github.jsonldjava.core.RDFParser; - - /** * Implementation of {@link RDFParser} which serializes the contents of a * {@link ModelSet} or {@link Model} into a JSON-LD document. diff --git a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java index cdb46dc1..2f75385a 100644 --- a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java +++ b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java @@ -1,6 +1,5 @@ package com.github.jsonldjava.rdf2go; - import java.util.List; import org.ontoware.rdf2go.RDF2Go; diff --git a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java index f5f85501..a55556a2 100644 --- a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java +++ b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java @@ -18,8 +18,6 @@ import com.github.jsonldjava.core.JsonLdProcessor; import com.github.jsonldjava.utils.Obj; - - /** * Unit tests for {@link RDF2GoRDFParser} containing a single test, including * literals with datatype and language. diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java index bc1928c6..ed5c340e 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java @@ -39,7 +39,8 @@ public SesameJSONLDParser() { * Creates a Sesame JSONLD Parser using the given {@link ValueFactory} to * create new {@link Value}s. * - * @param valueFactory The ValueFactory to use + * @param valueFactory + * The ValueFactory to use */ public SesameJSONLDParser(final ValueFactory valueFactory) { super(valueFactory); @@ -56,9 +57,9 @@ public void parse(final InputStream in, final String baseURI) throws IOException final SesameTripleCallback callback = new SesameTripleCallback(getRDFHandler(), valueFactory, getParserConfig(), getParseErrorListener()); - JsonLdOptions options = new JsonLdOptions(baseURI); + final JsonLdOptions options = new JsonLdOptions(baseURI); options.useNamespaces = true; - + try { JsonLdProcessor.toRDF(JsonUtils.fromInputStream(in), callback, options); } catch (final JsonLdError e) { @@ -77,9 +78,9 @@ public void parse(final Reader reader, final String baseURI) throws IOException, final SesameTripleCallback callback = new SesameTripleCallback(getRDFHandler(), valueFactory, getParserConfig(), getParseErrorListener()); - JsonLdOptions options = new JsonLdOptions(baseURI); + final JsonLdOptions options = new JsonLdOptions(baseURI); options.useNamespaces = true; - + try { JsonLdProcessor.toRDF(JsonUtils.fromReader(reader), callback, options); } catch (final JsonLdError e) { diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java index d73f792b..ac3d87a8 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java @@ -12,7 +12,6 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import org.openrdf.model.Model; diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java index 3e653136..13ad3515 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java @@ -173,10 +173,10 @@ public void setValueFactory(ValueFactory vf) { @Override public Object call(final RDFDataset dataset) { - for(Entry nextNamespace : dataset.getNamespaces().entrySet()) { + for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { try { handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); - } catch (RDFHandlerException e) { + } catch (final RDFHandlerException e) { throw new RuntimeException("Failed handling namespace", e); } } diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java index 58cd6435..21232d56 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java @@ -16,9 +16,6 @@ import org.openrdf.rio.RDFParser; import org.openrdf.rio.RDFWriter; -import com.github.jsonldjava.sesame.SesameJSONLDParser; -import com.github.jsonldjava.sesame.SesameJSONLDWriter; - /** * Unit tests for {@link SesameJSONLDParser} related to handling of datatypes * and languages. diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java index 57deaff5..261e6ffd 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java @@ -33,9 +33,6 @@ import org.openrdf.rio.helpers.JSONLDSettings; import org.openrdf.rio.helpers.StatementCollector; -import com.github.jsonldjava.sesame.SesameJSONLDParserFactory; -import com.github.jsonldjava.sesame.SesameJSONLDWriterFactory; - /** * @author Peter Ansell p_ansell@yahoo.com */ diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java index dfda0c20..a320a8d0 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java @@ -16,7 +16,6 @@ import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.sesame.SesameTripleCallback; import com.github.jsonldjava.utils.JsonUtils; public class SesameTripleCallbackTest { From a8e3f9165b640b3e805ad1a1e1382cedc52416ee Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 13:00:24 +1100 Subject: [PATCH 027/440] Add README notes about code cleanup and submitting pull requests --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index a30e0a95..46953cc3 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,20 @@ Implementation Reports conforming to the [JSON-LD Implementation Report](http:// Current possible values for `` include JSON-LD (`application/ld+json` or `jsonld`), NQuads (`text/plain`, `nquads`, `ntriples`, `nq` or `nt`) and Turtle (`text/turtle`, `turtle` or `ttl`). `*` can be used to generate reports in all available formats. +### Code style + +The JSONLD-Java project uses custom Eclipse formatting and cleanup style guides to ensure that Pull Requests are fairly simple to merge. + +These guides can be found in the /conf directory and can be installed in Eclipse using "Properties>Java Code Style>Formatter", followed by "Properties>Java Code Style>Clean Up" for each of the modules making up the JSONLD-Java project. + +If you don't use Eclipse, then don't worry, your pull requests can be cleaned up by a repository maintainer prior to merging, but it makes the initial check easier if the modified code uses the conventions. + +### Submitting Pull Requests + +Once you have made a change to fix a bug or add a new feature, you should commit and push the change to your fork. + +Then, you can open a pull request to merge your change into the master branch of the main repository. + CHANGELOG ========= From 7ea4111084927ec6810c1af3bb4e692114e49895 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 13:03:20 +1100 Subject: [PATCH 028/440] Clarify that we also implement JSON-LD-API Except for Futures/Promises, which we do not currently support --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46953cc3..9d1138fa 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Note: this is the documentation for the current unstable development branch. [Fo JSONLD-JAVA =========== -This is a Java implementation of the [JSON-LD specification](http://json-ld.org/). +This is a Java implementation of the [JSON-LD specification](http://www.w3.org/TR/json-ld/) and the [JSON-LD-API specification](http://www.w3.org/TR/json-ld-api/). USAGE ===== @@ -38,7 +38,7 @@ Code example Processor options ----------------- -A + The Options specified by the [JSON-LD API Specification](http://json-ld.org/spec/latest/json-ld-api/#jsonldoptions) are accessible via the `com.github.jsonldjava.core.JsonLdOptions` class, and each `JsonLdProcessor.*` function has an optional input to take an instance of this class. From eaa39affd46c414e640d09a646a7b819693a2b4b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 24 Mar 2014 13:05:34 +1100 Subject: [PATCH 029/440] Fix variable name in example code to match the previous line --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d1138fa..93a93b0e 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Code example // Call whichever JSONLD function you want! (e.g. compact) Object compact = JsonLdProcessor.compact(jsonObject, context, options); // Print out the result (or don't, it's your call!) - System.out.println(JsonUtils.toPrettyString(normalized)); + System.out.println(JsonUtils.toPrettyString(compact)); Processor options ----------------- From 568ec4f4db3838ba6e642e0f649ebb5db972de6e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 26 Mar 2014 09:02:18 +1100 Subject: [PATCH 030/440] Bump RDF2GO version to 5.0.0 and use Maven Central fixes #106 --- README.md | 3 +++ integration/rdf2go/pom.xml | 30 +++--------------------------- pom.xml | 4 ++-- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 93a93b0e..1a47270a 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,9 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-03-26 +* Bump RDF2GO to version 5.0.0 + ### 2014-03-24 * Allow loading remote @context from bundled JAR cache * Support JSON array in @context with toRDF diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index cc4f01b7..7b134157 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -20,30 +20,6 @@ - - - semweb4j-repo - Semweb4j.org maven repo - http://semweb4j.org/repo/ - - true - - - - semweb4j-snapshots - Semweb4j.org maven snapshot repo - http://semweb4j.org/snapshots/ - - false - - - true - always - fail - - - - ${project.groupId} @@ -92,11 +68,11 @@ org.semweb4j - rdf2go.impl.sesame23 + rdf2go.impl.sesame ${rdf2go.version} - runtime + test - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index 8a7f275d..b5c0639b 100755 --- a/pom.xml +++ b/pom.xml @@ -47,10 +47,10 @@ 0.13 4.2.5 - 2.3.1 + 2.3.2 2.11.0 4.11 - 4.7.4 + 5.0.0 2.7.10 1.7.5 From c0fd29b404b45276637546c23ebc80d6aa6edaf5 Mon Sep 17 00:00:00 2001 From: tjb1982 Date: Tue, 1 Apr 2014 14:14:58 -0400 Subject: [PATCH 031/440] Update README.md Added a little bit of syntax highlighting --- README.md | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 1a47270a..68a04db8 100644 --- a/README.md +++ b/README.md @@ -19,23 +19,23 @@ From Maven Code example ------------ - - // Open a valid json(-ld) input file - InputStream inputStream = new FileInputStream("input.json"); - // Read the file into an Object (The type of this object will be a List, Map, String, Boolean, - // Number or null depending on the root object in the file). - Object jsonObject = JsonUtils.fromInputStream(inputStream); - // Create a context JSON map containing prefixes and definitions - Map context = new HashMap(); - // Customise context... - // Create an instance of JsonLdOptions with the standard JSON-LD options - JsonLdOptions options = new JsonLdOptions(); - // Customise options... - // Call whichever JSONLD function you want! (e.g. compact) - Object compact = JsonLdProcessor.compact(jsonObject, context, options); - // Print out the result (or don't, it's your call!) - System.out.println(JsonUtils.toPrettyString(compact)); - +```java +// Open a valid json(-ld) input file +InputStream inputStream = new FileInputStream("input.json"); +// Read the file into an Object (The type of this object will be a List, Map, String, Boolean, +// Number or null depending on the root object in the file). +Object jsonObject = JsonUtils.fromInputStream(inputStream); +// Create a context JSON map containing prefixes and definitions +Map context = new HashMap(); +// Customise context... +// Create an instance of JsonLdOptions with the standard JSON-LD options +JsonLdOptions options = new JsonLdOptions(); +// Customise options... +// Call whichever JSONLD function you want! (e.g. compact) +Object compact = JsonLdProcessor.compact(jsonObject, context, options); +// Print out the result (or don't, it's your call!) +System.out.println(JsonUtils.toPrettyString(compact)); +``` Processor options ----------------- @@ -74,20 +74,20 @@ classpath together with the JSON-LD contexts to embed. (Note that you might have to recursively embed any nested contexts). The syntax of `jarcache.json` is best explained by example: - - [ - { - "Content-Location": "http://www.example.com/context", - "X-Classpath": "contexts/example.jsonld", - "Content-Type": "application/ld+json" - }, - { - "Content-Location": "http://data.example.net/other", - "X-Classpath": "contexts/other.jsonld", - "Content-Type": "application/ld+json" - } - ] - +```javascript +[ + { + "Content-Location": "http://www.example.com/context", + "X-Classpath": "contexts/example.jsonld", + "Content-Type": "application/ld+json" + }, + { + "Content-Location": "http://data.example.net/other", + "X-Classpath": "contexts/other.jsonld", + "Content-Type": "application/ld+json" + } +] +``` (See also [core/src/test/resources/jarcache.json](core/src/test/resources/jarcache.json)). This will mean that any JSON-LD document trying to import the `@context` From f9789749fdc657aa6c83c4a95e95e9620de74b51 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 10:50:35 +1000 Subject: [PATCH 032/440] Fix avoidable NPEs, null RDFHandler allowed for Sesame RDFParsers --- .../sesame/SesameTripleCallback.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java index 13ad3515..2123e8c0 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java @@ -69,10 +69,12 @@ private void triple(String s, String p, String o, String graph) { createResource(graph)); } - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } } } @@ -115,10 +117,12 @@ private void triple(String s, String p, String value, String datatype, String la result = vf.createStatement(subject, predicate, object, createResource(graph)); } - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } } } @@ -173,11 +177,13 @@ public void setValueFactory(ValueFactory vf) { @Override public Object call(final RDFDataset dataset) { - for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { - try { - handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); - } catch (final RDFHandlerException e) { - throw new RuntimeException("Failed handling namespace", e); + if (handler != null) { + for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { + try { + handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); + } catch (final RDFHandlerException e) { + throw new RuntimeException("Failed handling namespace", e); + } } } for (String graphName : dataset.keySet()) { From 8fd613306b32c85b5f79459b528237e95b737ab4 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 11:54:32 +1000 Subject: [PATCH 033/440] bump versions for dependencies --- pom.xml | 11 ++++++----- tools/pom.xml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index b5c0639b..92650290 100755 --- a/pom.xml +++ b/pom.xml @@ -47,12 +47,12 @@ 0.13 4.2.5 - 2.3.2 - 2.11.0 + 2.3.3 + 2.11.1 4.11 5.0.0 - 2.7.10 - 1.7.5 + 2.7.12-SNAPSHOT + 1.7.7 2.2.1 @@ -162,6 +162,7 @@ org.apache.maven.plugins maven-compiler-plugin + 3.1 1.6 1.6 @@ -201,7 +202,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.16 + 2.17 diff --git a/tools/pom.xml b/tools/pom.xml index adbd56f9..61b48d3f 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -40,7 +40,7 @@ org.codehaus.mojo appassembler-maven-plugin - 1.4 + 1.8 From 7970d6f082eb0607c35f3097558a2061fa4c7027 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 11:54:53 +1000 Subject: [PATCH 034/440] Implement new method added in 2.11.1 --- .../java/com/github/jsonldjava/jena/JsonLDReader.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java index 7de5dd26..821b94b2 100644 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java +++ b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java @@ -20,6 +20,9 @@ import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; import java.util.List; import java.util.Map; @@ -48,6 +51,12 @@ public class JsonLDReader implements ReaderRIOT { @Override public void read(InputStream in, String baseURI, ContentType ct, final StreamRDF output, Context context) { + read(new InputStreamReader(in, Charset.forName("UTF-8")), baseURI, ct, output, context); + } + + @Override + public void read(Reader in, String baseURI, ContentType ct, final StreamRDF output, + Context context) { try { final JsonLdTripleCallback callback = new JsonLdTripleCallback() { @@ -85,7 +94,7 @@ public Object call(RDFDataset dataset) { }; final JsonLdOptions options = new JsonLdOptions(baseURI); options.useNamespaces = true; - JsonLdProcessor.toRDF(JsonUtils.fromInputStream(in), callback, options); + JsonLdProcessor.toRDF(JsonUtils.fromReader(in), callback, options); } catch (final IOException e) { throw new RiotException("Could not read JSONLD: " + e, e); } catch (final JsonLdError e) { From c1dde758466f2af471fca9d1ef2e638522b1826f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 13:31:49 +1000 Subject: [PATCH 035/440] Ignore namespace prefix tests broken by default JSONLDMode.EXPAND Until there is a way to override the WriterConfig for RDFWriterTest, need to ignore tests that fail because RDFFormat.JSONLD declares that it supports namespaces, but the default mode, EXPAND, does not preserve them. To preserve namespaces, users must setup WriterConfig with JSONLDMode.COMPACT, as demonstrated in this commit --- .../sesame/SesameJSONLDWriterTest.java | 117 +++++++----------- 1 file changed, 43 insertions(+), 74 deletions(-) diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java index 261e6ffd..b5698ead 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java @@ -8,27 +8,20 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; +import org.junit.Ignore; import org.junit.Test; -import org.openrdf.model.BNode; import org.openrdf.model.Literal; import org.openrdf.model.Model; import org.openrdf.model.Statement; import org.openrdf.model.URI; -import org.openrdf.model.ValueFactory; import org.openrdf.model.impl.LinkedHashModel; -import org.openrdf.model.impl.ValueFactoryImpl; import org.openrdf.model.vocabulary.XMLSchema; import org.openrdf.rio.ParserConfig; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParseException; import org.openrdf.rio.RDFParser; import org.openrdf.rio.RDFWriter; import org.openrdf.rio.RDFWriterTest; -import org.openrdf.rio.WriterConfig; import org.openrdf.rio.helpers.BasicParserSettings; -import org.openrdf.rio.helpers.BasicWriterSettings; import org.openrdf.rio.helpers.JSONLDMode; import org.openrdf.rio.helpers.JSONLDSettings; import org.openrdf.rio.helpers.StatementCollector; @@ -44,83 +37,59 @@ public SesameJSONLDWriterTest() { @Test @Override - public void testRoundTrip() throws RDFHandlerException, IOException, RDFParseException { - // Overriding test as it is implemented as an RDF-1.0 test that is not - // compatible - // with RDF-1.1 Typed Literals after translating them to have xsd:String - // and rdf:langString. - final String ex = "http://example.org/"; - - final ValueFactory vf = new ValueFactoryImpl(); - final BNode bnode = vf.createBNode("anon"); - final URI uri1 = vf.createURI(ex, "uri1"); - final URI uri2 = vf.createURI(ex, "uri2"); - final Literal plainLit = vf.createLiteral("plain"); - final Literal dtLit = vf.createLiteral(1); - final Literal langLit = vf.createLiteral("test", "en"); - final Literal litWithNewline = vf.createLiteral("literal with newline\n"); - final Literal litWithSingleQuotes = vf.createLiteral("'''some single quote text''' - abc"); - final Literal litWithDoubleQuotes = vf - .createLiteral("\"\"\"some double quote text\"\"\" - abc"); - - final Statement st1 = vf.createStatement(bnode, uri1, plainLit); - final Statement st2 = vf.createStatement(uri1, uri2, langLit, uri2); - final Statement st3 = vf.createStatement(uri1, uri2, dtLit); - final Statement st4 = vf.createStatement(uri1, uri2, litWithNewline); - final Statement st5 = vf.createStatement(uri1, uri2, litWithSingleQuotes); - final Statement st6 = vf.createStatement(uri1, uri2, litWithDoubleQuotes); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final RDFWriter rdfWriter = rdfWriterFactory.getWriter(out); - final WriterConfig writerConfig = rdfWriter.getWriterConfig(); - writerConfig.set(BasicWriterSettings.RDF_LANGSTRING_TO_LANG_LITERAL, true); - writerConfig.set(BasicWriterSettings.XSD_STRING_TO_PLAIN_LITERAL, true); - writerConfig.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); + @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + public void testPerformance() throws Exception { + } + + @Test + @Override + @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + public void testRoundTrip() throws Exception { + } + + @Test + @Override + @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + public void testRoundTripPreserveBNodeIds() throws Exception { + } + + @Test + public void testRoundTripNamespaces() throws Exception { + String exNs = "http://example.org/"; + URI uri1 = vf.createURI(exNs, "uri1"); + URI uri2 = vf.createURI(exNs, "uri2"); + Literal plainLit = vf.createLiteral("plain", XMLSchema.STRING); + + Statement st1 = vf.createStatement(uri1, uri2, plainLit); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + RDFWriter rdfWriter = rdfWriterFactory.getWriter(out); + rdfWriter.getWriterConfig().set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); + rdfWriter.handleNamespace("ex", exNs); rdfWriter.startRDF(); - rdfWriter.handleNamespace("ex", ex); rdfWriter.handleStatement(st1); - rdfWriter.handleStatement(st2); - rdfWriter.handleStatement(st3); - rdfWriter.handleStatement(st4); - rdfWriter.handleStatement(st5); - rdfWriter.handleStatement(st6); rdfWriter.endRDF(); - final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - final RDFParser rdfParser = rdfParserFactory.getParser(); - final ParserConfig config = new ParserConfig(); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + RDFParser rdfParser = rdfParserFactory.getParser(); + ParserConfig config = new ParserConfig(); config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true); rdfParser.setParserConfig(config); rdfParser.setValueFactory(vf); - final Model model = new LinkedHashModel(); + Model model = new LinkedHashModel(); rdfParser.setRDFHandler(new StatementCollector(model)); rdfParser.parse(in, "foo:bar"); - assertEquals("Unexpected number of namespaces", 1, model.getNamespaces().size()); - assertEquals("Unexpected number of statements", 6, model.size()); - final Model bnodeModel = model.filter(null, uri1, - vf.createLiteral(plainLit.getLabel(), XMLSchema.STRING)); - assertEquals("Blank node was not round-tripped", 1, bnodeModel.size()); - assertTrue("Blank node was not round-tripped as a blank node", bnodeModel.subjects() - .iterator().next() instanceof BNode); - if (rdfParser.getRDFFormat().supportsContexts()) { - assertTrue(model.contains(st2)); - } else { - assertTrue(model.contains(vf.createStatement(uri1, uri2, langLit))); + + assertEquals("Unexpected number of statements, found " + model.size(), 1, model.size()); + + assertTrue("missing namespaced statement", model.contains(st1)); + + if (rdfParser.getRDFFormat().supportsNamespaces()) { + assertTrue("Expected at least one namespace, found " + model.getNamespaces().size(), + model.getNamespaces().size() >= 1); + assertEquals(exNs, model.getNamespace("ex").getName()); } - assertTrue(model.contains(st3)); - assertTrue( - "missing statement with literal ending on newline", - model.contains(vf.createStatement(uri1, uri2, - vf.createLiteral(litWithNewline.getLabel(), XMLSchema.STRING)))); - assertTrue( - "missing statement with single quotes", - model.contains(vf.createStatement(uri1, uri2, - vf.createLiteral(litWithSingleQuotes.getLabel(), XMLSchema.STRING)))); - assertTrue( - "missing statement with single quotes", - model.contains(vf.createStatement(uri1, uri2, - vf.createLiteral(litWithDoubleQuotes.getLabel(), XMLSchema.STRING)))); } } From c4a1ffba41fec16316228b6428f7bb82d5551c73 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 13:46:56 +1000 Subject: [PATCH 036/440] Add in the extension point for sesame tests --- .../sesame/SesameJSONLDWriterTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java index b5698ead..83ade4a8 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java @@ -21,6 +21,7 @@ import org.openrdf.rio.RDFParser; import org.openrdf.rio.RDFWriter; import org.openrdf.rio.RDFWriterTest; +import org.openrdf.rio.WriterConfig; import org.openrdf.rio.helpers.BasicParserSettings; import org.openrdf.rio.helpers.JSONLDMode; import org.openrdf.rio.helpers.JSONLDSettings; @@ -35,6 +36,21 @@ public SesameJSONLDWriterTest() { super(new SesameJSONLDWriterFactory(), new SesameJSONLDParserFactory()); } + /* + * TODO: Unignore tests when updating to Sesame-2.7.12 + */ + protected void setupWriterConfig(WriterConfig config) { + config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); + } + + /* + * TODO: Unignore tests when updating to Sesame-2.7.12 + */ + protected void setupParserConfig(ParserConfig config) { + config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); + config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true); + } + @Test @Override @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") From 93f4d46e7f62822a1b3d3be88e458bf51c845f4c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 13:54:08 +1000 Subject: [PATCH 037/440] release 0.4 --- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/jena/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 7447c84c..13a58bc4 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 9fc03876..34589bdf 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java-clerezza diff --git a/integration/jena/pom.xml b/integration/jena/pom.xml index 2c5a022b..e09d799e 100644 --- a/integration/jena/pom.xml +++ b/integration/jena/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java-jena diff --git a/integration/pom.xml b/integration/pom.xml index 9e7b6264..874d517c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 7b134157..c3d0626c 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 138cb742..bffde566 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 92650290..c1d7b18b 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.4-SNAPSHOT + 0.4 JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 61b48d3f..a60e8e28 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4-SNAPSHOT + 0.4 4.0.0 jsonld-java-tools From f0172cb814de748cc4323ee815ebafe8ad3ccb8a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 14:09:56 +1000 Subject: [PATCH 038/440] Update changelog for release --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 68a04db8..8b6ea6a8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.3/README.md) - JSONLD-JAVA =========== @@ -14,7 +12,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.4-SNAPSHOT + 0.4 Code example @@ -236,6 +234,12 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-04-22 +* Release version 0.4 +* Bump to Sesame-2.7.11 +* Bump to Jackson-2.3.3 +* Bump to Jena-2.11.1 + ### 2014-03-26 * Bump RDF2GO to version 5.0.0 From 95da3391f08c3ce64defcecf7267e5add737c01b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 14:12:10 +1000 Subject: [PATCH 039/440] bump version for next development snapshot --- README.md | 4 +++- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/jena/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 9 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8b6ea6a8..43cf7fe6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.4/README.md) + JSONLD-JAVA =========== @@ -12,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.4 + 0.5-SNAPSHOT Code example diff --git a/core/pom.xml b/core/pom.xml index 13a58bc4..d8ebade6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 34589bdf..019eeeb7 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/jena/pom.xml b/integration/jena/pom.xml index e09d799e..50713106 100644 --- a/integration/jena/pom.xml +++ b/integration/jena/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java-jena diff --git a/integration/pom.xml b/integration/pom.xml index 874d517c..bf19538c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index c3d0626c..cb763ff7 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index bffde566..d21e37e2 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index c1d7b18b..0fe89cf5 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.4 + 0.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index a60e8e28..6e30515b 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4 + 0.5-SNAPSHOT 4.0.0 jsonld-java-tools From 2bd831f000b3b497a4d92af996928c32e00d9a5e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 15:18:59 +1000 Subject: [PATCH 040/440] release 0.4.1 to fix sesame version --- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/jena/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 4 ++-- tools/pom.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index d8ebade6..ff7c0f58 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 019eeeb7..1f0f9218 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java-clerezza diff --git a/integration/jena/pom.xml b/integration/jena/pom.xml index 50713106..31883237 100644 --- a/integration/jena/pom.xml +++ b/integration/jena/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java-jena diff --git a/integration/pom.xml b/integration/pom.xml index bf19538c..1c7e67eb 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index cb763ff7..4820b19f 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index d21e37e2..9c7e583b 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 0fe89cf5..49eae7f1 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5-SNAPSHOT + 0.4.1 JSONLD Java :: Parent Json-LD Java Parent POM pom @@ -51,7 +51,7 @@ 2.11.1 4.11 5.0.0 - 2.7.12-SNAPSHOT + 2.7.11 1.7.7 diff --git a/tools/pom.xml b/tools/pom.xml index 6e30515b..6a5eda10 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.1 4.0.0 jsonld-java-tools From 867472c99efe2722cb8825ad2f78533229502846 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 15:20:43 +1000 Subject: [PATCH 041/440] update README --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 43cf7fe6..45e5cc1a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.4/README.md) - JSONLD-JAVA =========== @@ -14,7 +12,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5-SNAPSHOT + 0.4.1 Code example From 207c22c8fa0715ce6f04701696a309cab0cd0768 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Apr 2014 15:22:38 +1000 Subject: [PATCH 042/440] update readme --- README.md | 4 +++- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/jena/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 9 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 45e5cc1a..aa5e1736 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.4.1/README.md) + JSONLD-JAVA =========== @@ -12,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.4.1 + 0.5-SNAPSHOT Code example diff --git a/core/pom.xml b/core/pom.xml index ff7c0f58..d8ebade6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 1f0f9218..019eeeb7 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/jena/pom.xml b/integration/jena/pom.xml index 31883237..50713106 100644 --- a/integration/jena/pom.xml +++ b/integration/jena/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java-jena diff --git a/integration/pom.xml b/integration/pom.xml index 1c7e67eb..bf19538c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 4820b19f..cb763ff7 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 9c7e583b..d21e37e2 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 49eae7f1..4891f49e 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.4.1 + 0.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 6a5eda10..6e30515b 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4.1 + 0.5-SNAPSHOT 4.0.0 jsonld-java-tools From 706c3c53d9c71700f83bb9fdbf7742e5647bd9e5 Mon Sep 17 00:00:00 2001 From: rvesse Date: Thu, 22 May 2014 10:43:49 +0100 Subject: [PATCH 043/440] Copy namespaces to StreamRDF This commit improves the JsonLDReader so that it will copy the namespace prefixes from the JSON-LD context to the destination StreamRDF --- .../java/com/github/jsonldjava/jena/JsonLDReader.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java index 821b94b2..8debdb32 100644 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java +++ b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java @@ -25,6 +25,7 @@ import java.nio.charset.Charset; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.apache.jena.atlas.lib.InternalErrorException; import org.apache.jena.atlas.web.ContentType; @@ -61,8 +62,13 @@ public void read(Reader in, String baseURI, ContentType ct, final StreamRDF outp final JsonLdTripleCallback callback = new JsonLdTripleCallback() { @Override - // public Object call(Map dataset) { public Object call(RDFDataset dataset) { + // Copy across namespaces + for (Entry namespace : dataset.getNamespaces().entrySet()) { + output.prefix(namespace.getKey(), namespace.getValue()); + } + + // Copy across triples and quads for (final String gn : dataset.keySet()) { final Object x = dataset.get(gn); if ("@default".equals(gn)) { @@ -158,5 +164,4 @@ private Node createNode(Map map) { // return null ; } } - } From b4e1f6d7ff2caa860a0f5d2d10b6a61689ad6366 Mon Sep 17 00:00:00 2001 From: rvesse Date: Thu, 22 May 2014 11:06:03 +0100 Subject: [PATCH 044/440] Expand JsonLdReader tests to check namespaces round trip This commit modifies the JenaRiotReadWriteTest class to include tests to check that the namespaces are successfully round tripped and verify the changes in my previous commit. --- .../jena/JenaRiotReadWriteTest.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java index 06078471..45c236f0 100644 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java +++ b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java @@ -27,8 +27,11 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; +import java.util.Iterator; +import java.util.Map; import org.apache.jena.riot.RDFDataMgr; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -132,7 +135,7 @@ private Model loadModelFromClasspathResource(String resource) throws Exception { assertNotNull("Could not find resource on classpath: " + resource, url); return RDFDataMgr.loadModel(TestUtils.copyResourceToFile(testDir, resource)); } - + private void rtRJRds(String resource) throws Exception { final Dataset ds1 = loadDatasetFromClasspathResource("/com/github/jsonldjava/jena/" + resource); @@ -153,6 +156,22 @@ private void rtRJRds(String resource) throws Exception { assertTrue("Input dataset " + resource + " not isomorphic with roundtrip dataset", isIsomorphic(ds1, ds2)); + + // Check namespaces in the parsed dataset match those in the original data + checkNamespaces(ds2.getDefaultModel(), ds1.getDefaultModel().getNsPrefixMap()); + Iterator graphNames = ds2.listNames(); + while (graphNames.hasNext()) { + String gn = graphNames.next(); + checkNamespaces(ds2.getNamedModel(gn), ds1.getNamedModel(gn).getNsPrefixMap()); + } + } + + private void checkNamespaces(Model m, Map namespaces) { + if (namespaces == null) return; + + for (String prefix : namespaces.keySet()) { + Assert.assertEquals("Model does contain expected namespace " + prefix + ": <" + namespaces.get(prefix) + ">", namespaces.get(prefix), m.getNsPrefixURI(prefix)); + } } private void rtRJRg(String filename) throws Exception { @@ -174,5 +193,8 @@ private void rtRJRg(String filename) throws Exception { if (!model.isIsomorphicWith(model2)) { System.out.println("## ---- DIFFERENT"); } + + // Check namespaces in parsed graph match the original data + checkNamespaces(model2, model.getNsPrefixMap()); } } From c8aa923d791ede7d27e4336dd19ef421320bfa50 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 11 Jun 2014 15:44:37 +1000 Subject: [PATCH 045/440] remove Jena integration module as it is natively supported by Jena now --- integration/jena/README.md | 215 +----------------- integration/jena/pom.xml | 81 ------- .../github/jsonldjava/jena/JenaJSONLD.java | 179 --------------- .../jsonldjava/jena/JenaRDF2JSONLD.java | 88 ------- .../github/jsonldjava/jena/JenaRDFParser.java | 179 --------------- .../jsonldjava/jena/JenaTripleCallback.java | 101 -------- .../github/jsonldjava/jena/JsonLDReader.java | 167 -------------- .../github/jsonldjava/jena/JsonLDWriter.java | 165 -------------- .../github/jsonldjava/jena/ExampleTest.java | 164 ------------- .../jsonldjava/jena/JSONLDToRDFTest.java | 44 ---- .../jsonldjava/jena/JenaJSONReaderTest.java | 53 ----- .../jsonldjava/jena/JenaJSONWriterTest.java | 61 ----- .../jsonldjava/jena/JenaRDFParserTest.java | 72 ------ .../jena/JenaRiotReadWriteTest.java | 200 ---------------- .../jsonldjava/jena/JenaSystemTest.java | 97 -------- .../jena/JenaTripleCallbackTest.java | 82 ------- .../github/jsonldjava/jena/dataset1.jsonld | 26 --- .../com/github/jsonldjava/jena/dataset1.trig | 10 - .../com/github/jsonldjava/jena/graph1.jsonld | 50 ---- .../com/github/jsonldjava/jena/graph1.ttl | 14 -- .../github/jsonldjava/jena/relative.jsonld | 3 - .../jena/src/test/resources/log4j.properties | 6 - 22 files changed, 4 insertions(+), 2053 deletions(-) delete mode 100644 integration/jena/pom.xml delete mode 100644 integration/jena/src/main/java/com/github/jsonldjava/jena/JenaJSONLD.java delete mode 100644 integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDF2JSONLD.java delete mode 100644 integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java delete mode 100644 integration/jena/src/main/java/com/github/jsonldjava/jena/JenaTripleCallback.java delete mode 100644 integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java delete mode 100644 integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDWriter.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/ExampleTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JSONLDToRDFTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JenaSystemTest.java delete mode 100644 integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java delete mode 100644 integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.jsonld delete mode 100644 integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.trig delete mode 100644 integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.jsonld delete mode 100644 integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.ttl delete mode 100644 integration/jena/src/test/resources/com/github/jsonldjava/jena/relative.jsonld delete mode 100644 integration/jena/src/test/resources/log4j.properties diff --git a/integration/jena/README.md b/integration/jena/README.md index d06286ca..389745ad 100644 --- a/integration/jena/README.md +++ b/integration/jena/README.md @@ -1,212 +1,5 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.3/integration/jena/README.md) +============================ +JSONLD-Java Jena integration +============================ -=================================== -JSONLD-Java Jena integration module -=================================== - -This module integrates JSONLD-Java with Jena 2.11.0 or later. - -There are several levels of integration, detailed under Usage below. - -USAGE -===== - -From Maven ----------- - - - com.github.jsonld-java - jsonld-java-jena - 0.4-SNAPSHOT - - -(Adjust for most recent , as found in ``pom.xml``). - - -Initialization --------------- -JenaJSONLD must be initialized so that the readers and writers are registered with Jena. You would typically -do this from within a static {} block, although there is no danger in calling this several times: - - import com.github.jsonldjava.jena.*; - static { - JenaJSONLD.init(); - } - - -Parse JSON-LD (newer RIOT reader) ---------------------------------- - JenaJSONLD.init(); // Only needed once - String url = "http://json-ld.org/test-suite/tests/expand-0002-in.jsonld"; - // Detects language based on extension (ideally content type) - Model model = RDFDataMgr.loadModel(url); - - // or explicit with base URI, Lang and any supported source - InputStream inStream = new ByteArrayInputStream("{}".getBytes("UTF-8")); - RDFDataMgr.read(model, inStream, "http://example.com/", JenaJSONLD.JSONLD); - - - RDFDataMgr.write(System.out, model, Lang.TURTLE); - // - // a ; - // "v1"^^ ; - // "v2"^^ ; - // "v3"@en ; - // 4 ; - // 51 , 50 . - } - - -Write JSON-LD (newer RIOT writer) ---------------------------------- - - JenaJSONLD.init(); // Only needed once - - Model model = ModelFactory.createDefaultModel(); - Resource resource = model.createResource("http://example.com/test"); - Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - RDFDataMgr.write(System.out, model, JenaJSONLD.JSONLD); - // { - // "@context" : { - // "value" : { - // "@id" : "http://example.com/value", - // "@type" : "@id" - // } - // }, - // "@id" : "http://example.com/test", - // "http://example.com/value" : "Test" - // } - -Or more compact: - RDFDataMgr.write(System.out, model, JenaJSONLD.JSONLD_FORMAT_FLAT); - // "@context":{"value":{"@id":"http://example.com/value","@type":"@id"}},"@id":"http://example.com/test","http://example.com/value":"Test"} - - -Datasets are also supported: - - Dataset dataset = DatasetFactory.createMem(); - dataset.addNamedModel("http://example.com/graph", model); - RDFDataMgr.write(System.out, dataset, JenaJSONLD.JSONLD); - // { - // "@graph" : [ { - // "@id" : "http://example.com/test", - // "http://example.com/value" : "Test" - // } ], - // "@id" : "http://example.com/graph" - // } - - -Note that Jena's RDFDataMgr.write() does not currently support passing the -base URI parameter, although this is supported by the underlying writer. - - - -Parse JSON-LD (classic Jena RDFReader) --------------------------------------- - JenaJSONLD.init(); // Only needed once - - String url = "http://json-ld.org/test-suite/tests/expand-0002-in.jsonld"; - Model model = ModelFactory.createDefaultModel(); - model.read(url, "JSON-LD"); - - model.write(System.out, "TURTLE", "http://example.com/"); - // @base . - // a ; - // "v1"^^ ; - // "v2"^^ ; - // "v3"@en ; - // 4 ; - // 51 , 50 . - -Notes: -* Jena's classic reader factory looks up implementation using Class.forName() - and com.github.jsonldjava.jena.JenaJSONLD must therefore be in the same - classloader (e.g. on the classpath) as Jena - this does not work in OSGi. -* The optional baseURI parameter to read() is supported. If the base is unknown, - "" generally works fine, although Jena might not be able to serialise graphs - with relative URI references (e.g. ) as RDF/XML - - - -Write JSON-LD (classic Jena) ----------------------------- - JenaJSONLD.init(); // Only needed once - - Model model = ModelFactory.createDefaultModel(); - Resource resource = model.createResource("http://example.com/test"); - Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - model.write(System.out, "JSON-LD"); - // { - // "@context" : { - // "value" : { - // "@id" : "http://example.com/value", - // "@type" : "@id" - // } - // }, - // "@id" : "http://example.com/test", - // "http://example.com/value" : "Test" - // } - -Or made relative from a base URI(notice the relative @id below): - - model.write(System.out, "JSON-LD", "http://example.com/"); - // { - // "@context" : { - // "value" : { - // "@id" : "http://example.com/value", - // "@type" : "@id" - // } - // }, - // "@id" : "test", - // "http://example.com/value" : "Test" - // } - -Notes: -* The optional base URI parameter can be used to set a base that URIs are to be made - relative from (without including @base in the JSONLD) -* Same classpath considerations as for "Parse JSON-LD (classic Jena RDFReader)" above - - -Jena model to JSON-LD objects ------------------------------ - - JenaJSONLD.init(); // Only needed once - Model model = ModelFactory.createDefaultModel(); - Resource resource = model.createResource("http://example.com/test"); - Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - Options options = new Options(); - options.format = "application/ld+json"; - Object json = JSONLD.fromRDF(model, options); - String jsonStr = JSONUtils.toPrettyString(json); - System.out.println(jsonStr); - // [ { - // "@id" : "http://example.com/test", - // "http://example.com/value" : [ { - // "@value" : "Test" - // } ] - // } ] - - -JenaRDFParser -------------- - -This internal class is used by JSONLD-Java to "parse" an existing Jena model and generate JSON-LD. - -The JenaRDFParser expects input as an instance of `com.hp.hpl.jena.rdf.model.Model` containing the entire graph. - -See [JenaRDFParserTest.java](./src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java) for example Usage. - - -JenaTripleCallback ------------------- - -This internal class is used by JSONLD-Java to create an existing Jena model from an existing JSON-LD. - -The JenaTripleCallback returns an instance of `com.hp.hpl.jena.rdf.model.Model` - -See [JenaTripleCallbackTest.java](./src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java) for example Usage. +JSONLD-Java integration is provided natively by Jena since 2.11.2. diff --git a/integration/jena/pom.xml b/integration/jena/pom.xml deleted file mode 100644 index 50713106..00000000 --- a/integration/jena/pom.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - jsonld-java-integration - com.github.jsonld-java - 0.5-SNAPSHOT - - 4.0.0 - jsonld-java-jena - JSONLD Java :: Jena Integration - JSON-LD Java integration module for Jena - jar - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - org.apache.jena - jena-core - - - org.apache.jena - jena-arq - - - xerces - xercesImpl - runtime - - - xml-apis - xml-apis - runtime - - - junit - junit - test - - - org.slf4j - slf4j-log4j12 - test - - - commons-io - commons-io - 2.4 - test - - - - - - - xerces - xercesImpl - 2.11.0 - - - xml-apis - xml-apis - 1.4.01 - - - - - diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaJSONLD.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaJSONLD.java deleted file mode 100644 index fe9960ec..00000000 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaJSONLD.java +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.jsonldjava.jena; - -import org.apache.jena.riot.IO_Jena; -import org.apache.jena.riot.Lang; -import org.apache.jena.riot.LangBuilder; -import org.apache.jena.riot.RDFDataMgr; -import org.apache.jena.riot.RDFFormat; -import org.apache.jena.riot.RDFLanguages; -import org.apache.jena.riot.RDFParserRegistry; -import org.apache.jena.riot.RDFWriterRegistry; -import org.apache.jena.riot.ReaderRIOT; -import org.apache.jena.riot.ReaderRIOTFactory; -import org.apache.jena.riot.WriterDatasetRIOT; -import org.apache.jena.riot.WriterDatasetRIOTFactory; -import org.apache.jena.riot.WriterGraphRIOT; -import org.apache.jena.riot.WriterGraphRIOTFactory; -import org.apache.jena.riot.adapters.RDFReaderRIOT; -import org.apache.jena.riot.adapters.RDFWriterRIOT; -import org.apache.jena.riot.system.RiotLib; - -import com.github.jsonldjava.core.JsonLdProcessor; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.impl.IO_Ctl; - -/** - * Jena binding for JSON-LD. - *

- * The bindings must be initialized by calling {@link JenaJSONLD#init()}. After - * initialization, the language {@link JSONLD} can be used with - * {@link RDFDataMgr} for read/write of JSONLD. The file extension ".jsonld" and - * media type "application/ld+json" is also recognized. The classic - * {@link Model} can also read/write JSON-LD using the language "JSON-LD". - * - * - * @author Andy Seaborne - * @author Stian Soiland-Reyes - * - */ -public class JenaJSONLD { - - /** - * Factory for JSONLD RIOT graph reader. - * - */ - public static final class JsonLDReaderRIOTFactory implements ReaderRIOTFactory { - @Override - public ReaderRIOT create(Lang language) { - return new JsonLDReader(); - } - } - - /** - * Factory for JSONLD RIOT dataset writer. - * - */ - public static class JsonLDWriterDatasetRIOTFactory implements WriterDatasetRIOTFactory { - @Override - public WriterDatasetRIOT create(RDFFormat syntaxForm) { - return new JsonLDWriter(syntaxForm); - } - } - - /** - * Factory for JSONLD RIOT graph writer. - * - */ - public static class JsonLDWriterGraphRIOTFactory implements WriterGraphRIOTFactory { - @Override - public WriterGraphRIOT create(RDFFormat syntaxForm) { - return RiotLib.adapter(new JsonLDWriter(syntaxForm)); - } - } - - /** - * Classic RDFReader for JSONLD. Must be a subclass as registration is done - * by class. - */ - public static class JsonLDRDFReader extends RDFReaderRIOT { - public JsonLDRDFReader() { - super(JSONLD.getName()); - } - } - - /** - * Classic RDFWriter for JSONLD. Must be a subclass as registration is done - * by class. - */ - public static class JsonLDRDFWriter extends RDFWriterRIOT { - public JsonLDRDFWriter() { - super(JSONLD.getName()); - } - } - - public static Lang JSONLD = LangBuilder.create("JSON-LD", "application/ld+json") - // .addAltNames("RDF/JSON-LD") - .addFileExtensions("jsonld").build(); - - public static RDFFormat JSONLD_FORMAT_FLAT = new RDFFormat(JSONLD, RDFFormat.FLAT); - - public static RDFFormat JSONLD_FORMAT_PRETTY = new RDFFormat(JSONLD, RDFFormat.PRETTY); - - static { - init(); - } - - /** - * Initialize JSONLD readers and writers with Jena. - *

- * After initialization, the language {@link JSONLD} can be used with - * {@link RDFDataMgr} for read/write. Additionally the classic {@link Model} - * (as "JSON-LD") - * - * This method is safe to call multiple times. - * - */ - public static void init() { - IO_Ctl.init(); - registerReader(); - registerWriter(); - registerWithJsonLD(); - } - - protected static void registerWithJsonLD() { - JsonLdProcessor.registerRDFParser(JSONLD.getContentType().getContentType(), - new JenaRDFParser()); - } - - protected static void registerReader() { - // This just registers the name, not the parser. - RDFLanguages.register(JSONLD); - - // Register the parser factory. - final JsonLDReaderRIOTFactory rfactory = new JsonLDReaderRIOTFactory(); - RDFParserRegistry.registerLangTriples(JSONLD, rfactory); - RDFParserRegistry.registerLangQuads(JSONLD, rfactory); - - // Register for Model.read (old world) - IO_Jena.registerForModelRead(JSONLD.getName(), JsonLDRDFReader.class); - } - - protected static void registerWriter() { - - // Register the default format for the language. - RDFWriterRegistry.register(JSONLD, JSONLD_FORMAT_PRETTY); - - // For datasets - final WriterDatasetRIOTFactory wfactory = new JsonLDWriterDatasetRIOTFactory(); - // Uses the same code for each form. - RDFWriterRegistry.register(JSONLD_FORMAT_PRETTY, wfactory); - RDFWriterRegistry.register(JSONLD_FORMAT_FLAT, wfactory); - - // For graphs - final WriterGraphRIOTFactory wfactory2 = new JsonLDWriterGraphRIOTFactory(); - RDFWriterRegistry.register(JSONLD_FORMAT_PRETTY, wfactory2); - RDFWriterRegistry.register(JSONLD_FORMAT_FLAT, wfactory2); - - // Register for use with Model.write (old world) - IO_Jena.registerForModelWrite(JSONLD.getName(), JsonLDRDFWriter.class); - } - -} diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDF2JSONLD.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDF2JSONLD.java deleted file mode 100644 index dde07f0d..00000000 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDF2JSONLD.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.jsonldjava.jena; - -import java.util.Iterator; - -import org.apache.jena.atlas.logging.Log; -import org.apache.jena.riot.out.NodeToLabel; -import org.apache.jena.riot.system.SyntaxLabels; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.RDFDataset; -import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.sparql.core.DatasetGraph; -import com.hp.hpl.jena.sparql.core.Quad; - -// From RDF to JSON-LD java structure. -class JenaRDF2JSONLD implements com.github.jsonldjava.core.RDFParser { - NodeToLabel labels = SyntaxLabels.createNodeToLabel(); - - @Override - public RDFDataset parse(Object object) throws JsonLdError { - final RDFDataset result = new RDFDataset(); - if (object instanceof DatasetGraph) { - final DatasetGraph dsg = (DatasetGraph) object; - - final Iterator iter = dsg.find(); - for (; iter.hasNext();) { - final Quad q = iter.next(); - final Node s = q.getSubject(); - final Node p = q.getPredicate(); - final Node o = q.getObject(); - final Node g = q.getGraph(); - - final String gq = (g == null || Quad.isDefaultGraph(g)) ? null : g.getURI(); - final String sq = resourceString(s); - final String pq = p.getURI(); - if (o.isLiteral()) { - final String lex = o.getLiteralLexicalForm(); - String lang = o.getLiteralLanguage(); - String dt = o.getLiteralDatatypeURI(); - if (lang != null && lang.length() == 0) { - lang = null; - // dt = RDF.getURI()+"langString" ; - } - if (dt == null) { - dt = XSDDatatype.XSDstring.getURI(); - } - - result.addQuad(sq, pq, lex, dt, lang, gq); - } else { - final String oq = resourceString(o); - result.addQuad(sq, pq, oq, gq); - } - } - } else { - Log.warn(JenaRDF2JSONLD.class, "unknown"); - } - return result; - } - - private String resourceString(Node x) { - if (x.isURI()) { - return x.getURI(); - } - if (x.isBlank()) { - return labels.get(null, x); - } - return null; - } -} diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java deleted file mode 100644 index c109839c..00000000 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaRDFParser.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.github.jsonldjava.jena; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdError.Error; -import com.github.jsonldjava.core.RDFDataset; -import com.hp.hpl.jena.graph.Graph; -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.ResIterator; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.sparql.core.DatasetGraph; -import com.hp.hpl.jena.util.iterator.ExtendedIterator; - -public class JenaRDFParser implements com.github.jsonldjava.core.RDFParser { - - // name generator - protected Iterator _ng = new Iterator() { - final AtomicInteger i = new AtomicInteger(0); - - @Override - public void remove() { - // Do nothing for remove - } - - @Override - public String next() { - return "_:t" + i.incrementAndGet(); - } - - @Override - public boolean hasNext() { - return true; - } - }; - protected Map _bns = new LinkedHashMap(); - - protected String getNameForBlankNode(String node) { - if (!_bns.containsKey(node)) { - _bns.put(node, _ng.next()); - } - return _bns.get(node); - } - - public void setPrefix(String fullUri, String prefix) { - // TODO: graphs? - // _context.put(prefix, fullUri); - } - - public String getID(Node r) { - String rval = null; - if (r.isBlank()) { - rval = getNameForBlankNode(r.getBlankNodeLabel()); - } else { - rval = r.getURI(); - } - return rval; - } - - public String getID(Resource r) { - String rval = null; - if (r.isAnon()) { - rval = getNameForBlankNode(r.getId().toString()); - } else { - rval = r.getURI(); - } - return rval; - } - - public void importModel(RDFDataset result, Model model) { - - // Map the contexts from the Model to the RDFDataset - final Map nsPrefixMap = model.getNsPrefixMap(); - for (final String prefix : nsPrefixMap.keySet()) { - result.setNamespace(prefix, nsPrefixMap.get(prefix)); - } - - // iterate over the list of subjects and add the edges to the json-ld - // document - final ResIterator subjects = model.listSubjects(); - while (subjects.hasNext()) { - final Resource subject = subjects.next(); - importResource(result, subject); - } - } - - public void importResource(RDFDataset result, Resource subject) { - final String subj = getID(subject); - final StmtIterator statements = subject.getModel().listStatements(subject, (Property) null, - (RDFNode) null); - while (statements.hasNext()) { - final Statement statement = statements.next(); - final Property predicate = statement.getPredicate(); - final RDFNode object = statement.getObject(); - - if (object.isLiteral()) { - final Literal literal = object.asLiteral(); - final String value = literal.getLexicalForm(); - final String datatypeURI = literal.getDatatypeURI(); - String language = literal.getLanguage(); - if ("".equals(language)) { - language = null; - } - - result.addTriple(subj, predicate.getURI(), value, datatypeURI, language); - } else { - final Resource resource = object.asResource(); - final String res = getID(resource); - - result.addTriple(subj, predicate.getURI(), res); - } - } - } - - private void importGraph(RDFDataset result, Graph graph, String graphName) { - final ExtendedIterator triples = graph.find(null, null, null); - while (triples.hasNext()) { - final Triple t = triples.next(); - final String subj = getID(t.getSubject()); - final String prop = t.getPredicate().getURI(); - if (t.getObject().isLiteral()) { - final String value = t.getObject().getLiteralLexicalForm(); - final String datatypeURI = t.getObject().getLiteralDatatypeURI(); - String language = t.getObject().getLiteralLanguage(); - if ("".equals(language)) { - language = null; - } - result.addQuad(subj, prop, value, datatypeURI, language, graphName); - } else { - result.addQuad(subj, prop, getID(t.getObject()), graphName); - } - } - } - - private void importDatasetGraph(RDFDataset result, DatasetGraph input) { - - importGraph(result, input.getDefaultGraph(), "@default"); - - final Iterator graphNodes = input.listGraphNodes(); - while (graphNodes.hasNext()) { - final Node n = graphNodes.next(); - final Graph graph = input.getGraph(n); - final String graphName = n.getURI(); - - importGraph(result, graph, graphName); - } - } - - @Override - public RDFDataset parse(Object input) throws JsonLdError { - final RDFDataset result = new RDFDataset(); - // allow null input so we can use importModel and importResource before - // calling fromRDF - if (input == null) { - return result; - } - if (input instanceof DatasetGraph) { - importDatasetGraph(result, (DatasetGraph) input); - } else if (input instanceof Resource) { - importResource(result, (Resource) input); - } else if (input instanceof Model) { - importModel(result, (Model) input); - } else { - throw new JsonLdError(Error.INVALID_INPUT, - "Jena Serializer expects Model or resource input"); - } - return result; - } -} diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaTripleCallback.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaTripleCallback.java deleted file mode 100644 index 1e6bd14f..00000000 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JenaTripleCallback.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.github.jsonldjava.jena; - -import java.util.List; - -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.core.RDFDataset.Node; -import com.hp.hpl.jena.rdf.model.AnonId; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.shared.InvalidPropertyURIException; - -public class JenaTripleCallback implements JsonLdTripleCallback { - - private Model jenaModel = ModelFactory.createDefaultModel(); - - public void setJenaModel(Model jenaModel) { - this.jenaModel = jenaModel; - } - - public Model getJenaModel() { - return jenaModel; - } - - private void triple(Node subjectNode, Node propertyNode, Node objectNode, String graph) { - if (subjectNode == null || propertyNode == null || objectNode == null) { - // TODO: i don't know what to do here!!!! - return; - } - - final Resource subject = createResourceFromNode(subjectNode); - if (!propertyNode.isIRI()) { - throw new InvalidPropertyURIException(propertyNode.getValue()); - } - final Property property = jenaModel.createProperty(propertyNode.getValue()); - final Resource object = createResourceFromNode(objectNode); - - final Statement statement = jenaModel.createStatement(subject, property, object); - jenaModel.add(statement); - } - - private void triple(Node subjectNode, Node propertyNode, String value, String datatype, - String language, String graph) { - - final Resource subject = createResourceFromNode(subjectNode); - if (!propertyNode.isIRI()) { - throw new InvalidPropertyURIException(propertyNode.getValue()); - } - final Property property = jenaModel.createProperty(propertyNode.getValue()); - - RDFNode object; - if (language != null) { - object = jenaModel.createLiteral(value, language); - } else { - object = jenaModel.createTypedLiteral(value, datatype); - } - - final Statement statement = jenaModel.createStatement(subject, property, object); - jenaModel.add(statement); - } - - private Resource createResourceFromNode(Node node) { - Resource sR; - if (node.isIRI()) { - sR = jenaModel.createResource(node.getValue()); - } else { - String name = node.getValue(); - if (name.startsWith("_:")) { - name = node.getValue().substring(2, node.getValue().length()); - } - sR = jenaModel.createResource(new AnonId(name)); - } - return sR; - } - - @Override - public Object call(RDFDataset dataset) { - for (String graphName : dataset.graphNames()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject(), quad.getPredicate(), quad.getObject().getValue(), - quad.getObject().getDatatype(), quad.getObject().getLanguage(), - graphName); - } else { - triple(quad.getSubject(), quad.getPredicate(), quad.getObject(), graphName); - } - } - } - - return getJenaModel(); - } - -} diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java deleted file mode 100644 index 8debdb32..00000000 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDReader.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.jsonldjava.jena; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.Charset; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.jena.atlas.lib.InternalErrorException; -import org.apache.jena.atlas.web.ContentType; -import org.apache.jena.riot.ReaderRIOT; -import org.apache.jena.riot.RiotException; -import org.apache.jena.riot.lang.LabelToNode; -import org.apache.jena.riot.system.StreamRDF; -import org.apache.jena.riot.system.SyntaxLabels; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.utils.JsonUtils; -import com.hp.hpl.jena.datatypes.RDFDatatype; -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.graph.NodeFactory; -import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.sparql.core.Quad; -import com.hp.hpl.jena.sparql.util.Context; - -public class JsonLDReader implements ReaderRIOT { - @Override - public void read(InputStream in, String baseURI, ContentType ct, final StreamRDF output, - Context context) { - read(new InputStreamReader(in, Charset.forName("UTF-8")), baseURI, ct, output, context); - } - - @Override - public void read(Reader in, String baseURI, ContentType ct, final StreamRDF output, - Context context) { - try { - final JsonLdTripleCallback callback = new JsonLdTripleCallback() { - - @Override - public Object call(RDFDataset dataset) { - // Copy across namespaces - for (Entry namespace : dataset.getNamespaces().entrySet()) { - output.prefix(namespace.getKey(), namespace.getValue()); - } - - // Copy across triples and quads - for (final String gn : dataset.keySet()) { - final Object x = dataset.get(gn); - if ("@default".equals(gn)) { - @SuppressWarnings("unchecked") - final List> triples = (List>) x; - for (final Map t : triples) { - final Node s = createNode(t, "subject"); - final Node p = createNode(t, "predicate"); - final Node o = createNode(t, "object"); - final Triple triple = Triple.create(s, p, o); - output.triple(triple); - } - } else { - @SuppressWarnings("unchecked") - final List> quads = (List>) x; - final Node g = NodeFactory.createURI(gn); // Bnodes? - for (final Map q : quads) { - final Node s = createNode(q, "subject"); - final Node p = createNode(q, "predicate"); - final Node o = createNode(q, "object"); - output.quad(Quad.create(g, s, p, o)); - } - - } - - } - return null; - } - }; - final JsonLdOptions options = new JsonLdOptions(baseURI); - options.useNamespaces = true; - JsonLdProcessor.toRDF(JsonUtils.fromReader(in), callback, options); - } catch (final IOException e) { - throw new RiotException("Could not read JSONLD: " + e, e); - } catch (final JsonLdError e) { - throw new RiotException("Could not read JSONLD: " + e, e); - } - } - - private final LabelToNode labels = SyntaxLabels.createLabelToNode(); - - public static String LITERAL = "literal"; - public static String BLANK_NODE = "blank node"; - public static String IRI = "IRI"; - - private Node createNode(Map tripleMap, String key) { - @SuppressWarnings("unchecked") - final Map x = (Map) (tripleMap.get(key)); - return createNode(x); - } - - // See RDFParser - private Node createNode(Map map) { - final String type = (String) map.get("type"); - final String lex = (String) map.get("value"); - if (type.equals(IRI)) { - return NodeFactory.createURI(lex); - } else if (type.equals(BLANK_NODE)) { - return labels.get(null, lex); - } else if (type.equals(LITERAL)) { - final String lang = (String) map.get("language"); - final String datatype = (String) map.get("datatype"); - if (lang == null && datatype == null) { - return NodeFactory.createLiteral(lex); - } - if (lang != null) { - return NodeFactory.createLiteral(lex, lang, null); - } - final RDFDatatype dt = NodeFactory.getType(datatype); - return NodeFactory.createLiteral(lex, dt); - } else { - throw new InternalErrorException("Node is not a IRI, bNode or a literal: " + type); - // /* - // * "value" : The value of the node. - // * "subject" can be an IRI or blank node id. - // * "predicate" should only ever be an IRI - // * "object" can be and IRI or blank node id, or a literal value - // (represented as a string) - // * "type" : "IRI" if the value is an IRI or "blank node" if the - // value - // is a blank node. - // * "object" can also be "literal" in the case of literals. - // * The value of "object" can also contain the following optional - // key-value pairs: - // * "language" : the language value of a string literal - // * "datatype" : the datatype of the literal. (if not set will - // default - // to XSD:string, if set to null, null will be used). */ - // System.out.println(map.get("value")) ; - // System.out.println(map.get("type")) ; - // System.out.println(map.get("language")) ; - // System.out.println(map.get("datatype")) ; - // return null ; - } - } -} diff --git a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDWriter.java b/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDWriter.java deleted file mode 100644 index 13d953a0..00000000 --- a/integration/jena/src/main/java/com/github/jsonldjava/jena/JsonLDWriter.java +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.jsonldjava.jena; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.jena.atlas.io.IO; -import org.apache.jena.atlas.iterator.Action; -import org.apache.jena.atlas.iterator.Iter; -import org.apache.jena.atlas.lib.Chars; -import org.apache.jena.iri.IRI; -import org.apache.jena.riot.Lang; -import org.apache.jena.riot.RDFFormat; -import org.apache.jena.riot.RiotException; -import org.apache.jena.riot.system.PrefixMap; -import org.apache.jena.riot.writer.WriterDatasetRIOTBase; - -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; -import com.hp.hpl.jena.graph.Graph; -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.sparql.core.DatasetGraph; -import com.hp.hpl.jena.sparql.util.Context; -import com.hp.hpl.jena.vocabulary.RDF; - -class JsonLDWriter extends WriterDatasetRIOTBase { - private final RDFFormat format; - - public JsonLDWriter(RDFFormat syntaxForm) { - format = syntaxForm; - } - - @Override - public Lang getLang() { - return format.getLang(); - } - - @Override - public void write(Writer out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, - Context context) { - serialize(out, dataset, prefixMap, baseURI); - } - - private boolean isPretty() { - return RDFFormat.PRETTY.equals(format.getVariant()); - } - - @Override - public void write(OutputStream out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, - Context context) { - final Writer w = new OutputStreamWriter(out, Chars.charsetUTF8); - write(w, dataset, prefixMap, baseURI, context); - IO.flush(w); - } - - private void serialize(Writer writer, DatasetGraph dataset, PrefixMap prefixMap, String baseURI) { - final Map ctx = new LinkedHashMap(); - addProperties(ctx, dataset.getDefaultGraph()); - addPrefixes(ctx, prefixMap); - - try { - final JsonLdOptions opts = new JsonLdOptions(baseURI); - // opts.graph = false; - // opts.addBlankNodeIDs = false; - opts.setUseRdfType(true); - opts.setUseNativeTypes(true); - // opts.skipExpansion = false; - opts.setCompactArrays(true); - // opts.keepFreeFloatingNodes = false; - final JsonLdApi api = new JsonLdApi(opts); - final JenaRDFParser parser = new JenaRDFParser(); - final RDFDataset result = parser.parse(dataset); - Object obj = api.fromRDF(result); - final Map localCtx = new HashMap(); - localCtx.put("@context", ctx); - - // TODO: How/when to do simplify vs compact? - // if (false) - // obj = JSONLD.simplify(obj, opts); - // else - // Unclear as to the way to set better printing. - obj = JsonLdProcessor.compact(obj, localCtx, opts); - - if (isPretty()) { - JsonUtils.writePrettyPrint(writer, obj); - } else { - JsonUtils.write(writer, obj); - } - } catch (final IOException e) { - throw new RiotException("Could not write JSONLD: " + e, e); - } catch (final JsonLdError e) { - throw new RiotException("Could not process JSONLD: " + e, e); - } - } - - private static void addPrefixes(Map ctx, PrefixMap prefixMap) { - final Map pmap = prefixMap.getMapping(); - for (final Entry e : pmap.entrySet()) { - ctx.put(e.getKey(), e.getValue().toString()); - } - - } - - private void addProperties(final Map ctx, Graph graph) { - // Add some properties directly so it becomes "localname": .... - final Set dups = new HashSet(); - final Action x = new Action() { - @Override - public void apply(Triple item) { - final Node p = item.getPredicate(); - if (p.equals(RDF.type.asNode())) { - return; - } - final String x = p.getLocalName(); - if (dups.contains(x)) { - return; - } - - if (ctx.containsKey(x)) { - // Check different URI - // pmap2.remove(x) ; - // dups.add(x) ; - } else { - final Map x2 = new LinkedHashMap(); - x2.put("@id", p.getURI()); - x2.put("@type", "@id"); - ctx.put(x, x2); - } - } - }; - - Iter.iter(graph.find(null, null, null)).apply(x); - - } -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/ExampleTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/ExampleTest.java deleted file mode 100644 index 82f93623..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/ExampleTest.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.github.jsonldjava.jena; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -import org.apache.jena.riot.Lang; -import org.apache.jena.riot.RDFDataMgr; -import org.junit.Ignore; -import org.junit.Test; - -import com.github.jsonldjava.core.JsonLdApi; -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.utils.JsonUtils; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.query.DatasetFactory; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.Resource; - -/** - * Examples from README.md - */ -public class ExampleTest { - - @Ignore("Integration test") - @Test - public void jsonldToTurtleRIOT() throws Exception { - JenaJSONLD.init(); // Only needed once - final String url = "http://json-ld.org/test-suite/tests/expand-0002-in.jsonld"; - // Detects language based on extension (ideally content type) - final Model model = RDFDataMgr.loadModel(url); - - // or explicit with base URI, Lang and any supported source - final InputStream inStream = new ByteArrayInputStream("{}".getBytes("UTF-8")); - RDFDataMgr.read(model, inStream, "http://example.com/", JenaJSONLD.JSONLD); - - RDFDataMgr.write(System.out, model, Lang.TURTLE); - // - // a ; - // - // "v1"^^ ; - // "v2"^^ ; - // "v3"@en ; - // 4 ; - // 51 , 50 . - } - - @Test - public void modelTojsonldRIOT() throws Exception { - JenaJSONLD.init(); // Only needed once - - final Model model = ModelFactory.createDefaultModel(); - final Resource resource = model.createResource("http://example.com/test"); - final Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - RDFDataMgr.write(System.out, model, JenaJSONLD.JSONLD); - // { - // "@context" : { - // "value" : { - // "@id" : "http://example.com/value", - // "@type" : "@id" - // } - // }, - // "@id" : "http://example.com/test", - // "http://example.com/value" : "Test" - // } - - // Or more compact: - RDFDataMgr.write(System.out, model, JenaJSONLD.JSONLD_FORMAT_FLAT); - // "@context":{"value":{"@id":"http://example.com/value","@type":"@id"}},"@id":"http://example.com/test","http://example.com/value":"Test"} - - // Datasets are also supported - final Dataset dataset = DatasetFactory.createMem(); - dataset.addNamedModel("http://example.com/graph", model); - RDFDataMgr.write(System.out, dataset, JenaJSONLD.JSONLD); - // { - // "@graph" : [ { - // "@id" : "http://example.com/test", - // "http://example.com/value" : "Test" - // } ], - // "@id" : "http://example.com/graph" - // } - - } - - @Test - public void modelToJsonldClassic() throws Exception { - JenaJSONLD.init(); // Only needed once - - final Model model = ModelFactory.createDefaultModel(); - final Resource resource = model.createResource("http://example.com/test"); - final Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - model.write(System.out, "JSON-LD"); - // { - // "@context" : { - // "value" : { - // "@id" : "http://example.com/value", - // "@type" : "@id" - // } - // }, - // "@id" : "http://example.com/test", - // "http://example.com/value" : "Test" - // } - - // Or made relative from a base URI - // (notice the relative @id below) - model.write(System.out, "JSON-LD", "http://example.com/"); - // { - // "@context" : { - // "value" : { - // "@id" : "http://example.com/value", - // "@type" : "@id" - // } - // }, - // "@id" : "test", - // "http://example.com/value" : "Test" - // } - } - - @Ignore("Integration test") - @Test - public void jsonldToTurtleClassic() throws Exception { - JenaJSONLD.init(); // Only needed once - - final String url = "http://json-ld.org/test-suite/tests/expand-0002-in.jsonld"; - final Model model = ModelFactory.createDefaultModel(); - model.read(url, "JSON-LD"); - model.write(System.out, "TURTLE", "http://example.com/"); - // @base . - // a ; - // "v1"^^ ; - // "v2"^^ ; - // "v3"@en ; - // 4 ; - // 51 , 50 . - } - - @Test - public void modelToJsonLD() throws Exception { - JenaJSONLD.init(); // Only needed once - final Model model = ModelFactory.createDefaultModel(); - final Resource resource = model.createResource("http://example.com/test"); - final Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - final JsonLdOptions options = new JsonLdOptions(); - options.format = "application/ld+json"; - final JsonLdApi api = new JsonLdApi(options); - final RDFDataset dataset = new RDFDataset(api); - final Object json = api.fromRDF(dataset); - final String jsonStr = JsonUtils.toPrettyString(json); - System.out.println(jsonStr); - // [ { - // "@id" : "http://example.com/test", - // "http://example.com/value" : [ { - // "@value" : "Test" - // } ] - // } ] - } -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JSONLDToRDFTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JSONLDToRDFTest.java deleted file mode 100644 index e912a73d..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JSONLDToRDFTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.jsonldjava.jena; - -import static org.junit.Assert.assertTrue; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.github.jsonldjava.core.JsonLdApi; -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.utils.JsonUtils; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.Resource; - -public class JSONLDToRDFTest { - - @BeforeClass - public static void init() { - JenaJSONLD.init(); - } - - @Test - public void write() throws Exception { - final Model model = ModelFactory.createDefaultModel(); - final Resource resource = model.createResource("http://example.com/test"); - final Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - final JsonLdOptions options = new JsonLdOptions(); - options.format = "application/ld+json"; - final JenaRDFParser parser = new JenaRDFParser(); - final RDFDataset dataset = parser.parse(model); - final Object json = new JsonLdApi(options).fromRDF(dataset); - final String jsonStr = JsonUtils.toPrettyString(json); - // System.out.println(jsonStr); - assertTrue(jsonStr.contains("@id")); - assertTrue(jsonStr.contains("http://example.com/test")); - assertTrue(jsonStr.contains("http://example.com/value")); - assertTrue(jsonStr.contains("Test")); - } - -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java deleted file mode 100644 index 810b29fb..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONReaderTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.github.jsonldjava.jena; - -import static org.junit.Assert.assertEquals; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Statement; - -public class JenaJSONReaderTest { - - @BeforeClass - public static void init() { - JenaJSONLD.init(); - } - - @Test - public void readInputStream() throws Exception { - final Model model = ModelFactory.createDefaultModel(); - String jsonld = " { '@id': 'test', \n" + " 'http://example.com/value': 'Test' \n } "; - jsonld = jsonld.replace('\'', '"'); - final InputStream in = new ByteArrayInputStream(jsonld.getBytes("utf8")); - - final String baseUri = "http://example.com/"; - model.read(in, baseUri, "JSON-LD"); - // model.write(System.out, "TURTLE", ""); - checkRelative(model); - } - - private void checkRelative(Model model) { - assertEquals(1, model.size()); - final Statement statement = model.listStatements().next(); - assertEquals("http://example.com/value", statement.getPredicate().toString()); - assertEquals("Test", statement.getString()); - assertEquals("http://example.com/test", statement.getSubject().toString()); - } - - // @Ignore("Integration test") - @Test - public void readURL() throws Exception { - final Model model = ModelFactory.createDefaultModel(); - final String url = getClass().getResource("../jena/relative.jsonld").toExternalForm(); - final String baseUri = "http://example.com/"; - model.read(url, baseUri, "JSON-LD"); - model.write(System.out, "TURTLE", ""); - checkRelative(model); - } -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java deleted file mode 100644 index fb73eeeb..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaJSONWriterTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.github.jsonldjava.jena; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.StringWriter; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.Resource; - -public class JenaJSONWriterTest { - - @BeforeClass - public static void init() { - JenaJSONLD.init(); - } - - @Test - public void write() throws Exception { - final Model model = ModelFactory.createDefaultModel(); - final Resource resource = model.createResource("http://example.com/test"); - final Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - final StringWriter writer = new StringWriter(); - model.write(writer, "JSON-LD"); - - final String json = writer.toString(); - // System.out.println(json); - assertTrue(json.contains("@id")); - assertTrue(json.contains("http://example.com/test")); - assertTrue(json.contains("http://example.com/value")); - assertTrue(json.contains("Test")); - } - - @Test - public void writeWithBase() throws Exception { - final Model model = ModelFactory.createDefaultModel(); - final Resource resource = model.createResource("http://example.com/test"); - final Property property = model.createProperty("http://example.com/value"); - model.add(resource, property, "Test"); - - final StringWriter writer = new StringWriter(); - model.write(writer, "JSON-LD", "http://example.com/"); - - final String json = writer.toString(); - // System.out.println(json); - assertTrue(json.contains("@id")); - assertFalse(json.contains("http://example.com/test")); - assertTrue(json.contains("\"test\"")); - // Note that the PROPERTY might not be relativized and still is - // "http://example.com/value" - assertTrue(json.contains("Test")); - } - -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java deleted file mode 100644 index 640a1283..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRDFParserTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.github.jsonldjava.jena; - -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.Obj; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; - -public class JenaRDFParserTest { - private static Logger logger = LoggerFactory.getLogger(JenaRDFParserTest.class); - - @Test - public void test() throws JsonLdError { - - final String turtle = "@prefix const: .\n" - + "@prefix xsd: .\n" - + " const:code \"123\" .\n" - + " const:code \"ABC\"^^xsd:string .\n"; - - final List> expected = new ArrayList>() { - { - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo1"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "123"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo2"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "ABC"); - } - }); - } - }); - } - }); - } - }; - - final Model modelResult = ModelFactory.createDefaultModel().read( - new ByteArrayInputStream(turtle.getBytes()), "", "TURTLE"); - final JenaRDFParser parser = new JenaRDFParser(); - final Object json = JsonLdProcessor.fromRDF(modelResult, parser); - - assertTrue(Obj.equals(json, expected)); - } -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java deleted file mode 100644 index 45c236f0..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaRiotReadWriteTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.jsonldjava.jena; - -import static com.github.jsonldjava.jena.JenaJSONLD.JSONLD; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStream; -import java.util.Iterator; -import java.util.Map; - -import org.apache.jena.riot.RDFDataMgr; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -import com.github.jsonldjava.utils.TestUtils; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.query.DatasetFactory; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.sparql.lib.DatasetLib; -import com.hp.hpl.jena.sparql.sse.SSE; - -/** tests : JSONLD->RDF ; JSONLD->RDF->JSONLD */ -public class JenaRiotReadWriteTest { - - @BeforeClass - public static void init() { - /* - * Disable this to test that static { } in JenaJSONLD forces init() by - * accessing the field JenaJSONLD.JSONLD. - * - * It is enabled by default to enable selective test running. - */ - JenaJSONLD.init(); - } - - private static boolean isIsomorphic(Dataset ds1, Dataset ds2) { - return DatasetLib.isomorphic(ds1, ds2); - } - - @Rule - public TemporaryFolder tempDir = new TemporaryFolder(); - - private File testDir; - - @Before - public void setUp() throws Exception { - testDir = tempDir.newFolder("jenarioreadwritetest"); - } - - @Test - public void read_ds01() throws Exception { - datasetJ2R("graph1.jsonld", "graph1.ttl"); - } - - @Test - public void read_ds02() throws Exception { - datasetJ2R("dataset1.jsonld", "dataset1.trig"); - } - - @Test - public void read_g01() throws Exception { - graphJ2R("graph1.jsonld", "graph1.ttl"); - } - - @Test - public void roundtrip_01() throws Exception { - rtRJRg("graph1.ttl"); - } - - @Test - public void roundtrip_02() throws Exception { - rtRJRds("graph1.ttl"); - } - - @Test - public void roundtrip_03() throws Exception { - rtRJRds("dataset1.trig"); - } - - private void datasetJ2R(String inResource, String outResource) throws Exception { - final Dataset ds1 = loadDatasetFromClasspathResource("/com/github/jsonldjava/jena/" - + inResource); - final Dataset ds2 = loadDatasetFromClasspathResource("/com/github/jsonldjava/jena/" - + outResource); - assertTrue("Input dataset " + inResource + " not isomorphic to output dataset" - + outResource, isIsomorphic(ds1, ds2)); - } - - private void graphJ2R(String inResource, String outResource) throws Exception { - final Model model1 = loadModelFromClasspathResource("/com/github/jsonldjava/jena/" - + inResource); - assertFalse("Failed to load input model from classpath: " + inResource, model1.isEmpty()); - final Model model2 = loadModelFromClasspathResource("/com/github/jsonldjava/jena/" - + outResource); - assertFalse("Failed to load output model from classpath: " + outResource, model2.isEmpty()); - assertTrue("Input graph " + inResource + " not isomorphic to output dataset" + outResource, - model1.isIsomorphicWith(model2)); - } - - private Dataset loadDatasetFromClasspathResource(String resource) throws Exception { - final InputStream url = this.getClass().getResourceAsStream(resource); - assertNotNull("Could not find resource on classpath: " + resource, url); - return RDFDataMgr.loadDataset(TestUtils.copyResourceToFile(testDir, resource)); - } - - private Model loadModelFromClasspathResource(String resource) throws Exception { - final InputStream url = this.getClass().getResourceAsStream(resource); - assertNotNull("Could not find resource on classpath: " + resource, url); - return RDFDataMgr.loadModel(TestUtils.copyResourceToFile(testDir, resource)); - } - - private void rtRJRds(String resource) throws Exception { - final Dataset ds1 = loadDatasetFromClasspathResource("/com/github/jsonldjava/jena/" - + resource); - - // Write a JSON-LD - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - RDFDataMgr.write(out, ds1, JSONLD); - final ByteArrayInputStream r = new ByteArrayInputStream(out.toByteArray()); - - // Read as JSON-LD - final Dataset ds2 = DatasetFactory.createMem(); - RDFDataMgr.read(ds2, r, null, JSONLD); - - if (!isIsomorphic(ds1, ds2)) { - SSE.write(ds1); - SSE.write(ds2); - } - - assertTrue("Input dataset " + resource + " not isomorphic with roundtrip dataset", - isIsomorphic(ds1, ds2)); - - // Check namespaces in the parsed dataset match those in the original data - checkNamespaces(ds2.getDefaultModel(), ds1.getDefaultModel().getNsPrefixMap()); - Iterator graphNames = ds2.listNames(); - while (graphNames.hasNext()) { - String gn = graphNames.next(); - checkNamespaces(ds2.getNamedModel(gn), ds1.getNamedModel(gn).getNsPrefixMap()); - } - } - - private void checkNamespaces(Model m, Map namespaces) { - if (namespaces == null) return; - - for (String prefix : namespaces.keySet()) { - Assert.assertEquals("Model does contain expected namespace " + prefix + ": <" + namespaces.get(prefix) + ">", namespaces.get(prefix), m.getNsPrefixURI(prefix)); - } - } - - private void rtRJRg(String filename) throws Exception { - final Model model = loadModelFromClasspathResource("/com/github/jsonldjava/jena/" - + filename); - - // Write a JSON-LD - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - RDFDataMgr.write(out, model, JSONLD); - final ByteArrayInputStream r = new ByteArrayInputStream(out.toByteArray()); - - // Read as JSON-LD - final Model model2 = ModelFactory.createDefaultModel(); - RDFDataMgr.read(model2, r, null, JSONLD); - - assertFalse("JSON-LD model was empty", model2.isEmpty()); - - // Compare - if (!model.isIsomorphicWith(model2)) { - System.out.println("## ---- DIFFERENT"); - } - - // Check namespaces in parsed graph match the original data - checkNamespaces(model2, model.getNsPrefixMap()); - } -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaSystemTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaSystemTest.java deleted file mode 100644 index 5f1064b3..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaSystemTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.jsonldjava.jena; - -import org.apache.jena.riot.RDFDataMgr; -import org.apache.jena.riot.RDFFormat; -import org.apache.jena.riot.RDFLanguages; -import org.apache.jena.riot.RDFParserRegistry; -import org.apache.jena.riot.RDFWriterRegistry; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -// Test system integration / registration -public class JenaSystemTest extends Assert { - - @BeforeClass - public static void init() { - JenaJSONLD.init(); - } - - private static RDFFormat jsonldFmt1 = new RDFFormat(JenaJSONLD.JSONLD, RDFFormat.PRETTY); - private static RDFFormat jsonldFmt2 = new RDFFormat(JenaJSONLD.JSONLD, RDFFormat.FLAT); - - @Test - public void jenaSystem_basic_1() { - assertEquals("name", "JSON-LD", JenaJSONLD.JSONLD.getName()); - assertEquals("content-type", "application/ld+json", JenaJSONLD.JSONLD.getContentType() - .getContentType()); - } - - @Test - public void jenaSystem_read_1() { - assertTrue(RDFLanguages.isRegistered(JenaJSONLD.JSONLD)); - assertTrue(RDFLanguages.isTriples(JenaJSONLD.JSONLD)); - assertTrue(RDFLanguages.isQuads(JenaJSONLD.JSONLD)); - } - - @Test - public void jenaSystem_read_2() { - assertNotNull(RDFParserRegistry.getFactory(JenaJSONLD.JSONLD)); - } - - @Test - public void jenaSystem_write_1() { - assertTrue(RDFWriterRegistry.contains(JenaJSONLD.JSONLD)); - } - - @Test - public void jenaSystem_write_2() { - assertNotNull(RDFWriterRegistry.getWriterGraphFactory(JenaJSONLD.JSONLD)); - assertNotNull(RDFWriterRegistry.getWriterDatasetFactory(JenaJSONLD.JSONLD)); - assertNotNull(RDFWriterRegistry.defaultSerialization(JenaJSONLD.JSONLD)); - } - - @Test - public void jenaSystem_write_3() { - - assertEquals(jsonldFmt1, RDFWriterRegistry.defaultSerialization(JenaJSONLD.JSONLD)); - - assertNotNull(RDFWriterRegistry.getWriterGraphFactory(jsonldFmt1)); - assertNotNull(RDFWriterRegistry.getWriterGraphFactory(jsonldFmt2)); - - assertTrue(RDFWriterRegistry.registeredGraphFormats().contains(jsonldFmt1)); - assertTrue(RDFWriterRegistry.registeredGraphFormats().contains(jsonldFmt2)); - - assertNotNull(RDFWriterRegistry.getWriterDatasetFactory(jsonldFmt1)); - assertNotNull(RDFWriterRegistry.getWriterDatasetFactory(jsonldFmt2)); - - assertTrue(RDFWriterRegistry.registeredDatasetFormats().contains(jsonldFmt1)); - assertTrue(RDFWriterRegistry.registeredDatasetFormats().contains(jsonldFmt2)); - } - - @Test - public void jenaSystem_write_4() { - assertNotNull(RDFDataMgr.createGraphWriter(jsonldFmt1)); - assertNotNull(RDFDataMgr.createGraphWriter(jsonldFmt2)); - assertNotNull(RDFDataMgr.createDatasetWriter(jsonldFmt1)); - assertNotNull(RDFDataMgr.createDatasetWriter(jsonldFmt2)); - } -} diff --git a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java b/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java deleted file mode 100644 index e06bcce8..00000000 --- a/integration/jena/src/test/java/com/github/jsonldjava/jena/JenaTripleCallbackTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.github.jsonldjava.jena; - -import static org.junit.Assert.assertTrue; - -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.utils.Obj; -import com.hp.hpl.jena.rdf.model.Model; - -public class JenaTripleCallbackTest { - - @Test - public void triplesTest() throws JsonParseException, JsonMappingException, JsonLdError { - - final List> input = new ArrayList>() { - { - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo1"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "123"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo2"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "ABC"); - } - }); - } - }); - } - }); - } - }; - - final List expected = new ArrayList() { - { - add(" \"123\"^^ ."); - add(" \"ABC\"^^ ."); - } - }; - - final JsonLdTripleCallback callback = new JenaTripleCallback(); - final Model model = (Model) JsonLdProcessor.toRDF(input, callback); - - final StringWriter w = new StringWriter(); - model.write(w, "N-TRIPLE"); - - final List result = new ArrayList(Arrays.asList(w.getBuffer().toString() - .split("\n"))); - Collections.sort(result); - // System.out.println(expected); - // System.out.println(result); - assertTrue(Obj.equals(expected, result)); - } - -} diff --git a/integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.jsonld b/integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.jsonld deleted file mode 100644 index ed20dc04..00000000 --- a/integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.jsonld +++ /dev/null @@ -1,26 +0,0 @@ -[ { - "@id" : "http://example/G", - "@graph" : [ { - "@id" : "http://example/a" - }, { - "@id" : "http://example/z1", - "http://example/b" : [ { - "@id" : "http://example/a" - } ] - }, { - "@id" : "http://example/z2", - "http://example/b" : [ { - "@id" : "http://example/a" - } ] - } ] -}, { - "@id" : "http://example/s1", - "http://example/p" : [ { - "@value" : 1 - } ] -}, { - "@id" : "http://example/s2", - "http://example/q" : [ { - "@value" : 2 - } ] -} ] diff --git a/integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.trig b/integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.trig deleted file mode 100644 index 554686c4..00000000 --- a/integration/jena/src/test/resources/com/github/jsonldjava/jena/dataset1.trig +++ /dev/null @@ -1,10 +0,0 @@ -@prefix : . -@prefix xsd: . - -{ :s1 :p 1 . - :s2 :q 2 . } - -:G { - :z1 :b :a . - :z2 :b :a . -} diff --git a/integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.jsonld b/integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.jsonld deleted file mode 100644 index 0f092dc3..00000000 --- a/integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.jsonld +++ /dev/null @@ -1,50 +0,0 @@ -[ { - "@id" : "_:b0", - "http://example/r" : [ { - "@value" : "4.5", - "@type" : "http://www.w3.org/2001/XMLSchema#decimal" - } ] -}, { - "@id" : "_:b3" -}, { - "@id" : "http://example/a" -}, { - "@id" : "http://example/s", - "http://example/p" : [ { - "@value" : 2 - }, { - "@value" : 1 - } ] -}, { - "@id" : "http://example/s1", - "http://example/b" : [ { - "@id" : "http://example/a" - } ] -}, { - "@id" : "http://example/s2", - "http://example/b2" : [ { - "@id" : "_:b3" - } ], - "http://example/b" : [ { - "@id" : "http://example/a" - } ] -}, { - "@id" : "http://example/s3", - "http://example/b1" : [ { - "@id" : "_:b3" - } ] -}, { - "@id" : "http://example/x1", - "http://example/q" : [ { - "@list" : [ { - "@value" : "a" - }, { - "@value" : "b" - } ] - } ] -}, { - "@id" : "http://example/x2", - "http://example/q" : [ { - "@id" : "_:b0" - } ] -} ] diff --git a/integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.ttl b/integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.ttl deleted file mode 100644 index c66e4772..00000000 --- a/integration/jena/src/test/resources/com/github/jsonldjava/jena/graph1.ttl +++ /dev/null @@ -1,14 +0,0 @@ -@prefix : . -@prefix xsd: . - -:s :p 1 , 2 . - -:x1 :q ("a"^^xsd:string "b"^^xsd:string) . - -:s1 :b :a . -:s2 :b :a . - -:s3 :b1 _:aa . -:s2 :b2 _:aa . - -:x2 :q [ :r 4.5 ] . diff --git a/integration/jena/src/test/resources/com/github/jsonldjava/jena/relative.jsonld b/integration/jena/src/test/resources/com/github/jsonldjava/jena/relative.jsonld deleted file mode 100644 index 3e44f792..00000000 --- a/integration/jena/src/test/resources/com/github/jsonldjava/jena/relative.jsonld +++ /dev/null @@ -1,3 +0,0 @@ - { "@id": "test", - "http://example.com/value": "Test" - } \ No newline at end of file diff --git a/integration/jena/src/test/resources/log4j.properties b/integration/jena/src/test/resources/log4j.properties deleted file mode 100644 index b88520a7..00000000 --- a/integration/jena/src/test/resources/log4j.properties +++ /dev/null @@ -1,6 +0,0 @@ -log4j.rootLogger=INFO, R - -## Direct log messages to the console -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n From 5f4469a314af8e3c2c956796214d9d40d257db1a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 11 Jun 2014 15:49:12 +1000 Subject: [PATCH 046/440] remove jena module from integration parent --- integration/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/integration/pom.xml b/integration/pom.xml index bf19538c..49ce693c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -13,7 +13,6 @@ sesame - jena clerezza rdf2go From 404f339f2f669e53c7265cb8b16206535eb71737 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 11 Jun 2014 15:51:44 +1000 Subject: [PATCH 047/440] remove jena from pom.xml --- pom.xml | 1 - tools/pom.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4891f49e..81bbb8f5 100755 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,6 @@ 0.13 4.2.5 2.3.3 - 2.11.1 4.11 5.0.0 2.7.11 diff --git a/tools/pom.xml b/tools/pom.xml index 6e30515b..94fd4da3 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -19,7 +19,7 @@ ${project.groupId} - jsonld-java-jena + jsonld-java-sesame ${project.version} From af6379073e0adac316fd4f6ed19a1584f3708cb4 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Tue, 17 Jun 2014 11:16:31 +0100 Subject: [PATCH 048/440] Spelling mistake fix in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa5e1736..e9e939bd 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ Additional HTTP headers (such as `Content-Type` above) can be included, although these are generally ignored by JSONLD-Java. Unless overridden in `jarcache.json`, this `Cache-Control` header is -autoamtically injected together with the current `Date`, meaning that the +automatically injected together with the current `Date`, meaning that the resource loaded from the JAR will effectively never expire (the real HTTP server will never be consulted by the Apache HTTP client): From 185e09bce79a6d3a811d8f44aa02f254449a889f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:30:57 +1000 Subject: [PATCH 049/440] Bump to Sesame-2.7.12 --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 81bbb8f5..6b062fe6 100755 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 2.3.3 4.11 5.0.0 - 2.7.11 + 2.7.12 1.7.7 @@ -78,6 +78,11 @@ rdf.core ${clerezza.version} + + org.openrdf.sesame + sesame-bom + ${sesame.version} + org.openrdf.sesame sesame-model From 5d3777eeae29ad0bc866a511aa17738ab6e4bfa3 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:31:14 +1000 Subject: [PATCH 050/440] Ignore new test that doesn't function right now --- .../jsonldjava/sesame/SesameJSONLDWriterTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java index 83ade4a8..a90d519d 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java @@ -8,6 +8,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import org.junit.Ignore; import org.junit.Test; @@ -18,6 +19,8 @@ import org.openrdf.model.impl.LinkedHashModel; import org.openrdf.model.vocabulary.XMLSchema; import org.openrdf.rio.ParserConfig; +import org.openrdf.rio.RDFHandlerException; +import org.openrdf.rio.RDFParseException; import org.openrdf.rio.RDFParser; import org.openrdf.rio.RDFWriter; import org.openrdf.rio.RDFWriterTest; @@ -69,6 +72,13 @@ public void testRoundTrip() throws Exception { public void testRoundTripPreserveBNodeIds() throws Exception { } + @Test + @Override + @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + public void testIllegalPrefix() + throws RDFHandlerException, RDFParseException, IOException { + } + @Test public void testRoundTripNamespaces() throws Exception { String exNs = "http://example.org/"; From 403aa072085627d35a92257baf3d5477202ac69b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:35:02 +1000 Subject: [PATCH 051/440] rework test to fit with Sesame-2.7.12 --- .../sesame/SesameJSONLDWriterTest.java | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java index a90d519d..f323c37f 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java @@ -39,42 +39,34 @@ public SesameJSONLDWriterTest() { super(new SesameJSONLDWriterFactory(), new SesameJSONLDParserFactory()); } - /* - * TODO: Unignore tests when updating to Sesame-2.7.12 - */ + @Override protected void setupWriterConfig(WriterConfig config) { + super.setupWriterConfig(config); config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); } - /* - * TODO: Unignore tests when updating to Sesame-2.7.12 - */ + @Override protected void setupParserConfig(ParserConfig config) { + super.setupParserConfig(config); config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true); } - - @Test - @Override - @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") - public void testPerformance() throws Exception { - } @Test @Override - @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + @Ignore("Sesame-2.7 does not support RDF-1.1, so string/langString literals cause this to fail.") public void testRoundTrip() throws Exception { } @Test @Override - @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + @Ignore("Sesame-2.7 does not support RDF-1.1, so string/langString literals cause this to fail.") public void testRoundTripPreserveBNodeIds() throws Exception { } - + @Test @Override - @Ignore("Default RDFWriter.getWriterConfig doesn't use JSONLDMode.COMPACT, so namespaces are not preserved") + @Ignore("TODO: Determine why this test is breaking") public void testIllegalPrefix() throws RDFHandlerException, RDFParseException, IOException { } From e81944328c0d24a5cda98e969dfa998e250b5864 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:44:51 +1000 Subject: [PATCH 052/440] fix java-8 javadoc complaint --- core/src/main/java/com/github/jsonldjava/core/RDFDataset.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 422b61b6..062683a1 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -391,7 +391,7 @@ public Map getContext() { /** * parses a context object and sets any namespaces found within it * - * @param context + * @param contextLike * The context to parse * @throws JsonLdError * If the context can't be parsed From 5a27eaa0ad29b61b0979643deceae6553e85d0b2 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:50:45 +1000 Subject: [PATCH 053/440] Release 0.4.2 --- README.md | 9 ++++++--- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e9e939bd..2408819b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.4.1/README.md) - JSONLD-JAVA =========== @@ -14,7 +12,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5-SNAPSHOT + 0.4.2 Code example @@ -236,6 +234,11 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-06-30 +* Release version 0.4.2 +* Bump to Sesame-2.7.12 +* Remove Jena integration module, as it is now maintained by Jena team in their repository + ### 2014-04-22 * Release version 0.4 * Bump to Sesame-2.7.11 diff --git a/core/pom.xml b/core/pom.xml index d8ebade6..969f7464 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.2 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 019eeeb7..241bc409 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.2 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 49ce693c..3bc194b4 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.2 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index cb763ff7..0174fda4 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.2 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index d21e37e2..e7f66fa3 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.2 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 6b062fe6..919530d5 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5-SNAPSHOT + 0.4.2 JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 94fd4da3..8928845b 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.4.2 4.0.0 jsonld-java-tools From 791adedb335af304d6f44a939280286b669a347e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:54:02 +1000 Subject: [PATCH 054/440] bump to next development version --- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 969f7464..d8ebade6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4.2 + 0.5-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 241bc409..019eeeb7 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.2 + 0.5-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 3bc194b4..49ce693c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4.2 + 0.5-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 0174fda4..cb763ff7 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.2 + 0.5-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index e7f66fa3..d21e37e2 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.4.2 + 0.5-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 919530d5..6b062fe6 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.4.2 + 0.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 8928845b..94fd4da3 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.4.2 + 0.5-SNAPSHOT 4.0.0 jsonld-java-tools From 8aad8bc52a6eac84e2c7b7f51d3f5b66fda5fd05 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 15:56:09 +1000 Subject: [PATCH 055/440] bump message on readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2408819b..22734c04 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.4.2/README.md) + JSONLD-JAVA =========== @@ -12,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.4.2 + 0.5-SNAPSHOT Code example From 3557e2283af1ef376ebb75f3788c921fc0f03d4f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 30 Jun 2014 16:07:45 +1000 Subject: [PATCH 056/440] catch exception that should not be propagated --- .../com/github/jsonldjava/sesame/SesameJSONLDParser.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java index ed5c340e..37fe682c 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java @@ -15,6 +15,7 @@ import org.openrdf.rio.RDFParser; import org.openrdf.rio.helpers.RDFParserBase; +import com.fasterxml.jackson.core.JsonParseException; import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdOptions; import com.github.jsonldjava.core.JsonLdProcessor; @@ -64,6 +65,8 @@ public void parse(final InputStream in, final String baseURI) throws IOException JsonLdProcessor.toRDF(JsonUtils.fromInputStream(in), callback, options); } catch (final JsonLdError e) { throw new RDFParseException("Could not parse JSONLD", e); + } catch (final JsonParseException e) { + throw new RDFParseException("Could not parse JSONLD", e); } catch (final RuntimeException e) { if (e.getCause() != null && e.getCause() instanceof RDFParseException) { throw (RDFParseException) e.getCause(); @@ -85,6 +88,8 @@ public void parse(final Reader reader, final String baseURI) throws IOException, JsonLdProcessor.toRDF(JsonUtils.fromReader(reader), callback, options); } catch (final JsonLdError e) { throw new RDFParseException("Could not parse JSONLD", e); + } catch (final JsonParseException e) { + throw new RDFParseException("Could not parse JSONLD", e); } catch (final RuntimeException e) { if (e.getCause() != null && e.getCause() instanceof RDFParseException) { throw (RDFParseException) e.getCause(); From f70f0c741d51b2a12271b99a8e403592d5437c02 Mon Sep 17 00:00:00 2001 From: Jeen Broekstra Date: Tue, 1 Jul 2014 10:26:24 +0200 Subject: [PATCH 057/440] [maven-release-plugin] prepare release jsonld-java-parent-0.5-patched --- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 5 ++--- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index d8ebade6..1f959479 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.5-patched 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 019eeeb7..71bfb1dc 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.5-patched 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 49ce693c..93f54149 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.5-patched 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index cb763ff7..08faee66 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -1,10 +1,9 @@ - + jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.5-patched 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index d21e37e2..b8a28a15 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.5-patched 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 6b062fe6..8b5960a5 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5-SNAPSHOT + 0.5-patched JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 94fd4da3..1f03ccd5 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.5-patched 4.0.0 jsonld-java-tools From 2c6d0f2ab0c5d2fbf08a6f189deb3b74ea9cb77b Mon Sep 17 00:00:00 2001 From: Jeen Broekstra Date: Tue, 1 Jul 2014 11:01:08 +0200 Subject: [PATCH 058/440] getContentLengthLong is a Java7 method, replaced with getContentLength to keep J6-compatible. SesameTripleCallback now calls startRDF and endRDF on the RDFHandler to properly start/stop handling data. --- .../jsonldjava/utils/JarCacheResource.java | 3 +- .../sesame/SesameTripleCallback.java | 377 +++++++++--------- 2 files changed, 198 insertions(+), 182 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java index 92063838..3320cac5 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -23,7 +23,8 @@ public JarCacheResource(URL classpath) throws IOException { @Override public long length() { - return connection.getContentLengthLong(); + // TODO should be getContentLengthLong() but this is not available in Java 6. + return connection.getContentLength(); } @Override diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java index 2123e8c0..bc2b3db2 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java @@ -24,186 +24,201 @@ public class SesameTripleCallback implements JsonLdTripleCallback { - private ValueFactory vf; - - private RDFHandler handler; - - private ParserConfig parserConfig; - - private final ParseErrorListener parseErrorListener; - - public SesameTripleCallback() { - this(new StatementCollector(new LinkedHashModel())); - } - - public SesameTripleCallback(RDFHandler nextHandler) { - this(nextHandler, ValueFactoryImpl.getInstance()); - } - - public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf) { - this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); - } - - public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf, ParserConfig parserConfig, - ParseErrorListener parseErrorListener) { - this.handler = nextHandler; - this.vf = vf; - this.parserConfig = parserConfig; - this.parseErrorListener = parseErrorListener; - } - - private void triple(String s, String p, String o, String graph) { - if (s == null || p == null || o == null) { - // TODO: i don't know what to do here!!!! - return; - } - - Statement result; - // This method is always called with three Resources as subject - // predicate and - // object - if (graph == null) { - result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o)); - } else { - result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o), - createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - private Resource createResource(String resource) { - // Blank node without any given identifier - if (resource.equals("_:")) { - return vf.createBNode(); - } else if (resource.startsWith("_:")) { - return vf.createBNode(resource.substring(2)); - } else { - return vf.createURI(resource); - } - } - - private void triple(String s, String p, String value, String datatype, String language, - String graph) { - - if (s == null || p == null || value == null) { - // TODO: i don't know what to do here!!!! - return; - } - - final Resource subject = createResource(s); - - final URI predicate = vf.createURI(p); - final URI datatypeURI = datatype == null ? null : vf.createURI(datatype); - - Value object; - try { - object = RDFParserHelper.createLiteral(value, language, datatypeURI, getParserConfig(), - getParserErrorListener(), getValueFactory()); - } catch (final RDFParseException e) { - throw new RuntimeException(e); - } - - Statement result; - if (graph == null) { - result = vf.createStatement(subject, predicate, object); - } else { - result = vf.createStatement(subject, predicate, object, createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - public ParseErrorListener getParserErrorListener() { - return this.parseErrorListener; - } - - /** - * @return the handler - */ - public RDFHandler getHandler() { - return handler; - } - - /** - * @param handler - * the handler to set - */ - public void setHandler(RDFHandler handler) { - this.handler = handler; - } - - /** - * @return the parserConfig - */ - public ParserConfig getParserConfig() { - return parserConfig; - } - - /** - * @param parserConfig - * the parserConfig to set - */ - public void setParserConfig(ParserConfig parserConfig) { - this.parserConfig = parserConfig; - } - - /** - * @return the vf - */ - public ValueFactory getValueFactory() { - return vf; - } - - /** - * @param vf - * the vf to set - */ - public void setValueFactory(ValueFactory vf) { - this.vf = vf; - } - - @Override - public Object call(final RDFDataset dataset) { - if (handler != null) { - for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { - try { - handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); - } catch (final RDFHandlerException e) { - throw new RuntimeException("Failed handling namespace", e); - } - } - } - for (String graphName : dataset.keySet()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), quad.getObject().getDatatype(), quad - .getObject().getLanguage(), graphName); - } else { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), graphName); - } - } - } - - return getHandler(); - } + private ValueFactory vf; + + private RDFHandler handler; + + private ParserConfig parserConfig; + + private final ParseErrorListener parseErrorListener; + + public SesameTripleCallback() { + this(new StatementCollector(new LinkedHashModel())); + } + + public SesameTripleCallback(RDFHandler nextHandler) { + this(nextHandler, ValueFactoryImpl.getInstance()); + } + + public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf) { + this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); + } + + public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf, + ParserConfig parserConfig, ParseErrorListener parseErrorListener) { + this.handler = nextHandler; + this.vf = vf; + this.parserConfig = parserConfig; + this.parseErrorListener = parseErrorListener; + } + + private void triple(String s, String p, String o, String graph) { + if (s == null || p == null || o == null) { + // TODO: i don't know what to do here!!!! + return; + } + + Statement result; + // This method is always called with three Resources as subject + // predicate and + // object + if (graph == null) { + result = vf.createStatement(createResource(s), vf.createURI(p), + createResource(o)); + } else { + result = vf.createStatement(createResource(s), vf.createURI(p), + createResource(o), createResource(graph)); + } + + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } + } + } + + private Resource createResource(String resource) { + // Blank node without any given identifier + if (resource.equals("_:")) { + return vf.createBNode(); + } else if (resource.startsWith("_:")) { + return vf.createBNode(resource.substring(2)); + } else { + return vf.createURI(resource); + } + } + + private void triple(String s, String p, String value, String datatype, + String language, String graph) { + + if (s == null || p == null || value == null) { + // TODO: i don't know what to do here!!!! + return; + } + + final Resource subject = createResource(s); + + final URI predicate = vf.createURI(p); + final URI datatypeURI = datatype == null ? null : vf + .createURI(datatype); + + Value object; + try { + object = RDFParserHelper.createLiteral(value, language, + datatypeURI, getParserConfig(), getParserErrorListener(), + getValueFactory()); + } catch (final RDFParseException e) { + throw new RuntimeException(e); + } + + Statement result; + if (graph == null) { + result = vf.createStatement(subject, predicate, object); + } else { + result = vf.createStatement(subject, predicate, object, + createResource(graph)); + } + + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } + } + } + + public ParseErrorListener getParserErrorListener() { + return this.parseErrorListener; + } + + /** + * @return the handler + */ + public RDFHandler getHandler() { + return handler; + } + + /** + * @param handler + * the handler to set + */ + public void setHandler(RDFHandler handler) { + this.handler = handler; + } + + /** + * @return the parserConfig + */ + public ParserConfig getParserConfig() { + return parserConfig; + } + + /** + * @param parserConfig + * the parserConfig to set + */ + public void setParserConfig(ParserConfig parserConfig) { + this.parserConfig = parserConfig; + } + + /** + * @return the vf + */ + public ValueFactory getValueFactory() { + return vf; + } + + /** + * @param vf + * the vf to set + */ + public void setValueFactory(ValueFactory vf) { + this.vf = vf; + } + + @Override + public Object call(final RDFDataset dataset) { + if (handler != null) { + try { + handler.startRDF(); + for (final Entry nextNamespace : dataset + .getNamespaces().entrySet()) { + handler.handleNamespace(nextNamespace.getKey(), + nextNamespace.getValue()); + } + } catch (final RDFHandlerException e) { + throw new RuntimeException("Could not handle start of RDF", e); + } + } + for (String graphName : dataset.keySet()) { + final List quads = dataset.getQuads(graphName); + if ("@default".equals(graphName)) { + graphName = null; + } + for (final RDFDataset.Quad quad : quads) { + if (quad.getObject().isLiteral()) { + triple(quad.getSubject().getValue(), quad.getPredicate() + .getValue(), quad.getObject().getValue(), quad + .getObject().getDatatype(), quad.getObject() + .getLanguage(), graphName); + } else { + triple(quad.getSubject().getValue(), quad.getPredicate() + .getValue(), quad.getObject().getValue(), graphName); + } + } + } + if (handler != null) { + try { + handler.endRDF(); + } catch (final RDFHandlerException e) { + throw new RuntimeException("Could not handle end of RDF", e); + } + } + + return getHandler(); + } } From 75acec19512c2bb70a99d2c8b31692c6142df0c1 Mon Sep 17 00:00:00 2001 From: Jeen Broekstra Date: Tue, 1 Jul 2014 11:03:07 +0200 Subject: [PATCH 059/440] set version back --- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 1f959479..d8ebade6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-patched + 0.5-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 71bfb1dc..019eeeb7 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-patched + 0.5-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 93f54149..49ce693c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-patched + 0.5-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 08faee66..147357b5 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-patched + 0.5-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index b8a28a15..d21e37e2 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-patched + 0.5-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 8b5960a5..6b062fe6 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5-patched + 0.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 1f03ccd5..94fd4da3 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-patched + 0.5-SNAPSHOT 4.0.0 jsonld-java-tools From 5e04f2f76c33f67c99722fb6ed9836a09899d572 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 09:34:39 +1000 Subject: [PATCH 060/440] Reformat SesameTripleCallback --- .../sesame/SesameTripleCallback.java | 385 +++++++++--------- 1 file changed, 189 insertions(+), 196 deletions(-) diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java index bc2b3db2..9e4d39cd 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java @@ -24,201 +24,194 @@ public class SesameTripleCallback implements JsonLdTripleCallback { - private ValueFactory vf; - - private RDFHandler handler; - - private ParserConfig parserConfig; - - private final ParseErrorListener parseErrorListener; - - public SesameTripleCallback() { - this(new StatementCollector(new LinkedHashModel())); - } - - public SesameTripleCallback(RDFHandler nextHandler) { - this(nextHandler, ValueFactoryImpl.getInstance()); - } - - public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf) { - this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); - } - - public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf, - ParserConfig parserConfig, ParseErrorListener parseErrorListener) { - this.handler = nextHandler; - this.vf = vf; - this.parserConfig = parserConfig; - this.parseErrorListener = parseErrorListener; - } - - private void triple(String s, String p, String o, String graph) { - if (s == null || p == null || o == null) { - // TODO: i don't know what to do here!!!! - return; - } - - Statement result; - // This method is always called with three Resources as subject - // predicate and - // object - if (graph == null) { - result = vf.createStatement(createResource(s), vf.createURI(p), - createResource(o)); - } else { - result = vf.createStatement(createResource(s), vf.createURI(p), - createResource(o), createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - private Resource createResource(String resource) { - // Blank node without any given identifier - if (resource.equals("_:")) { - return vf.createBNode(); - } else if (resource.startsWith("_:")) { - return vf.createBNode(resource.substring(2)); - } else { - return vf.createURI(resource); - } - } - - private void triple(String s, String p, String value, String datatype, - String language, String graph) { - - if (s == null || p == null || value == null) { - // TODO: i don't know what to do here!!!! - return; - } - - final Resource subject = createResource(s); - - final URI predicate = vf.createURI(p); - final URI datatypeURI = datatype == null ? null : vf - .createURI(datatype); - - Value object; - try { - object = RDFParserHelper.createLiteral(value, language, - datatypeURI, getParserConfig(), getParserErrorListener(), - getValueFactory()); - } catch (final RDFParseException e) { - throw new RuntimeException(e); - } - - Statement result; - if (graph == null) { - result = vf.createStatement(subject, predicate, object); - } else { - result = vf.createStatement(subject, predicate, object, - createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - public ParseErrorListener getParserErrorListener() { - return this.parseErrorListener; - } - - /** - * @return the handler - */ - public RDFHandler getHandler() { - return handler; - } - - /** - * @param handler - * the handler to set - */ - public void setHandler(RDFHandler handler) { - this.handler = handler; - } - - /** - * @return the parserConfig - */ - public ParserConfig getParserConfig() { - return parserConfig; - } - - /** - * @param parserConfig - * the parserConfig to set - */ - public void setParserConfig(ParserConfig parserConfig) { - this.parserConfig = parserConfig; - } - - /** - * @return the vf - */ - public ValueFactory getValueFactory() { - return vf; - } - - /** - * @param vf - * the vf to set - */ - public void setValueFactory(ValueFactory vf) { - this.vf = vf; - } - - @Override - public Object call(final RDFDataset dataset) { - if (handler != null) { - try { - handler.startRDF(); - for (final Entry nextNamespace : dataset - .getNamespaces().entrySet()) { - handler.handleNamespace(nextNamespace.getKey(), - nextNamespace.getValue()); - } - } catch (final RDFHandlerException e) { - throw new RuntimeException("Could not handle start of RDF", e); - } - } - for (String graphName : dataset.keySet()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject().getValue(), quad.getPredicate() - .getValue(), quad.getObject().getValue(), quad - .getObject().getDatatype(), quad.getObject() - .getLanguage(), graphName); - } else { - triple(quad.getSubject().getValue(), quad.getPredicate() - .getValue(), quad.getObject().getValue(), graphName); - } - } - } - if (handler != null) { - try { - handler.endRDF(); - } catch (final RDFHandlerException e) { - throw new RuntimeException("Could not handle end of RDF", e); - } - } - - return getHandler(); - } + private ValueFactory vf; + + private RDFHandler handler; + + private ParserConfig parserConfig; + + private final ParseErrorListener parseErrorListener; + + public SesameTripleCallback() { + this(new StatementCollector(new LinkedHashModel())); + } + + public SesameTripleCallback(RDFHandler nextHandler) { + this(nextHandler, ValueFactoryImpl.getInstance()); + } + + public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf) { + this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); + } + + public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf, ParserConfig parserConfig, + ParseErrorListener parseErrorListener) { + this.handler = nextHandler; + this.vf = vf; + this.parserConfig = parserConfig; + this.parseErrorListener = parseErrorListener; + } + + private void triple(String s, String p, String o, String graph) { + if (s == null || p == null || o == null) { + // TODO: i don't know what to do here!!!! + return; + } + + Statement result; + // This method is always called with three Resources as subject + // predicate and + // object + if (graph == null) { + result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o)); + } else { + result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o), + createResource(graph)); + } + + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } + } + } + + private Resource createResource(String resource) { + // Blank node without any given identifier + if (resource.equals("_:")) { + return vf.createBNode(); + } else if (resource.startsWith("_:")) { + return vf.createBNode(resource.substring(2)); + } else { + return vf.createURI(resource); + } + } + + private void triple(String s, String p, String value, String datatype, String language, + String graph) { + + if (s == null || p == null || value == null) { + // TODO: i don't know what to do here!!!! + return; + } + + final Resource subject = createResource(s); + + final URI predicate = vf.createURI(p); + final URI datatypeURI = datatype == null ? null : vf.createURI(datatype); + + Value object; + try { + object = RDFParserHelper.createLiteral(value, language, datatypeURI, getParserConfig(), + getParserErrorListener(), getValueFactory()); + } catch (final RDFParseException e) { + throw new RuntimeException(e); + } + + Statement result; + if (graph == null) { + result = vf.createStatement(subject, predicate, object); + } else { + result = vf.createStatement(subject, predicate, object, createResource(graph)); + } + + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } + } + } + + public ParseErrorListener getParserErrorListener() { + return this.parseErrorListener; + } + + /** + * @return the handler + */ + public RDFHandler getHandler() { + return handler; + } + + /** + * @param handler + * the handler to set + */ + public void setHandler(RDFHandler handler) { + this.handler = handler; + } + + /** + * @return the parserConfig + */ + public ParserConfig getParserConfig() { + return parserConfig; + } + + /** + * @param parserConfig + * the parserConfig to set + */ + public void setParserConfig(ParserConfig parserConfig) { + this.parserConfig = parserConfig; + } + + /** + * @return the vf + */ + public ValueFactory getValueFactory() { + return vf; + } + + /** + * @param vf + * the vf to set + */ + public void setValueFactory(ValueFactory vf) { + this.vf = vf; + } + + @Override + public Object call(final RDFDataset dataset) { + if (handler != null) { + try { + handler.startRDF(); + for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { + handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); + } + } catch (final RDFHandlerException e) { + throw new RuntimeException("Could not handle start of RDF", e); + } + } + for (String graphName : dataset.keySet()) { + final List quads = dataset.getQuads(graphName); + if ("@default".equals(graphName)) { + graphName = null; + } + for (final RDFDataset.Quad quad : quads) { + if (quad.getObject().isLiteral()) { + triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad + .getObject().getValue(), quad.getObject().getDatatype(), quad + .getObject().getLanguage(), graphName); + } else { + triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad + .getObject().getValue(), graphName); + } + } + } + if (handler != null) { + try { + handler.endRDF(); + } catch (final RDFHandlerException e) { + throw new RuntimeException("Could not handle end of RDF", e); + } + } + + return getHandler(); + } } From ab54626ae68d99bbd261769bdb14ab74e887f691 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 09:36:33 +1000 Subject: [PATCH 061/440] Reformat JarCacheResource --- .../java/com/github/jsonldjava/utils/JarCacheResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java index 3320cac5..9cfac88e 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -23,7 +23,8 @@ public JarCacheResource(URL classpath) throws IOException { @Override public long length() { - // TODO should be getContentLengthLong() but this is not available in Java 6. + // TODO should be getContentLengthLong() but this is not available in + // Java 6. return connection.getContentLength(); } From 28359d273d258a2cc0b3083215b0f1a8f8db101b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 09:40:16 +1000 Subject: [PATCH 062/440] add animal-sniffer-maven-plugin to verify java-6 APIs only used --- pom.xml | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 6b062fe6..b6cb06f0 100755 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - - + + oss-parent org.sonatype.oss @@ -11,8 +12,8 @@ 0.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM - pom - + pom + http://github.com/jsonld-java/jsonld-java/ @@ -34,17 +35,17 @@ Peter Ansell - + core integration tools - + UTF-8 UTF-8 - + 0.13 4.2.5 2.3.3 @@ -136,7 +137,7 @@ org.apache.jena jena-arq ${jena.version} - + org.apache.httpcomponents httpclient @@ -159,7 +160,7 @@ - + @@ -208,6 +209,26 @@ maven-surefire-plugin 2.17 + + org.codehaus.mojo + animal-sniffer-maven-plugin + 1.11 + + + test + + check + + + + + + org.codehaus.mojo.signature + java16 + 1.0 + + + From 32600735764c9e35be8bf2cce6adc6201f2eac8e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 09:49:48 +1000 Subject: [PATCH 063/440] Remove references to commons-logging and replace with slf4j --- core/pom.xml | 31 ++++++++++------- .../jsonldjava/utils/JarCacheResource.java | 6 ++-- .../jsonldjava/utils/JarCacheStorage.java | 8 ++--- integration/clerezza/pom.xml | 2 +- integration/rdf2go/pom.xml | 13 ++++---- integration/sesame/pom.xml | 2 +- pom.xml | 33 +++++++++++++++++-- tools/pom.xml | 11 +------ 8 files changed, 67 insertions(+), 39 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index d8ebade6..be090b66 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -1,5 +1,6 @@ - - + + jsonld-java-parent com.github.jsonld-java @@ -9,7 +10,7 @@ jsonld-java JSONLD Java :: Core Json-LD core implementation - jar + jar @@ -24,14 +25,6 @@ org.slf4j slf4j-api - - org.apache.httpcomponents - httpclient - - - org.apache.httpcomponents - httpclient-cache - junit junit @@ -39,7 +32,7 @@ org.slf4j - slf4j-jdk14 + slf4j-log4j12 test @@ -57,6 +50,20 @@ sesame-rio-nquads test + + org.apache.httpcomponents + httpclient-cache + + + org.apache.httpcomponents + httpclient + + + + org.slf4j + jcl-over-slf4j + diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java index 9cfac88e..216a942c 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -5,15 +5,15 @@ import java.net.URL; import java.net.URLConnection; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.http.client.cache.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JarCacheResource implements Resource { private static final long serialVersionUID = -7101296464577357444L; - private final Log log = LogFactory.getLog(getClass()); + private final Logger log = LoggerFactory.getLogger(getClass()); private final URLConnection connection; diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 9c629f12..181ed3df 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -14,8 +14,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HeaderConstants; @@ -29,6 +27,8 @@ import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.HTTP; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -38,7 +38,7 @@ public class JarCacheStorage implements HttpCacheStorage { private static final String JARCACHE_JSON = "jarcache.json"; - private final Log log = LogFactory.getLog(getClass()); + private final Logger log = LoggerFactory.getLogger(getClass()); private final CacheConfig cacheConfig = new CacheConfig(); private ClassLoader classLoader; @@ -171,7 +171,7 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach throws MalformedURLException, IOException { final URL classpath = new URL(baseURL, cacheNode.get("X-Classpath").asText()); log.debug("Cache hit for " + requestedUri); - log.trace(cacheNode); + log.trace("{}", cacheNode); final List
responseHeaders = new ArrayList
(); if (!cacheNode.has(HTTP.DATE_HEADER)) { diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 019eeeb7..7d110d36 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -49,7 +49,7 @@ org.slf4j - slf4j-jdk14 + slf4j-log4j12 test diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 147357b5..74a2b9be 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -1,4 +1,5 @@ - + jsonld-java-integration @@ -24,8 +25,8 @@ ${project.groupId} jsonld-java ${project.version} - jar - compile + jar + compile ${project.groupId} @@ -41,10 +42,10 @@ org.slf4j - slf4j-jdk14 + slf4j-log4j12 test - + org.semweb4j rdf2go.api @@ -71,7 +72,7 @@ ${rdf2go.version} test - + diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index d21e37e2..5bad4d6b 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -46,7 +46,7 @@ org.slf4j - slf4j-jdk14 + slf4j-log4j12 test diff --git a/pom.xml b/pom.xml index b6cb06f0..88ee1d22 100755 --- a/pom.xml +++ b/pom.xml @@ -110,6 +110,12 @@ junit ${junit.version} test + + + commons-logging + commons-logging + + org.slf4j @@ -118,9 +124,9 @@ org.slf4j - slf4j-jdk14 + jcl-over-slf4j ${slf4j.version} - test + runtime org.slf4j @@ -142,16 +148,34 @@ org.apache.httpcomponents httpclient ${httpclient.version} + + + commons-logging + commons-logging + + org.apache.httpcomponents httpclient-cache ${httpclient.version} + + + commons-logging + commons-logging + + org.apache.httpcomponents httpcore ${httpclient.version} + + + commons-logging + commons-logging + + org.mockito @@ -229,6 +253,11 @@ + + org.codehaus.mojo + appassembler-maven-plugin + 1.8 + diff --git a/tools/pom.xml b/tools/pom.xml index 94fd4da3..54d3377e 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -29,21 +29,12 @@ org.slf4j - slf4j-jdk14 + slf4j-log4j12 runtime - - - - org.codehaus.mojo - appassembler-maven-plugin - 1.8 - - - org.codehaus.mojo From b451c02330377811c84c33e0587d1fb2d3e423a2 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 09:52:52 +1000 Subject: [PATCH 064/440] Add log4j.properties files for testing and for running tools --- core/src/test/resources/log4j.properties | 5 +++++ integration/clerezza/src/test/resources/log4j.properties | 5 +++++ integration/rdf2go/src/test/resources/log4j.properties | 5 +++++ integration/sesame/src/test/resources/log4j.properties | 5 +++++ tools/src/main/resources/log4j.properties | 5 +++++ 5 files changed, 25 insertions(+) create mode 100644 core/src/test/resources/log4j.properties create mode 100644 integration/clerezza/src/test/resources/log4j.properties create mode 100644 integration/rdf2go/src/test/resources/log4j.properties create mode 100644 integration/sesame/src/test/resources/log4j.properties create mode 100644 tools/src/main/resources/log4j.properties diff --git a/core/src/test/resources/log4j.properties b/core/src/test/resources/log4j.properties new file mode 100644 index 00000000..136eba0c --- /dev/null +++ b/core/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, R + +log4j.appender.R=org.apache.log4j.ConsoleAppender +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/integration/clerezza/src/test/resources/log4j.properties b/integration/clerezza/src/test/resources/log4j.properties new file mode 100644 index 00000000..136eba0c --- /dev/null +++ b/integration/clerezza/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, R + +log4j.appender.R=org.apache.log4j.ConsoleAppender +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/integration/rdf2go/src/test/resources/log4j.properties b/integration/rdf2go/src/test/resources/log4j.properties new file mode 100644 index 00000000..136eba0c --- /dev/null +++ b/integration/rdf2go/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, R + +log4j.appender.R=org.apache.log4j.ConsoleAppender +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/integration/sesame/src/test/resources/log4j.properties b/integration/sesame/src/test/resources/log4j.properties new file mode 100644 index 00000000..136eba0c --- /dev/null +++ b/integration/sesame/src/test/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, R + +log4j.appender.R=org.apache.log4j.ConsoleAppender +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/tools/src/main/resources/log4j.properties b/tools/src/main/resources/log4j.properties new file mode 100644 index 00000000..136eba0c --- /dev/null +++ b/tools/src/main/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, R + +log4j.appender.R=org.apache.log4j.ConsoleAppender +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n From 17ed8061e9b13982ad3e2d7986a07db9cdb51689 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 09:59:42 +1000 Subject: [PATCH 065/440] add animal-sniffer plugin to modules that require it --- core/pom.xml | 8 ++++++++ integration/clerezza/pom.xml | 16 ++++++++++++---- integration/rdf2go/pom.xml | 15 ++++++++------- integration/sesame/pom.xml | 9 ++++++++- tools/pom.xml | 15 ++++++++++----- 5 files changed, 46 insertions(+), 17 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index be090b66..3eb4f7c7 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -65,5 +65,13 @@ jcl-over-slf4j + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 7d110d36..04e63051 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -1,5 +1,6 @@ - - + + jsonld-java-integration com.github.jsonld-java @@ -9,7 +10,7 @@ jsonld-java-clerezza JSONLD Java :: Clerezza Integration JSON-LD Java integration module for Clerezza - jar + jar @@ -53,6 +54,13 @@ test - + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 74a2b9be..ade74733 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -45,17 +45,12 @@ slf4j-log4j12 test - org.semweb4j rdf2go.api ${rdf2go.version} compile - - org.slf4j - slf4j-api - org.slf4j slf4j-log4j12 @@ -72,7 +67,13 @@ ${rdf2go.version} test - - + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 5bad4d6b..908547ec 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -50,6 +50,13 @@ test - + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + diff --git a/tools/pom.xml b/tools/pom.xml index 54d3377e..7d6ae02d 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -1,5 +1,6 @@ - - + + jsonld-java-parent com.github.jsonld-java @@ -33,7 +34,7 @@ runtime - + @@ -56,8 +57,12 @@ - + + org.codehaus.mojo + animal-sniffer-maven-plugin + + - + From ac20eb819673c75df1ef4eeceffc0adc090179c6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 10:06:16 +1000 Subject: [PATCH 066/440] Improve javadoc for JsonLdProcessor.toRDF --- .../java/com/github/jsonldjava/core/JsonLdProcessor.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index fedf2fe2..8b19a590 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -459,7 +459,10 @@ public static Object fromRDF(Object input, RDFParser parser) throws JsonLdError * format to use to output a string: 'application/nquads' for * N-Quads (default). [loadContext(url, callback(err, url, * result))] the context loader. - * @return A JSON-LD object. + * @return The result of executing + * {@link JsonLdTripleCallback#call(RDFDataset)} on the results, or + * if {@link JsonLdOptions#format} is not null, a result in that + * format if it is found, or otherwise the raw {@link RDFDataset}. * @throws JsonLdError * If there is an error converting the dataset to JSON-LD. */ From 5724aa75870cc966fe117e7b4a8a351aae42c396 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 2 Jul 2014 10:08:06 +1000 Subject: [PATCH 067/440] Update readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 22734c04..3474778f 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,10 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-07-02 +* Fix use of Java-7 API so we are still Java-6 compatible +* Ensure that Sesame RDFHandler endRDF and startRDF are called in SesameTripleCallback + ### 2014-06-30 * Release version 0.4.2 * Bump to Sesame-2.7.12 From 71aa4ea3c325b2337a745d612e794058342fcf0a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 14 Jul 2014 10:52:59 +1000 Subject: [PATCH 068/440] release notes and version bump for 0.5.0 --- README.md | 8 +++++--- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3474778f..22f579b4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.4.2/README.md) - JSONLD-JAVA =========== @@ -14,7 +12,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5-SNAPSHOT + 0.5.0 Code example @@ -236,6 +234,10 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-07-14 +* Release version 0.5.0 +* Fix Jackson parse exceptions being propagated through Sesame without wrapping as RDFParseExceptions + ### 2014-07-02 * Fix use of Java-7 API so we are still Java-6 compatible * Ensure that Sesame RDFHandler endRDF and startRDF are called in SesameTripleCallback diff --git a/core/pom.xml b/core/pom.xml index 3eb4f7c7..25d794d0 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.5.0 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 04e63051..c90f5006 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.5.0 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 49ce693c..52e95730 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.5.0 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index ade74733..754f655e 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.5.0 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 908547ec..f20346b5 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5-SNAPSHOT + 0.5.0 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 88ee1d22..d8f09628 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5-SNAPSHOT + 0.5.0 JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 7d6ae02d..4c1670a1 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5-SNAPSHOT + 0.5.0 4.0.0 jsonld-java-tools From 106bd707effed6242aeba403203368daed790395 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 14 Jul 2014 11:03:15 +1000 Subject: [PATCH 069/440] bump version numbers to next snapshot --- README.md | 4 +++- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 22f579b4..77d61a42 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.5.0/README.md) + JSONLD-JAVA =========== @@ -12,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT Code example diff --git a/core/pom.xml b/core/pom.xml index 25d794d0..3d3e445a 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index c90f5006..2758a3f9 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 52e95730..d9da0710 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 754f655e..29cb7967 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index f20346b5..c348d3a2 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index d8f09628..300189c4 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5.0 + 0.5.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 4c1670a1..3e7e177a 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.0 + 0.5.1-SNAPSHOT 4.0.0 jsonld-java-tools From 95f7ce662436c759076d55c66421fe63b91462f3 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 30 Jul 2014 10:22:09 +1000 Subject: [PATCH 070/440] bump to junit-4.12-beta-1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 300189c4..c3f039b1 100755 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 0.13 4.2.5 2.3.3 - 4.11 + 4.12-beta-1 5.0.0 2.7.12 1.7.7 From 088fba43742371c272f44927d11dfcdb77f430ac Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 11 Aug 2014 10:25:02 +1000 Subject: [PATCH 071/440] Add Sesame Empty prefix from TriG round-trip test --- .../sesame/SesameEmptyPrefixTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java new file mode 100644 index 00000000..770f33db --- /dev/null +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java @@ -0,0 +1,34 @@ +package com.github.jsonldjava.sesame; + +import static org.junit.Assert.assertTrue; + +import java.io.StringReader; +import java.io.StringWriter; + +import org.junit.Test; +import org.openrdf.model.Model; +import org.openrdf.model.util.ModelUtil; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.Rio; + +public class SesameEmptyPrefixTest { + + @Test + public void testEmptyPrefix() throws Exception { + String input = "@prefix : ." + + "@prefix dc: ." + + " :G { " + + " dc:isVersionOf . }"; + Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); + + StringWriter output = new StringWriter(); + Rio.write(parse, output, RDFFormat.JSONLD); + + System.out.println(output); + + Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + + assertTrue(ModelUtil.equals(parse, reparse)); + } + +} From f74b5eb8aeb57350f06c68045b9ed12975ac0371 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 11 Aug 2014 10:31:36 +1000 Subject: [PATCH 072/440] Add test using COMPACT mode to verify it also works --- .../sesame/SesameEmptyPrefixTest.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java index 770f33db..2e4b23a5 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java @@ -10,11 +10,14 @@ import org.openrdf.model.util.ModelUtil; import org.openrdf.rio.RDFFormat; import org.openrdf.rio.Rio; +import org.openrdf.rio.WriterConfig; +import org.openrdf.rio.helpers.JSONLDMode; +import org.openrdf.rio.helpers.JSONLDSettings; public class SesameEmptyPrefixTest { @Test - public void testEmptyPrefix() throws Exception { + public void testEmptyPrefixDefault() throws Exception { String input = "@prefix : ." + "@prefix dc: ." + " :G { " @@ -31,4 +34,24 @@ public void testEmptyPrefix() throws Exception { assertTrue(ModelUtil.equals(parse, reparse)); } + @Test + public void testEmptyPrefixCompact() throws Exception { + String input = "@prefix : ." + + "@prefix dc: ." + + " :G { " + + " dc:isVersionOf . }"; + Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); + + WriterConfig config = new WriterConfig(); + config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); + + StringWriter output = new StringWriter(); + Rio.write(parse, output, RDFFormat.JSONLD, config); + + System.out.println(output); + + Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + + assertTrue(ModelUtil.equals(parse, reparse)); + } } From c3478ddd1c80f310bb9df8e1b38a6eeef7c4540a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florent=20Andr=C3=A9?= Date: Sat, 25 Oct 2014 03:28:38 +0200 Subject: [PATCH 073/440] #87 enable osgi for artifacts. --- core/pom.xml | 23 ++++++++++++++++++++++- integration/clerezza/pom.xml | 7 ++++++- integration/rdf2go/pom.xml | 7 ++++++- integration/sesame/pom.xml | 7 ++++++- pom.xml | 5 +++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 3d3e445a..b777192a 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -10,7 +10,7 @@ jsonld-java JSONLD Java :: Core Json-LD core implementation - jar + bundle @@ -71,6 +71,27 @@ org.codehaus.mojo animal-sniffer-maven-plugin + + org.apache.felix + maven-bundle-plugin + true + + + + jackson-core|jackson-databind|slf4j-api;scope=compile + + com.fasterxml.jackson.annotation.*;resolution:=optional, + * + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 2758a3f9..88b90461 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -10,7 +10,7 @@ jsonld-java-clerezza JSONLD Java :: Clerezza Integration JSON-LD Java integration module for Clerezza - jar + bundle @@ -60,6 +60,11 @@ org.codehaus.mojo animal-sniffer-maven-plugin + + org.apache.felix + maven-bundle-plugin + true + diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 29cb7967..2209c2ac 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -10,7 +10,7 @@ jsonld-java-rdf2go JSONLD Java :: RDF2Go JSON-LD Java integration module for RDF2Go - jar + bundle @@ -74,6 +74,11 @@ org.codehaus.mojo animal-sniffer-maven-plugin + + org.apache.felix + maven-bundle-plugin + true + diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index c348d3a2..32dd3ca6 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -9,7 +9,7 @@ jsonld-java-sesame JSONLD Java :: Sesame Integration JSON-LD Java integration module for Sesame - jar + bundle @@ -56,6 +56,11 @@ org.codehaus.mojo animal-sniffer-maven-plugin + + org.apache.felix + maven-bundle-plugin + true + diff --git a/pom.xml b/pom.xml index c3f039b1..a4f890e1 100755 --- a/pom.xml +++ b/pom.xml @@ -258,6 +258,11 @@ appassembler-maven-plugin 1.8 + + org.apache.felix + maven-bundle-plugin + 2.0.1 + From d612fc802a9379ce236bf0b944c7b0d931d39cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florent=20Andr=C3=A9?= Date: Sat, 25 Oct 2014 11:51:15 +0200 Subject: [PATCH 074/440] use import package with version range for slf4j as jsonld-core's dependencies are already bundle. Note : if you use java security in your osgi stack, you need to add this 2 permissions to get the lib working : (java.lang.RuntimePermission accessDeclaredMembers) (java.lang.reflect.ReflectPermission suppressAccessChecks) --- core/pom.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index b777192a..11d09021 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -77,12 +77,10 @@ true - - jackson-core|jackson-databind|slf4j-api;scope=compile - com.fasterxml.jackson.annotation.*;resolution:=optional, - * - + org.slf4j.*; version="[1.0.0,2)", + * + From 97715d57dd7083603ac5624ac5ebe412b80b87ec Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 29 Oct 2014 08:58:55 +1100 Subject: [PATCH 075/440] Disable RDF2GO again, need to remove the Aduna repository from the RDF2GO pom files before reenabling it --- integration/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/pom.xml b/integration/pom.xml index d9da0710..28732bcd 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -14,6 +14,6 @@ sesame clerezza - rdf2go + From 0abd0ac0758301e15100d9f41fcabbe8ee4bd54c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 29 Oct 2014 09:03:41 +1100 Subject: [PATCH 076/440] Add OSGi note to readme, fixes #87 also bump sesame to 2.7.13 --- README.md | 4 ++++ pom.xml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77d61a42..7b9ad478 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,10 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-10-29 +* Add OSGi metadata to Jar files +* Bump to Sesame-2.7.13 + ### 2014-07-14 * Release version 0.5.0 * Fix Jackson parse exceptions being propagated through Sesame without wrapping as RDFParseExceptions diff --git a/pom.xml b/pom.xml index a4f890e1..74e46e6c 100755 --- a/pom.xml +++ b/pom.xml @@ -49,9 +49,9 @@ 0.13 4.2.5 2.3.3 - 4.12-beta-1 + 4.12-beta-2 5.0.0 - 2.7.12 + 2.7.13 1.7.7 From 61808a7e6e20f99e26b33ae637d106e645633dcf Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 13 Nov 2014 09:10:00 +1100 Subject: [PATCH 077/440] Sanity check only use native type for integer/double and regex --- .../java/com/github/jsonldjava/core/RDFDataset.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 062683a1..4c60f310 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -190,8 +190,9 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { } else if ("false".equals(value)) { rval.put("@value", Boolean.FALSE); } - } else if (Pattern.matches( - "^[+-]?[0-9]+((?:\\.?[0-9]+((?:E?[+-]?[0-9]+)|)|))$", value)) { + } else if ((XSD_INTEGER.equals(type) || XSD_DOUBLE.equals(type)) + && Pattern.matches( + "^[+-]?[0-9]+((?:\\.?[0-9]+((?:E?[+-]?[0-9]+)|)|))$", value)) { try { final Double d = Double.parseDouble(value); if (!Double.isNaN(d) && !Double.isInfinite(d)) { @@ -203,9 +204,8 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { } else if (XSD_DOUBLE.equals(type)) { rval.put("@value", d); } else { - // we don't know the type, so we should add - // it to the JSON-LD - rval.put("@type", type); + throw new RuntimeException( + "This should never happen as we checked the type was either integer or double"); } } } catch (final NumberFormatException e) { From bcdeddacf760e797ce3350c33be3c9b79c1f988a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 13 Nov 2014 09:25:00 +1100 Subject: [PATCH 078/440] GITHUB-126 : Use the regexes from the XML Schema Datatypes 1.1 spec --- .../java/com/github/jsonldjava/core/RDFDataset.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 4c60f310..f929a60e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -190,9 +190,14 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { } else if ("false".equals(value)) { rval.put("@value", Boolean.FALSE); } - } else if ((XSD_INTEGER.equals(type) || XSD_DOUBLE.equals(type)) - && Pattern.matches( - "^[+-]?[0-9]+((?:\\.?[0-9]+((?:E?[+-]?[0-9]+)|)|))$", value)) { + } else if ( + // http://www.w3.org/TR/xmlschema11-2/#integer + (XSD_INTEGER.equals(type) && Pattern.matches("^[\\-+]?[0-9]+$", value)) + // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep + || (XSD_DOUBLE.equals(type) && Pattern + .matches( + "^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)? |(\\+|-)?INF|NaN$", + value))) { try { final Double d = Double.parseDouble(value); if (!Double.isNaN(d) && !Double.isInfinite(d)) { From eeec5cdda02dbd0963d115c5384a37d593767bd6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 13 Nov 2014 09:34:14 +1100 Subject: [PATCH 079/440] Remove native type conversion for +-INF and NaN --- .../main/java/com/github/jsonldjava/core/RDFDataset.java | 2 +- .../test/java/com/github/jsonldjava/core/RegexTest.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index f929a60e..b090eba9 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -196,7 +196,7 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep || (XSD_DOUBLE.equals(type) && Pattern .matches( - "^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)? |(\\+|-)?INF|NaN$", + "^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?$", value))) { try { final Double d = Double.parseDouble(value); diff --git a/core/src/test/java/com/github/jsonldjava/core/RegexTest.java b/core/src/test/java/com/github/jsonldjava/core/RegexTest.java index 2eb5e07f..abd4b239 100644 --- a/core/src/test/java/com/github/jsonldjava/core/RegexTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/RegexTest.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.junit.Test; @@ -208,4 +209,11 @@ public void test_unescape() { assertTrue("http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef\uD800\uDC00\uDB40\uDDEF" .equals(r)); } + + @Test + public void testDoubleRegex() throws Exception { + assertTrue(Pattern.matches( + "^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?$", + "1.1E-1")); + } } From 91c916eec8ec12f3a9af81473181bad2641c39ac Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 13 Nov 2014 09:36:57 +1100 Subject: [PATCH 080/440] Also add type to boolean if the syntax check fails --- core/src/main/java/com/github/jsonldjava/core/RDFDataset.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index b090eba9..0f5013ca 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -189,6 +189,9 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { rval.put("@value", Boolean.TRUE); } else if ("false".equals(value)) { rval.put("@value", Boolean.FALSE); + } else { + // Else do not replace the value, and add the boolean type in + rval.put("@type", type); } } else if ( // http://www.w3.org/TR/xmlschema11-2/#integer From cec6e2077aa4cacb6fc7c4bfc1babf610f8eca31 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 13 Nov 2014 10:38:59 +1100 Subject: [PATCH 081/440] Precompile the patterns for efficiency and maintainability --- .../github/jsonldjava/core/RDFDataset.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 0f5013ca..ef8a07e4 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -34,8 +34,15 @@ * */ public class RDFDataset extends LinkedHashMap { + private static final long serialVersionUID = 2796344994239879165L; + + private static final Pattern PATTERN_INTEGER = Pattern.compile("^[\\-+]?[0-9]+$"); + private static final Pattern PATTERN_DOUBLE = Pattern + .compile("^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?$"); public static class Quad extends LinkedHashMap implements Comparable { + private static final long serialVersionUID = -7021918051975883082L; + public Quad(final String subject, final String predicate, final String object, final String graph) { this(subject, predicate, object.startsWith("_:") ? new BlankNode(object) : new IRI( @@ -104,6 +111,8 @@ public int compareTo(Quad o) { public static abstract class Node extends LinkedHashMap implements Comparable { + private static final long serialVersionUID = 1460990331795672793L; + public abstract boolean isLiteral(); public abstract boolean isIRI(); @@ -190,17 +199,15 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { } else if ("false".equals(value)) { rval.put("@value", Boolean.FALSE); } else { - // Else do not replace the value, and add the boolean type in + // Else do not replace the value, and add the + // boolean type in rval.put("@type", type); } } else if ( // http://www.w3.org/TR/xmlschema11-2/#integer - (XSD_INTEGER.equals(type) && Pattern.matches("^[\\-+]?[0-9]+$", value)) - // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep - || (XSD_DOUBLE.equals(type) && Pattern - .matches( - "^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?$", - value))) { + (XSD_INTEGER.equals(type) && PATTERN_INTEGER.matcher(value).matches()) + // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep + || (XSD_DOUBLE.equals(type) && PATTERN_DOUBLE.matcher(value).matches())) { try { final Double d = Double.parseDouble(value); if (!Double.isNaN(d) && !Double.isInfinite(d)) { @@ -235,6 +242,8 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { } public static class Literal extends Node { + private static final long serialVersionUID = 8124736271571220251L; + public Literal(String value, String datatype, String language) { super(); put("type", "literal"); @@ -290,6 +299,8 @@ public int compareTo(Node o) { } public static class IRI extends Node { + private static final long serialVersionUID = 1540232072155490782L; + public IRI(String iri) { super(); put("type", "IRI"); @@ -313,6 +324,8 @@ public boolean isBlankNode() { } public static class BlankNode extends Node { + private static final long serialVersionUID = -2842402820440697318L; + public BlankNode(String attribute) { super(); put("type", "blank node"); From 2623f32a5c83af717d6b2b683ab9fbef4523f33a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 14 Nov 2014 09:34:39 +1100 Subject: [PATCH 082/440] Add note to readme about fix --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7b9ad478..34b262fd 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,9 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-11-14 +* Fix identification of integer, boolean, and decimal in RDF-JSONLD with useNativeTypes + ### 2014-10-29 * Add OSGi metadata to Jar files * Bump to Sesame-2.7.13 From 8bbcb0403f2cf9b0b2e0a583744bcf50b4f3d761 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 14 Nov 2014 12:50:08 +1100 Subject: [PATCH 083/440] reenable rdf2go and bump to version 5.0.1 --- integration/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration/pom.xml b/integration/pom.xml index 28732bcd..d9da0710 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -14,6 +14,6 @@ sesame clerezza - + rdf2go diff --git a/pom.xml b/pom.xml index 74e46e6c..8bcfc0ae 100755 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 4.2.5 2.3.3 4.12-beta-2 - 5.0.0 + 5.0.1 2.7.13 1.7.7 From 7b6d62cee7d4efc8fd84a0678c20699aa275cafc Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 14 Nov 2014 12:57:43 +1100 Subject: [PATCH 084/440] Release 0.5.1 --- README.md | 5 ++--- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 34b262fd..1831a3de 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.5.0/README.md) - JSONLD-JAVA =========== @@ -14,7 +12,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 Code example @@ -238,6 +236,7 @@ CHANGELOG ### 2014-11-14 * Fix identification of integer, boolean, and decimal in RDF-JSONLD with useNativeTypes +* Release 0.5.1 ### 2014-10-29 * Add OSGi metadata to Jar files diff --git a/core/pom.xml b/core/pom.xml index 11d09021..b05b5573 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 88b90461..afb6437a 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index d9da0710..0b71ce22 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 2209c2ac..16c5a5d8 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 32dd3ca6..255d46f5 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 8bcfc0ae..2b47d484 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5.1-SNAPSHOT + 0.5.1 JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 3e7e177a..72d8bc11 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.1-SNAPSHOT + 0.5.1 4.0.0 jsonld-java-tools From c3788a3ddcd8cbcdb0fccb26b011f926e361b4be Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 14 Nov 2014 13:06:02 +1100 Subject: [PATCH 085/440] bump to next snapshot version --- README.md | 4 +++- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1831a3de..97428184 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.5.1/README.md) + JSONLD-JAVA =========== @@ -12,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT Code example diff --git a/core/pom.xml b/core/pom.xml index b05b5573..eeb04020 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index afb6437a..a89798bc 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 0b71ce22..7d82a576 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 16c5a5d8..342ad09c 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 255d46f5..f1acae5e 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index 2b47d484..e109c8dc 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5.1 + 0.5.2-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 72d8bc11..5d5e5360 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.1 + 0.5.2-SNAPSHOT 4.0.0 jsonld-java-tools From 2d824d42a9f15f10721f02451347e0af49a5583c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 30 Dec 2014 10:24:00 +1000 Subject: [PATCH 086/440] update plugins --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e109c8dc..5b50b806 100755 --- a/pom.xml +++ b/pom.xml @@ -236,7 +236,7 @@ org.codehaus.mojo animal-sniffer-maven-plugin - 1.11 + 1.13 test @@ -256,7 +256,7 @@ org.codehaus.mojo appassembler-maven-plugin - 1.8 + 1.9 org.apache.felix From 999ea764ec35a3d52d4de99ee67613eb733e6717 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 30 Dec 2014 10:31:38 +1000 Subject: [PATCH 087/440] update dependency versions --- pom.xml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 5b50b806..c2d59275 100755 --- a/pom.xml +++ b/pom.xml @@ -46,13 +46,13 @@ UTF-8 UTF-8 - 0.13 + 0.14 4.2.5 2.3.3 - 4.12-beta-2 + 4.12 5.0.1 - 2.7.13 - 1.7.7 + 2.7.14 + 1.7.9 2.2.1 @@ -134,16 +134,6 @@ ${slf4j.version} test - - org.apache.jena - jena-core - ${jena.version} - - - org.apache.jena - jena-arq - ${jena.version} - org.apache.httpcomponents httpclient @@ -180,7 +170,7 @@ org.mockito mockito-core - 1.9.5 + 1.10.17 From eefed40e91f82245d5eb2d79242d540cee0d28f4 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 30 Dec 2014 16:38:34 +1100 Subject: [PATCH 088/440] GH-131 : Add breaking test for numeric locale representation --- .../sesame/SesameLocaleNumericTest.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java new file mode 100644 index 00000000..3b062c85 --- /dev/null +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java @@ -0,0 +1,73 @@ +package com.github.jsonldjava.sesame; + +import static org.junit.Assert.assertTrue; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Locale; + +import org.junit.Test; +import org.openrdf.model.Model; +import org.openrdf.model.util.ModelUtil; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.Rio; + +/** + * Test for locale-insensitive numeric representations that match the XML Schema + * Datatype specification. + * + * @author Peter Ansell p_ansell@yahoo.com + * @see Github + * issue #133 + */ +public class SesameLocaleNumericTest { + + @Test + public void testLocaleUS() throws Exception { + Locale oldDefault = Locale.getDefault(); + + try { + Locale.setDefault(Locale.US); + String input = getTestString(); + Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); + + StringWriter output = new StringWriter(); + Rio.write(parse, output, RDFFormat.JSONLD); + + System.out.println(output); + + Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + + assertTrue(ModelUtil.equals(parse, reparse)); + } finally { + Locale.setDefault(oldDefault); + } + } + + @Test + public void testLocaleFrench() throws Exception { + Locale oldDefault = Locale.getDefault(); + + try { + Locale.setDefault(Locale.FRANCE); + String input = getTestString(); + Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); + + StringWriter output = new StringWriter(); + Rio.write(parse, output, RDFFormat.JSONLD); + + System.out.println(output); + + Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + + assertTrue(ModelUtil.equals(parse, reparse)); + } finally { + Locale.setDefault(oldDefault); + } + } + + private String getTestString() { + return "{" + "\"@id\": \"http://www.ex.com/product\"," + "\"http://schema.org/price\": {" + + "\"@value\": 100.00" + "}}}"; + } +} From 50eb6f8cf973f3f671afdf259905baab05964e69 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 31 Dec 2014 10:21:46 +1100 Subject: [PATCH 089/440] Always use Locale.US to format XSD Double representations. Fixes #131 --- README.md | 5 +++++ .../src/main/java/com/github/jsonldjava/core/RDFDataset.java | 3 +++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 97428184..bc2c88e6 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,11 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2014-12-31 +* Fix locale sensitive serialisation of XSD double/decimal typed literals to always be Locale.US +* Bump to Sesame-2.7.14 +* Bump to Clerezza-0.14 + ### 2014-11-14 * Fix identification of integer, boolean, and decimal in RDF-JSONLD with useNativeTypes * Release 0.5.1 diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index ef8a07e4..d728b2a3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -16,10 +16,12 @@ import static com.github.jsonldjava.core.JsonLdUtils.isValue; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -650,6 +652,7 @@ private Node objectToRDF(Object item) { || XSD_DOUBLE.equals(datatype)) { // canonical double representation final DecimalFormat df = new DecimalFormat("0.0###############E0"); + df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); return new Literal(df.format(value), datatype == null ? XSD_DOUBLE : (String) datatype, null); } else { From c29a4d1933aa2d59b067681c6e56c0d13565e4e1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 31 Dec 2014 10:25:44 +1100 Subject: [PATCH 090/440] Use DecimalFormatSymbols.getInstance that supports SPI Not sure if SPI is important for Locale.US, but better to be safe --- core/src/main/java/com/github/jsonldjava/core/RDFDataset.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index d728b2a3..7f3030bf 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -652,7 +652,7 @@ private Node objectToRDF(Object item) { || XSD_DOUBLE.equals(datatype)) { // canonical double representation final DecimalFormat df = new DecimalFormat("0.0###############E0"); - df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); + df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); return new Literal(df.format(value), datatype == null ? XSD_DOUBLE : (String) datatype, null); } else { From 76281a43f754dbf4a04f3c0f1d5f111f89b87cc5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 31 Dec 2014 12:39:35 +1100 Subject: [PATCH 091/440] Add a helper function for newMap to simplify reading of some code Also enables tuning in the future in a single location --- .../com/github/jsonldjava/core/Context.java | 27 ++++--- .../com/github/jsonldjava/core/JsonLdApi.java | 73 +++++++++---------- .../jsonldjava/core/JsonLdProcessor.java | 12 +-- .../github/jsonldjava/core/JsonLdUtils.java | 5 +- .../github/jsonldjava/core/RDFDataset.java | 16 +--- .../jsonldjava/core/RDFDatasetUtils.java | 26 ++++--- .../java/com/github/jsonldjava/utils/Obj.java | 25 +++++++ 7 files changed, 101 insertions(+), 83 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 3d8a8730..434b9ad7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -1,6 +1,7 @@ package com.github.jsonldjava.core; import static com.github.jsonldjava.core.JsonLdUtils.compareShortestLeast; +import static com.github.jsonldjava.utils.Obj.newMap; import java.util.ArrayList; import java.util.Collections; @@ -56,7 +57,7 @@ private void init(JsonLdOptions options) { if (options.getBase() != null) { this.put("@base", options.getBase()); } - this.termDefinitions = new LinkedHashMap(); + this.termDefinitions = newMap(); } /** @@ -288,9 +289,7 @@ private void createTermDefinition(Map context, String term, } if (value instanceof String) { - final Map tmp = new LinkedHashMap(); - tmp.put("@id", value); - value = tmp; + value = newMap("@id", value); } if (!(value instanceof Map)) { @@ -301,7 +300,7 @@ private void createTermDefinition(Map context, String term, final Map val = (Map) value; // 9) create a new term definition - final Map definition = new LinkedHashMap(); + final Map definition = newMap(); // 10) if (val.containsKey("@type")) { @@ -828,7 +827,7 @@ public Map getInverse() { } // 1) - inverse = new LinkedHashMap(); + inverse = newMap(); // 2) String defaultLanguage = (String) this.get("@language"); @@ -865,16 +864,16 @@ public int compare(String a, String b) { // 3.4 + 3.5) Map containerMap = (Map) inverse.get(iri); if (containerMap == null) { - containerMap = new LinkedHashMap(); + containerMap = newMap(); inverse.put(iri, containerMap); } // 3.6 + 3.7) Map typeLanguageMap = (Map) containerMap.get(container); if (typeLanguageMap == null) { - typeLanguageMap = new LinkedHashMap(); - typeLanguageMap.put("@language", new LinkedHashMap()); - typeLanguageMap.put("@type", new LinkedHashMap()); + typeLanguageMap = newMap(); + typeLanguageMap.put("@language", newMap()); + typeLanguageMap.put("@type", newMap()); containerMap.put(container, typeLanguageMap); } @@ -1024,7 +1023,7 @@ Map getTermDefinition(String key) { } public Object expandValue(String activeProperty, Object value) throws JsonLdError { - final Map rval = new LinkedHashMap(); + final Map rval = newMap(); final Map td = getTermDefinition(activeProperty); // 1) if (td != null && "@id".equals(td.get("@type"))) { @@ -1068,7 +1067,7 @@ public Object getContextValue(String activeProperty, String string) throws JsonL } public Map serialize() { - final Map ctx = new LinkedHashMap(); + final Map ctx = newMap(); if (this.get("@base") != null && !this.get("@base").equals(options.getBase())) { ctx.put("@base", this.get("@base")); } @@ -1088,7 +1087,7 @@ public Map serialize() { final String cid = this.compactIri((String) definition.get("@id")); ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); } else { - final Map defn = new LinkedHashMap(); + final Map defn = newMap(); final String cid = this.compactIri((String) definition.get("@id")); final Boolean reverseProperty = Boolean.TRUE.equals(definition.get("@reverse")); if (!(term.equals(cid) && !reverseProperty)) { @@ -1110,7 +1109,7 @@ public Map serialize() { } } - final Map rval = new LinkedHashMap(); + final Map rval = newMap(); if (!(ctx == null || ctx.isEmpty())) { rval.put("@context", ctx); } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index e5c72646..e2889f5f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -6,6 +6,7 @@ import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE; import static com.github.jsonldjava.core.JsonLdUtils.isKeyword; +import static com.github.jsonldjava.utils.Obj.newMap; import java.util.ArrayList; import java.util.Collection; @@ -191,7 +192,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, final boolean insideReverse = ("@reverse".equals(activeProperty)); // 6) - final Map result = new LinkedHashMap(); + final Map result = newMap(); // 7) final List keys = new ArrayList(elem.keySet()); Collections.sort(keys); @@ -352,7 +353,7 @@ else if ("@index".equals(expandedProperty) || "@value".equals(expandedProperty) // 7.6.4.2) if (!"@list".equals(container)) { // 7.6.4.2.1) - final Map wrapper = new LinkedHashMap(); + final Map wrapper = newMap(); // TODO: SPEC: no mention of vocab = true wrapper.put(activeCtx.compactIri("@list", true), compactedItem); compactedItem = wrapper; @@ -380,7 +381,7 @@ else if (result.containsKey(itemActiveProperty)) { if (result.containsKey(itemActiveProperty)) { mapObject = (Map) result.get(itemActiveProperty); } else { - mapObject = new LinkedHashMap(); + mapObject = newMap(); result.put(itemActiveProperty, mapObject); } @@ -533,7 +534,7 @@ else if (element instanceof Map) { activeCtx = activeCtx.parse(elem.get("@context")); } // 6) - Map result = new LinkedHashMap(); + Map result = newMap(); // 7) final List keys = new ArrayList(elem.keySet()); Collections.sort(keys); @@ -693,7 +694,7 @@ else if ("@reverse".equals(expandedProperty)) { .containsKey("@reverse") ? 1 : 0)) { // 7.4.11.3.1) if (!result.containsKey("@reverse")) { - result.put("@reverse", new LinkedHashMap()); + result.put("@reverse", newMap()); } // 7.4.11.3.2) final Map reverseMap = (Map) result @@ -762,7 +763,7 @@ else if ("@language".equals(activeCtx.getContainer(key)) && value instanceof Map + item.toString() + " to be a string"); } // 7.5.2.2.2) - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("@value", item); tmp.put("@language", language.toLowerCase()); ((List) expandedValue).add(tmp); @@ -815,7 +816,7 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { tmp = new ArrayList(); ((List) tmp).add(expandedValue); } - expandedValue = new LinkedHashMap(); + expandedValue = newMap(); ((Map) expandedValue).put("@list", tmp); } } @@ -823,7 +824,7 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { if (activeCtx.isReverseProperty(key)) { // 7.10.1) if (!result.containsKey("@reverse")) { - result.put("@reverse", new LinkedHashMap()); + result.put("@reverse", newMap()); } // 7.10.2) final Map reverseMap = (Map) result @@ -1014,7 +1015,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG // 2) if (!nodeMap.containsKey(activeGraph)) { - nodeMap.put(activeGraph, new LinkedHashMap()); + nodeMap.put(activeGraph, newMap()); } final Map graph = (Map) nodeMap.get(activeGraph); Map node = (Map) (activeSubject == null ? null : graph @@ -1060,8 +1061,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG // 5) else if (elem.containsKey("@list")) { // 5.1) - final Map result = new LinkedHashMap(); - result.put("@list", new ArrayList()); + final Map result = newMap("@list", new ArrayList()); // 5.2) // for (final Object item : (List) elem.get("@list")) { // generateNodeMap(item, nodeMap, activeGraph, activeSubject, @@ -1088,8 +1088,7 @@ else if (elem.containsKey("@list")) { } // 6.3) if (!graph.containsKey(id)) { - final Map tmp = new LinkedHashMap(); - tmp.put("@id", id); + final Map tmp = newMap("@id", id); graph.put(id, tmp); } // 6.4) TODO: SPEC this line is asked for by the spec, but it breaks @@ -1103,8 +1102,7 @@ else if (elem.containsKey("@list")) { } // 6.6) else if (activeProperty != null) { - final Map reference = new LinkedHashMap(); - reference.put("@id", id); + final Map reference = newMap("@id", id); // 6.6.2) if (list == null) { // 6.6.2.1+2) @@ -1139,8 +1137,7 @@ else if (activeProperty != null) { // 6.9) if (elem.containsKey("@reverse")) { // 6.9.1) - final Map referencedNode = new LinkedHashMap(); - referencedNode.put("@id", id); + final Map referencedNode = newMap("@id", id); // 6.9.2+6.9.4) final Map reverseMap = (Map) elem .remove("@reverse"); @@ -1294,9 +1291,10 @@ public List frame(Object input, List frame) throws JsonLdError { final List framed = new ArrayList(); // NOTE: frame validation is done by the function not allowing anything // other than list to me passed - frame(state, this.nodeMap, - (frame != null && frame.size() > 0 ? (Map) frame.get(0) - : new LinkedHashMap()), framed, null); + frame(state, + this.nodeMap, + (frame != null && frame.size() > 0 ? (Map) frame.get(0) : newMap()), + framed, null); return framed; } @@ -1336,7 +1334,7 @@ private void frame(FramingContext state, Map nodes, Map output = new LinkedHashMap(); + final Map output = newMap(); output.put("@id", id); // prepare embed meta info @@ -1414,7 +1412,7 @@ private void frame(FramingContext state, Map nodes, Map) item).containsKey("@list")) { // add empty list - final Map list = new LinkedHashMap(); + final Map list = newMap(); list.put("@list", new ArrayList()); addFrameOutput(state, output, prop, list); @@ -1423,7 +1421,7 @@ private void frame(FramingContext state, Map nodes, Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); final String itemid = (String) ((Map) listitem) .get("@id"); // TODO: nodes may need to be node_map, @@ -1442,7 +1440,7 @@ private void frame(FramingContext state, Map nodes, Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); final String itemid = (String) ((Map) item).get("@id"); // TODO: nodes may need to be node_map, which is // global @@ -1471,7 +1469,7 @@ else if (JsonLdUtils.isNodeReference(item)) { Map propertyFrame = pf.size() > 0 ? (Map) pf .get(0) : null; if (propertyFrame == null) { - propertyFrame = new LinkedHashMap(); + propertyFrame = newMap(); } final boolean omitDefaultOn = getFrameFlag(propertyFrame, "@omitDefault", state.omitDefault); @@ -1485,8 +1483,7 @@ else if (JsonLdUtils.isNodeReference(item)) { tmp.add(def); def = tmp; } - final Map tmp1 = new LinkedHashMap(); - tmp1.put("@preserve", def); + final Map tmp1 = newMap("@preserve", def); final List tmp2 = new ArrayList(); tmp2.add(tmp1); output.put(prop, tmp2); @@ -1531,8 +1528,7 @@ private static void removeEmbed(FramingContext state, String id) { final String property = embed.property; // create reference to replace embed - final Map node = new LinkedHashMap(); - node.put("@id", id); + final Map node = newMap("@id", id); // remove existing embed if (JsonLdUtils.isNode(parent)) { @@ -1557,7 +1553,7 @@ private static void removeDependents(Map embeds, String id) { // get embed keys as a separate array to enable deleting keys in map for (final String id_dep : embeds.keySet()) { final EmbedNode e = embeds.get(id_dep); - final Object p = e.parent != null ? e.parent : new LinkedHashMap(); + final Object p = e.parent != null ? e.parent : newMap(); if (!(p instanceof Map)) { continue; } @@ -1571,7 +1567,7 @@ private static void removeDependents(Map embeds, String id) { private Map filterNodes(FramingContext state, Map nodes, Map frame) throws JsonLdError { - final Map rval = new LinkedHashMap(); + final Map rval = newMap(); for (final String id : nodes.keySet()) { final Map element = (Map) nodes.get(id); if (element != null && filterNode(state, element, frame)) { @@ -1674,11 +1670,10 @@ private void embedValues(FramingContext state, Map element, Stri state.embeds.put(sid, embed); // recurse into subject - o = new LinkedHashMap(); + o = newMap(); Map s = (Map) this.nodeMap.get(sid); if (s == null) { - s = new LinkedHashMap(); - s.put("@id", sid); + s = newMap("@id", sid); } for (final String prop : s.keySet()) { // copy keywords @@ -1971,8 +1966,8 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { public RDFDataset toRDF() throws JsonLdError { // TODO: make the default generateNodeMap call (i.e. without a // graphName) create and return the nodeMap - final Map nodeMap = new LinkedHashMap(); - nodeMap.put("@default", new LinkedHashMap()); + final Map nodeMap = newMap(); + nodeMap.put("@default", newMap()); generateNodeMap(this.value, nodeMap); final RDFDataset dataset = new RDFDataset(this); @@ -2011,7 +2006,7 @@ public RDFDataset toRDF() throws JsonLdError { public Object normalize(Map dataset) throws JsonLdError { // create quads and map bnodes to their associated quads final List quads = new ArrayList(); - final Map bnodes = new LinkedHashMap(); + final Map bnodes = newMap(); for (String graphName : dataset.keySet()) { final List> triples = (List>) dataset .get(graphName); @@ -2021,12 +2016,12 @@ public Object normalize(Map dataset) throws JsonLdError { for (final Map quad : triples) { if (graphName != null) { if (graphName.indexOf("_:") == 0) { - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("type", "blank node"); tmp.put("value", graphName); quad.put("name", tmp); } else { - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("type", "IRI"); tmp.put("value", graphName); quad.put("name", tmp); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 8b19a590..99250795 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -1,5 +1,7 @@ package com.github.jsonldjava.core; +import static com.github.jsonldjava.utils.Obj.newMap; + import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; @@ -61,9 +63,9 @@ public static Map compact(Object input, Object context, JsonLdOp // TODO: SPEC: the result result is a NON EMPTY array, if (compacted instanceof List) { if (((List) compacted).isEmpty()) { - compacted = new LinkedHashMap(); + compacted = newMap(); } else { - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); // TODO: SPEC: doesn't specify to use vocab = true here tmp.put(activeCtx.compactIri("@graph", true), compacted); compacted = tmp; @@ -181,8 +183,8 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // http://json-ld.org/spec/latest/json-ld-api/#flattening-algorithm // 1) - final Map nodeMap = new LinkedHashMap(); - nodeMap.put("@default", new LinkedHashMap()); + final Map nodeMap = newMap(); + nodeMap.put("@default", newMap()); // 2) new JsonLdApi(opts).generateNodeMap(expanded, nodeMap); // 3) @@ -193,7 +195,7 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // 4.1+4.2) Map entry; if (!defaultGraph.containsKey(graphName)) { - entry = new LinkedHashMap(); + entry = newMap(); entry.put("@id", graphName); defaultGraph.put(graphName, entry); } else { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 8aba7ecf..e148b45b 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -1,10 +1,11 @@ package com.github.jsonldjava.core; +import static com.github.jsonldjava.utils.Obj.newMap; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -358,7 +359,7 @@ static List expandLanguageMap(Map languageMap) throws Js if (!isString(item)) { throw new JsonLdError(JsonLdError.Error.SYNTAX_ERROR); } - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("@value", item); tmp.put("@language", key.toLowerCase()); rval.add(tmp); diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 7f3030bf..0b6b86ca 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -14,6 +14,7 @@ import static com.github.jsonldjava.core.JsonLdUtils.isObject; import static com.github.jsonldjava.core.JsonLdUtils.isString; import static com.github.jsonldjava.core.JsonLdUtils.isValue; +import static com.github.jsonldjava.utils.Obj.newMap; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -168,20 +169,11 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { // JSON object consisting // of a single member @id whose value is set to value. if (isIRI() || isBlankNode()) { - return new LinkedHashMap() { - { - put("@id", getValue()); - } - }; + return newMap("@id", getValue()); } - ; // convert literal object to JSON-LD - final Map rval = new LinkedHashMap() { - { - put("@value", getValue()); - } - }; + final Map rval = newMap("@value", getValue()); // add language if (getLanguage() != null) { @@ -402,7 +394,7 @@ public Map getNamespaces() { * @return The context map */ public Map getContext() { - final Map rval = new LinkedHashMap(); + final Map rval = newMap(); rval.putAll(context); // replace "" with "@vocab" if (rval.containsKey("")) { diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 6a7187e6..3d592ea0 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -14,12 +14,15 @@ import static com.github.jsonldjava.core.JsonLdUtils.isObject; import static com.github.jsonldjava.core.JsonLdUtils.isValue; import static com.github.jsonldjava.core.Regex.HEX; +import static com.github.jsonldjava.utils.Obj.newMap; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -54,7 +57,7 @@ static List graphToRDF(Map graph, UniqueNamer namer) { for (final Object item : (List) items) { // RDF subjects - final Map subject = new LinkedHashMap(); + final Map subject = newMap(); if (id.indexOf("_:") == 0) { subject.put("type", "blank node"); subject.put("value", namer.getName(id)); @@ -64,7 +67,7 @@ static List graphToRDF(Map graph, UniqueNamer namer) { } // RDF predicates - final Map predicate = new LinkedHashMap(); + final Map predicate = newMap(); predicate.put("type", "IRI"); predicate.put("value", property); @@ -76,7 +79,7 @@ static List graphToRDF(Map graph, UniqueNamer namer) { // convert value or node object to triple else { final Object object = objectToRDF(item, namer); - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("subject", subject); tmp.put("predicate", predicate); tmp.put("object", object); @@ -106,23 +109,23 @@ static List graphToRDF(Map graph, UniqueNamer namer) { */ private static void listToRDF(List list, UniqueNamer namer, Map subject, Map predicate, List triples) { - final Map first = new LinkedHashMap(); + final Map first = newMap(); first.put("type", "IRI"); first.put("value", RDF_FIRST); - final Map rest = new LinkedHashMap(); + final Map rest = newMap(); rest.put("type", "IRI"); rest.put("value", RDF_REST); - final Map nil = new LinkedHashMap(); + final Map nil = newMap(); nil.put("type", "IRI"); nil.put("value", RDF_NIL); for (final Object item : list) { - final Map blankNode = new LinkedHashMap(); + final Map blankNode = newMap(); blankNode.put("type", "blank node"); blankNode.put("value", namer.getName()); { - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("subject", subject); tmp.put("predicate", predicate); tmp.put("object", blankNode); @@ -134,7 +137,7 @@ private static void listToRDF(List list, UniqueNamer namer, final Object object = objectToRDF(item, namer); { - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("subject", subject); tmp.put("predicate", predicate); tmp.put("object", object); @@ -143,7 +146,7 @@ private static void listToRDF(List list, UniqueNamer namer, predicate = rest; } - final Map tmp = new LinkedHashMap(); + final Map tmp = newMap(); tmp.put("subject", subject); tmp.put("predicate", predicate); tmp.put("object", nil); @@ -162,7 +165,7 @@ private static void listToRDF(List list, UniqueNamer namer, * @return the RDF literal or RDF resource. */ private static Object objectToRDF(Object item, UniqueNamer namer) { - final Map object = new LinkedHashMap(); + final Map object = newMap(); // convert value object to RDF if (isValue(item)) { @@ -179,6 +182,7 @@ private static Object objectToRDF(Object item, UniqueNamer namer) { } else if (value instanceof Double || value instanceof Float) { // canonical double representation final DecimalFormat df = new DecimalFormat("0.0###############E0"); + df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); object.put("value", df.format(value)); object.put("datatype", datatype == null ? XSD_DOUBLE : datatype); } else { diff --git a/core/src/main/java/com/github/jsonldjava/utils/Obj.java b/core/src/main/java/com/github/jsonldjava/utils/Obj.java index 9e96d2df..87656583 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/Obj.java +++ b/core/src/main/java/com/github/jsonldjava/utils/Obj.java @@ -1,9 +1,34 @@ package com.github.jsonldjava.utils; +import java.util.LinkedHashMap; import java.util.Map; public class Obj { + /** + * Helper function for creating maps and tuning them as necessary. + * + * @return A new {@link Map} instance. + */ + public static Map newMap() { + return new LinkedHashMap(2, 0.75f); + } + + /** + * Helper function for creating maps and tuning them as necessary. + * + * @param key + * A key to add to the map on creation. + * @param value + * A value to attach to the key in the new map. + * @return A new {@link Map} instance. + */ + public static Map newMap(String key, Object value) { + Map result = newMap(); + result.put(key, value); + return result; + } + /** * Used to make getting values from maps embedded in maps embedded in maps * easier TODO: roll out the loops for efficiency From 6fa5f052d64ec789a5676f8850ddae314628fb33 Mon Sep 17 00:00:00 2001 From: Stephen Kahmann Date: Wed, 11 Feb 2015 23:39:50 -0500 Subject: [PATCH 092/440] Replaced httpclient and httpcore with osgi bundles --- core/pom.xml | 18 +++++++++--------- pom.xml | 49 ++++++++++++++++--------------------------------- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index eeb04020..35a43374 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -50,15 +50,15 @@ sesame-rio-nquads test - - org.apache.httpcomponents - httpclient-cache - - - org.apache.httpcomponents - httpclient - - org.slf4j diff --git a/pom.xml b/pom.xml index c2d59275..1d42724e 100755 --- a/pom.xml +++ b/pom.xml @@ -134,39 +134,22 @@ ${slf4j.version} test - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpclient-cache - ${httpclient.version} - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpcore - ${httpclient.version} - - - commons-logging - commons-logging - - - + + org.apache.httpcomponents + httpclient-osgi + 4.2.5 + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpcore-osgi + 4.2.5 + org.mockito mockito-core From b0c3fe92c7c4b31ebbe7258a80bdbd02c3ffced6 Mon Sep 17 00:00:00 2001 From: Stephen Kahmann Date: Wed, 11 Feb 2015 23:43:32 -0500 Subject: [PATCH 093/440] Used http version property --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1d42724e..aaf630f6 100755 --- a/pom.xml +++ b/pom.xml @@ -137,7 +137,7 @@ org.apache.httpcomponents httpclient-osgi - 4.2.5 + ${httpclient.version} commons-logging @@ -148,7 +148,7 @@ org.apache.httpcomponents httpcore-osgi - 4.2.5 + ${httpclient.version} org.mockito From 5d6036b8a252aa170c8693a164b1f3f8082bd057 Mon Sep 17 00:00:00 2001 From: Stephen Kahmann Date: Wed, 11 Feb 2015 23:49:43 -0500 Subject: [PATCH 094/440] Updated maven-bundle-plugin version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aaf630f6..bc95b2af 100755 --- a/pom.xml +++ b/pom.xml @@ -234,7 +234,7 @@ org.apache.felix maven-bundle-plugin - 2.0.1 + 2.5.3 From 8197e04260d3af3e47cd48478046f7ecb4abe657 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 12:38:49 +1100 Subject: [PATCH 095/440] start the redesign of the playground options parser --- tools/pom.xml | 5 + .../github/jsonldjava/tools/Playground.java | 413 +++++++++++------- 2 files changed, 269 insertions(+), 149 deletions(-) diff --git a/tools/pom.xml b/tools/pom.xml index 5d5e5360..a7d73e21 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -33,6 +33,11 @@ slf4j-log4j12 runtime + + net.sf.jopt-simple + jopt-simple + 4.6 + diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index c9055765..1695037a 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -4,10 +4,24 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.regex.Pattern; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.RDFParserRegistry; + +import joptsimple.OptionException; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; +import joptsimple.ValueConversionException; +import joptsimple.ValueConverter; + import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdOptions; import com.github.jsonldjava.core.JsonLdProcessor; @@ -15,180 +29,281 @@ public class Playground { - static boolean validOption(String opt) { - return "--ignorekeys".equals(opt) || "--expand".equals(opt) || "--compact".equals(opt) + private static boolean validOption(String opt) { + return "--expand".equals(opt) || "--compact".equals(opt) || "--frame".equals(opt) || "--normalize".equals(opt) || "--simplify".equals(opt) - || "--debug".equals(opt) || "--base".equals(opt) || "--flatten".equals(opt) - || "--fromRDF".equals(opt) || "--toRDF".equals(opt) || "--outputForm".equals(opt); + || "--flatten".equals(opt) || "--fromRDF".equals(opt) || "--toRDF".equals(opt); } - static boolean hasContext(String opt) { + private static boolean hasContext(String opt) { return "--compact".equals(opt) || "--frame".equals(opt) || "--flatten".equals(opt); } - public static void main(String[] args) { - boolean debug = false; - try { - if (args.length < 2 || !args[0].startsWith("--")) { - usage(); - } else { - - final JsonLdOptions opts = new JsonLdOptions(""); - Object inobj = null; - Object ctxobj = null; - String opt = null; - for (int i = 0; i < args.length;) { - if ("--debug".equals(args[i])) { - i++; - debug = true; - } else if ("--base".equals(args[i])) { - i++; - opts.setBase(args[i++]); - } else if ("--outputForm".equals(args[i])) { - i++; - opts.outputForm = args[i++]; - } else if (validOption(args[i])) { - if (opt != null) { - System.out - .println("Error: can only do one operation on the input at a time"); - usage(); - return; - } - opt = args[i]; - i++; - if (args.length <= i) { - System.out.println("Error: missing file names after argument " - + args[i - 1]); - usage(); - return; - } - File in = new File(args[i++]); - if (!in.exists()) { - System.out.println("Error: file \"" + args[i - 1] + "\" doesn't exist"); - usage(); - return; - } - // if base is currently null, set it - if (opts.getBase() == null || opts.getBase().equals("")) { - opts.setBase(in.toURI().toASCIIString()); - } - if ("--fromRDF".equals(opt)) { - final BufferedReader buf = new BufferedReader(new InputStreamReader( - new FileInputStream(in), "UTF-8")); - inobj = ""; - String line; - while ((line = buf.readLine()) != null) { - line = line.trim(); - if (line.length() == 0 || line.charAt(0) == '#') { - continue; + private static Map getOutputFormats() { + Map outputFormats = new HashMap(); + + for(RDFFormat format : RDFParserRegistry.getInstance().getKeys()) { + outputFormats.put(format.getName().replaceAll("-", "").replaceAll("/", "").toLowerCase(), format); + } + + return outputFormats; + } + + public static void main(String[] args) throws Exception { + + final Map formats = getOutputFormats(); + final Set outputForms = new LinkedHashSet(Arrays.asList("compacted", "expanded", "flattened")); + + final OptionParser parser = new OptionParser(); + + final OptionSpec help = parser.accepts("help").forHelp(); + + final OptionSpec base = parser.accepts("base") + .withRequiredArg() + .ofType(String.class) + .describedAs("base URI"); + + final OptionSpec inputFile = + parser.accepts("inputFile").withRequiredArg().ofType(File.class) + .describedAs("The input file"); + + final OptionSpec context = + parser.accepts("context").withRequiredArg().ofType(File.class) + .describedAs("The context"); + + final OptionSpec outputFormat = + parser.accepts("format") + .withOptionalArg() + .ofType(String.class) + .defaultsTo(RDFFormat.NQUADS.getName()) + .withValuesConvertedBy(new ValueConverter() { + @Override + public RDFFormat convert(String arg0) { + // Normalise the name to provide alternatives + String formatName = arg0.replaceAll("-", "").replaceAll("/", "").toLowerCase(); + if(formats.containsKey(formatName)) { + return formats.get(formatName); } - inobj = ((String) inobj) + line + "\n"; + throw new ValueConversionException("Format was not known: " + arg0); } - } else { - inobj = JsonUtils.fromInputStream(new FileInputStream(in)); - } - if ("--fromRDF".equals(opt) || "--toRDF".equals(opt) - || "--normalize".equals(opt)) { - // get format option - if (args.length > i && !args[i].startsWith("--")) { - opts.format = args[i++]; - // remove any quotes - if (Pattern.matches("^['\"`].*['\"`]$", opts.format)) { - opts.format = opts.format - .substring(1, opts.format.length() - 1); - } + @Override + public String valuePattern() { + return null; } - // default to nquads - if (opts.format == null || "null".equals(opts.format)) { - opts.format = "application/nquads"; - } - } else if (hasContext(opt)) { - if (args.length > i) { - - in = new File(args[i++]); - if (!in.exists()) { - if (args[i - 1].startsWith("--")) { - // the frame is optional, so if it turns - // out we have another option after the - // --frame options - // we have to make sure we process it - i--; - } else { - System.out.println("Error: file \"" + args[i - 1] - + "\" doesn't exist"); - usage(); - return; - } - } - ctxobj = JsonUtils.fromInputStream(new FileInputStream(in)); + + @Override + public Class valueType() { + return RDFFormat.class; } + }) + .describedAs( + "The output file format to use. Defaults to nquads."); + + final OptionSpec processingOption = parser.accepts("process") + .withRequiredArg() + .ofType(String.class) + .required() + .withValuesConvertedBy(new ValueConverter() { + @Override + public String convert(String value) { + if(validOption(value.toLowerCase())) { + return value.toLowerCase(); } - } else { - System.out.println("Invalid option: " + args[i]); - usage(); - return; + throw new ValueConversionException("Processing option was not known: " + value); } - } - if (opt == null) { - System.out.println("Error: missing processing option"); - usage(); - return; - } + @Override + public Class valueType() { + return String.class; + } - Object outobj = null; - if ("--expand".equals(opt)) { - outobj = JsonLdProcessor.expand(inobj, opts); - } else if ("--compact".equals(opt)) { - if (ctxobj == null) { - System.out.println("Error: The compaction context must not be null."); - usage(); - return; + @Override + public String valuePattern() { + return null; } - outobj = JsonLdProcessor.compact(inobj, ctxobj, opts); - } else if ("--normalize".equals(opt)) { - outobj = JsonLdProcessor.normalize(inobj, opts); - } else if ("--frame".equals(opt)) { - if (ctxobj != null && !(ctxobj instanceof Map)) { - System.out - .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); - usage(); - return; + }) + + ; + + final OptionSpec outputForm = parser.accepts("outputForm") + .withOptionalArg() + .ofType(String.class) + .defaultsTo("expanded") + .withValuesConvertedBy(new ValueConverter() { + @Override + public String convert(String value) { + if(outputForms.contains(value.toLowerCase())) { + return value.toLowerCase(); + } + throw new ValueConversionException("Output form was not known: " + value); } - outobj = JsonLdProcessor.frame(inobj, ctxobj, opts); - } else if ("--flatten".equals(opt)) { - outobj = JsonLdProcessor.flatten(inobj, ctxobj, opts); - } else if ("--toRDF".equals(opt)) { - opts.useNamespaces = true; - outobj = JsonLdProcessor.toRDF(inobj, opts); - } else if ("--fromRDF".equals(opt)) { - outobj = JsonLdProcessor.fromRDF(inobj, opts); - } else { - System.out.println("Error: invalid option \"" + opt + "\""); - usage(); - return; - } - if ("--toRDF".equals(opt) || "--normalize".equals(opt)) { - System.out.println((String) outobj); - } else { - System.out.println(JsonUtils.toPrettyString(outobj)); + @Override + public String valuePattern() { + return null; + } + + @Override + public Class valueType() { + return String.class; + } + }) + .describedAs("outputForm"); + + OptionSet options = null; + + try + { + options = parser.parse(args); + } + catch(final OptionException e) + { + System.out.println(e.getMessage()); + parser.printHelpOn(System.out); + throw e; + } + + if(options.has(help)) + { + parser.printHelpOn(System.out); + return; + } + + final JsonLdOptions opts = new JsonLdOptions(""); + Object inobj = null; + Object ctxobj = null; + String opt = null; + + if(options.has(base)) { + opts.setBase(options.valueOf(base)); + } + + if(options.has(outputForm)) { + opts.outputForm = options.valueOf(outputForm); + } + + if(options.has(outputFormat)) { + opts.format = options.valueOf(outputFormat).getDefaultMIMEType(); + } + + + opt = args[i]; + i++; + if (args.length <= i) { + System.out.println("Error: missing file names after argument " + + args[i - 1]); + usage(); + return; + } + File in = new File(args[i++]); + if (!in.exists()) { + System.out.println("Error: file \"" + args[i - 1] + "\" doesn't exist"); + usage(); + return; + } + // if base is currently null, set it + if (opts.getBase() == null || opts.getBase().equals("")) { + opts.setBase(in.toURI().toASCIIString()); + } + if ("--fromRDF".equals(opt)) { + final BufferedReader buf = new BufferedReader(new InputStreamReader( + new FileInputStream(in), "UTF-8")); + inobj = ""; + String line; + while ((line = buf.readLine()) != null) { + line = line.trim(); + if (line.length() == 0 || line.charAt(0) == '#') { + continue; + } + inobj = ((String) inobj) + line + "\n"; } + + } else { + inobj = JsonUtils.fromInputStream(new FileInputStream(in)); } - } catch (final Exception e) { - System.out.println("ERROR: " + e.getMessage()); - if (e instanceof JsonLdError) { - for (final Entry detail : ((JsonLdError) e).getDetails().entrySet()) { - System.out.println(detail.getKey() + ": " + detail.getValue()); + if ("--fromRDF".equals(opt) || "--toRDF".equals(opt) + || "--normalize".equals(opt)) { + // get format option + if (args.length > i && !args[i].startsWith("--")) { + opts.format = args[i++]; + // remove any quotes + if (Pattern.matches("^['\"`].*['\"`]$", opts.format)) { + opts.format = opts.format + .substring(1, opts.format.length() - 1); + } + } + // default to nquads + if (opts.format == null || "null".equals(opts.format)) { + opts.format = "application/nquads"; + } + } else if (hasContext(opt)) { + if (args.length > i) { + + in = new File(args[i++]); + if (!in.exists()) { + if (args[i - 1].startsWith("--")) { + // the frame is optional, so if it turns + // out we have another option after the + // --frame options + // we have to make sure we process it + i--; + } else { + System.out.println("Error: file \"" + args[i - 1] + + "\" doesn't exist"); + usage(); + return; + } + } + ctxobj = JsonUtils.fromInputStream(new FileInputStream(in)); } } - if (debug) { - e.printStackTrace(); + } + + if (opt == null) { + System.out.println("Error: missing processing option"); + usage(); + return; + } + + Object outobj = null; + if ("--expand".equals(opt)) { + outobj = JsonLdProcessor.expand(inobj, opts); + } else if ("--compact".equals(opt)) { + if (ctxobj == null) { + System.out.println("Error: The compaction context must not be null."); + usage(); + return; } + outobj = JsonLdProcessor.compact(inobj, ctxobj, opts); + } else if ("--normalize".equals(opt)) { + outobj = JsonLdProcessor.normalize(inobj, opts); + } else if ("--frame".equals(opt)) { + if (ctxobj != null && !(ctxobj instanceof Map)) { + System.out + .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); + usage(); + return; + } + outobj = JsonLdProcessor.frame(inobj, ctxobj, opts); + } else if ("--flatten".equals(opt)) { + outobj = JsonLdProcessor.flatten(inobj, ctxobj, opts); + } else if ("--toRDF".equals(opt)) { + opts.useNamespaces = true; + outobj = JsonLdProcessor.toRDF(inobj, opts); + } else if ("--fromRDF".equals(opt)) { + outobj = JsonLdProcessor.fromRDF(inobj, opts); + } else { + System.out.println("Error: invalid option \"" + opt + "\""); usage(); return; } + + if ("--toRDF".equals(opt) || "--normalize".equals(opt)) { + System.out.println((String) outobj); + } else { + System.out.println(JsonUtils.toPrettyString(outobj)); + } } private static void usage() { @@ -203,7 +318,7 @@ private static void usage() { System.out .println("\t\t--compact : compact the input JSON-LD applying the optional context file"); System.out - .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquad)"); + .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquads)"); System.out .println("\t\t--frame : frame the input JSON-LD with the optional frame file"); System.out From 67bb931bd8905485f355a349b7cbc91074a53779 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 14:25:09 +1100 Subject: [PATCH 096/440] further work on getting the jsonldplayground working smoothly --- jsonldplayground | 4 +- tools/pom.xml | 41 +++ .../github/jsonldjava/tools/Playground.java | 236 ++++++++---------- 3 files changed, 144 insertions(+), 137 deletions(-) diff --git a/jsonldplayground b/jsonldplayground index 8dade6f4..a838ff3a 100755 --- a/jsonldplayground +++ b/jsonldplayground @@ -7,8 +7,8 @@ # run ./jsonldplayground for the usage if [ ! -d "tools/target/appassembler/bin" ]; then - mvn -quiet clean install + mvn -quiet clean install -DskipTests fi chmod u+x tools/target/appassembler/bin/* -tools/target/appassembler/bin/jsonldplayground +tools/target/appassembler/bin/jsonldplayground "$@" diff --git a/tools/pom.xml b/tools/pom.xml index a7d73e21..84fae49e 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -38,6 +38,47 @@ jopt-simple 4.6 + + org.openrdf.sesame + sesame-rio-nquads + runtime + + + org.openrdf.sesame + sesame-rio-turtle + ${sesame.version} + runtime + + + org.openrdf.sesame + sesame-rio-rdfxml + ${sesame.version} + runtime + + + org.openrdf.sesame + sesame-rio-rdfjson + ${sesame.version} + runtime + + + org.openrdf.sesame + sesame-rio-ntriples + ${sesame.version} + runtime + + + org.openrdf.sesame + sesame-rio-trig + ${sesame.version} + runtime + + + org.openrdf.sesame + sesame-rio-trix + ${sesame.version} + runtime + diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index 1695037a..ae156284 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -3,7 +3,10 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashSet; @@ -14,6 +17,7 @@ import org.openrdf.rio.RDFFormat; import org.openrdf.rio.RDFParserRegistry; +import org.openrdf.rio.Rio; import joptsimple.OptionException; import joptsimple.OptionParser; @@ -25,18 +29,19 @@ import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdOptions; import com.github.jsonldjava.core.JsonLdProcessor; +import com.github.jsonldjava.sesame.SesameRDFParser; +import com.github.jsonldjava.sesame.SesameTripleCallback; import com.github.jsonldjava.utils.JsonUtils; public class Playground { - private static boolean validOption(String opt) { - return "--expand".equals(opt) || "--compact".equals(opt) - || "--frame".equals(opt) || "--normalize".equals(opt) || "--simplify".equals(opt) - || "--flatten".equals(opt) || "--fromRDF".equals(opt) || "--toRDF".equals(opt); + private static Set getProcessingOptions() { + return new LinkedHashSet(Arrays.asList("expand", "compact", + "frame", "normalize", "flatten", "fromrdf", "tordf")); } private static boolean hasContext(String opt) { - return "--compact".equals(opt) || "--frame".equals(opt) || "--flatten".equals(opt); + return "compact".equals(opt) || "frame".equals(opt) || "flatten".equals(opt); } private static Map getOutputFormats() { @@ -61,10 +66,14 @@ public static void main(String[] args) throws Exception { final OptionSpec base = parser.accepts("base") .withRequiredArg() .ofType(String.class) + .defaultsTo("") .describedAs("base URI"); final OptionSpec inputFile = - parser.accepts("inputFile").withRequiredArg().ofType(File.class) + parser.accepts("inputFile") + .withRequiredArg() + .ofType(File.class) + .required() .describedAs("The input file"); final OptionSpec context = @@ -75,7 +84,6 @@ public static void main(String[] args) throws Exception { parser.accepts("format") .withOptionalArg() .ofType(String.class) - .defaultsTo(RDFFormat.NQUADS.getName()) .withValuesConvertedBy(new ValueConverter() { @Override public RDFFormat convert(String arg0) { @@ -107,7 +115,7 @@ public Class valueType() { .withValuesConvertedBy(new ValueConverter() { @Override public String convert(String value) { - if(validOption(value.toLowerCase())) { + if(getProcessingOptions().contains(value.toLowerCase())) { return value.toLowerCase(); } throw new ValueConversionException("Processing option was not known: " + value); @@ -123,8 +131,7 @@ public String valuePattern() { return null; } }) - - ; + .describedAs("The processing to perform. One of: " + getProcessingOptions().toString()); final OptionSpec outputForm = parser.accepts("outputForm") .withOptionalArg() @@ -149,7 +156,7 @@ public Class valueType() { return String.class; } }) - .describedAs("outputForm"); + .describedAs("The way to output the results from fromRDF. Defaults to expanded."); OptionSet options = null; @@ -173,163 +180,122 @@ public Class valueType() { final JsonLdOptions opts = new JsonLdOptions(""); Object inobj = null; Object ctxobj = null; - String opt = null; - if(options.has(base)) { - opts.setBase(options.valueOf(base)); - } + opts.setBase(options.valueOf(base)); + opts.outputForm = options.valueOf(outputForm); + opts.format = options.has(outputFormat) ? options.valueOf(outputFormat).getDefaultMIMEType() : "application/nquads"; + RDFFormat sesameOutputFormat = options.has(outputFormat) ? options.valueOf(outputFormat) : RDFFormat.NQUADS; + + String processingOptionValue = options.valueOf(processingOption); - if(options.has(outputForm)) { - opts.outputForm = options.valueOf(outputForm); + if (!options.valueOf(inputFile).exists()) { + System.out.println("Error: input file \"" + options.valueOf(inputFile) + "\" doesn't exist"); + parser.printHelpOn(System.out); + return; } - - if(options.has(outputFormat)) { - opts.format = options.valueOf(outputFormat).getDefaultMIMEType(); + // if base is currently null, set it + if (opts.getBase() == null || opts.getBase().equals("")) { + opts.setBase(options.valueOf(inputFile).toURI().toASCIIString()); } + if ("fromrdf".equals(processingOptionValue)) { + inobj = readFile(options.valueOf(inputFile)); + } else { + inobj = JsonUtils.fromInputStream(new FileInputStream(options.valueOf(inputFile))); + } - opt = args[i]; - i++; - if (args.length <= i) { - System.out.println("Error: missing file names after argument " - + args[i - 1]); - usage(); + if (hasContext(processingOptionValue) && options.has(context)) { + if (!options.valueOf(context).exists()) { + System.out.println("Error: context file \"" + options.valueOf(context) + + "\" doesn't exist"); + parser.printHelpOn(System.out); return; } - File in = new File(args[i++]); - if (!in.exists()) { - System.out.println("Error: file \"" + args[i - 1] + "\" doesn't exist"); - usage(); - return; - } - // if base is currently null, set it - if (opts.getBase() == null || opts.getBase().equals("")) { - opts.setBase(in.toURI().toASCIIString()); - } - if ("--fromRDF".equals(opt)) { - final BufferedReader buf = new BufferedReader(new InputStreamReader( - new FileInputStream(in), "UTF-8")); - inobj = ""; - String line; - while ((line = buf.readLine()) != null) { - line = line.trim(); - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - inobj = ((String) inobj) + line + "\n"; - } - - } else { - inobj = JsonUtils.fromInputStream(new FileInputStream(in)); - } - if ("--fromRDF".equals(opt) || "--toRDF".equals(opt) - || "--normalize".equals(opt)) { - // get format option - if (args.length > i && !args[i].startsWith("--")) { - opts.format = args[i++]; - // remove any quotes - if (Pattern.matches("^['\"`].*['\"`]$", opts.format)) { - opts.format = opts.format - .substring(1, opts.format.length() - 1); - } - } - // default to nquads - if (opts.format == null || "null".equals(opts.format)) { - opts.format = "application/nquads"; - } - } else if (hasContext(opt)) { - if (args.length > i) { - - in = new File(args[i++]); - if (!in.exists()) { - if (args[i - 1].startsWith("--")) { - // the frame is optional, so if it turns - // out we have another option after the - // --frame options - // we have to make sure we process it - i--; - } else { - System.out.println("Error: file \"" + args[i - 1] - + "\" doesn't exist"); - usage(); - return; - } - } - ctxobj = JsonUtils.fromInputStream(new FileInputStream(in)); - } - } - } - - if (opt == null) { - System.out.println("Error: missing processing option"); - usage(); - return; + ctxobj = JsonUtils.fromInputStream(new FileInputStream(options.valueOf(context))); } - + Object outobj = null; - if ("--expand".equals(opt)) { + if ("fromrdf".equals(processingOptionValue)) { + outobj = JsonLdProcessor.fromRDF(inobj, opts); + } else if ("tordf".equals(processingOptionValue)) { + opts.useNamespaces = true; + outobj = JsonLdProcessor.toRDF(inobj, new SesameTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), opts); + } else if ("expand".equals(processingOptionValue)) { outobj = JsonLdProcessor.expand(inobj, opts); - } else if ("--compact".equals(opt)) { + } else if ("compact".equals(processingOptionValue)) { if (ctxobj == null) { System.out.println("Error: The compaction context must not be null."); - usage(); + parser.printHelpOn(System.out); return; } outobj = JsonLdProcessor.compact(inobj, ctxobj, opts); - } else if ("--normalize".equals(opt)) { + } else if ("normalize".equals(processingOptionValue)) { outobj = JsonLdProcessor.normalize(inobj, opts); - } else if ("--frame".equals(opt)) { + } else if ("frame".equals(processingOptionValue)) { if (ctxobj != null && !(ctxobj instanceof Map)) { System.out .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); - usage(); + parser.printHelpOn(System.out); return; } outobj = JsonLdProcessor.frame(inobj, ctxobj, opts); - } else if ("--flatten".equals(opt)) { + } else if ("flatten".equals(processingOptionValue)) { outobj = JsonLdProcessor.flatten(inobj, ctxobj, opts); - } else if ("--toRDF".equals(opt)) { - opts.useNamespaces = true; - outobj = JsonLdProcessor.toRDF(inobj, opts); - } else if ("--fromRDF".equals(opt)) { - outobj = JsonLdProcessor.fromRDF(inobj, opts); } else { - System.out.println("Error: invalid option \"" + opt + "\""); - usage(); + System.out.println("Error: invalid processing option \"" + processingOptionValue + "\""); + parser.printHelpOn(System.out); return; } - if ("--toRDF".equals(opt) || "--normalize".equals(opt)) { + if ("tordf".equals(processingOptionValue)) { + // Already serialised above + } else if("normalize".equals(processingOptionValue)) { System.out.println((String) outobj); } else { System.out.println(JsonUtils.toPrettyString(outobj)); } } - private static void usage() { - System.out.println("Usage: jsonldplayground "); - System.out.println("\tinput: a filename or JsonLdUrl to the rdf input (in rdfxml or n3)"); - System.out.println("\toptions:"); - System.out - .println("\t\t--ignorekeys : a (space separated) list of keys to ignore (e.g. @geojson)"); - System.out.println("\t\t--base : base URI"); - System.out.println("\t\t--debug: Print out stack traces when errors occur"); - System.out.println("\t\t--expand : expand the input JSON-LD"); - System.out - .println("\t\t--compact : compact the input JSON-LD applying the optional context file"); - System.out - .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquads)"); - System.out - .println("\t\t--frame : frame the input JSON-LD with the optional frame file"); - System.out - .println("\t\t--flatten : flatten the input JSON-LD applying the optional context file"); - System.out - .println("\t\t--fromRDF : generate JSON-LD from the input rdf (format defaults to nquads)"); - System.out - .println("\t\t--toRDF : generate RDF from the input JSON-LD (format defaults to nquads)"); - System.out - .println("\t\t--outputForm [compacted|expanded|flattened] : the way to output the results from fromRDF (defaults to expanded)"); - System.out.println("\t\t--simplify : simplify the input JSON-LD"); - System.exit(1); + private static String readFile(File in) throws IOException { + final BufferedReader buf = new BufferedReader(new InputStreamReader( + new FileInputStream(in), "UTF-8")); + String inobj = ""; + try { + String line; + while ((line = buf.readLine()) != null) { + line = line.trim(); + inobj = ((String) inobj) + line + "\n"; + } + } finally { + buf.close(); + } + return inobj; } + +// private static void usage() { +// System.out.println("Usage: jsonldplayground "); +// System.out.println("\tinput: a filename or JsonLdUrl to the rdf input (in rdfxml or n3)"); +// System.out.println("\toptions:"); +// System.out +// .println("\t\t--ignorekeys : a (space separated) list of keys to ignore (e.g. @geojson)"); +// System.out.println("\t\t--base : base URI"); +// System.out.println("\t\t--debug: Print out stack traces when errors occur"); +// System.out.println("\t\t--expand : expand the input JSON-LD"); +// System.out +// .println("\t\t--compact : compact the input JSON-LD applying the optional context file"); +// System.out +// .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquads)"); +// System.out +// .println("\t\t--frame : frame the input JSON-LD with the optional frame file"); +// System.out +// .println("\t\t--flatten : flatten the input JSON-LD applying the optional context file"); +// System.out +// .println("\t\t--fromRDF : generate JSON-LD from the input rdf (format defaults to nquads)"); +// System.out +// .println("\t\t--toRDF : generate RDF from the input JSON-LD (format defaults to nquads)"); +// System.out +// .println("\t\t--outputForm [compacted|expanded|flattened] : the way to output the results from fromRDF (defaults to expanded)"); +// System.out.println("\t\t--simplify : simplify the input JSON-LD"); +// System.exit(1); +// } } From 8d6b37d8e233e1a71ea46e5ee50f5c54556050ed Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 14:42:11 +1100 Subject: [PATCH 097/440] Allow all Sesame parsers to be recognised by the Playground fromRDF function --- .../java/com/github/jsonldjava/core/JsonLdProcessor.java | 2 +- .../main/java/com/github/jsonldjava/tools/Playground.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 99250795..303c1b91 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -424,7 +424,7 @@ public static Object fromRDF(Object input, JsonLdOptions options, RDFParser pars } else if ("flattened".equals(options.outputForm)) { return flatten(rval, dataset.getContext(), options); } else { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR); + throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, "Output form was unknown: " + options.outputForm); } } return rval; diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index ae156284..6e9d753b 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -6,6 +6,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; +import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.HashMap; @@ -15,6 +16,7 @@ import java.util.Set; import java.util.regex.Pattern; +import org.openrdf.model.Model; import org.openrdf.rio.RDFFormat; import org.openrdf.rio.RDFParserRegistry; import org.openrdf.rio.Rio; @@ -29,6 +31,7 @@ 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.sesame.SesameRDFParser; import com.github.jsonldjava.sesame.SesameTripleCallback; import com.github.jsonldjava.utils.JsonUtils; @@ -185,6 +188,7 @@ public Class valueType() { opts.outputForm = options.valueOf(outputForm); opts.format = options.has(outputFormat) ? options.valueOf(outputFormat).getDefaultMIMEType() : "application/nquads"; RDFFormat sesameOutputFormat = options.has(outputFormat) ? options.valueOf(outputFormat) : RDFFormat.NQUADS; + RDFFormat sesameInputFormat = Rio.getParserFormatForFileName(options.valueOf(inputFile).getName(), RDFFormat.JSONLD); String processingOptionValue = options.valueOf(processingOption); @@ -216,7 +220,9 @@ public Class valueType() { Object outobj = null; if ("fromrdf".equals(processingOptionValue)) { - outobj = JsonLdProcessor.fromRDF(inobj, opts); + Model inModel = Rio.parse(new StringReader((String) inobj), opts.getBase(), sesameInputFormat); + + outobj = JsonLdProcessor.fromRDF(inModel, opts, new SesameRDFParser()); } else if ("tordf".equals(processingOptionValue)) { opts.useNamespaces = true; outobj = JsonLdProcessor.toRDF(inobj, new SesameTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), opts); From 9fe075df19769893d74ebc4a2e01dbb70cb47900 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 14:50:45 +1100 Subject: [PATCH 098/440] more work on the CLI instructions --- .../com/github/jsonldjava/tools/Playground.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index 6e9d753b..dc4086ce 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -95,7 +95,8 @@ public RDFFormat convert(String arg0) { if(formats.containsKey(formatName)) { return formats.get(formatName); } - throw new ValueConversionException("Format was not known: " + arg0); + throw new ValueConversionException("Format was not known: " + arg0 + " (Valid values are: " + formats + ")" + ); } @Override @@ -109,7 +110,7 @@ public Class valueType() { } }) .describedAs( - "The output file format to use. Defaults to nquads."); + "The output file format to use. Defaults to nquads. Valid values are: " + formats); final OptionSpec processingOption = parser.accepts("process") .withRequiredArg() @@ -121,7 +122,8 @@ public String convert(String value) { if(getProcessingOptions().contains(value.toLowerCase())) { return value.toLowerCase(); } - throw new ValueConversionException("Processing option was not known: " + value); + throw new ValueConversionException("Processing option was not known: " + value + + " (Valid values are: " + getProcessingOptions() + ")"); } @Override @@ -134,7 +136,7 @@ public String valuePattern() { return null; } }) - .describedAs("The processing to perform. One of: " + getProcessingOptions().toString()); + .describedAs("The processing to perform. Valid values are: " + getProcessingOptions().toString()); final OptionSpec outputForm = parser.accepts("outputForm") .withOptionalArg() @@ -146,7 +148,7 @@ public String convert(String value) { if(outputForms.contains(value.toLowerCase())) { return value.toLowerCase(); } - throw new ValueConversionException("Output form was not known: " + value); + throw new ValueConversionException("Output form was not known: " + value + " (Valid values are: " + outputForms + ")"); } @Override @@ -159,7 +161,7 @@ public Class valueType() { return String.class; } }) - .describedAs("The way to output the results from fromRDF. Defaults to expanded."); + .describedAs("The way to output the results from fromRDF. Defaults to expanded. Valid values are: " + outputForms); OptionSet options = null; From b6c395e814e60ca56e8a714470df3a3f3de62a63 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 14:53:49 +1100 Subject: [PATCH 099/440] improve the output format debugging --- .../src/main/java/com/github/jsonldjava/tools/Playground.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index dc4086ce..3947992a 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -95,7 +95,7 @@ public RDFFormat convert(String arg0) { if(formats.containsKey(formatName)) { return formats.get(formatName); } - throw new ValueConversionException("Format was not known: " + arg0 + " (Valid values are: " + formats + ")" + throw new ValueConversionException("Format was not known: " + arg0 + " (Valid values are: " + formats.keySet() + ")" ); } @@ -110,7 +110,7 @@ public Class valueType() { } }) .describedAs( - "The output file format to use. Defaults to nquads. Valid values are: " + formats); + "The output file format to use. Defaults to nquads. Valid values are: " + formats.keySet()); final OptionSpec processingOption = parser.accepts("process") .withRequiredArg() From 0e2e2448c4ff490b676a8bcc540ad03f2e2b9300 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 15:18:57 +1100 Subject: [PATCH 100/440] add changelog entry for jopt-simple and the playground changes --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index bc2c88e6..d04235da 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,10 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2015-03-01 +* Use jopt-simple for the playground cli to simplify the coding and improve error messages +* Allow RDF parsing and writing using all of the available Sesame Rio parsers through the playground cli + ### 2014-12-31 * Fix locale sensitive serialisation of XSD double/decimal typed literals to always be Locale.US * Bump to Sesame-2.7.14 From ef63e515c3801821e8f656516fb77b3c10182978 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 15:19:27 +1100 Subject: [PATCH 101/440] automated cleanup --- .../com/github/jsonldjava/core/Context.java | 46 +-- .../jsonldjava/core/DocumentLoader.java | 4 +- .../com/github/jsonldjava/core/JsonLdApi.java | 118 ++++---- .../github/jsonldjava/core/JsonLdError.java | 46 +-- .../github/jsonldjava/core/JsonLdOptions.java | 6 +- .../jsonldjava/core/JsonLdProcessor.java | 39 +-- .../jsonldjava/core/JsonLdTripleCallback.java | 12 +- .../github/jsonldjava/core/JsonLdUtils.java | 86 +++--- .../jsonldjava/core/NormalizeUtils.java | 28 +- .../github/jsonldjava/core/RDFDataset.java | 34 +-- .../jsonldjava/core/RDFDatasetUtils.java | 33 ++- .../com/github/jsonldjava/core/RDFParser.java | 12 +- .../com/github/jsonldjava/core/Regex.java | 4 +- .../github/jsonldjava/core/UniqueNamer.java | 8 +- .../jsonldjava/impl/TurtleRDFParser.java | 16 +- .../jsonldjava/impl/TurtleTripleCallback.java | 8 +- .../jsonldjava/utils/JarCacheStorage.java | 6 +- .../github/jsonldjava/utils/JsonLdUrl.java | 4 +- .../github/jsonldjava/utils/JsonUtils.java | 26 +- .../java/com/github/jsonldjava/utils/Obj.java | 10 +- .../core/JsonLdPerformanceTest.java | 8 +- .../jsonldjava/core/JsonLdProcessorTest.java | 4 +- .../com/github/jsonldjava/core/RegexTest.java | 9 +- .../jsonldjava/impl/TurtleRDFParserTest.java | 12 +- .../jsonldjava/utils/EarlTestSuite.java | 2 +- .../github/jsonldjava/utils/TestUtils.java | 4 +- .../jsonldjava/rdf2go/RDF2GoRDFParser.java | 2 +- .../rdf2go/RDF2GoTripleCallback.java | 2 +- .../rdf2go/RDF2GoRDFParserTest.java | 2 +- .../rdf2go/RDF2GoTripleCallbackTest.java | 2 +- .../jsonldjava/sesame/SesameJSONLDParser.java | 12 +- .../sesame/SesameJSONLDParserFactory.java | 4 +- .../jsonldjava/sesame/SesameJSONLDWriter.java | 8 +- .../sesame/SesameJSONLDWriterFactory.java | 4 +- .../sesame/SesameEmptyPrefixTest.java | 18 +- .../sesame/SesameJSONLDParserHandlerTest.java | 6 +- .../sesame/SesameJSONLDWriterTest.java | 31 +- .../sesame/SesameLocaleNumericTest.java | 24 +- tools/pom.xml | 2 +- .../github/jsonldjava/tools/Playground.java | 267 +++++++++--------- 40 files changed, 485 insertions(+), 484 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 434b9ad7..bfcdf4f3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -17,9 +17,9 @@ /** * A helper class which still stores all the values in a map but gives member * variables easily access certain keys - * + * * @author tristan - * + * */ public class Context extends LinkedHashMap { @@ -62,9 +62,9 @@ private void init(JsonLdOptions options) { /** * Value Compaction Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#value-compaction - * + * * @param activeProperty * The Active Property * @param value @@ -123,9 +123,9 @@ && getTermDefinition(activeProperty).containsKey("@language") && languageMapping /** * Context Processing Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms - * + * * @param localContext * The Local Context object. * @param remoteContexts @@ -254,9 +254,9 @@ public Context parse(Object localContext) throws JsonLdError { /** * Create Term Definition Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition - * + * * @param result * @param context * @param key @@ -433,9 +433,9 @@ else if (term.indexOf(":") >= 0) { /** * IRI Expansion Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion - * + * * @param value * @param relative * @param vocab @@ -504,12 +504,12 @@ else if (relative) { /** * IRI Compaction Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction - * + * * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI * has an associated value it may be passed. - * + * * @param iri * the IRI to compact. * @param value @@ -519,7 +519,7 @@ else if (relative) { * @vocab, false not to. * @param reverse * true if a reverse property is being compacted, false if not. - * + * * @return the compacted term, prefix, keyword alias, or the original IRI. */ String compactIri(String iri, Object value, boolean relativeToVocab, boolean reverse) { @@ -757,14 +757,14 @@ else if (((Map) value).containsKey("@type")) { *

* No guarantees of the prefixes are given, beyond that it will not contain * ":". - * + * * @param onlyCommonPrefixes * If true, the result will not include * "not so useful" prefixes, such as "term1": * "http://example.com/term1", e.g. all IRIs will end with "/" or * "#". If false, all potential prefixes are * returned. - * + * * @return A map from prefix string to IRI string */ public Map getPrefixes(boolean onlyCommonPrefixes) { @@ -811,12 +811,12 @@ public Context clone() { /** * Inverse Context Creation - * + * * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation - * + * * Generates an inverse context for use in the compaction algorithm, if not * already generated for the given active context. - * + * * @return the inverse context. */ public Map getInverse() { @@ -930,15 +930,15 @@ public int compare(String a, String b) { /** * Term Selection - * + * * http://json-ld.org/spec/latest/json-ld-api/#term-selection - * + * * This algorithm, invoked via the IRI Compaction algorithm, makes use of an * active context's inverse context to find the term that is best used to * compact an IRI. Other information about a value associated with the IRI * is given, including which container mappings and which type mapping or * language mapping would be best used to express the value. - * + * * @return the selected term. */ private String selectTerm(String iri, List containers, String typeLanguage, @@ -974,7 +974,7 @@ private String selectTerm(String iri, List containers, String typeLangua /** * Retrieve container mapping. - * + * * @param property * The Property to get a container mapping for. * @return The container mapping diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 528e72e7..8da04c24 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -46,7 +46,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { /** * Returns a Map, List, or String containing the contents of the JSON * resource resolved from the JsonLdUrl. - * + * * @param url * The JsonLdUrl to resolve * @return The Map, List, or String that represent the JSON resource @@ -86,7 +86,7 @@ public Object fromURL(java.net.URL url) throws JsonParseException, IOException { * including support for http and https URLs that are requested using * Content Negotiation with application/ld+json as the preferred content * type. - * + * * @param url * The {@link java.net.URL} identifying the source. * @return An InputStream containing the contents of the source. diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index e2889f5f..770687e8 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -28,7 +28,7 @@ * A container object to maintain state relating to JsonLdOptions and the * current Context, and push these into the relevant algorithms in * JsonLdProcessor as necessary. - * + * * @author tristan */ public class JsonLdApi { @@ -50,7 +50,7 @@ public JsonLdApi() { /** * Constructs a JsonLdApi object using the given object as the initial * JSON-LD object, and the given JsonLdOptions. - * + * * @param input * The initial JSON-LD object. * @param opts @@ -67,7 +67,7 @@ public JsonLdApi(Object input, JsonLdOptions opts) throws JsonLdError { /** * Constructs a JsonLdApi object using the given object as the initial * JSON-LD object, the given context, and the given JsonLdOptions. - * + * * @param input * The initial JSON-LD object. * @param context @@ -88,7 +88,7 @@ public JsonLdApi(Object input, Object context, JsonLdOptions opts) throws JsonLd * without initialization.
* If the JsonLdOptions parameter is null, then the default options are * used. - * + * * @param opts * The JsonLdOptions to use. */ @@ -104,7 +104,7 @@ public JsonLdApi(JsonLdOptions opts) { * Initializes this object by cloning the input object using * {@link JsonLdUtils#clone(Object)}, and by parsing the context using * {@link Context#parse(Object)}. - * + * * @param input * The initial object, which is to be cloned and used in * operations. @@ -137,9 +137,9 @@ private void initialize(Object input, Object context) throws JsonLdError { /** * Compaction Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#compaction-algorithm - * + * * @param activeCtx * The Active Context * @param activeProperty @@ -266,7 +266,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, } if (value instanceof List) { ((List) result.get(property)) - .addAll((List) value); + .addAll((List) value); } else { ((List) result.get(property)).add(value); } @@ -414,7 +414,7 @@ else if (result.containsKey(itemActiveProperty)) { // 7.6.6.1) final Boolean check = (!compactArrays || "@set".equals(container) || "@list".equals(container) || "@list".equals(expandedProperty) || "@graph" - .equals(expandedProperty)) + .equals(expandedProperty)) && (!(compactedItem instanceof List)); if (check) { final List tmp = new ArrayList(); @@ -431,7 +431,7 @@ else if (result.containsKey(itemActiveProperty)) { } if (compactedItem instanceof List) { ((List) result.get(itemActiveProperty)) - .addAll((List) compactedItem); + .addAll((List) compactedItem); } else { ((List) result.get(itemActiveProperty)).add(compactedItem); } @@ -450,9 +450,9 @@ else if (result.containsKey(itemActiveProperty)) { /** * Compaction Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#compaction-algorithm - * + * * @param activeCtx * The Active Context * @param activeProperty @@ -478,9 +478,9 @@ public Object compact(Context activeCtx, String activeProperty, Object element) /** * Expansion Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#expansion-algorithm - * + * * @param activeCtx * The Active Context * @param activeProperty @@ -683,7 +683,7 @@ else if ("@reverse".equals(expandedProperty)) { // 7.4.11.2.2) if (item instanceof List) { ((List) result.get(property)) - .addAll((List) item); + .addAll((List) item); } else { ((List) result.get(property)).add(item); } @@ -850,7 +850,7 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.10.4.3) if (item instanceof List) { ((List) reverseMap.get(expandedProperty)) - .addAll((List) item); + .addAll((List) item); } else { ((List) reverseMap.get(expandedProperty)).add(item); } @@ -865,7 +865,7 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.11.2) if (expandedValue instanceof List) { ((List) result.get(expandedProperty)) - .addAll((List) expandedValue); + .addAll((List) expandedValue); } else { ((List) result.get(expandedProperty)).add(expandedValue); } @@ -943,7 +943,7 @@ else if (result.containsKey("@set") || result.containsKey("@list")) { // 12.1) if (result != null && (result.size() == 0 || result.containsKey("@value") || result - .containsKey("@list"))) { + .containsKey("@list"))) { result = null; } // 12.2) @@ -966,9 +966,9 @@ else if (result != null && result.containsKey("@id") && result.size() == 1) { /** * Expansion Algorithm - * + * * http://json-ld.org/spec/latest/json-ld-api/#expansion-algorithm - * + * * @param activeCtx * The Active Context * @param element @@ -1000,7 +1000,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG void generateNodeMap(Object element, Map nodeMap, String activeGraph, Object activeSubject, String activeProperty, Map list) - throws JsonLdError { + throws JsonLdError { // 1) if (element instanceof List) { // 1.1) @@ -1176,14 +1176,14 @@ else if (activeProperty != null) { /** * Blank Node identifier map specified in: - * + * * http://www.w3.org/TR/json-ld-api/#generate-blank-node-identifier */ private final Map blankNodeIdentifierMap = new LinkedHashMap(); /** * Counter specified in: - * + * * http://www.w3.org/TR/json-ld-api/#generate-blank-node-identifier */ private int blankNodeCounter = 0; @@ -1191,9 +1191,9 @@ else if (activeProperty != null) { /** * Generates a blank node identifier for the given key using the algorithm * specified in: - * + * * http://www.w3.org/TR/json-ld-api/#generate-blank-node-identifier - * + * * @param id * The id, or null to generate a fresh, unused, blank node * identifier. @@ -1214,9 +1214,9 @@ String generateBlankNodeIdentifier(String id) { /** * Generates a fresh, unused, blank node identifier using the algorithm * specified in: - * + * * http://www.w3.org/TR/json-ld-api/#generate-blank-node-identifier - * + * * @return A fresh, unused, blank node identifier. */ String generateBlankNodeIdentifier() { @@ -1270,7 +1270,7 @@ private class EmbedNode { /** * Performs JSON-LD framing. - * + * * @param input * the expanded JSON-LD to frame. * @param frame @@ -1301,7 +1301,7 @@ public List frame(Object input, List frame) throws JsonLdError { /** * Frames subjects according to the given frame. - * + * * @param state * the current framing state. * @param subjects @@ -1429,7 +1429,7 @@ private void frame(FramingContext state, Map nodes, Map) ((List) frame.get(prop)) - .get(0), list, "@list"); + .get(0), list, "@list"); } else { // include other values automatcially (TODO: // may need JsonLdUtils.clone(n)) @@ -1468,26 +1468,26 @@ else if (JsonLdUtils.isNodeReference(item)) { final List pf = (List) frame.get(prop); Map propertyFrame = pf.size() > 0 ? (Map) pf .get(0) : null; - if (propertyFrame == null) { - propertyFrame = newMap(); - } - final boolean omitDefaultOn = getFrameFlag(propertyFrame, "@omitDefault", - state.omitDefault); - if (!omitDefaultOn && !output.containsKey(prop)) { - Object def = "@null"; - if (propertyFrame.containsKey("@default")) { - def = JsonLdUtils.clone(propertyFrame.get("@default")); - } - if (!(def instanceof List)) { - final List tmp = new ArrayList(); - tmp.add(def); - def = tmp; - } - final Map tmp1 = newMap("@preserve", def); - final List tmp2 = new ArrayList(); - tmp2.add(tmp1); - output.put(prop, tmp2); - } + if (propertyFrame == null) { + propertyFrame = newMap(); + } + final boolean omitDefaultOn = getFrameFlag(propertyFrame, "@omitDefault", + state.omitDefault); + if (!omitDefaultOn && !output.containsKey(prop)) { + Object def = "@null"; + if (propertyFrame.containsKey("@default")) { + def = JsonLdUtils.clone(propertyFrame.get("@default")); + } + if (!(def instanceof List)) { + final List tmp = new ArrayList(); + tmp.add(def); + def = tmp; + } + final Map tmp1 = newMap("@preserve", def); + final List tmp2 = new ArrayList(); + tmp2.add(tmp1); + output.put(prop, tmp2); + } } // add output to parent @@ -1514,7 +1514,7 @@ private Boolean getFrameFlag(Map frame, String name, boolean the /** * Removes an existing embed. - * + * * @param state * the current framing state. * @param id @@ -1615,7 +1615,7 @@ private boolean filterNode(FramingContext state, Map node, /** * Adds framing output to the given parent. - * + * * @param state * the current framing state. * @param parent @@ -1642,7 +1642,7 @@ private static void addFrameOutput(FramingContext state, Object parent, String p /** * Embeds values for the given subject and property into the given output * during the framing algorithm. - * + * * @param state * the current framing state. * @param element @@ -1706,7 +1706,7 @@ private void embedValues(FramingContext state, Map element, Stri /** * Helper class for node usages - * + * * @author tristan */ private class UsagesNode { @@ -1772,7 +1772,7 @@ public Map serialize() { /** * Converts RDF statements into JSON-LD. - * + * * @param dataset * the RDF statements. * @return A list of JSON-LD objects found in the given dataset. @@ -1843,7 +1843,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { if (object.isBlankNode() || object.isIRI()) { // 3.5.8.1-3) nodeMap.get(object.getValue()).usages - .add(new UsagesNode(node, predicate, value)); + .add(new UsagesNode(node, predicate, value)); } } } @@ -1958,7 +1958,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { /** * Adds RDF triples for each graph in the current node map to an RDF * dataset. - * + * * @return the RDF dataset. * @throws JsonLdError * If there was an error converting from JSON-LD to RDF. @@ -1996,7 +1996,7 @@ public RDFDataset toRDF() throws JsonLdError { /** * Performs RDF normalization on the given JSON-LD input. - * + * * @param dataset * the expanded JSON-LD object to normalize. * @return The normalized JSON-LD object @@ -2044,7 +2044,7 @@ public Object normalize(Map dataset) throws JsonLdError { }); } ((List) ((Map) bnodes.get(id)).get("quads")) - .add(quad); + .add(quad); } } } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java index 3776fded..64d3e16e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java @@ -21,30 +21,30 @@ public JsonLdError(Error type) { public enum Error { LOADING_DOCUMENT_FAILED("loading document failed"), LIST_OF_LISTS("list of lists"), INVALID_INDEX_VALUE( "invalid @index value"), CONFLICTING_INDEXES("conflicting indexes"), INVALID_ID_VALUE( - "invalid @id value"), INVALID_LOCAL_CONTEXT("invalid local context"), MULTIPLE_CONTEXT_LINK_HEADERS( - "multiple context link headers"), LOADING_REMOTE_CONTEXT_FAILED( - "loading remote context failed"), INVALID_REMOTE_CONTEXT("invalid remote context"), RECURSIVE_CONTEXT_INCLUSION( - "recursive context inclusion"), INVALID_BASE_IRI("invalid base IRI"), INVALID_VOCAB_MAPPING( - "invalid vocab mapping"), INVALID_DEFAULT_LANGUAGE("invalid default language"), KEYWORD_REDEFINITION( - "keyword redefinition"), INVALID_TERM_DEFINITION("invalid term definition"), INVALID_REVERSE_PROPERTY( - "invalid reverse property"), INVALID_IRI_MAPPING("invalid IRI mapping"), CYCLIC_IRI_MAPPING( - "cyclic IRI mapping"), INVALID_KEYWORD_ALIAS("invalid keyword alias"), INVALID_TYPE_MAPPING( - "invalid type mapping"), INVALID_LANGUAGE_MAPPING("invalid language mapping"), COLLIDING_KEYWORDS( - "colliding keywords"), INVALID_CONTAINER_MAPPING("invalid container mapping"), INVALID_TYPE_VALUE( - "invalid type value"), INVALID_VALUE_OBJECT("invalid value object"), INVALID_VALUE_OBJECT_VALUE( - "invalid value object value"), INVALID_LANGUAGE_TAGGED_STRING( - "invalid language-tagged string"), INVALID_LANGUAGE_TAGGED_VALUE( - "invalid language-tagged value"), INVALID_TYPED_VALUE("invalid typed value"), INVALID_SET_OR_LIST_OBJECT( - "invalid set or list object"), INVALID_LANGUAGE_MAP_VALUE( - "invalid language map value"), COMPACTION_TO_LIST_OF_LISTS( - "compaction to list of lists"), INVALID_REVERSE_PROPERTY_MAP( - "invalid reverse property map"), INVALID_REVERSE_VALUE("invalid @reverse value"), INVALID_REVERSE_PROPERTY_VALUE( - "invalid reverse property value"), + "invalid @id value"), INVALID_LOCAL_CONTEXT("invalid local context"), MULTIPLE_CONTEXT_LINK_HEADERS( + "multiple context link headers"), LOADING_REMOTE_CONTEXT_FAILED( + "loading remote context failed"), INVALID_REMOTE_CONTEXT("invalid remote context"), RECURSIVE_CONTEXT_INCLUSION( + "recursive context inclusion"), INVALID_BASE_IRI("invalid base IRI"), INVALID_VOCAB_MAPPING( + "invalid vocab mapping"), INVALID_DEFAULT_LANGUAGE("invalid default language"), KEYWORD_REDEFINITION( + "keyword redefinition"), INVALID_TERM_DEFINITION("invalid term definition"), INVALID_REVERSE_PROPERTY( + "invalid reverse property"), INVALID_IRI_MAPPING("invalid IRI mapping"), CYCLIC_IRI_MAPPING( + "cyclic IRI mapping"), INVALID_KEYWORD_ALIAS("invalid keyword alias"), INVALID_TYPE_MAPPING( + "invalid type mapping"), INVALID_LANGUAGE_MAPPING("invalid language mapping"), COLLIDING_KEYWORDS( + "colliding keywords"), INVALID_CONTAINER_MAPPING("invalid container mapping"), INVALID_TYPE_VALUE( + "invalid type value"), INVALID_VALUE_OBJECT("invalid value object"), INVALID_VALUE_OBJECT_VALUE( + "invalid value object value"), INVALID_LANGUAGE_TAGGED_STRING( + "invalid language-tagged string"), INVALID_LANGUAGE_TAGGED_VALUE( + "invalid language-tagged value"), INVALID_TYPED_VALUE("invalid typed value"), INVALID_SET_OR_LIST_OBJECT( + "invalid set or list object"), INVALID_LANGUAGE_MAP_VALUE( + "invalid language map value"), COMPACTION_TO_LIST_OF_LISTS( + "compaction to list of lists"), INVALID_REVERSE_PROPERTY_MAP( + "invalid reverse property map"), INVALID_REVERSE_VALUE("invalid @reverse value"), INVALID_REVERSE_PROPERTY_VALUE( + "invalid reverse property value"), - // non spec related errors - SYNTAX_ERROR("syntax error"), NOT_IMPLEMENTED("not implemnted"), UNKNOWN_FORMAT( - "unknown format"), INVALID_INPUT("invalid input"), PARSE_ERROR("parse error"), UNKNOWN_ERROR( - "unknown error"); + // non spec related errors + SYNTAX_ERROR("syntax error"), NOT_IMPLEMENTED("not implemnted"), UNKNOWN_FORMAT( + "unknown format"), INVALID_INPUT("invalid input"), PARSE_ERROR("parse error"), UNKNOWN_ERROR( + "unknown error"); private final String error; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 18cc126c..51f3145d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -4,9 +4,9 @@ * The JsonLdOptions type as specified in the JSON-LD-API * specification. - * + * * @author tristan - * + * */ public class JsonLdOptions { @@ -19,7 +19,7 @@ public JsonLdOptions() { /** * Constructs an instance of JsonLdOptions using the given base. - * + * * @param base * The base IRI for the document. */ diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 303c1b91..aeb0c9a6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -20,9 +20,9 @@ * >JsonLdProcessor interface, except that it does not currently support * asynchronous processing, and hence does not return Promises, instead directly * returning the results. - * + * * @author tristan - * + * */ public class JsonLdProcessor { @@ -30,7 +30,7 @@ public class JsonLdProcessor { * Compacts the given input using the context according to the steps in the * * Compaction algorithm. - * + * * @param input * The input JSON-LD object. * @param context @@ -88,7 +88,7 @@ public static Map compact(Object input, Object context, JsonLdOp * Expands the given input according to the steps in the Expansion * algorithm. - * + * * @param input * The input JSON-LD object. * @param opts @@ -159,7 +159,7 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL * Expands the given input according to the steps in the Expansion * algorithm, using the default {@link JsonLdOptions}. - * + * * @param input * The input JSON-LD object. * @return The expanded JSON-LD document @@ -253,7 +253,7 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) * according to the steps in the Flattening * algorithm: - * + * * @param input * The input JSON-LD object. * @param opts @@ -271,7 +271,7 @@ public static Object flatten(Object input, JsonLdOptions opts) throws JsonLdErro * Frames the given input using the frame according to the steps in the * Framing Algorithm. - * + * * @param input * The input JSON-LD object. * @param frame @@ -315,7 +315,7 @@ public static Map frame(Object input, Object frame, JsonLdOption /** * A registry for RDF Parsers (in this case, JSONLDSerializers) used by * fromRDF if no specific serializer is specified and options.format is set. - * + * * TODO: this would fit better in the document loader class */ private static Map rdfParsers = new LinkedHashMap() { @@ -336,7 +336,7 @@ public static void removeRDFParser(String format) { /** * Converts an RDF dataset to JSON-LD. - * + * * @param dataset * a serialized string of RDF in a format specified by the format * option or an RDF dataset to convert. @@ -374,7 +374,7 @@ public static Object fromRDF(Object dataset, JsonLdOptions options) throws JsonL /** * Converts an RDF dataset to JSON-LD, using the default * {@link JsonLdOptions}. - * + * * @param dataset * a serialized string of RDF in a format specified by the format * option or an RDF dataset to convert. @@ -389,7 +389,7 @@ public static Object fromRDF(Object dataset) throws JsonLdError { /** * Converts an RDF dataset to JSON-LD, using a specific instance of * {@link RDFParser}. - * + * * @param input * a serialized string of RDF in a format specified by the format * option or an RDF dataset to convert. @@ -424,7 +424,8 @@ public static Object fromRDF(Object input, JsonLdOptions options, RDFParser pars } else if ("flattened".equals(options.outputForm)) { return flatten(rval, dataset.getContext(), options); } else { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, "Output form was unknown: " + options.outputForm); + throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, "Output form was unknown: " + + options.outputForm); } } return rval; @@ -433,7 +434,7 @@ public static Object fromRDF(Object input, JsonLdOptions options, RDFParser pars /** * Converts an RDF dataset to JSON-LD, using a specific instance of * {@link RDFParser}, and the default {@link JsonLdOptions}. - * + * * @param input * a serialized string of RDF in a format specified by the format * option or an RDF dataset to convert. @@ -450,7 +451,7 @@ public static Object fromRDF(Object input, RDFParser parser) throws JsonLdError /** * Outputs the RDF dataset found in the given JSON-LD object. - * + * * @param input * the JSON-LD input. * @param callback @@ -510,7 +511,7 @@ public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOp /** * Outputs the RDF dataset found in the given JSON-LD object. - * + * * @param input * the JSON-LD input. * @param options @@ -529,7 +530,7 @@ public static Object toRDF(Object input, JsonLdOptions options) throws JsonLdErr /** * Outputs the RDF dataset found in the given JSON-LD object, using the * default {@link JsonLdOptions}. - * + * * @param input * the JSON-LD input. * @param callback @@ -546,7 +547,7 @@ public static Object toRDF(Object input, JsonLdTripleCallback callback) throws J /** * Outputs the RDF dataset found in the given JSON-LD object, using the * default {@link JsonLdOptions}. - * + * * @param input * the JSON-LD input. * @return A JSON-LD object. @@ -560,7 +561,7 @@ public static Object toRDF(Object input) throws JsonLdError { /** * Performs RDF dataset normalization on the given JSON-LD input. The output * is an RDF dataset unless the 'format' option is used. - * + * * @param input * the JSON-LD input to normalize. * @param options @@ -585,7 +586,7 @@ public static Object normalize(Object input, JsonLdOptions options) throws JsonL * Performs RDF dataset normalization on the given JSON-LD input. The output * is an RDF dataset unless the 'format' option is used. Uses the default * {@link JsonLdOptions}. - * + * * @param input * the JSON-LD input to normalize. * @return The JSON-LD object diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdTripleCallback.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdTripleCallback.java index 5fb9ff11..f626bf24 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdTripleCallback.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdTripleCallback.java @@ -1,9 +1,9 @@ package com.github.jsonldjava.core; /** - * + * * @author Tristan - * + * * TODO: in the JSONLD RDF API the callback we're representing here is * QuadCallback which takes a list of quads (subject, predicat, object, * graph). for the moment i'm just going to use the dataset provided by @@ -13,18 +13,18 @@ public interface JsonLdTripleCallback { /** * Construct output based on internal RDF dataset format - * + * * @param dataset * The format of the dataset is a Map with the following * structure: { GRAPH_1: [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ], * GRAPH_2: [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ], ... GRAPH_N: [ * TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ] } - * + * * GRAPH: Is the graph name/IRI. if no graph is present for a * triple, it will be listed under the "@default" graph TRIPLE: * Is a map with the following structure: { "subject" : SUBJECT * "predicate" : PREDICATE "object" : OBJECT } - * + * * Each of the values in the triple map are also maps with the * following key-value pairs: "value" : The value of the node. * "subject" can be an IRI or blank node id. "predicate" should @@ -37,7 +37,7 @@ public interface JsonLdTripleCallback { * literal "datatype" : the datatype of the literal. (if not set * will default to XSD:string, if set to null, null will be * used). - * + * * @return the resulting RDF object in the desired format */ public Object call(RDFDataset dataset); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index e148b45b..890f8751 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -18,11 +18,11 @@ public class JsonLdUtils { /** * Returns whether or not the given value is a keyword (or a keyword alias). - * + * * @param v * the value to check. * @param [ctx] the active context to check against. - * + * * @return true if the value is a keyword, false if not. */ static boolean isKeyword(Object key) { @@ -145,10 +145,10 @@ public static boolean isAbsoluteIri(String value) { /** * Returns true if the given value is a subject with properties. - * + * * @param v * the value to check. - * + * * @return true if the value is a subject with properties, false if not. */ static boolean isNode(Object v) { @@ -166,10 +166,10 @@ static boolean isNode(Object v) { /** * Returns true if the given value is a subject reference. - * + * * @param v * the value to check. - * + * * @return true if the value is a subject reference, false if not. */ static boolean isNodeReference(Object v) { @@ -193,11 +193,11 @@ public static boolean isRelativeIri(String value) { /** * Adds a value to a subject. If the value is an array, all values in the * array will be added. - * + * * Note: If the value is a subject that already exists as a property of the * given subject, this method makes no attempt to deeply merge properties. * Instead, the value will not be added. - * + * * @param subject * the subject to add the value to. * @param property @@ -258,14 +258,14 @@ static void addValue(Map subject, String property, Object value) /** * Prepends a base IRI to the given relative IRI. - * + * * @param base * the base IRI. * @param iri * the relative IRI. - * + * * @return the absolute IRI. - * + * * TODO: the JsonLdUrl class isn't as forgiving as the Node.js url * parser, we may need to re-implement the parser here to support * the flexibility required @@ -336,10 +336,10 @@ private static String prependBase(Object baseobj, String iri) { /** * Expands a language map. - * + * * @param languageMap * the language map to expand. - * + * * @return the expanded language map. * @throws JsonLdError */ @@ -371,7 +371,7 @@ static List expandLanguageMap(Map languageMap) throws Js /** * Throws an exception if the given value is not a valid @type value. - * + * * @param v * the value to check. * @throws JsonLdError @@ -409,12 +409,12 @@ static boolean validateTypeValue(Object v) throws JsonLdError { /** * Removes a base IRI from the given absolute IRI. - * + * * @param base * the base IRI. * @param iri * the absolute IRI. - * + * * @return the relative IRI if relative to base, otherwise the absolute IRI. */ private static String removeBase(Object baseobj, String iri) { @@ -493,14 +493,14 @@ else if (iri.indexOf("//") != 0) { /** * Removes the @preserve keywords as the last step of the framing algorithm. - * + * * @param ctx * the active context used to compact the input. * @param input * the framed, compacted output. * @param options * the compaction options used. - * + * * @return the resulting output. * @throws JsonLdError */ @@ -553,7 +553,7 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro /** * replicate javascript .join because i'm too lazy to keep doing it manually - * + * * @param iriSegments * @param string * @return @@ -572,7 +572,7 @@ private static String _join(List list, String joiner) { /** * replicates the functionality of javascript .split, which has different * results to java's String.split if there is a trailing / - * + * * @param string * @param delim * @return @@ -589,12 +589,12 @@ private static List _split(String string, String delim) { /** * Compares two strings first based on length and then lexicographically. - * + * * @param a * the first string. * @param b * the second string. - * + * * @return -1 if a < b, 1 if a > b, 0 if a == b. */ static int compareShortestLeast(String a, String b) { @@ -608,14 +608,14 @@ static int compareShortestLeast(String a, String b) { /** * Determines if the given value is a property of the given subject. - * + * * @param subject * the subject to check. * @param property * the property to check. * @param value * the value to check. - * + * * @return true if the value exists, false if not. */ static boolean hasValue(Map subject, String property, Object value) { @@ -652,16 +652,16 @@ private static boolean hasProperty(Map subject, String property) /** * Compares two JSON-LD values for equality. Two JSON-LD values will be * considered equal if: - * + * * 1. They are both primitives of the same type and value. 2. They are both @values * with the same @value, @type, and @language, OR 3. They both have @ids * they are the same. - * + * * @param v1 * the first value. * @param v2 * the second value. - * + * * @return true if v1 and v2 are considered equal, false if not. */ static boolean compareValues(Object v1, Object v2) { @@ -673,12 +673,12 @@ static boolean compareValues(Object v1, Object v2) { && isValue(v2) && Obj.equals(((Map) v1).get("@value"), ((Map) v2).get("@value")) - && Obj.equals(((Map) v1).get("@type"), - ((Map) v2).get("@type")) - && Obj.equals(((Map) v1).get("@language"), - ((Map) v2).get("@language")) - && Obj.equals(((Map) v1).get("@index"), - ((Map) v2).get("@index"))) { + && Obj.equals(((Map) v1).get("@type"), + ((Map) v2).get("@type")) + && Obj.equals(((Map) v1).get("@language"), + ((Map) v2).get("@language")) + && Obj.equals(((Map) v1).get("@index"), + ((Map) v2).get("@index"))) { return true; } @@ -694,7 +694,7 @@ && isValue(v2) /** * Removes a value from a subject. - * + * * @param subject * the subject. * @param property @@ -735,10 +735,10 @@ static void removeValue(Map subject, String property, /** * Returns true if the given value is a blank node. - * + * * @param v * the value to check. - * + * * @return true if the value is a blank node, false if not. */ static boolean isBlankNode(Object v) { @@ -760,7 +760,7 @@ static boolean isBlankNode(Object v) { /** * Finds all @context URLs in the given JSON-LD input. - * + * * @param input * the JSON-LD input. * @param urls @@ -768,7 +768,7 @@ static boolean isBlankNode(Object v) { * @param replace * true to replace the URLs in the given input with the * @contexts from the urls map, false not to. - * + * * @return true if new URLs to resolve were found, false if not. */ private static boolean findContextUrls(Object input, Map urls, Boolean replace) { @@ -862,7 +862,7 @@ static Object clone(Object value) {// throws /** * Returns true if the given value is a JSON-LD Array - * + * * @param v * the value to check. * @return @@ -873,7 +873,7 @@ static Boolean isArray(Object v) { /** * Returns true if the given value is a JSON-LD List - * + * * @param v * the value to check. * @return @@ -884,7 +884,7 @@ static Boolean isList(Object v) { /** * Returns true if the given value is a JSON-LD Object - * + * * @param v * the value to check. * @return @@ -895,7 +895,7 @@ static Boolean isObject(Object v) { /** * Returns true if the given value is a JSON-LD value - * + * * @param v * the value to check. * @return @@ -906,7 +906,7 @@ static Boolean isValue(Object v) { /** * Returns true if the given value is a JSON-LD string - * + * * @param v * the value to check. * @return diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index 100a377e..96382edc 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -106,11 +106,11 @@ public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { } } normalized - .add(toNQuad( - (RDFDataset.Quad) quad, - quad.containsKey("name") - && quad.get("name") != null ? (String) ((Map) quad - .get("name")).get("value") : null)); + .add(toNQuad( + (RDFDataset.Quad) quad, + quad.containsKey("name") + && quad.get("name") != null ? (String) ((Map) quad + .get("name")).get("value") : null)); } // sort normalized output @@ -211,7 +211,7 @@ private static class HashResult { * incorporating all information about its subgraph of bnodes. This method * will recursively pick adjacent bnode permutations that produce the * lexicographically-least 'path' serializations. - * + * * @param id * the ID of the bnode to hash paths for. * @param bnodes @@ -413,14 +413,14 @@ private static HashResult hashPaths(String id, Map bnodes, Uniqu /** * Hashes all of the quads about a blank node. - * + * * @param id * the ID of the bnode to hash quads for. * @param bnodes * the mapping of bnodes to quads. * @param namer * the canonical bnode namer. - * + * * @return the new hash. */ private static String hashQuads(String id, Map bnodes, UniqueNamer namer) { @@ -448,7 +448,7 @@ private static String hashQuads(String id, Map bnodes, UniqueNam /** * A helper class to sha1 hash all the strings in a collection - * + * * @param nquads * @return */ @@ -480,18 +480,18 @@ private static String encodeHex(final byte[] data) { * A helper function that gets the blank node name from an RDF quad node * (subject or object). If the node is a blank node and its value does not * match the given blank node ID, it will be returned. - * + * * @param node * the RDF quad node. * @param id * the ID of the blank node to look next to. - * + * * @return the adjacent blank node name or null if none was found. */ private static String getAdjacentBlankNodeName(Map node, String id) { return "blank node".equals(node.get("type")) && (!node.containsKey("value") || !Obj.equals(node.get("value"), id)) ? (String) node - .get("value") : null; + .get("value") : null; } private static class Permutator { @@ -512,7 +512,7 @@ public Permutator(List list) { /** * Returns true if there is another permutation. - * + * * @return true if there is another permutation, false if not. */ public boolean hasNext() { @@ -522,7 +522,7 @@ public boolean hasNext() { /** * Gets the next permutation. Call hasNext() to ensure there is another * one first. - * + * * @return the next permutation. */ public List next() { diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 0b6b86ca..e1bf55c1 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -32,9 +32,9 @@ * dataset store. Currently each item just wraps a Map based on the old format * so everything doesn't break. Will phase this out once everything is using the * new format. - * + * * @author Tristan - * + * */ public class RDFDataset extends LinkedHashMap { private static final long serialVersionUID = 2796344994239879165L; @@ -113,7 +113,7 @@ public int compareTo(Quad o) { } public static abstract class Node extends LinkedHashMap implements - Comparable { + Comparable { private static final long serialVersionUID = 1460990331795672793L; public abstract boolean isLiteral(); @@ -155,12 +155,12 @@ public int compareTo(Node o) { /** * Converts an RDF triple object to a JSON-LD object. - * + * * @param o * the RDF triple object to convert. * @param useNativeTypes * true to output native types, false not to. - * + * * @return the JSON-LD object. * @throws JsonLdError */ @@ -198,9 +198,9 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { rval.put("@type", type); } } else if ( - // http://www.w3.org/TR/xmlschema11-2/#integer - (XSD_INTEGER.equals(type) && PATTERN_INTEGER.matcher(value).matches()) - // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep + // http://www.w3.org/TR/xmlschema11-2/#integer + (XSD_INTEGER.equals(type) && PATTERN_INTEGER.matcher(value).matches()) + // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep || (XSD_DOUBLE.equals(type) && PATTERN_DOUBLE.matcher(value).matches())) { try { final Double d = Double.parseDouble(value); @@ -361,7 +361,7 @@ public RDFDataset() { /* * public RDFDataset(String blankNodePrefix) { this(new * UniqueNamer(blankNodePrefix)); } - * + * * public RDFDataset(UniqueNamer namer) { this(); this.namer = namer; } */ public RDFDataset(JsonLdApi jsonLdApi) { @@ -390,7 +390,7 @@ public Map getNamespaces() { /** * Returns a valid context containing any namespaces set - * + * * @return The context map */ public Map getContext() { @@ -405,7 +405,7 @@ public Map getContext() { /** * parses a context object and sets any namespaces found within it - * + * * @param contextLike * The context to parse * @throws JsonLdError @@ -441,7 +441,7 @@ public void parseContext(Object contextLike) throws JsonLdError { /** * Adds a triple to the @default graph of this dataset - * + * * @param subject * the subject for the triple * @param predicate @@ -461,7 +461,7 @@ public void addTriple(final String subject, final String predicate, final String /** * Adds a triple to the specified graph of this dataset - * + * * @param s * the subject for the triple * @param p @@ -489,7 +489,7 @@ public void addQuad(final String s, final String p, final String value, final St /** * Adds a triple to the default graph of this dataset - * + * * @param subject * the subject for the triple * @param predicate @@ -503,7 +503,7 @@ public void addTriple(final String subject, final String predicate, final String /** * Adds a triple to the specified graph of this dataset - * + * * @param subject * the subject for the triple * @param predicate @@ -526,7 +526,7 @@ public void addQuad(final String subject, final String predicate, final String o /** * Creates an array of RDF triples for the given graph. - * + * * @param graphName * The graph URI * @param graph @@ -623,7 +623,7 @@ else if (JsonLdUtils.isRelativeIri(property)) { /** * Converts a JSON-LD value object to an RDF literal or a JSON-LD string or * node object to an RDF resource. - * + * * @param item * the JSON-LD value or node object. * @return the RDF literal or RDF resource. diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 3d592ea0..c3e512b3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -20,7 +20,6 @@ import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -31,12 +30,12 @@ public class RDFDatasetUtils { /** * Creates an array of RDF triples for the given graph. - * + * * @param graph * the graph to create RDF triples for. * @param namer * a UniqueNamer for assigning blank node names. - * + * * @return the array of RDF triples for the given graph. * @deprecated Use {@link RDFDataset#graphToRDF(String, Map)} instead */ @@ -95,7 +94,7 @@ static List graphToRDF(Map graph, UniqueNamer namer) { /** * Converts a @list value into linked list of blank node RDF triples (an RDF * collection). - * + * * @param list * the @list value. * @param namer @@ -156,12 +155,12 @@ private static void listToRDF(List list, UniqueNamer namer, /** * Converts a JSON-LD value object to an RDF literal or a JSON-LD string or * node object to an RDF resource. - * + * * @param item * the JSON-LD value or node object. * @param namer * the UniqueNamer to use to assign blank node names. - * + * * @return the RDF literal or RDF resource. */ private static Object objectToRDF(Object item, UniqueNamer namer) { @@ -316,8 +315,8 @@ public static String unescape(String str) { if (m.group(1) == null) { final String hex = m.group(2) != null ? m.group(2) : m.group(3); final int v = Integer.parseInt(hex, 16);// hex = - // hex.replaceAll("^(?:00)+", - // ""); + // hex.replaceAll("^(?:00)+", + // ""); if (v > 0xFFFF) { // deal with UTF-32 // Integer v = Integer.parseInt(hex, 16); @@ -380,16 +379,16 @@ public static String escape(String str) { final char hi = str.charAt(i); if (hi <= 0x8 || hi == 0xB || hi == 0xC || (hi >= 0xE && hi <= 0x1F) || (hi >= 0x7F && hi <= 0xA0) || // 0xA0 is end of - // non-printable latin-1 - // supplement - // characters + // non-printable latin-1 + // supplement + // characters ((hi >= 0x24F // 0x24F is the end of latin extensions && !Character.isHighSurrogate(hi)) // TODO: there's probably a lot of other characters that // shouldn't be escaped that // fall outside these ranges, this is one example from the // json-ld tests - )) { + )) { rval += String.format("\\u%04x", (int) hi); } else if (Character.isHighSurrogate(hi)) { final char lo = str.charAt(++i); @@ -412,9 +411,9 @@ public static String escape(String str) { case '\r': rval += "\\r"; break; - // case '\'': - // rval += "\\'"; - // break; + // case '\'': + // rval += "\\'"; + // break; case '\"': rval += "\\\""; // rval += "\\u0022"; @@ -463,10 +462,10 @@ private static class Regex { /** * Parses RDF in the form of N-Quads. - * + * * @param input * the N-Quads input to parse. - * + * * @return an RDF dataset. * @throws JsonLdError * If there was an error parsing the N-Quads document. diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFParser.java b/core/src/main/java/com/github/jsonldjava/core/RDFParser.java index bc54d36c..4b6fed61 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFParser.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFParser.java @@ -3,9 +3,9 @@ /** * Interface for parsing RDF into the RDF Dataset objects to be used by * JSONLD.fromRDF - * + * * @author Tristan - * + * */ public interface RDFParser { @@ -14,12 +14,12 @@ public interface RDFParser { * with the following structure: { GRAPH_1: [ TRIPLE_1, TRIPLE_2, ..., * TRIPLE_N ], GRAPH_2: [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ], ... GRAPH_N: * [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ] } - * + * * GRAPH: Must be the graph name/IRI. if no graph is present for a triple, * add it to the "@default" graph TRIPLE: Must be a map with the following * structure: { "subject" : SUBJECT "predicate" : PREDICATE "object" : * OBJECT } - * + * * Each of the values in the triple map must also be a map with the * following key-value pairs: "value" : The value of the node. "subject" can * be an IRI or blank node id. "predicate" should only ever be an IRI @@ -30,13 +30,13 @@ public interface RDFParser { * key-value pairs: "language" : the language value of a string literal * "datatype" : the datatype of the literal. (if not set will default to * XSD:string, if set to null, null will be used). - * + * * The RDFDatasetUtils class has the following helper methods to make * generating this format easier: result = getInitialRDFDatasetResult(); * triple = generateTriple(s,p,o); triple = * generateTriple(s,p,value,datatype,language); * addTripleToRDFDatasetResult(result, graphName, triple); - * + * * @param input * The RDF library specific input to parse * @return The input parsed using the internal RDF Dataset format diff --git a/core/src/main/java/com/github/jsonldjava/core/Regex.java b/core/src/main/java/com/github/jsonldjava/core/Regex.java index f95cea78..a34a1ee7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Regex.java +++ b/core/src/main/java/com/github/jsonldjava/core/Regex.java @@ -4,8 +4,8 @@ public class Regex { final public static Pattern TRICKY_UTF_CHARS = Pattern.compile( - // ("1.7".equals(System.getProperty("java.specification.version")) ? - // "[\\x{10000}-\\x{EFFFF}]" : + // ("1.7".equals(System.getProperty("java.specification.version")) ? + // "[\\x{10000}-\\x{EFFFF}]" : "[\uD800\uDC00-\uDB7F\uDFFF]" // this seems to work with jdk1.6 ); // for ttl diff --git a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java index 46fc7c81..98e2fb45 100644 --- a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java +++ b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java @@ -11,7 +11,7 @@ public class UniqueNamer { /** * Creates a new UniqueNamer. A UniqueNamer issues unique names, keeping * track of any previously issued names. - * + * * @param prefix * the prefix to use ('<prefix><counter>'). */ @@ -23,7 +23,7 @@ public UniqueNamer(String prefix) { /** * Copies this UniqueNamer. - * + * * @return a copy of this UniqueNamer. */ @Override @@ -37,10 +37,10 @@ public UniqueNamer clone() { /** * Gets the new name for the given old name, where if no old name is given a * new name will be generated. - * + * * @param oldName * the old name to get the new name for. - * + * * @return the new name. */ public String getName(String oldName) { diff --git a/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java b/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java index bbb384b1..ab2959e6 100644 --- a/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java +++ b/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java @@ -42,11 +42,11 @@ /** * A (probably terribly slow) Parser for turtle. Turtle is the internal * RDFDataset used by JSOND-Java - * + * * TODO: this probably needs to be changed to use a proper parser/lexer - * + * * @author Tristan - * + * */ public class TurtleRDFParser implements RDFParser { @@ -109,9 +109,9 @@ private class State { // int bnodes = 0; UniqueNamer namer = new UniqueNamer("_:b");// {{ getName(); }}; // call - // getName() after - // construction to make - // first active bnode _:b1 + // getName() after + // construction to make + // first active bnode _:b1 private final Stack> stack = new Stack>(); public boolean expectingBnodeClose = false; @@ -180,7 +180,7 @@ public void advanceLinePosition(int len) throws JsonLdError { if ("".equals(line) && !endIsOK()) { throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, "Error while parsing Turtle; unexpected end of input. {line: " + lineNumber - + ", position:" + linePosition + "}"); + + ", position:" + linePosition + "}"); } } @@ -450,7 +450,7 @@ else if (state.line.startsWith("(")) { if (!RDF_FIRST.equals(state.curPredicate)) { throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, "Error while parsing Turtle; unexpected ). {line: " + state.lineNumber - + "position: " + state.linePosition + "}"); + + "position: " + state.linePosition + "}"); } result.addTriple(state.curSubject, RDF_REST, RDF_NIL); state.pop(); diff --git a/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java b/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java index 67705ad4..92e4aad7 100644 --- a/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java +++ b/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java @@ -27,8 +27,8 @@ public class TurtleTripleCallback implements JsonLdTripleCallback { private static final int MAX_LINE_LENGTH = 160; private static final int TAB_SPACES = 4; private static final String COLS_KEY = "..cols.."; // this shouldn't be a - // valid iri/bnode i - // hope! + // valid iri/bnode i + // hope! final Map availableNamespaces = new LinkedHashMap() { { // TODO: fill with default namespaces @@ -330,7 +330,7 @@ private String generateTurtle(Map>> ttl, int in if (!isObject) { rval += " .\n"; if (subjIter.hasNext()) { // add blank space if we have another - // object below this + // object below this rval += "\n"; } } @@ -351,7 +351,7 @@ private String tabs(int tabs) { /** * checks the URI for a prefix, and if one is found, set used prefixes to * true - * + * * @param predicate * @return */ diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 181ed3df..04977867 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -122,7 +122,7 @@ private Enumeration getResources() throws IOException { /** * Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) to a * SoftReference to its content as JsonNode. - * + * * @see #getJarCache(URL) */ protected ConcurrentMap> jarCaches = new ConcurrentHashMap>(); @@ -176,7 +176,7 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach final List
responseHeaders = new ArrayList
(); if (!cacheNode.has(HTTP.DATE_HEADER)) { responseHeaders - .add(new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()))); + .add(new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()))); } if (!cacheNode.has(HeaderConstants.CACHE_CONTROL)) { responseHeaders.add(new BasicHeader(HeaderConstants.CACHE_CONTROL, @@ -202,7 +202,7 @@ public void removeEntry(String key) throws IOException { @Override public void updateEntry(String key, HttpCacheUpdateCallback callback) throws IOException, - HttpCacheUpdateException { + HttpCacheUpdateException { // ignored } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java index 0051b099..b7a316c4 100755 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java @@ -104,7 +104,7 @@ public static JsonLdUrl parse(String url) { /** * Removes dot segments from a JsonLdUrl path. - * + * * @param path * the path to remove dot segments from. * @param hasAuthority @@ -286,7 +286,7 @@ public static String resolve(String baseUri, String pathToResolve) { /** * Parses the authority for the pre-parsed given JsonLdUrl. - * + * * @param parsed * the pre-parsed JsonLdUrl. */ diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 8b9dfa41..31b98636 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -25,9 +25,9 @@ /** * Functions used to make loading, parsing, and serializing JSON easy using * Jackson. - * + * * @author tristan - * + * */ public class JsonUtils { /** @@ -54,7 +54,7 @@ public class JsonUtils { * that can be used as input for the {@link JsonLdApi} and * {@link JsonLdProcessor} methods.
* Uses UTF-8 as the character encoding when decoding the InputStream. - * + * * @param input * The JSON-LD document in an InputStream. * @return A JSON Object. @@ -72,7 +72,7 @@ public static Object fromInputStream(InputStream input) throws IOException { * Parses a JSON-LD document from the given {@link InputStream} to an object * that can be used as input for the {@link JsonLdApi} and * {@link JsonLdProcessor} methods. - * + * * @param input * The JSON-LD document in an InputStream. * @param enc @@ -92,7 +92,7 @@ public static Object fromInputStream(InputStream input, String enc) throws IOExc * Parses a JSON-LD document from the given {@link Reader} to an object that * can be used as input for the {@link JsonLdApi} and * {@link JsonLdProcessor} methods. - * + * * @param reader * The JSON-LD document in a Reader. * @return A JSON Object. @@ -129,7 +129,7 @@ public static Object fromReader(Reader reader) throws IOException { /** * Parses a JSON-LD document from a string to an object that can be used as * input for the {@link JsonLdApi} and {@link JsonLdProcessor} methods. - * + * * @param jsonString * The JSON-LD document as a string. * @return A JSON Object. @@ -146,7 +146,7 @@ public static Object fromString(String jsonString) throws JsonParseException, IO * Parses a JSON-LD document, from the contents of the JSON resource * resolved from the JsonLdUrl, to an object that can be used as input for * the {@link JsonLdApi} and {@link JsonLdProcessor} methods. - * + * * @param url * The JsonLdUrl to resolve * @return A JSON Object. @@ -162,7 +162,7 @@ public static Object fromURL(java.net.URL url) throws JsonParseException, IOExce /** * Writes the given JSON-LD Object out to a String, using indentation and * new lines to improve readability. - * + * * @param jsonObject * The JSON-LD Object to serialize. * @return A JSON document serialised to a String. @@ -172,7 +172,7 @@ public static Object fromURL(java.net.URL url) throws JsonParseException, IOExce * If there is an IO error during serialization. */ public static String toPrettyString(Object jsonObject) throws JsonGenerationException, - IOException { + IOException { final StringWriter sw = new StringWriter(); writePrettyPrint(sw, jsonObject); return sw.toString(); @@ -180,7 +180,7 @@ public static String toPrettyString(Object jsonObject) throws JsonGenerationExce /** * Writes the given JSON-LD Object out to a String. - * + * * @param jsonObject * The JSON-LD Object to serialize. * @return A JSON document serialised to a String. @@ -197,7 +197,7 @@ public static String toString(Object jsonObject) throws JsonGenerationException, /** * Writes the given JSON-LD Object out to the given Writer. - * + * * @param writer * The writer that is to receive the serialized JSON-LD object. * @param jsonObject @@ -208,7 +208,7 @@ public static String toString(Object jsonObject) throws JsonGenerationException, * If there is an IO error during serialization. */ public static void write(Writer writer, Object jsonObject) throws JsonGenerationException, - IOException { + IOException { final JsonGenerator jw = JSON_FACTORY.createGenerator(writer); jw.writeObject(jsonObject); } @@ -216,7 +216,7 @@ public static void write(Writer writer, Object jsonObject) throws JsonGeneration /** * Writes the given JSON-LD Object out to the given Writer, using * indentation and new lines to improve readability. - * + * * @param writer * The writer that is to receive the serialized JSON-LD object. * @param jsonObject diff --git a/core/src/main/java/com/github/jsonldjava/utils/Obj.java b/core/src/main/java/com/github/jsonldjava/utils/Obj.java index 87656583..a7f371de 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/Obj.java +++ b/core/src/main/java/com/github/jsonldjava/utils/Obj.java @@ -7,7 +7,7 @@ public class Obj { /** * Helper function for creating maps and tuning them as necessary. - * + * * @return A new {@link Map} instance. */ public static Map newMap() { @@ -16,7 +16,7 @@ public static Map newMap() { /** * Helper function for creating maps and tuning them as necessary. - * + * * @param key * A key to add to the map on creation. * @param value @@ -24,7 +24,7 @@ public static Map newMap() { * @return A new {@link Map} instance. */ public static Map newMap(String key, Object value) { - Map result = newMap(); + final Map result = newMap(); result.put(key, value); return result; } @@ -32,7 +32,7 @@ public static Map newMap(String key, Object value) { /** * Used to make getting values from maps embedded in maps embedded in maps * easier TODO: roll out the loops for efficiency - * + * * @param map * The map to get a key from * @param keys @@ -93,7 +93,7 @@ public static Object remove(Object map, String k1, String k2) { /** * A null-safe equals check using v1.equals(v2) if they are both not null. - * + * * @param v1 * The source object for the equals check. * @param v2 diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 667f5d57..baa72e88 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.core; @@ -13,16 +13,16 @@ import com.github.jsonldjava.utils.JsonUtils; /** - * + * * @author Peter Ansell p_ansell@yahoo.com */ public class JsonLdPerformanceTest { /** * Test performance parsing using test data from: - * + * * https://dl.dropboxusercontent.com/s/yha7x0paj8zvvz5/2000007922.jsonld.gz - * + * * @throws Exception */ @Ignore("Enable as necessary for manual testing, particularly to test that it fails due to irregular URIs") diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 4a16a93e..d1562ec4 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -156,7 +156,7 @@ public static void prepareReportFrame() { @AfterClass public static void writeReport() throws JsonGenerationException, JsonMappingException, - IOException, JsonLdError { + IOException, JsonLdError { // Only write reports if "-Dreport.format=..." is set String reportFormat = System.getProperty("report.format"); @@ -581,7 +581,7 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { { put("@id", "http://json-ld.org/test-suite/tests/error-expand-manifest.jsonld" - .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); + .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); } }); } diff --git a/core/src/test/java/com/github/jsonldjava/core/RegexTest.java b/core/src/test/java/com/github/jsonldjava/core/RegexTest.java index abd4b239..89854f85 100644 --- a/core/src/test/java/com/github/jsonldjava/core/RegexTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/RegexTest.java @@ -19,9 +19,9 @@ public void test_TRICKY_UTF_CHARS() throws IOException { final char[] u1 = Character.toChars(i); // char[] u2 = Character.toChars(0xeffff); final String test = Character.toString(u1[0]) + Character.toString(u1[1]);// + - // Character.toString(u2[0]) - // + - // Character.toString(u2[1]); + // Character.toString(u2[0]) + // + + // Character.toString(u2[1]); // Matcher matcher = Regex.TRICKY_UTF_CHARS.matcher(test); // while (matcher.find()) { // String s = matcher.group(0); @@ -212,8 +212,7 @@ public void test_unescape() { @Test public void testDoubleRegex() throws Exception { - assertTrue(Pattern.matches( - "^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?$", + assertTrue(Pattern.matches("^(\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?$", "1.1E-1")); } } diff --git a/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java b/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java index e3d32b4b..7c16d507 100644 --- a/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java +++ b/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java @@ -108,10 +108,10 @@ public void simpleTest() throws JsonLdError { }; final Object json = null; /* - * JsonLdProcessor.fromRDF(input, new - * JsonLdOptions() { { format = "text/turtle"; - * } }, new TurtleRDFParser()); - */ + * JsonLdProcessor.fromRDF(input, new + * JsonLdOptions() { { format = "text/turtle"; + * } }, new TurtleRDFParser()); + */ assertTrue(Obj.equals(expected, json)); } @@ -203,7 +203,7 @@ public void runTest() throws IOException, JsonLdError { /** * Compare datasets, normalizing the blank nodes and adding baseIRI to * relative IRIs - * + * * @param result * @param expected * @return @@ -409,7 +409,7 @@ public boolean isLocked(final String b) { /** * return either the locked mapping, or the highest matching - * + * * @param b * @return */ diff --git a/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java b/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java index 4b5f7911..23569186 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java +++ b/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java @@ -32,7 +32,7 @@ public EarlTestSuite(String manifestURL) throws IOException { /** * Loads an earl test suite - * + * * @param manifestURL * the JsonLdUrl of the manifest file * @param cacheDir diff --git a/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java b/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java index f73d26bc..2dcbb91e 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java +++ b/core/src/test/java/com/github/jsonldjava/utils/TestUtils.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.utils; @@ -16,7 +16,7 @@ /** * @author Peter Ansell p_ansell@yahoo.com - * + * */ public class TestUtils { diff --git a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java index 89fc4c08..e8b3c27f 100644 --- a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java +++ b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java @@ -21,7 +21,7 @@ /** * Implementation of {@link RDFParser} which serializes the contents of a * {@link ModelSet} or {@link Model} into a JSON-LD document. - * + * * @author Ismael Rivera */ public class RDF2GoRDFParser implements RDFParser { diff --git a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java index 2f75385a..a6cfa22a 100644 --- a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java +++ b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java @@ -14,7 +14,7 @@ /** * Implementation of {@link JsonLdTripleCallback} which serializes JSONLD * datasets into a {@link ModelSet} object. - * + * * @author Ismael Rivera */ public class RDF2GoTripleCallback implements JsonLdTripleCallback { diff --git a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java index a55556a2..c0ee196c 100644 --- a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java +++ b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java @@ -21,7 +21,7 @@ /** * Unit tests for {@link RDF2GoRDFParser} containing a single test, including * literals with datatype and language. - * + * * @author Ismael Rivera */ public class RDF2GoRDFParserTest { diff --git a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java index 246e403e..b93b62c2 100644 --- a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java +++ b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java @@ -16,7 +16,7 @@ /** * Unit tests for {@link RDF2GoTripleCallback}. - * + * * @author Ismael Rivera */ public class RDF2GoTripleCallbackTest { diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java index 37fe682c..4e7d9483 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.sesame; @@ -23,9 +23,9 @@ /** * An {@link RDFParser} that links to {@link SesameTripleCallback}. - * + * * @author Peter Ansell p_ansell@yahoo.com - * + * */ public class SesameJSONLDParser extends RDFParserBase implements RDFParser { @@ -39,7 +39,7 @@ public SesameJSONLDParser() { /** * Creates a Sesame JSONLD Parser using the given {@link ValueFactory} to * create new {@link Value}s. - * + * * @param valueFactory * The ValueFactory to use */ @@ -54,7 +54,7 @@ public RDFFormat getRDFFormat() { @Override public void parse(final InputStream in, final String baseURI) throws IOException, - RDFParseException, RDFHandlerException { + RDFParseException, RDFHandlerException { final SesameTripleCallback callback = new SesameTripleCallback(getRDFHandler(), valueFactory, getParserConfig(), getParseErrorListener()); @@ -77,7 +77,7 @@ public void parse(final InputStream in, final String baseURI) throws IOException @Override public void parse(final Reader reader, final String baseURI) throws IOException, - RDFParseException, RDFHandlerException { + RDFParseException, RDFHandlerException { final SesameTripleCallback callback = new SesameTripleCallback(getRDFHandler(), valueFactory, getParserConfig(), getParseErrorListener()); diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java index d63fc476..9306d7f4 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.sesame; @@ -10,7 +10,7 @@ /** * An {@link RDFParserFactory} that creates instances of * {@link SesameJSONLDParser}. - * + * * @author Peter Ansell p_ansell@yahoo.com */ public class SesameJSONLDParserFactory implements RDFParserFactory { diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java index ac3d87a8..13670149 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.sesame; @@ -36,7 +36,7 @@ /** * @author Peter Ansell p_ansell@yahoo.com - * + * */ public class SesameJSONLDWriter extends RDFWriterBase implements RDFWriter { @@ -48,7 +48,7 @@ public class SesameJSONLDWriter extends RDFWriterBase implements RDFWriter { /** * Create a SesameJSONLDWriter using a {@link java.io.OutputStream} - * + * * @param outputStream * The OutputStream to write to. */ @@ -58,7 +58,7 @@ public SesameJSONLDWriter(OutputStream outputStream) { /** * Create a SesameJSONLDWriter using a {@link java.io.Writer} - * + * * @param writer * The Writer to write to. */ diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java index ff8f92dd..6d4fe639 100644 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java +++ b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.sesame; @@ -13,7 +13,7 @@ /** * An {@link RDFWriterFactory} that creates instances of * {@link SesameJSONLDWriter}. - * + * * @author Peter Ansell p_ansell@yahoo.com */ public class SesameJSONLDWriterFactory implements RDFWriterFactory { diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java index 2e4b23a5..68eef817 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java @@ -18,39 +18,39 @@ public class SesameEmptyPrefixTest { @Test public void testEmptyPrefixDefault() throws Exception { - String input = "@prefix : ." + final String input = "@prefix : ." + "@prefix dc: ." + " :G { " + " dc:isVersionOf . }"; - Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); + final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); - StringWriter output = new StringWriter(); + final StringWriter output = new StringWriter(); Rio.write(parse, output, RDFFormat.JSONLD); System.out.println(output); - Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + final Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); assertTrue(ModelUtil.equals(parse, reparse)); } @Test public void testEmptyPrefixCompact() throws Exception { - String input = "@prefix : ." + final String input = "@prefix : ." + "@prefix dc: ." + " :G { " + " dc:isVersionOf . }"; - Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); + final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); - WriterConfig config = new WriterConfig(); + final WriterConfig config = new WriterConfig(); config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); - StringWriter output = new StringWriter(); + final StringWriter output = new StringWriter(); Rio.write(parse, output, RDFFormat.JSONLD, config); System.out.println(output); - Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + final Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); assertTrue(ModelUtil.equals(parse, reparse)); } diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java index 21232d56..4545b13a 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.sesame; @@ -19,7 +19,7 @@ /** * Unit tests for {@link SesameJSONLDParser} related to handling of datatypes * and languages. - * + * * @author Peter Ansell p_ansell@yahoo.com */ public class SesameJSONLDParserHandlerTest extends AbstractParserHandlingTest { @@ -54,7 +54,7 @@ protected RDFParser getParser() { /** * Helper method to write the given model to JSON-LD and return an * InputStream containing the results. - * + * * @param statements * @return An {@link InputStream} containing the results. * @throws RDFHandlerException diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java index f323c37f..32d7f776 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java @@ -1,5 +1,5 @@ /** - * + * */ package com.github.jsonldjava.sesame; @@ -63,39 +63,38 @@ public void testRoundTrip() throws Exception { @Ignore("Sesame-2.7 does not support RDF-1.1, so string/langString literals cause this to fail.") public void testRoundTripPreserveBNodeIds() throws Exception { } - + @Test @Override @Ignore("TODO: Determine why this test is breaking") - public void testIllegalPrefix() - throws RDFHandlerException, RDFParseException, IOException { + public void testIllegalPrefix() throws RDFHandlerException, RDFParseException, IOException { } - + @Test public void testRoundTripNamespaces() throws Exception { - String exNs = "http://example.org/"; - URI uri1 = vf.createURI(exNs, "uri1"); - URI uri2 = vf.createURI(exNs, "uri2"); - Literal plainLit = vf.createLiteral("plain", XMLSchema.STRING); + final String exNs = "http://example.org/"; + final URI uri1 = vf.createURI(exNs, "uri1"); + final URI uri2 = vf.createURI(exNs, "uri2"); + final Literal plainLit = vf.createLiteral("plain", XMLSchema.STRING); - Statement st1 = vf.createStatement(uri1, uri2, plainLit); + final Statement st1 = vf.createStatement(uri1, uri2, plainLit); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - RDFWriter rdfWriter = rdfWriterFactory.getWriter(out); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final RDFWriter rdfWriter = rdfWriterFactory.getWriter(out); rdfWriter.getWriterConfig().set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); rdfWriter.handleNamespace("ex", exNs); rdfWriter.startRDF(); rdfWriter.handleStatement(st1); rdfWriter.endRDF(); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - RDFParser rdfParser = rdfParserFactory.getParser(); - ParserConfig config = new ParserConfig(); + final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + final RDFParser rdfParser = rdfParserFactory.getParser(); + final ParserConfig config = new ParserConfig(); config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true); rdfParser.setParserConfig(config); rdfParser.setValueFactory(vf); - Model model = new LinkedHashModel(); + final Model model = new LinkedHashModel(); rdfParser.setRDFHandler(new StatementCollector(model)); rdfParser.parse(in, "foo:bar"); diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java index 3b062c85..45371964 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java @@ -15,7 +15,7 @@ /** * Test for locale-insensitive numeric representations that match the XML Schema * Datatype specification. - * + * * @author Peter Ansell p_ansell@yahoo.com * @see Github * issue #133 @@ -24,19 +24,20 @@ public class SesameLocaleNumericTest { @Test public void testLocaleUS() throws Exception { - Locale oldDefault = Locale.getDefault(); + final Locale oldDefault = Locale.getDefault(); try { Locale.setDefault(Locale.US); - String input = getTestString(); - Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); + final String input = getTestString(); + final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); - StringWriter output = new StringWriter(); + final StringWriter output = new StringWriter(); Rio.write(parse, output, RDFFormat.JSONLD); System.out.println(output); - Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + final Model reparse = Rio.parse(new StringReader(output.toString()), "", + RDFFormat.JSONLD); assertTrue(ModelUtil.equals(parse, reparse)); } finally { @@ -46,19 +47,20 @@ public void testLocaleUS() throws Exception { @Test public void testLocaleFrench() throws Exception { - Locale oldDefault = Locale.getDefault(); + final Locale oldDefault = Locale.getDefault(); try { Locale.setDefault(Locale.FRANCE); - String input = getTestString(); - Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); + final String input = getTestString(); + final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); - StringWriter output = new StringWriter(); + final StringWriter output = new StringWriter(); Rio.write(parse, output, RDFFormat.JSONLD); System.out.println(output); - Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); + final Model reparse = Rio.parse(new StringReader(output.toString()), "", + RDFFormat.JSONLD); assertTrue(ModelUtil.equals(parse, reparse)); } finally { diff --git a/tools/pom.xml b/tools/pom.xml index 84fae49e..a665fb5c 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -36,7 +36,7 @@ net.sf.jopt-simple jopt-simple - 4.6 + 4.8 org.openrdf.sesame diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index 3947992a..a1111f46 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -3,23 +3,14 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; -import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; -import java.util.regex.Pattern; - -import org.openrdf.model.Model; -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.RDFParserRegistry; -import org.openrdf.rio.Rio; import joptsimple.OptionException; import joptsimple.OptionParser; @@ -28,10 +19,13 @@ import joptsimple.ValueConversionException; import joptsimple.ValueConverter; -import com.github.jsonldjava.core.JsonLdError; +import org.openrdf.model.Model; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.RDFParserRegistry; +import org.openrdf.rio.Rio; + import com.github.jsonldjava.core.JsonLdOptions; import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.core.RDFDataset; import com.github.jsonldjava.sesame.SesameRDFParser; import com.github.jsonldjava.sesame.SesameTripleCallback; import com.github.jsonldjava.utils.JsonUtils; @@ -39,8 +33,8 @@ public class Playground { private static Set getProcessingOptions() { - return new LinkedHashSet(Arrays.asList("expand", "compact", - "frame", "normalize", "flatten", "fromrdf", "tordf")); + return new LinkedHashSet(Arrays.asList("expand", "compact", "frame", "normalize", + "flatten", "fromrdf", "tordf")); } private static boolean hasContext(String opt) { @@ -48,82 +42,79 @@ private static boolean hasContext(String opt) { } private static Map getOutputFormats() { - Map outputFormats = new HashMap(); - - for(RDFFormat format : RDFParserRegistry.getInstance().getKeys()) { - outputFormats.put(format.getName().replaceAll("-", "").replaceAll("/", "").toLowerCase(), format); + final Map outputFormats = new HashMap(); + + for (final RDFFormat format : RDFParserRegistry.getInstance().getKeys()) { + outputFormats.put(format.getName().replaceAll("-", "").replaceAll("/", "") + .toLowerCase(), format); } - + return outputFormats; } - + public static void main(String[] args) throws Exception { - + final Map formats = getOutputFormats(); - final Set outputForms = new LinkedHashSet(Arrays.asList("compacted", "expanded", "flattened")); - + final Set outputForms = new LinkedHashSet(Arrays.asList("compacted", + "expanded", "flattened")); + final OptionParser parser = new OptionParser(); - + final OptionSpec help = parser.accepts("help").forHelp(); - - final OptionSpec base = parser.accepts("base") - .withRequiredArg() - .ofType(String.class) - .defaultsTo("") - .describedAs("base URI"); - - final OptionSpec inputFile = - parser.accepts("inputFile") - .withRequiredArg() - .ofType(File.class) - .required() - .describedAs("The input file"); - - final OptionSpec context = - parser.accepts("context").withRequiredArg().ofType(File.class) - .describedAs("The context"); - - final OptionSpec outputFormat = - parser.accepts("format") - .withOptionalArg() - .ofType(String.class) - .withValuesConvertedBy(new ValueConverter() { - @Override - public RDFFormat convert(String arg0) { - // Normalise the name to provide alternatives - String formatName = arg0.replaceAll("-", "").replaceAll("/", "").toLowerCase(); - if(formats.containsKey(formatName)) { - return formats.get(formatName); - } - throw new ValueConversionException("Format was not known: " + arg0 + " (Valid values are: " + formats.keySet() + ")" - ); - } - - @Override - public String valuePattern() { - return null; - } - - @Override - public Class valueType() { - return RDFFormat.class; - } - }) - .describedAs( - "The output file format to use. Defaults to nquads. Valid values are: " + formats.keySet()); - - final OptionSpec processingOption = parser.accepts("process") + + final OptionSpec base = parser.accepts("base").withRequiredArg() + .ofType(String.class).defaultsTo("").describedAs("base URI"); + + final OptionSpec inputFile = parser.accepts("inputFile").withRequiredArg() + .ofType(File.class).required().describedAs("The input file"); + + final OptionSpec context = parser.accepts("context").withRequiredArg() + .ofType(File.class).describedAs("The context"); + + final OptionSpec outputFormat = parser + .accepts("format") + .withOptionalArg() + .ofType(String.class) + .withValuesConvertedBy(new ValueConverter() { + @Override + public RDFFormat convert(String arg0) { + // Normalise the name to provide alternatives + final String formatName = arg0.replaceAll("-", "").replaceAll("/", "") + .toLowerCase(); + if (formats.containsKey(formatName)) { + return formats.get(formatName); + } + throw new ValueConversionException("Format was not known: " + arg0 + + " (Valid values are: " + formats.keySet() + ")"); + } + + @Override + public String valuePattern() { + return null; + } + + @Override + public Class valueType() { + return RDFFormat.class; + } + }) + .describedAs( + "The output file format to use. Defaults to nquads. Valid values are: " + + formats.keySet()); + + final OptionSpec processingOption = parser + .accepts("process") .withRequiredArg() .ofType(String.class) .required() .withValuesConvertedBy(new ValueConverter() { @Override public String convert(String value) { - if(getProcessingOptions().contains(value.toLowerCase())) { + if (getProcessingOptions().contains(value.toLowerCase())) { return value.toLowerCase(); } - throw new ValueConversionException("Processing option was not known: " + value - + " (Valid values are: " + getProcessingOptions() + ")"); + throw new ValueConversionException("Processing option was not known: " + + value + " (Valid values are: " + getProcessingOptions() + ")"); } @Override @@ -136,19 +127,23 @@ public String valuePattern() { return null; } }) - .describedAs("The processing to perform. Valid values are: " + getProcessingOptions().toString()); - - final OptionSpec outputForm = parser.accepts("outputForm") + .describedAs( + "The processing to perform. Valid values are: " + + getProcessingOptions().toString()); + + final OptionSpec outputForm = parser + .accepts("outputForm") .withOptionalArg() .ofType(String.class) .defaultsTo("expanded") .withValuesConvertedBy(new ValueConverter() { @Override public String convert(String value) { - if(outputForms.contains(value.toLowerCase())) { + if (outputForms.contains(value.toLowerCase())) { return value.toLowerCase(); } - throw new ValueConversionException("Output form was not known: " + value + " (Valid values are: " + outputForms + ")"); + throw new ValueConversionException("Output form was not known: " + value + + " (Valid values are: " + outputForms + ")"); } @Override @@ -161,23 +156,21 @@ public Class valueType() { return String.class; } }) - .describedAs("The way to output the results from fromRDF. Defaults to expanded. Valid values are: " + outputForms); + .describedAs( + "The way to output the results from fromRDF. Defaults to expanded. Valid values are: " + + outputForms); OptionSet options = null; - - try - { + + try { options = parser.parse(args); - } - catch(final OptionException e) - { + } catch (final OptionException e) { System.out.println(e.getMessage()); parser.printHelpOn(System.out); throw e; } - - if(options.has(help)) - { + + if (options.has(help)) { parser.printHelpOn(System.out); return; } @@ -185,17 +178,21 @@ public Class valueType() { final JsonLdOptions opts = new JsonLdOptions(""); Object inobj = null; Object ctxobj = null; - + opts.setBase(options.valueOf(base)); opts.outputForm = options.valueOf(outputForm); - opts.format = options.has(outputFormat) ? options.valueOf(outputFormat).getDefaultMIMEType() : "application/nquads"; - RDFFormat sesameOutputFormat = options.has(outputFormat) ? options.valueOf(outputFormat) : RDFFormat.NQUADS; - RDFFormat sesameInputFormat = Rio.getParserFormatForFileName(options.valueOf(inputFile).getName(), RDFFormat.JSONLD); - - String processingOptionValue = options.valueOf(processingOption); - + opts.format = options.has(outputFormat) ? options.valueOf(outputFormat) + .getDefaultMIMEType() : "application/nquads"; + final RDFFormat sesameOutputFormat = options.has(outputFormat) ? options + .valueOf(outputFormat) : RDFFormat.NQUADS; + final RDFFormat sesameInputFormat = Rio.getParserFormatForFileName( + options.valueOf(inputFile).getName(), RDFFormat.JSONLD); + + final String processingOptionValue = options.valueOf(processingOption); + if (!options.valueOf(inputFile).exists()) { - System.out.println("Error: input file \"" + options.valueOf(inputFile) + "\" doesn't exist"); + System.out.println("Error: input file \"" + options.valueOf(inputFile) + + "\" doesn't exist"); parser.printHelpOn(System.out); return; } @@ -203,13 +200,13 @@ public Class valueType() { if (opts.getBase() == null || opts.getBase().equals("")) { opts.setBase(options.valueOf(inputFile).toURI().toASCIIString()); } - + if ("fromrdf".equals(processingOptionValue)) { inobj = readFile(options.valueOf(inputFile)); } else { inobj = JsonUtils.fromInputStream(new FileInputStream(options.valueOf(inputFile))); } - + if (hasContext(processingOptionValue) && options.has(context)) { if (!options.valueOf(context).exists()) { System.out.println("Error: context file \"" + options.valueOf(context) @@ -219,15 +216,18 @@ public Class valueType() { } ctxobj = JsonUtils.fromInputStream(new FileInputStream(options.valueOf(context))); } - + Object outobj = null; if ("fromrdf".equals(processingOptionValue)) { - Model inModel = Rio.parse(new StringReader((String) inobj), opts.getBase(), sesameInputFormat); - + final Model inModel = Rio.parse(new StringReader((String) inobj), opts.getBase(), + sesameInputFormat); + outobj = JsonLdProcessor.fromRDF(inModel, opts, new SesameRDFParser()); } else if ("tordf".equals(processingOptionValue)) { opts.useNamespaces = true; - outobj = JsonLdProcessor.toRDF(inobj, new SesameTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), opts); + outobj = JsonLdProcessor.toRDF(inobj, + new SesameTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), + opts); } else if ("expand".equals(processingOptionValue)) { outobj = JsonLdProcessor.expand(inobj, opts); } else if ("compact".equals(processingOptionValue)) { @@ -242,7 +242,7 @@ public Class valueType() { } else if ("frame".equals(processingOptionValue)) { if (ctxobj != null && !(ctxobj instanceof Map)) { System.out - .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); + .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); parser.printHelpOn(System.out); return; } @@ -250,14 +250,15 @@ public Class valueType() { } else if ("flatten".equals(processingOptionValue)) { outobj = JsonLdProcessor.flatten(inobj, ctxobj, opts); } else { - System.out.println("Error: invalid processing option \"" + processingOptionValue + "\""); + System.out + .println("Error: invalid processing option \"" + processingOptionValue + "\""); parser.printHelpOn(System.out); return; } if ("tordf".equals(processingOptionValue)) { // Already serialised above - } else if("normalize".equals(processingOptionValue)) { + } else if ("normalize".equals(processingOptionValue)) { System.out.println((String) outobj); } else { System.out.println(JsonUtils.toPrettyString(outobj)); @@ -272,7 +273,7 @@ private static String readFile(File in) throws IOException { String line; while ((line = buf.readLine()) != null) { line = line.trim(); - inobj = ((String) inobj) + line + "\n"; + inobj = (inobj) + line + "\n"; } } finally { buf.close(); @@ -280,30 +281,30 @@ private static String readFile(File in) throws IOException { return inobj; } -// private static void usage() { -// System.out.println("Usage: jsonldplayground "); -// System.out.println("\tinput: a filename or JsonLdUrl to the rdf input (in rdfxml or n3)"); -// System.out.println("\toptions:"); -// System.out -// .println("\t\t--ignorekeys : a (space separated) list of keys to ignore (e.g. @geojson)"); -// System.out.println("\t\t--base : base URI"); -// System.out.println("\t\t--debug: Print out stack traces when errors occur"); -// System.out.println("\t\t--expand : expand the input JSON-LD"); -// System.out -// .println("\t\t--compact : compact the input JSON-LD applying the optional context file"); -// System.out -// .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquads)"); -// System.out -// .println("\t\t--frame : frame the input JSON-LD with the optional frame file"); -// System.out -// .println("\t\t--flatten : flatten the input JSON-LD applying the optional context file"); -// System.out -// .println("\t\t--fromRDF : generate JSON-LD from the input rdf (format defaults to nquads)"); -// System.out -// .println("\t\t--toRDF : generate RDF from the input JSON-LD (format defaults to nquads)"); -// System.out -// .println("\t\t--outputForm [compacted|expanded|flattened] : the way to output the results from fromRDF (defaults to expanded)"); -// System.out.println("\t\t--simplify : simplify the input JSON-LD"); -// System.exit(1); -// } + // private static void usage() { + // System.out.println("Usage: jsonldplayground "); + // System.out.println("\tinput: a filename or JsonLdUrl to the rdf input (in rdfxml or n3)"); + // System.out.println("\toptions:"); + // System.out + // .println("\t\t--ignorekeys : a (space separated) list of keys to ignore (e.g. @geojson)"); + // System.out.println("\t\t--base : base URI"); + // System.out.println("\t\t--debug: Print out stack traces when errors occur"); + // System.out.println("\t\t--expand : expand the input JSON-LD"); + // System.out + // .println("\t\t--compact : compact the input JSON-LD applying the optional context file"); + // System.out + // .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquads)"); + // System.out + // .println("\t\t--frame : frame the input JSON-LD with the optional frame file"); + // System.out + // .println("\t\t--flatten : flatten the input JSON-LD applying the optional context file"); + // System.out + // .println("\t\t--fromRDF : generate JSON-LD from the input rdf (format defaults to nquads)"); + // System.out + // .println("\t\t--toRDF : generate RDF from the input JSON-LD (format defaults to nquads)"); + // System.out + // .println("\t\t--outputForm [compacted|expanded|flattened] : the way to output the results from fromRDF (defaults to expanded)"); + // System.out.println("\t\t--simplify : simplify the input JSON-LD"); + // System.exit(1); + // } } From 46ffdc194e71c3a9e4e6b3b8466c9f04425e05fd Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 15:41:15 +1100 Subject: [PATCH 102/440] cleanup xml indentation --- core/pom.xml | 29 +++++++++++++++-------------- pom.xml | 34 +++++++++++++++++----------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 35a43374..1f2bf429 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -50,15 +50,15 @@ sesame-rio-nquads test - - org.apache.httpcomponents - httpclient-osgi - - - org.apache.httpcomponents - httpcore-osgi - - org.slf4j @@ -78,13 +78,14 @@ - org.slf4j.*; version="[1.0.0,2)", - * - - + org.slf4j.*; version="[1.0.0,2)", + * + + - + org.apache.maven.plugins diff --git a/pom.xml b/pom.xml index bc95b2af..ce6e487e 100755 --- a/pom.xml +++ b/pom.xml @@ -134,22 +134,22 @@ ${slf4j.version} test - - org.apache.httpcomponents - httpclient-osgi - ${httpclient.version} - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpcore-osgi - ${httpclient.version} - + + org.apache.httpcomponents + httpclient-osgi + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpcore-osgi + ${httpclient.version} + org.mockito mockito-core @@ -234,7 +234,7 @@ org.apache.felix maven-bundle-plugin - 2.5.3 + 2.5.3 From 9d4e8e563f37695dcb60b626d1ca8f93e4468d07 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 15:51:11 +1100 Subject: [PATCH 103/440] note the httpclient dependency change and bump to 0.6.0-SNAPSHOT to recognise the possible semantic change --- README.md | 3 ++- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- integration/sesame/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d04235da..cdddc49b 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT Code example @@ -239,6 +239,7 @@ CHANGELOG ### 2015-03-01 * Use jopt-simple for the playground cli to simplify the coding and improve error messages * Allow RDF parsing and writing using all of the available Sesame Rio parsers through the playground cli +* Make the httpclient dependency OSGi compliant ### 2014-12-31 * Fix locale sensitive serialisation of XSD double/decimal typed literals to always be Locale.US diff --git a/core/pom.xml b/core/pom.xml index 1f2bf429..f8a377af 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index a89798bc..7cb41644 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 7d82a576..c0abbc70 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 342ad09c..d5e2af1a 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index f1acae5e..420bd763 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -3,7 +3,7 @@ jsonld-java-integration com.github.jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT 4.0.0 jsonld-java-sesame diff --git a/pom.xml b/pom.xml index ce6e487e..be9fcd8a 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index a665fb5c..3d53a30d 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.5.2-SNAPSHOT + 0.6.0-SNAPSHOT 4.0.0 jsonld-java-tools From a09d6004c90b017666f98d2f61c2bae4ca7f1c36 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 16:09:40 +1100 Subject: [PATCH 104/440] add jacoco and coveralls plugins to build process --- .travis.yml | 2 ++ core/pom.xml | 4 +++ integration/clerezza/pom.xml | 4 +++ integration/rdf2go/pom.xml | 4 +++ integration/sesame/pom.xml | 4 +++ pom.xml | 49 ++++++++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+) diff --git a/.travis.yml b/.travis.yml index 51132ede..1da9493c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,3 +7,5 @@ notifications: email: - ansell.peter@gmail.com - tristan.king@gmail.com +after_success: +- mvn clean test jacoco:report coveralls:jacoco diff --git a/core/pom.xml b/core/pom.xml index f8a377af..c43cc2b8 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -91,6 +91,10 @@ org.apache.maven.plugins maven-jar-plugin + + org.jacoco + jacoco-maven-plugin + diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index 7cb41644..d301c81e 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -65,6 +65,10 @@ maven-bundle-plugin true + + org.jacoco + jacoco-maven-plugin + diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index d5e2af1a..1c25ba10 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -79,6 +79,10 @@ maven-bundle-plugin true + + org.jacoco + jacoco-maven-plugin + diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 420bd763..50c0198a 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -61,6 +61,10 @@ maven-bundle-plugin true + + org.jacoco + jacoco-maven-plugin + diff --git a/pom.xml b/pom.xml index be9fcd8a..7f2bc1bc 100755 --- a/pom.xml +++ b/pom.xml @@ -236,6 +236,55 @@ maven-bundle-plugin 2.5.3 + + + org.eluder.coveralls + coveralls-maven-plugin + 2.2.0 + + + org.jacoco + jacoco-maven-plugin + 0.7.2.201409121644 + + + prepare-agent + + prepare-agent + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jacoco + + jacoco-maven-plugin + + + [0.7.2.201409121644,) + + + prepare-agent + + + + + + + + + + From 7ebaf65c3b729e9e9a01223cbac7c5b928d9df59 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 16:33:14 +1100 Subject: [PATCH 105/440] indent the after success line in travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1da9493c..60449950 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,4 @@ notifications: - ansell.peter@gmail.com - tristan.king@gmail.com after_success: -- mvn clean test jacoco:report coveralls:jacoco + - mvn clean test jacoco:report coveralls:jacoco From a2fe9e63c94534d2ed27f9381cab0343638d6485 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 18:15:59 +1100 Subject: [PATCH 106/440] try newer version of coveralls plugin --- .travis.yml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 60449950..2ee09394 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,4 @@ notifications: - ansell.peter@gmail.com - tristan.king@gmail.com after_success: - - mvn clean test jacoco:report coveralls:jacoco + - mvn clean test jacoco:report coveralls:report diff --git a/pom.xml b/pom.xml index 7f2bc1bc..725c68dd 100755 --- a/pom.xml +++ b/pom.xml @@ -240,7 +240,7 @@ org.eluder.coveralls coveralls-maven-plugin - 2.2.0 + 3.0.1 org.jacoco From 5d11750846d642945dbd244fdb9e11d4fff0eec5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 1 Mar 2015 18:25:57 +1100 Subject: [PATCH 107/440] add build status and code coverage status --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index cdddc49b..d86e40b8 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ JSONLD-JAVA This is a Java implementation of the [JSON-LD specification](http://www.w3.org/TR/json-ld/) and the [JSON-LD-API specification](http://www.w3.org/TR/json-ld-api/). +[![Build Status](https://travis-ci.org/jsonld-java/jsonld-java.svg?branch=master)](https://travis-ci.org/jsonld-java/jsonld-java) [![Coverage Status](https://coveralls.io/repos/jsonld-java/jsonld-java/badge.svg?branch=master)](https://coveralls.io/r/jsonld-java/jsonld-java?branch=master) + USAGE ===== From 65c073151cb61cf6655f56dc073687c001f24663 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 12 Mar 2015 09:09:17 +1100 Subject: [PATCH 108/440] Add regression test for context array elimination. Refs #138 --- .../core/ContextCompactionTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java new file mode 100644 index 00000000..fb08bee7 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -0,0 +1,56 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.github.jsonldjava.utils.JsonUtils; + +public class ContextCompactionTest { + + @Test + public void testCompaction() throws Exception { + + final Map contextAbbrevs = new HashMap(); + contextAbbrevs.put("so", "http://schema.org/"); + + final Map json = new HashMap(); + json.put("@context", contextAbbrevs); + json.put("@id", "http://example.org/my_work"); + + final List types = new LinkedList(); + types.add("so:CreativeWork"); + + json.put("@type", types); + json.put("so:name", "My Work"); + json.put("so:url", "http://example.org/my_work"); + + final JsonLdOptions options = new JsonLdOptions(); + options.setBase("http://schema.org/"); + options.setCompactArrays(true); + + System.out.println("Before compact"); + System.out.println(JsonUtils.toPrettyString(json)); + + final List newContexts = new LinkedList(); + newContexts.add("http://schema.org/"); + final Map compacted = JsonLdProcessor.compact(json, newContexts, options); + + System.out.println("\n\nAfter compact:"); + System.out.println(JsonUtils.toPrettyString(compacted)); + + assertTrue("Compaction removed the context", compacted.containsKey("@context")); + assertFalse("Compaction of context should be a string, not a list", + compacted.get("@context") instanceof List); + } + +} From 134b7a9c8fcbff874a9aaf00f1b11266f76a86ad Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 12 Mar 2015 09:56:02 +1100 Subject: [PATCH 109/440] Also compact the @context array if it contains a single element. Fixes #138 --- .../java/com/github/jsonldjava/core/JsonLdProcessor.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index aeb0c9a6..00cf1f5e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -76,7 +76,13 @@ public static Map compact(Object input, Object context, JsonLdOp // the keySet if ((context instanceof Map && !((Map) context).isEmpty()) || (context instanceof List && !((List) context).isEmpty())) { - ((Map) compacted).put("@context", context); + + if (context instanceof List && ((List) context).size() == 1) { + ((Map) compacted).put("@context", + ((List) context).get(0)); + } else { + ((Map) compacted).put("@context", context); + } } } From 3ff934e286955d8edccfb19e643188904ac7e92e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 12 Mar 2015 10:04:20 +1100 Subject: [PATCH 110/440] Only do compaction of the context array if compactArrays is true --- .../main/java/com/github/jsonldjava/core/JsonLdProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 00cf1f5e..8ea35f59 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -77,7 +77,8 @@ public static Map compact(Object input, Object context, JsonLdOp if ((context instanceof Map && !((Map) context).isEmpty()) || (context instanceof List && !((List) context).isEmpty())) { - if (context instanceof List && ((List) context).size() == 1) { + if (context instanceof List && ((List) context).size() == 1 + && opts.getCompactArrays()) { ((Map) compacted).put("@context", ((List) context).get(0)); } else { From 443dddff02d609aba42ffa31ecb66ff91683b62f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 12 Mar 2015 10:06:48 +1100 Subject: [PATCH 111/440] bump to Sesame-2.7.15 --- README.md | 4 ++++ pom.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d86e40b8..6013c81e 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,10 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2015-03-12 +* Compact context arrays if they contain a single element during compaction +* Bump to Sesame-2.7.15 + ### 2015-03-01 * Use jopt-simple for the playground cli to simplify the coding and improve error messages * Allow RDF parsing and writing using all of the available Sesame Rio parsers through the playground cli diff --git a/pom.xml b/pom.xml index 725c68dd..f82d6566 100755 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ 2.3.3 4.12 5.0.1 - 2.7.14 + 2.7.15 1.7.9 From 5ba3e500661040d7c0ab90f9fb730767c7620434 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sat, 22 Aug 2015 17:39:53 +0100 Subject: [PATCH 112/440] #144 : Check for trailing content when parsing JSON object --- .../github/jsonldjava/utils/JsonUtils.java | 12 ++++++- .../jsonldjava/utils/JsonUtilsTest.java | 31 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 31b98636..a6734c86 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -103,7 +103,7 @@ public static Object fromInputStream(InputStream input, String enc) throws IOExc */ public static Object fromReader(Reader reader) throws IOException { final JsonParser jp = JSON_FACTORY.createParser(reader); - Object rval = null; + Object rval ; final JsonToken initialToken = jp.nextToken(); if (initialToken == JsonToken.START_ARRAY) { @@ -123,6 +123,16 @@ public static Object fromReader(Reader reader) throws IOException { throw new JsonParseException("document doesn't start with a valid json element : " + initialToken, jp.getCurrentLocation()); } + + JsonToken t ; + try { t = jp.nextToken(); } + catch (JsonParseException ex) { + throw new JsonParseException("Document contains more content after json-ld element - (possible mismatched {}?)", + jp.getCurrentLocation()); + } + if ( t != null ) + throw new JsonParseException("Document contains possible json content after the json-ld element - (possible mismatched {}?)", + jp.getCurrentLocation()); return rval; } diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 4dc3a503..8bc77495 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -2,8 +2,11 @@ import static org.junit.Assert.assertTrue; +import java.io.IOException ; import java.util.Map; +import com.fasterxml.jackson.core.JsonParseException ; + import org.junit.Test; public class JsonUtilsTest { @@ -31,4 +34,32 @@ public void fromStringTest() { assertTrue(true); } } + + @Test + public void trailingContent_1() throws JsonParseException, IOException { trailingContent("{}") ; } + + @Test + public void trailingContent_2() throws JsonParseException, IOException { trailingContent("{} \t \r \n \r\n ") ; } + + @Test(expected=JsonParseException.class) + public void trailingContent_3() throws JsonParseException, IOException { trailingContent("{}x") ; } + + @Test(expected=JsonParseException.class) + public void trailingContent_4() throws JsonParseException, IOException { trailingContent("{} x") ; } + + @Test(expected=JsonParseException.class) + public void trailingContent_5() throws JsonParseException, IOException { trailingContent("{} \"x\"") ; } + + @Test(expected=JsonParseException.class) + public void trailingContent_6() throws JsonParseException, IOException { trailingContent("{} {}") ; } + + @Test(expected=JsonParseException.class) + public void trailingContent_7() throws JsonParseException, IOException { trailingContent("{},{}") ; } + + @Test(expected=JsonParseException.class) + public void trailingContent_8() throws JsonParseException, IOException { trailingContent("{},[]") ; } + + private void trailingContent(String string) throws JsonParseException, IOException { + JsonUtils.fromString(string) ; + } } From b9d564ffa56aba51a3b6c8f96ade45ef00646ebe Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sat, 22 Aug 2015 17:40:31 +0100 Subject: [PATCH 113/440] Fix test data for #144 : remove unnecessary content --- .../com/github/jsonldjava/sesame/SesameLocaleNumericTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java index 45371964..de1da54c 100644 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java +++ b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java @@ -70,6 +70,6 @@ public void testLocaleFrench() throws Exception { private String getTestString() { return "{" + "\"@id\": \"http://www.ex.com/product\"," + "\"http://schema.org/price\": {" - + "\"@value\": 100.00" + "}}}"; + + "\"@value\": 100.00" + "}}"; } } From 2fbe6f6cf480cd297608bf52d6e4d9749be992ee Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 08:55:27 +1000 Subject: [PATCH 114/440] Deprecate Sesame-2.7 integration in favour of sesame-rio-jsonld --- integration/pom.xml | 2 +- integration/sesame/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/pom.xml b/integration/pom.xml index c0abbc70..9829a7fd 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -12,7 +12,7 @@ pom - sesame + clerezza rdf2go diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml index 50c0198a..fa526e9d 100644 --- a/integration/sesame/pom.xml +++ b/integration/sesame/pom.xml @@ -7,8 +7,8 @@ 4.0.0 jsonld-java-sesame - JSONLD Java :: Sesame Integration - JSON-LD Java integration module for Sesame + JSONLD Java :: Sesame-2.7 Integration + JSON-LD Java integration module for Sesame-2.7 bundle From 7b63544ccf35585e5e285b76b69005ab61cc8986 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 09:12:29 +1000 Subject: [PATCH 115/440] Add changelog entry --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6013c81e..031e1691 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,10 @@ Then, you can open a pull request to merge your change into the master branch of CHANGELOG ========= +### 2015-08-25 +* Deprecate Sesame-2.7 module in favour of sesame-rio-jsonld for Sesame-2.8 and 4.0 +* Fix bug where parsing did not fail if content was present after the end of a full JSON top level element + ### 2015-03-12 * Compact context arrays if they contain a single element during compaction * Bump to Sesame-2.7.15 From 604ad674ed635a7014e30f627e95dbe3ec8ccf3f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 09:17:46 +1000 Subject: [PATCH 116/440] Reformat --- .../jsonldjava/utils/JsonUtilsTest.java | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 8bc77495..b87182d7 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -2,10 +2,10 @@ import static org.junit.Assert.assertTrue; -import java.io.IOException ; +import java.io.IOException; import java.util.Map; -import com.fasterxml.jackson.core.JsonParseException ; +import com.fasterxml.jackson.core.JsonParseException; import org.junit.Test; @@ -34,32 +34,48 @@ public void fromStringTest() { assertTrue(true); } } - + @Test - public void trailingContent_1() throws JsonParseException, IOException { trailingContent("{}") ; } + public void trailingContent_1() throws JsonParseException, IOException { + trailingContent("{}"); + } @Test - public void trailingContent_2() throws JsonParseException, IOException { trailingContent("{} \t \r \n \r\n ") ; } + public void trailingContent_2() throws JsonParseException, IOException { + trailingContent("{} \t \r \n \r\n "); + } - @Test(expected=JsonParseException.class) - public void trailingContent_3() throws JsonParseException, IOException { trailingContent("{}x") ; } + @Test(expected = JsonParseException.class) + public void trailingContent_3() throws JsonParseException, IOException { + trailingContent("{}x"); + } - @Test(expected=JsonParseException.class) - public void trailingContent_4() throws JsonParseException, IOException { trailingContent("{} x") ; } + @Test(expected = JsonParseException.class) + public void trailingContent_4() throws JsonParseException, IOException { + trailingContent("{} x"); + } - @Test(expected=JsonParseException.class) - public void trailingContent_5() throws JsonParseException, IOException { trailingContent("{} \"x\"") ; } + @Test(expected = JsonParseException.class) + public void trailingContent_5() throws JsonParseException, IOException { + trailingContent("{} \"x\""); + } - @Test(expected=JsonParseException.class) - public void trailingContent_6() throws JsonParseException, IOException { trailingContent("{} {}") ; } + @Test(expected = JsonParseException.class) + public void trailingContent_6() throws JsonParseException, IOException { + trailingContent("{} {}"); + } - @Test(expected=JsonParseException.class) - public void trailingContent_7() throws JsonParseException, IOException { trailingContent("{},{}") ; } + @Test(expected = JsonParseException.class) + public void trailingContent_7() throws JsonParseException, IOException { + trailingContent("{},{}"); + } - @Test(expected=JsonParseException.class) - public void trailingContent_8() throws JsonParseException, IOException { trailingContent("{},[]") ; } + @Test(expected = JsonParseException.class) + public void trailingContent_8() throws JsonParseException, IOException { + trailingContent("{},[]"); + } private void trailingContent(String string) throws JsonParseException, IOException { - JsonUtils.fromString(string) ; + JsonUtils.fromString(string); } } From 825bdde5b796676684534ec45e4747afc10960c0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 09:33:26 +1000 Subject: [PATCH 117/440] Remove the Sesame integration module and move the sesame.version property to tools so it is clear that is the only place it is used --- core/pom.xml | 14 +- integration/jena/README.md | 5 - integration/sesame/README.md | 70 ------ integration/sesame/pom.xml | 71 ------ .../jsonldjava/sesame/SesameJSONLDParser.java | 101 -------- .../sesame/SesameJSONLDParserFactory.java | 28 --- .../jsonldjava/sesame/SesameJSONLDWriter.java | 148 ------------ .../sesame/SesameJSONLDWriterFactory.java | 36 --- .../jsonldjava/sesame/SesameRDFParser.java | 96 -------- .../sesame/SesameTripleCallback.java | 217 ------------------ .../services/org.openrdf.rio.RDFParserFactory | 1 - .../services/org.openrdf.rio.RDFWriterFactory | 1 - .../sesame/SesameEmptyPrefixTest.java | 57 ----- .../sesame/SesameJSONLDParserHandlerTest.java | 80 ------- .../sesame/SesameJSONLDWriterTest.java | 112 --------- .../sesame/SesameLocaleNumericTest.java | 75 ------ .../sesame/SesameTripleCallbackTest.java | 55 ----- .../src/test/resources/log4j.properties | 5 - pom.xml | 32 +-- tools/pom.xml | 26 ++- .../github/jsonldjava/tools/Playground.java | 2 - 21 files changed, 30 insertions(+), 1202 deletions(-) delete mode 100644 integration/jena/README.md delete mode 100644 integration/sesame/README.md delete mode 100644 integration/sesame/pom.xml delete mode 100644 integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java delete mode 100644 integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java delete mode 100644 integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java delete mode 100644 integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java delete mode 100644 integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameRDFParser.java delete mode 100644 integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java delete mode 100644 integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory delete mode 100644 integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFWriterFactory delete mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java delete mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java delete mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java delete mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java delete mode 100644 integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java delete mode 100644 integration/sesame/src/test/resources/log4j.properties diff --git a/core/pom.xml b/core/pom.xml index c43cc2b8..06885e2e 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -40,16 +40,6 @@ mockito-core test - - org.openrdf.sesame - sesame-rio-api - test - - - org.openrdf.sesame - sesame-rio-nquads - test - org.apache.httpcomponents httpclient-osgi @@ -64,6 +54,10 @@ org.slf4j jcl-over-slf4j + + commons-io + commons-io + diff --git a/integration/jena/README.md b/integration/jena/README.md deleted file mode 100644 index 389745ad..00000000 --- a/integration/jena/README.md +++ /dev/null @@ -1,5 +0,0 @@ -============================ -JSONLD-Java Jena integration -============================ - -JSONLD-Java integration is provided natively by Jena since 2.11.2. diff --git a/integration/sesame/README.md b/integration/sesame/README.md deleted file mode 100644 index 1172fe05..00000000 --- a/integration/sesame/README.md +++ /dev/null @@ -1,70 +0,0 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.3/integration/sesame/README.md) - -JSONLD-Java Sesame Integration module -===================================== - -USAGE -===== - -From Maven ----------- - - - com.github.jsonld-java - jsonld-java-sesame - 0.4-SNAPSHOT - - -(Adjust for most recent , as found in ``pom.xml``). - - -Parsing JSON-LD using Sesame ----------------------------- - -To parse a JSON-LD document to a Model: - - InputStream inputStream = ...; - String baseURI = "http://example.org/baseuri/"; - org.openrdf.model.Model statements = Rio.parse(inputStream, baseURI, RDFFormat.JSONLD); - -To parse a JSON-LD document into a RepositoryConnection: - - org.openrdf.repository.Repository myRepository = ...; - InputStream inputStream = ...; - String baseURI = "http://example.org/baseuri/"; - org.openrdf.model.Resource contextToInsertTo = ...; - - org.openrdf.repository.RepositoryConnection repositoryConnection = myRepository.getConnection(); - try { - repositoryConnection.add(inputStream, baseURI, RDFFormat.JSONLD, contextToInsertTo); - } finally { - repositoryConnection.close(); - } - -Writing JSON-LD using Sesame ----------------------------- - -To write a Java Iterable to a JSON-LD document: - - Iterable statements = ...; - OutputStream outputStream = ...; - Rio.write(statements, outputStream, RDFFormat.JSONLD); - -To export statements from a Repository to a JSON-LD document: - - org.openrdf.repository.Repository myRepository = ...; - org.openrdf.model.Resource contextToExport = ...; - OutputStream outputStream = ...; - - org.openrdf.repository.RepositoryConnection repositoryConnection = myRepository.getConnection(); - try { - org.openrdf.rio.RDFWriter writer = Rio.createWriter(RDFFormat.JSONLD, outputStream); - // Optionally define what JSON-LD profile is to be used - // The Expand mode is used by default - writer.getWriterConfig().set(JSONLDSettings.JSONLD_MODE, JSONLDMode.EXPAND); - // Switch from the default JSON pretty-print to a white-space reduced JSON representation - writer.getWriterConfig().set(BasicWriterSettings.PRETTY_PRINT, false); - repositoryConnection.export(writer, contextToExport); - } finally { - repositoryConnection.close(); - } diff --git a/integration/sesame/pom.xml b/integration/sesame/pom.xml deleted file mode 100644 index fa526e9d..00000000 --- a/integration/sesame/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - jsonld-java-integration - com.github.jsonld-java - 0.6.0-SNAPSHOT - - 4.0.0 - jsonld-java-sesame - JSONLD Java :: Sesame-2.7 Integration - JSON-LD Java integration module for Sesame-2.7 - bundle - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - org.openrdf.sesame - sesame-model - - - org.openrdf.sesame - sesame-rio-api - - - org.openrdf.sesame - sesame-rio-testsuite - test - - - junit - junit - test - - - org.slf4j - slf4j-log4j12 - test - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - - - org.apache.felix - maven-bundle-plugin - true - - - org.jacoco - jacoco-maven-plugin - - - - - diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java deleted file mode 100644 index 4e7d9483..00000000 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParser.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * - */ -package com.github.jsonldjava.sesame; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -import org.openrdf.model.Value; -import org.openrdf.model.ValueFactory; -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParseException; -import org.openrdf.rio.RDFParser; -import org.openrdf.rio.helpers.RDFParserBase; - -import com.fasterxml.jackson.core.JsonParseException; -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; - -/** - * An {@link RDFParser} that links to {@link SesameTripleCallback}. - * - * @author Peter Ansell p_ansell@yahoo.com - * - */ -public class SesameJSONLDParser extends RDFParserBase implements RDFParser { - - /** - * Default constructor - */ - public SesameJSONLDParser() { - super(); - } - - /** - * Creates a Sesame JSONLD Parser using the given {@link ValueFactory} to - * create new {@link Value}s. - * - * @param valueFactory - * The ValueFactory to use - */ - public SesameJSONLDParser(final ValueFactory valueFactory) { - super(valueFactory); - } - - @Override - public RDFFormat getRDFFormat() { - return RDFFormat.JSONLD; - } - - @Override - public void parse(final InputStream in, final String baseURI) throws IOException, - RDFParseException, RDFHandlerException { - final SesameTripleCallback callback = new SesameTripleCallback(getRDFHandler(), - valueFactory, getParserConfig(), getParseErrorListener()); - - final JsonLdOptions options = new JsonLdOptions(baseURI); - options.useNamespaces = true; - - try { - JsonLdProcessor.toRDF(JsonUtils.fromInputStream(in), callback, options); - } catch (final JsonLdError e) { - throw new RDFParseException("Could not parse JSONLD", e); - } catch (final JsonParseException e) { - throw new RDFParseException("Could not parse JSONLD", e); - } catch (final RuntimeException e) { - if (e.getCause() != null && e.getCause() instanceof RDFParseException) { - throw (RDFParseException) e.getCause(); - } - throw e; - } - } - - @Override - public void parse(final Reader reader, final String baseURI) throws IOException, - RDFParseException, RDFHandlerException { - final SesameTripleCallback callback = new SesameTripleCallback(getRDFHandler(), - valueFactory, getParserConfig(), getParseErrorListener()); - - final JsonLdOptions options = new JsonLdOptions(baseURI); - options.useNamespaces = true; - - try { - JsonLdProcessor.toRDF(JsonUtils.fromReader(reader), callback, options); - } catch (final JsonLdError e) { - throw new RDFParseException("Could not parse JSONLD", e); - } catch (final JsonParseException e) { - throw new RDFParseException("Could not parse JSONLD", e); - } catch (final RuntimeException e) { - if (e.getCause() != null && e.getCause() instanceof RDFParseException) { - throw (RDFParseException) e.getCause(); - } - throw e; - } - } - -} diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java deleted file mode 100644 index 9306d7f4..00000000 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDParserFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * - */ -package com.github.jsonldjava.sesame; - -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.RDFParser; -import org.openrdf.rio.RDFParserFactory; - -/** - * An {@link RDFParserFactory} that creates instances of - * {@link SesameJSONLDParser}. - * - * @author Peter Ansell p_ansell@yahoo.com - */ -public class SesameJSONLDParserFactory implements RDFParserFactory { - - @Override - public RDFFormat getRDFFormat() { - return RDFFormat.JSONLD; - } - - @Override - public RDFParser getParser() { - return new SesameJSONLDParser(); - } - -} diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java deleted file mode 100644 index 13670149..00000000 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriter.java +++ /dev/null @@ -1,148 +0,0 @@ -/** - * - */ -package com.github.jsonldjava.sesame; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.openrdf.model.Model; -import org.openrdf.model.Namespace; -import org.openrdf.model.Statement; -import org.openrdf.model.impl.LinkedHashModel; -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFWriter; -import org.openrdf.rio.helpers.BasicWriterSettings; -import org.openrdf.rio.helpers.JSONLDMode; -import org.openrdf.rio.helpers.JSONLDSettings; -import org.openrdf.rio.helpers.RDFWriterBase; -import org.openrdf.rio.helpers.StatementCollector; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; - -/** - * @author Peter Ansell p_ansell@yahoo.com - * - */ -public class SesameJSONLDWriter extends RDFWriterBase implements RDFWriter { - - private final Model model = new LinkedHashModel(); - - private final StatementCollector statementCollector = new StatementCollector(model); - - private final Writer writer; - - /** - * Create a SesameJSONLDWriter using a {@link java.io.OutputStream} - * - * @param outputStream - * The OutputStream to write to. - */ - public SesameJSONLDWriter(OutputStream outputStream) { - this(new BufferedWriter(new OutputStreamWriter(outputStream, Charset.forName("UTF-8")))); - } - - /** - * Create a SesameJSONLDWriter using a {@link java.io.Writer} - * - * @param writer - * The Writer to write to. - */ - public SesameJSONLDWriter(Writer writer) { - this.writer = writer; - } - - @Override - public void handleNamespace(String prefix, String uri) throws RDFHandlerException { - model.setNamespace(prefix, uri); - } - - @Override - public void startRDF() throws RDFHandlerException { - statementCollector.clear(); - model.clear(); - } - - @Override - public void endRDF() throws RDFHandlerException { - final SesameRDFParser serialiser = new SesameRDFParser(); - try { - Object output = JsonLdProcessor.fromRDF(model, serialiser); - - final JSONLDMode mode = getWriterConfig().get(JSONLDSettings.JSONLD_MODE); - - final JsonLdOptions opts = new JsonLdOptions(); - // opts.addBlankNodeIDs = - // getWriterConfig().get(BasicParserSettings.PRESERVE_BNODE_IDS); - opts.setUseRdfType(getWriterConfig().get(JSONLDSettings.USE_RDF_TYPE)); - opts.setUseNativeTypes(getWriterConfig().get(JSONLDSettings.USE_NATIVE_TYPES)); - // opts.optimize = getWriterConfig().get(JSONLDSettings.OPTIMIZE); - - if (mode == JSONLDMode.EXPAND) { - output = JsonLdProcessor.expand(output, opts); - } - // TODO: Implement inframe in JSONLDSettings - final Object inframe = null; - if (mode == JSONLDMode.FLATTEN) { - output = JsonLdProcessor.flatten(output, inframe, opts); - } - if (mode == JSONLDMode.COMPACT) { - final Map ctx = new LinkedHashMap(); - addPrefixes(ctx, model.getNamespaces()); - final Map localCtx = new HashMap(); - localCtx.put("@context", ctx); - - output = JsonLdProcessor.compact(output, localCtx, opts); - } - if (getWriterConfig().get(BasicWriterSettings.PRETTY_PRINT)) { - JsonUtils.writePrettyPrint(writer, output); - } else { - JsonUtils.write(writer, output); - } - - } catch (final JsonLdError e) { - throw new RDFHandlerException("Could not render JSONLD", e); - } catch (final JsonGenerationException e) { - throw new RDFHandlerException("Could not render JSONLD", e); - } catch (final JsonMappingException e) { - throw new RDFHandlerException("Could not render JSONLD", e); - } catch (final IOException e) { - throw new RDFHandlerException("Could not render JSONLD", e); - } - } - - @Override - public void handleStatement(Statement st) throws RDFHandlerException { - statementCollector.handleStatement(st); - } - - @Override - public void handleComment(String comment) throws RDFHandlerException { - } - - @Override - public RDFFormat getRDFFormat() { - return RDFFormat.JSONLD; - } - - private static void addPrefixes(Map ctx, Set namespaces) { - for (final Namespace ns : namespaces) { - ctx.put(ns.getPrefix(), ns.getName()); - } - - } -} diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java deleted file mode 100644 index 6d4fe639..00000000 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameJSONLDWriterFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * - */ -package com.github.jsonldjava.sesame; - -import java.io.OutputStream; -import java.io.Writer; - -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.RDFWriter; -import org.openrdf.rio.RDFWriterFactory; - -/** - * An {@link RDFWriterFactory} that creates instances of - * {@link SesameJSONLDWriter}. - * - * @author Peter Ansell p_ansell@yahoo.com - */ -public class SesameJSONLDWriterFactory implements RDFWriterFactory { - - @Override - public RDFFormat getRDFFormat() { - return RDFFormat.JSONLD; - } - - @Override - public RDFWriter getWriter(OutputStream out) { - return new SesameJSONLDWriter(out); - } - - @Override - public RDFWriter getWriter(Writer writer) { - return new SesameJSONLDWriter(writer); - } - -} diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameRDFParser.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameRDFParser.java deleted file mode 100644 index 25a20da3..00000000 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameRDFParser.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.github.jsonldjava.sesame; - -import java.util.Set; - -import org.openrdf.model.BNode; -import org.openrdf.model.Graph; -import org.openrdf.model.Literal; -import org.openrdf.model.Model; -import org.openrdf.model.Namespace; -import org.openrdf.model.Resource; -import org.openrdf.model.Statement; -import org.openrdf.model.URI; -import org.openrdf.model.Value; -import org.openrdf.model.vocabulary.RDF; -import org.openrdf.model.vocabulary.XMLSchema; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.RDFDataset; - -public class SesameRDFParser implements com.github.jsonldjava.core.RDFParser { - - public void setPrefix(RDFDataset result, String fullUri, String prefix) { - result.setNamespace(fullUri, prefix); - } - - public void handleStatement(RDFDataset result, Statement nextStatement) { - // TODO: from a basic look at the code it seems some of these could be - // null - // null values for IRIs will probably break things further down the line - // and i'm not sure yet if this should be something handled later on, or - // something that should be checked here - final String subject = getResourceValue(nextStatement.getSubject()); - final String predicate = getResourceValue(nextStatement.getPredicate()); - final Value object = nextStatement.getObject(); - final String graphName = getResourceValue(nextStatement.getContext()); - - if (object instanceof Literal) { - final Literal literal = (Literal) object; - final String value = literal.getLabel(); - final String language = literal.getLanguage(); - - String datatype = getResourceValue(literal.getDatatype()); - - // In RDF-1.1, Language Literals internally have the datatype - // rdf:langString - if (language != null && datatype == null) { - datatype = RDF.LANGSTRING.stringValue(); - } - - // In RDF-1.1, RDF-1.0 Plain Literals are now Typed Literals with - // type xsd:String - if (language == null && datatype == null) { - datatype = XMLSchema.STRING.stringValue(); - } - - result.addQuad(subject, predicate, value, datatype, language, graphName); - - } else { - result.addQuad(subject, predicate, getResourceValue((Resource) object), graphName); - } - } - - private String getResourceValue(Resource subject) { - if (subject == null) { - return null; - } else if (subject instanceof URI) { - return subject.stringValue(); - } else if (subject instanceof BNode) { - return "_:" + subject.stringValue(); - } - - throw new IllegalStateException("Did not recognise resource type: " - + subject.getClass().getName()); - } - - @Override - public RDFDataset parse(Object input) throws JsonLdError { - final RDFDataset result = new RDFDataset(); - if (input instanceof Statement) { - handleStatement(result, (Statement) input); - } else if (input instanceof Graph) { - if (input instanceof Model) { - final Set namespaces = ((Model) input).getNamespaces(); - for (final Namespace nextNs : namespaces) { - result.setNamespace(nextNs.getName(), nextNs.getPrefix()); - } - } - - for (final Statement nextStatement : (Graph) input) { - handleStatement(result, nextStatement); - } - } - return result; - } - -} diff --git a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java b/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java deleted file mode 100644 index 9e4d39cd..00000000 --- a/integration/sesame/src/main/java/com/github/jsonldjava/sesame/SesameTripleCallback.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.github.jsonldjava.sesame; - -import java.util.List; -import java.util.Map.Entry; - -import org.openrdf.model.Resource; -import org.openrdf.model.Statement; -import org.openrdf.model.URI; -import org.openrdf.model.Value; -import org.openrdf.model.ValueFactory; -import org.openrdf.model.impl.LinkedHashModel; -import org.openrdf.model.impl.ValueFactoryImpl; -import org.openrdf.rio.ParseErrorListener; -import org.openrdf.rio.ParserConfig; -import org.openrdf.rio.RDFHandler; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParseException; -import org.openrdf.rio.helpers.ParseErrorLogger; -import org.openrdf.rio.helpers.RDFParserHelper; -import org.openrdf.rio.helpers.StatementCollector; - -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; - -public class SesameTripleCallback implements JsonLdTripleCallback { - - private ValueFactory vf; - - private RDFHandler handler; - - private ParserConfig parserConfig; - - private final ParseErrorListener parseErrorListener; - - public SesameTripleCallback() { - this(new StatementCollector(new LinkedHashModel())); - } - - public SesameTripleCallback(RDFHandler nextHandler) { - this(nextHandler, ValueFactoryImpl.getInstance()); - } - - public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf) { - this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); - } - - public SesameTripleCallback(RDFHandler nextHandler, ValueFactory vf, ParserConfig parserConfig, - ParseErrorListener parseErrorListener) { - this.handler = nextHandler; - this.vf = vf; - this.parserConfig = parserConfig; - this.parseErrorListener = parseErrorListener; - } - - private void triple(String s, String p, String o, String graph) { - if (s == null || p == null || o == null) { - // TODO: i don't know what to do here!!!! - return; - } - - Statement result; - // This method is always called with three Resources as subject - // predicate and - // object - if (graph == null) { - result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o)); - } else { - result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o), - createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - private Resource createResource(String resource) { - // Blank node without any given identifier - if (resource.equals("_:")) { - return vf.createBNode(); - } else if (resource.startsWith("_:")) { - return vf.createBNode(resource.substring(2)); - } else { - return vf.createURI(resource); - } - } - - private void triple(String s, String p, String value, String datatype, String language, - String graph) { - - if (s == null || p == null || value == null) { - // TODO: i don't know what to do here!!!! - return; - } - - final Resource subject = createResource(s); - - final URI predicate = vf.createURI(p); - final URI datatypeURI = datatype == null ? null : vf.createURI(datatype); - - Value object; - try { - object = RDFParserHelper.createLiteral(value, language, datatypeURI, getParserConfig(), - getParserErrorListener(), getValueFactory()); - } catch (final RDFParseException e) { - throw new RuntimeException(e); - } - - Statement result; - if (graph == null) { - result = vf.createStatement(subject, predicate, object); - } else { - result = vf.createStatement(subject, predicate, object, createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - public ParseErrorListener getParserErrorListener() { - return this.parseErrorListener; - } - - /** - * @return the handler - */ - public RDFHandler getHandler() { - return handler; - } - - /** - * @param handler - * the handler to set - */ - public void setHandler(RDFHandler handler) { - this.handler = handler; - } - - /** - * @return the parserConfig - */ - public ParserConfig getParserConfig() { - return parserConfig; - } - - /** - * @param parserConfig - * the parserConfig to set - */ - public void setParserConfig(ParserConfig parserConfig) { - this.parserConfig = parserConfig; - } - - /** - * @return the vf - */ - public ValueFactory getValueFactory() { - return vf; - } - - /** - * @param vf - * the vf to set - */ - public void setValueFactory(ValueFactory vf) { - this.vf = vf; - } - - @Override - public Object call(final RDFDataset dataset) { - if (handler != null) { - try { - handler.startRDF(); - for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { - handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); - } - } catch (final RDFHandlerException e) { - throw new RuntimeException("Could not handle start of RDF", e); - } - } - for (String graphName : dataset.keySet()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), quad.getObject().getDatatype(), quad - .getObject().getLanguage(), graphName); - } else { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), graphName); - } - } - } - if (handler != null) { - try { - handler.endRDF(); - } catch (final RDFHandlerException e) { - throw new RuntimeException("Could not handle end of RDF", e); - } - } - - return getHandler(); - } - -} diff --git a/integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory b/integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory deleted file mode 100644 index 52bb706a..00000000 --- a/integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory +++ /dev/null @@ -1 +0,0 @@ -com.github.jsonldjava.sesame.SesameJSONLDParserFactory diff --git a/integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFWriterFactory b/integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFWriterFactory deleted file mode 100644 index 7d22b362..00000000 --- a/integration/sesame/src/main/resources/META-INF/services/org.openrdf.rio.RDFWriterFactory +++ /dev/null @@ -1 +0,0 @@ -com.github.jsonldjava.sesame.SesameJSONLDWriterFactory diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java deleted file mode 100644 index 68eef817..00000000 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameEmptyPrefixTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.github.jsonldjava.sesame; - -import static org.junit.Assert.assertTrue; - -import java.io.StringReader; -import java.io.StringWriter; - -import org.junit.Test; -import org.openrdf.model.Model; -import org.openrdf.model.util.ModelUtil; -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.Rio; -import org.openrdf.rio.WriterConfig; -import org.openrdf.rio.helpers.JSONLDMode; -import org.openrdf.rio.helpers.JSONLDSettings; - -public class SesameEmptyPrefixTest { - - @Test - public void testEmptyPrefixDefault() throws Exception { - final String input = "@prefix : ." - + "@prefix dc: ." - + " :G { " - + " dc:isVersionOf . }"; - final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); - - final StringWriter output = new StringWriter(); - Rio.write(parse, output, RDFFormat.JSONLD); - - System.out.println(output); - - final Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); - - assertTrue(ModelUtil.equals(parse, reparse)); - } - - @Test - public void testEmptyPrefixCompact() throws Exception { - final String input = "@prefix : ." - + "@prefix dc: ." - + " :G { " - + " dc:isVersionOf . }"; - final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.TRIG); - - final WriterConfig config = new WriterConfig(); - config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); - - final StringWriter output = new StringWriter(); - Rio.write(parse, output, RDFFormat.JSONLD, config); - - System.out.println(output); - - final Model reparse = Rio.parse(new StringReader(output.toString()), "", RDFFormat.JSONLD); - - assertTrue(ModelUtil.equals(parse, reparse)); - } -} diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java deleted file mode 100644 index 4545b13a..00000000 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDParserHandlerTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * - */ -package com.github.jsonldjava.sesame; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.StringWriter; -import java.nio.charset.Charset; - -import org.openrdf.model.Model; -import org.openrdf.model.Namespace; -import org.openrdf.model.Statement; -import org.openrdf.rio.AbstractParserHandlingTest; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParser; -import org.openrdf.rio.RDFWriter; - -/** - * Unit tests for {@link SesameJSONLDParser} related to handling of datatypes - * and languages. - * - * @author Peter Ansell p_ansell@yahoo.com - */ -public class SesameJSONLDParserHandlerTest extends AbstractParserHandlingTest { - - @Override - protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements) - throws Exception { - return writeJSONLD(unknownDatatypeStatements); - } - - @Override - protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements) throws Exception { - return writeJSONLD(knownDatatypeStatements); - } - - @Override - protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements) - throws Exception { - return writeJSONLD(unknownLanguageStatements); - } - - @Override - protected InputStream getKnownLanguageStream(Model knownLanguageStatements) throws Exception { - return writeJSONLD(knownLanguageStatements); - } - - @Override - protected RDFParser getParser() { - return new SesameJSONLDParser(); - } - - /** - * Helper method to write the given model to JSON-LD and return an - * InputStream containing the results. - * - * @param statements - * @return An {@link InputStream} containing the results. - * @throws RDFHandlerException - */ - private InputStream writeJSONLD(Model statements) throws RDFHandlerException { - final StringWriter writer = new StringWriter(); - - final RDFWriter jsonldWriter = new SesameJSONLDWriter(writer); - jsonldWriter.startRDF(); - for (final Namespace prefix : statements.getNamespaces()) { - jsonldWriter.handleNamespace(prefix.getPrefix(), prefix.getName()); - } - for (final Statement nextStatement : statements) { - jsonldWriter.handleStatement(nextStatement); - } - jsonldWriter.endRDF(); - - // System.out.println(writer.toString()); - - return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8"))); - } - -} diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java deleted file mode 100644 index 32d7f776..00000000 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameJSONLDWriterTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * - */ -package com.github.jsonldjava.sesame; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.junit.Ignore; -import org.junit.Test; -import org.openrdf.model.Literal; -import org.openrdf.model.Model; -import org.openrdf.model.Statement; -import org.openrdf.model.URI; -import org.openrdf.model.impl.LinkedHashModel; -import org.openrdf.model.vocabulary.XMLSchema; -import org.openrdf.rio.ParserConfig; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParseException; -import org.openrdf.rio.RDFParser; -import org.openrdf.rio.RDFWriter; -import org.openrdf.rio.RDFWriterTest; -import org.openrdf.rio.WriterConfig; -import org.openrdf.rio.helpers.BasicParserSettings; -import org.openrdf.rio.helpers.JSONLDMode; -import org.openrdf.rio.helpers.JSONLDSettings; -import org.openrdf.rio.helpers.StatementCollector; - -/** - * @author Peter Ansell p_ansell@yahoo.com - */ -public class SesameJSONLDWriterTest extends RDFWriterTest { - - public SesameJSONLDWriterTest() { - super(new SesameJSONLDWriterFactory(), new SesameJSONLDParserFactory()); - } - - @Override - protected void setupWriterConfig(WriterConfig config) { - super.setupWriterConfig(config); - config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); - } - - @Override - protected void setupParserConfig(ParserConfig config) { - super.setupParserConfig(config); - config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); - config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true); - } - - @Test - @Override - @Ignore("Sesame-2.7 does not support RDF-1.1, so string/langString literals cause this to fail.") - public void testRoundTrip() throws Exception { - } - - @Test - @Override - @Ignore("Sesame-2.7 does not support RDF-1.1, so string/langString literals cause this to fail.") - public void testRoundTripPreserveBNodeIds() throws Exception { - } - - @Test - @Override - @Ignore("TODO: Determine why this test is breaking") - public void testIllegalPrefix() throws RDFHandlerException, RDFParseException, IOException { - } - - @Test - public void testRoundTripNamespaces() throws Exception { - final String exNs = "http://example.org/"; - final URI uri1 = vf.createURI(exNs, "uri1"); - final URI uri2 = vf.createURI(exNs, "uri2"); - final Literal plainLit = vf.createLiteral("plain", XMLSchema.STRING); - - final Statement st1 = vf.createStatement(uri1, uri2, plainLit); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final RDFWriter rdfWriter = rdfWriterFactory.getWriter(out); - rdfWriter.getWriterConfig().set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT); - rdfWriter.handleNamespace("ex", exNs); - rdfWriter.startRDF(); - rdfWriter.handleStatement(st1); - rdfWriter.endRDF(); - - final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - final RDFParser rdfParser = rdfParserFactory.getParser(); - final ParserConfig config = new ParserConfig(); - config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); - config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true); - rdfParser.setParserConfig(config); - rdfParser.setValueFactory(vf); - final Model model = new LinkedHashModel(); - rdfParser.setRDFHandler(new StatementCollector(model)); - - rdfParser.parse(in, "foo:bar"); - - assertEquals("Unexpected number of statements, found " + model.size(), 1, model.size()); - - assertTrue("missing namespaced statement", model.contains(st1)); - - if (rdfParser.getRDFFormat().supportsNamespaces()) { - assertTrue("Expected at least one namespace, found " + model.getNamespaces().size(), - model.getNamespaces().size() >= 1); - assertEquals(exNs, model.getNamespace("ex").getName()); - } - } -} diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java deleted file mode 100644 index de1da54c..00000000 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameLocaleNumericTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.github.jsonldjava.sesame; - -import static org.junit.Assert.assertTrue; - -import java.io.StringReader; -import java.io.StringWriter; -import java.util.Locale; - -import org.junit.Test; -import org.openrdf.model.Model; -import org.openrdf.model.util.ModelUtil; -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.Rio; - -/** - * Test for locale-insensitive numeric representations that match the XML Schema - * Datatype specification. - * - * @author Peter Ansell p_ansell@yahoo.com - * @see Github - * issue #133 - */ -public class SesameLocaleNumericTest { - - @Test - public void testLocaleUS() throws Exception { - final Locale oldDefault = Locale.getDefault(); - - try { - Locale.setDefault(Locale.US); - final String input = getTestString(); - final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); - - final StringWriter output = new StringWriter(); - Rio.write(parse, output, RDFFormat.JSONLD); - - System.out.println(output); - - final Model reparse = Rio.parse(new StringReader(output.toString()), "", - RDFFormat.JSONLD); - - assertTrue(ModelUtil.equals(parse, reparse)); - } finally { - Locale.setDefault(oldDefault); - } - } - - @Test - public void testLocaleFrench() throws Exception { - final Locale oldDefault = Locale.getDefault(); - - try { - Locale.setDefault(Locale.FRANCE); - final String input = getTestString(); - final Model parse = Rio.parse(new StringReader(input), "", RDFFormat.JSONLD); - - final StringWriter output = new StringWriter(); - Rio.write(parse, output, RDFFormat.JSONLD); - - System.out.println(output); - - final Model reparse = Rio.parse(new StringReader(output.toString()), "", - RDFFormat.JSONLD); - - assertTrue(ModelUtil.equals(parse, reparse)); - } finally { - Locale.setDefault(oldDefault); - } - } - - private String getTestString() { - return "{" + "\"@id\": \"http://www.ex.com/product\"," + "\"http://schema.org/price\": {" - + "\"@value\": 100.00" + "}}"; - } -} diff --git a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java b/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java deleted file mode 100644 index a320a8d0..00000000 --- a/integration/sesame/src/test/java/com/github/jsonldjava/sesame/SesameTripleCallbackTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.jsonldjava.sesame; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.util.Iterator; - -import org.junit.Test; -import org.openrdf.model.Graph; -import org.openrdf.model.Statement; -import org.openrdf.model.impl.LinkedHashModel; -import org.openrdf.model.impl.ValueFactoryImpl; -import org.openrdf.rio.ParserConfig; -import org.openrdf.rio.helpers.ParseErrorCollector; -import org.openrdf.rio.helpers.StatementCollector; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; - -public class SesameTripleCallbackTest { - - @Test - public void triplesTest() throws JsonLdError, IOException { - // String inputstring = - // "{\"@id\":{\"@id\":\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/machine/DVC-1_8\"},\"http://igreen-projekt.de/ontologies/isoxml#deviceElement\":\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceelement/DET-1_8\",\"http://igreen-projekt.de/ontologies/isoxml#deviceID\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"DVC-1\"},\"http://igreen-projekt.de/ontologies/isoxml#deviceLocalizationLabel\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"FF000000406564\"},\"http://igreen-projekt.de/ontologies/isoxml#deviceProcessData\":[\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/13_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/6_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/14_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/11_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/8_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/4_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/5_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/10_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/2_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/21_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/15_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/16_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/19_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/17_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/3_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/12_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/7_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/18_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/9_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/22_8\",\"http://pc-4107.kl.dfki.de:38080/onlinebox/resource/deviceprocessdata/20_8\"],\"http://igreen-projekt.de/ontologies/isoxml#deviceSerialNumber\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"12345\"},\"http://igreen-projekt.de/ontologies/isoxml#deviceSoftwareVersion\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"01.009\"},\"http://igreen-projekt.de/ontologies/isoxml#deviceStructureLabel\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"31303030303030\"},\"http://igreen-projekt.de/ontologies/isoxml#workingSetMasterNAME\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"A000860020800001\"},\"http://www.w3.org/1999/02/22-rdf-syntax-ns#type\":{\"@iri\":\"http://www.agroxml.de/rdfs#Machine\"},\"http://www.w3.org/2000/01/rdf-schema#label\":{\"@datatype\":\"http://www.w3.org/2001/XMLSchema#string\",\"@literal\":\"Krone Device\"}}"; - final String inputstring = "{ \"@id\":\"http://nonexistent.com/abox#Document1823812\", \"@type\":\"http://nonexistent.com/tbox#Document\" }"; - final String expectedString = "(http://nonexistent.com/abox#Document1823812, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://nonexistent.com/tbox#Document) [null]"; - final Object input = JsonUtils.fromString(inputstring); - - final Graph graph = new LinkedHashModel(); - final ParseErrorCollector parseErrorListener = new ParseErrorCollector(); - final ParserConfig parserConfig = new ParserConfig(); - final SesameTripleCallback callback = new SesameTripleCallback( - new StatementCollector(graph), ValueFactoryImpl.getInstance(), parserConfig, - parseErrorListener); - - JsonLdProcessor.toRDF(input, callback); - - final Iterator statements = graph.iterator(); - - // contains only one statement (type) - while (statements.hasNext()) { - final Statement stmt = statements.next(); - - System.out.println(stmt.toString()); - assertEquals("Output was not as expected", stmt.toString(), expectedString); - } - - assertEquals(0, parseErrorListener.getFatalErrors().size()); - assertEquals(0, parseErrorListener.getErrors().size()); - assertEquals(0, parseErrorListener.getWarnings().size()); - } - -} diff --git a/integration/sesame/src/test/resources/log4j.properties b/integration/sesame/src/test/resources/log4j.properties deleted file mode 100644 index 136eba0c..00000000 --- a/integration/sesame/src/test/resources/log4j.properties +++ /dev/null @@ -1,5 +0,0 @@ -log4j.rootLogger=INFO, R - -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/pom.xml b/pom.xml index f82d6566..05252672 100755 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,6 @@ 2.3.3 4.12 5.0.1 - 2.7.15 1.7.9 @@ -79,32 +78,6 @@ rdf.core ${clerezza.version} - - org.openrdf.sesame - sesame-bom - ${sesame.version} - - - org.openrdf.sesame - sesame-model - ${sesame.version} - - - org.openrdf.sesame - sesame-rio-api - ${sesame.version} - - - org.openrdf.sesame - sesame-rio-nquads - ${sesame.version} - - - org.openrdf.sesame - sesame-rio-testsuite - ${sesame.version} - test - junit junit @@ -155,6 +128,11 @@ mockito-core 1.10.17 + + commons-io + commons-io + 2.4 + diff --git a/tools/pom.xml b/tools/pom.xml index 3d53a30d..9845468c 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -12,17 +12,16 @@ JSON-LD Java tools jar + + 2.8.5 + + ${project.groupId} jsonld-java ${project.version} - - ${project.groupId} - jsonld-java-sesame - ${project.version} - junit junit @@ -38,9 +37,26 @@ jopt-simple 4.8 + + org.openrdf.sesame + sesame-model + ${sesame.version} + + + org.openrdf.sesame + sesame-rio-api + ${sesame.version} + + + org.openrdf.sesame + sesame-rio-jsonld + ${sesame.version} + runtime + org.openrdf.sesame sesame-rio-nquads + ${sesame.version} runtime diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index a1111f46..1587fbfc 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -26,8 +26,6 @@ import com.github.jsonldjava.core.JsonLdOptions; import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.sesame.SesameRDFParser; -import com.github.jsonldjava.sesame.SesameTripleCallback; import com.github.jsonldjava.utils.JsonUtils; public class Playground { From accb42483890f84a4394a014ed5d92354bc3573d Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 10:50:04 +1000 Subject: [PATCH 118/440] Restore two Sesame classes needed by Playground as package private for the playground --- .../github/jsonldjava/tools/Playground.java | 4 +- .../tools/SesameJSONLDRDFParser.java | 100 ++++++++ .../tools/SesameJSONLDTripleCallback.java | 221 ++++++++++++++++++ 3 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java create mode 100644 tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index 1587fbfc..530d6a21 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -220,11 +220,11 @@ public Class valueType() { final Model inModel = Rio.parse(new StringReader((String) inobj), opts.getBase(), sesameInputFormat); - outobj = JsonLdProcessor.fromRDF(inModel, opts, new SesameRDFParser()); + outobj = JsonLdProcessor.fromRDF(inModel, opts, new SesameJSONLDRDFParser()); } else if ("tordf".equals(processingOptionValue)) { opts.useNamespaces = true; outobj = JsonLdProcessor.toRDF(inobj, - new SesameTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), + new SesameJSONLDTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), opts); } else if ("expand".equals(processingOptionValue)) { outobj = JsonLdProcessor.expand(inobj, opts); diff --git a/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java b/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java new file mode 100644 index 00000000..1645e1a5 --- /dev/null +++ b/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java @@ -0,0 +1,100 @@ +package com.github.jsonldjava.tools; + +import java.util.Set; + +import org.openrdf.model.BNode; +import org.openrdf.model.Graph; +import org.openrdf.model.Literal; +import org.openrdf.model.Model; +import org.openrdf.model.Namespace; +import org.openrdf.model.Resource; +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.XMLSchema; + +import com.github.jsonldjava.core.JsonLdError; +import com.github.jsonldjava.core.RDFDataset; + +/** + * Implementation of RDFParser for Sesame-2.8. + * + * @author Peter Ansell + */ +class SesameJSONLDRDFParser implements com.github.jsonldjava.core.RDFParser { + + public void setPrefix(RDFDataset result, String fullUri, String prefix) { + result.setNamespace(fullUri, prefix); + } + + public void handleStatement(RDFDataset result, Statement nextStatement) { + // TODO: from a basic look at the code it seems some of these could be + // null values for IRIs will probably break things further down the line + // and i'm not sure yet if this should be something handled later on, or + // something that should be checked here + final String subject = getResourceValue(nextStatement.getSubject()); + final String predicate = getResourceValue(nextStatement.getPredicate()); + final Value object = nextStatement.getObject(); + final String graphName = getResourceValue(nextStatement.getContext()); + + if (object instanceof Literal) { + final Literal literal = (Literal) object; + final String value = literal.getLabel(); + final String language = literal.getLanguage(); + + String datatype = getResourceValue(literal.getDatatype()); + + // In RDF-1.1, Language Literals internally have the datatype + // rdf:langString + if (language != null && datatype == null) { + datatype = RDF.LANGSTRING.stringValue(); + } + + // In RDF-1.1, RDF-1.0 Plain Literals are now Typed Literals with + // type xsd:String + if (language == null && datatype == null) { + datatype = XMLSchema.STRING.stringValue(); + } + + result.addQuad(subject, predicate, value, datatype, language, graphName); + + } else { + result.addQuad(subject, predicate, getResourceValue((Resource) object), graphName); + } + } + + private String getResourceValue(Resource subject) { + if (subject == null) { + return null; + } else if (subject instanceof URI) { + return subject.stringValue(); + } else if (subject instanceof BNode) { + return "_:" + subject.stringValue(); + } + + throw new IllegalStateException("Did not recognise resource type: " + + subject.getClass().getName()); + } + + @Override + public RDFDataset parse(Object input) throws JsonLdError { + final RDFDataset result = new RDFDataset(); + if (input instanceof Statement) { + handleStatement(result, (Statement) input); + } else if (input instanceof Graph) { + if (input instanceof Model) { + final Set namespaces = ((Model) input).getNamespaces(); + for (final Namespace nextNs : namespaces) { + result.setNamespace(nextNs.getName(), nextNs.getPrefix()); + } + } + + for (final Statement nextStatement : (Graph) input) { + handleStatement(result, nextStatement); + } + } + return result; + } + +} diff --git a/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java b/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java new file mode 100644 index 00000000..0029da57 --- /dev/null +++ b/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java @@ -0,0 +1,221 @@ +package com.github.jsonldjava.tools; + +import java.util.List; +import java.util.Map.Entry; + +import org.openrdf.model.Resource; +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.model.impl.LinkedHashModel; +import org.openrdf.model.impl.ValueFactoryImpl; +import org.openrdf.rio.ParseErrorListener; +import org.openrdf.rio.ParserConfig; +import org.openrdf.rio.RDFHandler; +import org.openrdf.rio.RDFHandlerException; +import org.openrdf.rio.RDFParseException; +import org.openrdf.rio.helpers.ParseErrorLogger; +import org.openrdf.rio.helpers.RDFParserHelper; +import org.openrdf.rio.helpers.StatementCollector; + +import com.github.jsonldjava.core.JsonLdTripleCallback; +import com.github.jsonldjava.core.RDFDataset; + +/** + * Implementation of JsonLdTripleCallback for Sesame-2.8. + * + * @author Peter Ansell + */ +class SesameJSONLDTripleCallback implements JsonLdTripleCallback { + + private ValueFactory vf; + + private RDFHandler handler; + + private ParserConfig parserConfig; + + private final ParseErrorListener parseErrorListener; + + public SesameJSONLDTripleCallback() { + this(new StatementCollector(new LinkedHashModel())); + } + + public SesameJSONLDTripleCallback(RDFHandler nextHandler) { + this(nextHandler, ValueFactoryImpl.getInstance()); + } + + public SesameJSONLDTripleCallback(RDFHandler nextHandler, ValueFactory vf) { + this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); + } + + public SesameJSONLDTripleCallback(RDFHandler nextHandler, ValueFactory vf, + ParserConfig parserConfig, ParseErrorListener parseErrorListener) { + this.handler = nextHandler; + this.vf = vf; + this.parserConfig = parserConfig; + this.parseErrorListener = parseErrorListener; + } + + private void triple(String s, String p, String o, String graph) { + if (s == null || p == null || o == null) { + // TODO: i don't know what to do here!!!! + return; + } + + Statement result; + // This method is always called with three Resources as subject + // predicate and object + if (graph == null) { + result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o)); + } else { + result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o), + createResource(graph)); + } + + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } + } + } + + private Resource createResource(String resource) { + // Blank node without any given identifier + if (resource.equals("_:")) { + return vf.createBNode(); + } else if (resource.startsWith("_:")) { + return vf.createBNode(resource.substring(2)); + } else { + return vf.createURI(resource); + } + } + + private void triple(String s, String p, String value, String datatype, String language, + String graph) { + + if (s == null || p == null || value == null) { + // TODO: i don't know what to do here!!!! + return; + } + + final Resource subject = createResource(s); + + final URI predicate = vf.createURI(p); + final URI datatypeURI = datatype == null ? null : vf.createURI(datatype); + + Value object; + try { + object = RDFParserHelper.createLiteral(value, language, datatypeURI, getParserConfig(), + getParserErrorListener(), getValueFactory()); + } catch (final RDFParseException e) { + throw new RuntimeException(e); + } + + Statement result; + if (graph == null) { + result = vf.createStatement(subject, predicate, object); + } else { + result = vf.createStatement(subject, predicate, object, createResource(graph)); + } + + if (handler != null) { + try { + handler.handleStatement(result); + } catch (final RDFHandlerException e) { + throw new RuntimeException(e); + } + } + } + + public ParseErrorListener getParserErrorListener() { + return this.parseErrorListener; + } + + /** + * @return the handler + */ + public RDFHandler getHandler() { + return handler; + } + + /** + * @param handler + * the handler to set + */ + public void setHandler(RDFHandler handler) { + this.handler = handler; + } + + /** + * @return the parserConfig + */ + public ParserConfig getParserConfig() { + return parserConfig; + } + + /** + * @param parserConfig + * the parserConfig to set + */ + public void setParserConfig(ParserConfig parserConfig) { + this.parserConfig = parserConfig; + } + + /** + * @return the vf + */ + public ValueFactory getValueFactory() { + return vf; + } + + /** + * @param vf + * the vf to set + */ + public void setValueFactory(ValueFactory vf) { + this.vf = vf; + } + + @Override + public Object call(final RDFDataset dataset) { + if (handler != null) { + try { + handler.startRDF(); + for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { + handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); + } + } catch (final RDFHandlerException e) { + throw new RuntimeException("Could not handle start of RDF", e); + } + } + for (String graphName : dataset.keySet()) { + final List quads = dataset.getQuads(graphName); + if ("@default".equals(graphName)) { + graphName = null; + } + for (final RDFDataset.Quad quad : quads) { + if (quad.getObject().isLiteral()) { + triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad + .getObject().getValue(), quad.getObject().getDatatype(), quad + .getObject().getLanguage(), graphName); + } else { + triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad + .getObject().getValue(), graphName); + } + } + } + if (handler != null) { + try { + handler.endRDF(); + } catch (final RDFHandlerException e) { + throw new RuntimeException("Could not handle end of RDF", e); + } + } + + return getHandler(); + } + +} From 19305f997c200bca4c939bc843d49b598358439f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 11:14:44 +1000 Subject: [PATCH 119/440] Make the outputformat default value natively integrated to joptsimple --- .../com/github/jsonldjava/tools/Playground.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java index 530d6a21..ae2b8a07 100644 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java @@ -96,6 +96,7 @@ public Class valueType() { return RDFFormat.class; } }) + .defaultsTo(RDFFormat.NQUADS) .describedAs( "The output file format to use. Defaults to nquads. Valid values are: " + formats.keySet()); @@ -181,8 +182,7 @@ public Class valueType() { opts.outputForm = options.valueOf(outputForm); opts.format = options.has(outputFormat) ? options.valueOf(outputFormat) .getDefaultMIMEType() : "application/nquads"; - final RDFFormat sesameOutputFormat = options.has(outputFormat) ? options - .valueOf(outputFormat) : RDFFormat.NQUADS; + final RDFFormat sesameOutputFormat = options.valueOf(outputFormat); final RDFFormat sesameInputFormat = Rio.getParserFormatForFileName( options.valueOf(inputFile).getName(), RDFFormat.JSONLD); @@ -223,9 +223,10 @@ public Class valueType() { outobj = JsonLdProcessor.fromRDF(inModel, opts, new SesameJSONLDRDFParser()); } else if ("tordf".equals(processingOptionValue)) { opts.useNamespaces = true; - outobj = JsonLdProcessor.toRDF(inobj, - new SesameJSONLDTripleCallback(Rio.createWriter(sesameOutputFormat, System.out)), - opts); + outobj = JsonLdProcessor + .toRDF(inobj, + new SesameJSONLDTripleCallback(Rio.createWriter(sesameOutputFormat, + System.out)), opts); } else if ("expand".equals(processingOptionValue)) { outobj = JsonLdProcessor.expand(inobj, opts); } else if ("compact".equals(processingOptionValue)) { @@ -240,7 +241,7 @@ public Class valueType() { } else if ("frame".equals(processingOptionValue)) { if (ctxobj != null && !(ctxobj instanceof Map)) { System.out - .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); + .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); parser.printHelpOn(System.out); return; } From 65b3247e2b59fffcdd55f2cbf19ef26b6fc6d16b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 11:20:42 +1000 Subject: [PATCH 120/440] Rework the readme slightly --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 031e1691..5c80d54b 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,9 @@ disable the JAR Cache (see above), unless reinitiated: RDF implementation specific code -------------------------------- -All code specific to various RDF implementations (e.g. jena, sesame, etc) are stored in the [integration modules](./integration). Readmes for how to use these modules should be present in their respective folders. +All code specific to various RDF implementations are stored in the [integration modules](./integration). Readmes for how to use these modules should be present in their respective folders. + +The implementation specific integration classes for both Sesame and Jena have been moved into their respective codebases. PLAYGROUND ---------- @@ -187,14 +189,14 @@ This is a simple application which provides command line access to JSON-LD funct run the following to get usage details: - ./jsonldplayground + ./jsonldplayground --help For Developers -------------- ### Compiling & Packaging -`jsonld-java` uses maven to compile. From the base `jsonld-java` module run `mvn install -DskipTests=true` to install the jar into your local maven repository. +`jsonld-java` uses maven to compile. From the base `jsonld-java` module run `mvn clean install` to install the jar into your local maven repository. ### Running tests @@ -239,7 +241,7 @@ CHANGELOG ========= ### 2015-08-25 -* Deprecate Sesame-2.7 module in favour of sesame-rio-jsonld for Sesame-2.8 and 4.0 +* Remove Sesame-2.7 module in favour of sesame-rio-jsonld for Sesame-2.8 and 4.0 * Fix bug where parsing did not fail if content was present after the end of a full JSON top level element ### 2015-03-12 From 6fe8a9a3e45a59e59e346a49769181a4d2bd5cf1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 11:23:03 +1000 Subject: [PATCH 121/440] Release 0.6.0 --- README.md | 4 +--- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 5c80d54b..335c02c6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.5.1/README.md) - JSONLD-JAVA =========== @@ -16,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.6.0-SNAPSHOT + 0.6.0 Code example diff --git a/core/pom.xml b/core/pom.xml index 06885e2e..0405a11d 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.0-SNAPSHOT + 0.6.0 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index d301c81e..d9882c9d 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.6.0-SNAPSHOT + 0.6.0 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 9829a7fd..10973142 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.0-SNAPSHOT + 0.6.0 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 1c25ba10..68731994 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.6.0-SNAPSHOT + 0.6.0 4.0.0 jsonld-java-rdf2go diff --git a/pom.xml b/pom.xml index 05252672..cacdba52 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.6.0-SNAPSHOT + 0.6.0 JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 9845468c..04b7697f 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.0-SNAPSHOT + 0.6.0 4.0.0 jsonld-java-tools From 9abf748178af2e779b0af1c74fbd807a2ddfa8e2 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 11:27:14 +1000 Subject: [PATCH 122/440] bump to next development version --- core/pom.xml | 2 +- integration/clerezza/pom.xml | 2 +- integration/pom.xml | 2 +- integration/rdf2go/pom.xml | 2 +- pom.xml | 2 +- tools/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 0405a11d..1f4a9e13 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.0 + 0.6.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml index d9882c9d..5e7e78f5 100644 --- a/integration/clerezza/pom.xml +++ b/integration/clerezza/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.6.0 + 0.6.1-SNAPSHOT 4.0.0 jsonld-java-clerezza diff --git a/integration/pom.xml b/integration/pom.xml index 10973142..201518bf 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -3,7 +3,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.0 + 0.6.1-SNAPSHOT 4.0.0 jsonld-java-integration diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml index 68731994..ee3f2bd0 100644 --- a/integration/rdf2go/pom.xml +++ b/integration/rdf2go/pom.xml @@ -4,7 +4,7 @@ jsonld-java-integration com.github.jsonld-java - 0.6.0 + 0.6.1-SNAPSHOT 4.0.0 jsonld-java-rdf2go diff --git a/pom.xml b/pom.xml index cacdba52..5b771092 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.6.0 + 0.6.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom diff --git a/tools/pom.xml b/tools/pom.xml index 04b7697f..577a30ef 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.0 + 0.6.1-SNAPSHOT 4.0.0 jsonld-java-tools From 151351872576ad227a06acd19e6b52e2cc1f27b7 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 25 Aug 2015 11:27:52 +1000 Subject: [PATCH 123/440] update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 335c02c6..6befb64c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.6.0/README.md) + JSONLD-JAVA =========== @@ -14,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.6.0 + 0.6.1-SNAPSHOT Code example From 358c45dc4eb675d4c18b8e58003e2380cf44cc1b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 14:31:11 +1000 Subject: [PATCH 124/440] Move packages out to separate repositories to split up their dependencies and to break the circular dependency for tools --- integration/README.md | 179 ---------- integration/clerezza/README.md | 26 -- integration/clerezza/pom.xml | 75 ----- .../clerezza/ClerezzaTripleCallback.java | 105 ------ .../clerezza/ClerezzaTripleCallbackTest.java | 54 --- .../src/test/resources/log4j.properties | 5 - .../testfiles/curies-in-context.jsonld | 10 - .../test/resources/testfiles/product.jsonld | 35 -- integration/pom.xml | 19 -- integration/rdf2go/README.md | 34 -- integration/rdf2go/pom.xml | 88 ----- .../jsonldjava/rdf2go/RDF2GoRDFParser.java | 136 -------- .../rdf2go/RDF2GoTripleCallback.java | 74 ----- .../rdf2go/RDF2GoRDFParserTest.java | 111 ------- .../rdf2go/RDF2GoTripleCallbackTest.java | 42 --- .../src/test/resources/log4j.properties | 5 - jsonldplayground | 14 - tools/pom.xml | 130 -------- .../github/jsonldjava/tools/Playground.java | 309 ------------------ .../tools/SesameJSONLDRDFParser.java | 100 ------ .../tools/SesameJSONLDTripleCallback.java | 221 ------------- tools/src/main/resources/log4j.properties | 5 - 22 files changed, 1777 deletions(-) delete mode 100644 integration/README.md delete mode 100644 integration/clerezza/README.md delete mode 100644 integration/clerezza/pom.xml delete mode 100644 integration/clerezza/src/main/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallback.java delete mode 100644 integration/clerezza/src/test/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallbackTest.java delete mode 100644 integration/clerezza/src/test/resources/log4j.properties delete mode 100644 integration/clerezza/src/test/resources/testfiles/curies-in-context.jsonld delete mode 100644 integration/clerezza/src/test/resources/testfiles/product.jsonld delete mode 100644 integration/pom.xml delete mode 100644 integration/rdf2go/README.md delete mode 100644 integration/rdf2go/pom.xml delete mode 100644 integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java delete mode 100644 integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java delete mode 100644 integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java delete mode 100644 integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java delete mode 100644 integration/rdf2go/src/test/resources/log4j.properties delete mode 100755 jsonldplayground delete mode 100644 tools/pom.xml delete mode 100644 tools/src/main/java/com/github/jsonldjava/tools/Playground.java delete mode 100644 tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java delete mode 100644 tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java delete mode 100644 tools/src/main/resources/log4j.properties diff --git a/integration/README.md b/integration/README.md deleted file mode 100644 index 0cab0b40..00000000 --- a/integration/README.md +++ /dev/null @@ -1,179 +0,0 @@ -JSONLD-JAVA INTEGRATION MODULES -=============================== - -This is the base package to provide JSON-LD integration with other Java RDF libraries. - -CREATING AN INTEGRATION MODULE -============================== - -Fork the jsonld-java project ----------------------------- - -If you're creating a module for a RDF library that isn't already supported by the jsonld-java integration modules you can create your module directly in the jsonld-java project. This will allow other people who may be interested in your module to find it easier and allow it to be released along with the core code and updated by the comunity. - -See https://help.github.com/articles/fork-a-repo for details on forking a repository. - -Create module in Eclipse ------------------------- - -### Install m2e - -Make sure you have [m2e](http://eclipse.org/m2e/) installed. - -### Import `jsonld-java` project into Eclipse - - * `File` -> `Import` - * Select `Existing Maven Projects` - * `Browse` to the directory you cloned `jsonld-java` to - * `Select All` - * `Finish` - -### Create new Maven Module - - * Right click on the `jsonld-java-integration` project and select `New` -> `Project` - * Select `Maven Module` - * Enter a `Module Name` which matches the RDF Library you're integrating (e.g. `jena`) - * `Next` -> `Next` (you should now be at the `Specify Archetype parameters` page - * Change `Package` to `com.github.jsonldjava.YOURMODULE` - * `Finish` - -### Clean up automatically generated pom.xml - -Make the generated pom.xml match the one listed below. - -### Remove generated code - -Delete the App.java and AppTest.java files. - -Create module manually ----------------------- - -### Create folder for your module - -After cloning your fork of jsonld-java, create a new directory for your module under `/jsonld-java/integration/`. - -### Create pom.xml for your module - -Here is the basic outline for what your module's pom.xml should look like - - - - - jsonld-java-integration - com.github.jsonld-java - 0.1-SNAPSHOT - - 4.0.0 - jsonld-java-{your module} - JSONLD Java :: {your module name} - JSON-LD Java integration module for {RDF Library your module integrates} - jar - - - - {YOU} - - - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - junit - junit - test - - - org.slf4j - slf4j-jdk14 - test - - - - -Make sure you edit the following: - * `project/artifactId` : set this to `jsonld-java-{module id}`, where `{module id}` usually represents the RDF library you're integrating (e.g. `jsonld-java-jena`) - * `project/name` : set this to `JSONLD Java :: {Module Name}`, wher `{module name}` is usually the name of the RDF library you're integrating. - * `project/description` - * `project/developers/developer/...` : Give youself credit by filling in the developer field. At least put your `` in ([see here for all available options](http://maven.apache.org/pom.html#Developers)). - * `project/dependencies/...` : remember to add any dependencies your project needs - -### Import into your favorite editor - -For Example: Follow the first few steps in the section above to import the whole `jsonld-java` project or only your new module into eclipse. - -Create RDFParser Implementation -------------------------------- - -The interface `com.github.jsonldjava.core.RDFParser` is used to parse RDF from the library into the JSONLD-Java internal RDF format. See the documentation in [`RDFParser.java`](../core/src/main/java/com/github/jsonldjava/core/RDFParser.java) for details on how to implement this interface. - -Create TripleCallback Implementation ------------------------------------- - -The interface `com.github.jsonldjava.core.JSONLDTripleCallback` is used to generate a representation of the JSON-LD input in the RDF library. See the documentation in [`JSONLDTripleCallback.java`](../core/src/main/java/com/github/jsonldjava/core/JSONLDTripleCallback.java) for details on how to implement this interface. - -Using your Implementations --------------------------- - -### RDFParser - -A JSONLD RDF parser is a class that can parse your frameworks' RDF model -and generate JSON-LD. - -There are two ways to use your `RDFParser` implementation. - -Register your parser with the `JSONLD` class and set `options.format` when you call `fromRDF` - - JSONLD.registerRDFParser("format/identifier", new YourRDFParser()); - Object jsonld = JSONLD.fromRDF(yourInput, new Options("") {{ format = "format/identifier" }}); - -or pass an instance of your `RDFParser` into the `fromRDF` function - - Object jsonld = JSONLD.fromRDF(yourInput, new YourRDFParser()); - -### JSONLDTripleCallback - -A JSONLD triple callback is a class that can populate your framework's -RDF model from JSON-LD - being called for each triple (technically quad). - -Pass an instance of your `TripleCallback` to `JSONLD.toRDF` - - Object yourOutput = JSONLD.toRDF(jsonld, new YourTripleCallback()); - - -Integrate with your framework ------------------------------ -Your framework might have its own system of readers and writers, where -you should register JSON-LD as a supported format. Remember that here -the "parse" direction is opposite of above, a 'reader' in e.g. Jena will -be a class that can parse JSON-LD and populate a Jena model. - - - -Write Tests ------------ - -It's helpful to have a test or two for your implementations to make sure they work and continue to work with future versions. - -Write README.md ---------------- - -Write a `README.md` file under `jsonld-java/integration//` with instrutions on how to use your module. - -Submit your module ------------------- - -Once you've `commit`ted your code, and `push`ed it into your github fork you can issue a [Pull Request](https://help.github.com/articles/using-pull-requests) so that we can pull your new module into the jsonld-java codebase. diff --git a/integration/clerezza/README.md b/integration/clerezza/README.md deleted file mode 100644 index 9208af61..00000000 --- a/integration/clerezza/README.md +++ /dev/null @@ -1,26 +0,0 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.3/integration/clerezza/README.md) - -JSONLD-Java Clerezza Integration module -======================================= - -USAGE -===== - -From Maven ----------- - - - com.github.jsonld-java - jsonld-java-clerezza - 0.4-SNAPSHOT - - -(Adjust for most recent , as found in ``pom.xml``). - - -ClerezzaTripleCallback ------------------- - -The ClerezzaTripleCallback returns an instance of `org.apache.clerezza.rdf.core.MGraph` - -See [ClerezzaTripleCallbackTest.java](./src/test/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallbackTest.java) for example Usage. diff --git a/integration/clerezza/pom.xml b/integration/clerezza/pom.xml deleted file mode 100644 index 5e7e78f5..00000000 --- a/integration/clerezza/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - jsonld-java-integration - com.github.jsonld-java - 0.6.1-SNAPSHOT - - 4.0.0 - jsonld-java-clerezza - JSONLD Java :: Clerezza Integration - JSON-LD Java integration module for Clerezza - bundle - - - - Reto Bachmann-Gmür - - - Tristan King - - - Peter Ansell - - - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - org.apache.clerezza - rdf.core - - - junit - junit - test - - - org.slf4j - slf4j-log4j12 - test - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - - - org.apache.felix - maven-bundle-plugin - true - - - org.jacoco - jacoco-maven-plugin - - - - - diff --git a/integration/clerezza/src/main/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallback.java b/integration/clerezza/src/main/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallback.java deleted file mode 100644 index cc91d364..00000000 --- a/integration/clerezza/src/main/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallback.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.github.jsonldjava.clerezza; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.clerezza.rdf.core.BNode; -import org.apache.clerezza.rdf.core.Language; -import org.apache.clerezza.rdf.core.MGraph; -import org.apache.clerezza.rdf.core.NonLiteral; -import org.apache.clerezza.rdf.core.Resource; -import org.apache.clerezza.rdf.core.UriRef; -import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl; -import org.apache.clerezza.rdf.core.impl.SimpleMGraph; -import org.apache.clerezza.rdf.core.impl.TripleImpl; -import org.apache.clerezza.rdf.core.impl.TypedLiteralImpl; - -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; - -public class ClerezzaTripleCallback implements JsonLdTripleCallback { - - private MGraph mGraph = new SimpleMGraph(); - private Map bNodeMap = new HashMap(); - - public void setMGraph(MGraph mGraph) { - this.mGraph = mGraph; - bNodeMap = new HashMap(); - } - - public MGraph getMGraph() { - return mGraph; - } - - private void triple(String s, String p, String o, String graph) { - if (s == null || p == null || o == null) { - // TODO: i don't know what to do here!!!! - return; - } - - final NonLiteral subject = getNonLiteral(s); - final UriRef predicate = new UriRef(p); - final NonLiteral object = getNonLiteral(o); - mGraph.add(new TripleImpl(subject, predicate, object)); - } - - private void triple(String s, String p, String value, String datatype, String language, - String graph) { - final NonLiteral subject = getNonLiteral(s); - final UriRef predicate = new UriRef(p); - Resource object; - if (language != null) { - object = new PlainLiteralImpl(value, new Language(language)); - } else { - if (datatype != null) { - object = new TypedLiteralImpl(value, new UriRef(datatype)); - } else { - object = new PlainLiteralImpl(value); - } - } - - mGraph.add(new TripleImpl(subject, predicate, object)); - } - - private NonLiteral getNonLiteral(String s) { - if (s.startsWith("_:")) { - return getBNode(s); - } else { - return new UriRef(s); - } - } - - private BNode getBNode(String s) { - if (bNodeMap.containsKey(s)) { - return bNodeMap.get(s); - } else { - final BNode result = new BNode(); - bNodeMap.put(s, result); - return result; - } - } - - @Override - public Object call(RDFDataset dataset) { - for (String graphName : dataset.graphNames()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), quad.getObject().getDatatype(), quad - .getObject().getLanguage(), graphName); - } else { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), graphName); - } - } - } - - return getMGraph(); - } - -} diff --git a/integration/clerezza/src/test/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallbackTest.java b/integration/clerezza/src/test/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallbackTest.java deleted file mode 100644 index dac25e7c..00000000 --- a/integration/clerezza/src/test/java/com/github/jsonldjava/clerezza/ClerezzaTripleCallbackTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.github.jsonldjava.clerezza; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.clerezza.rdf.core.MGraph; -import org.apache.clerezza.rdf.core.Triple; -import org.junit.Test; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; - -public class ClerezzaTripleCallbackTest { - - @Test - public void triplesTest() throws IOException, JsonLdError { - final InputStream in = getClass().getClassLoader().getResourceAsStream( - "testfiles/product.jsonld"); - final Object input = JsonUtils.fromInputStream(in); - - final ClerezzaTripleCallback callback = new ClerezzaTripleCallback(); - - final MGraph graph = (MGraph) JsonLdProcessor.toRDF(input, callback); - - for (final Triple t : graph) { - System.out.println(t); - } - assertEquals("Graph size", 13, graph.size()); - - } - - @Test - public void curiesInContextTest() throws IOException, JsonLdError { - final InputStream in = getClass().getClassLoader().getResourceAsStream( - "testfiles/curies-in-context.jsonld"); - final Object input = JsonUtils.fromInputStream(in); - - final ClerezzaTripleCallback callback = new ClerezzaTripleCallback(); - - final MGraph graph = (MGraph) JsonLdProcessor.toRDF(input, callback); - - for (final Triple t : graph) { - System.out.println(t); - assertTrue("Predicate got fully expanded", t.getPredicate().getUnicodeString() - .startsWith("http")); - } - assertEquals("Graph size", 3, graph.size()); - - } -} diff --git a/integration/clerezza/src/test/resources/log4j.properties b/integration/clerezza/src/test/resources/log4j.properties deleted file mode 100644 index 136eba0c..00000000 --- a/integration/clerezza/src/test/resources/log4j.properties +++ /dev/null @@ -1,5 +0,0 @@ -log4j.rootLogger=INFO, R - -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/integration/clerezza/src/test/resources/testfiles/curies-in-context.jsonld b/integration/clerezza/src/test/resources/testfiles/curies-in-context.jsonld deleted file mode 100644 index 0490d79e..00000000 --- a/integration/clerezza/src/test/resources/testfiles/curies-in-context.jsonld +++ /dev/null @@ -1,10 +0,0 @@ -{ - "@context": { - "Person": "foaf:Person", - "foaf": "http://xmlns.com/foaf/0.1/", - "name": "foaf:name" - }, - "@type": "Person", - "name": "Santa Claus", - "foaf:nick": "Sämi" -} \ No newline at end of file diff --git a/integration/clerezza/src/test/resources/testfiles/product.jsonld b/integration/clerezza/src/test/resources/testfiles/product.jsonld deleted file mode 100644 index 666d2cfb..00000000 --- a/integration/clerezza/src/test/resources/testfiles/product.jsonld +++ /dev/null @@ -1,35 +0,0 @@ -{ - "@context": { - "gr": "http://purl.org/goodrelations/v1#", - "pto": "http://www.productontology.org/id/", - "foaf": "http://xmlns.com/foaf/0.1/", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "foaf:page": { - "@type": "@id" - }, - "gr:acceptedPaymentMethods": { - "@type": "@id" - }, - "gr:hasBusinessFunction": { - "@type": "@id" - }, - "gr:hasCurrencyValue": { - "@type": "xsd:float" - } - }, - "@id": "http://example.org/cars/for-sale#tesla", - "@type": "gr:Offering", - "gr:name": "Used Tesla Roadster", - "gr:description": "Need to sell fast and furiously", - "gr:hasBusinessFunction": "gr:Sell", - "gr:acceptedPaymentMethods": "gr:Cash", - "gr:hasPriceSpecification": { - "gr:hasCurrencyValue": "85000", - "gr:hasCurrency": "USD" - }, - "gr:includes": { - "@type": ["gr:Individual", "pto:Vehicle"], - "gr:name": "Tesla Roadster", - "foaf:page": "http://www.teslamotors.com/roadster" - } -} \ No newline at end of file diff --git a/integration/pom.xml b/integration/pom.xml deleted file mode 100644 index 201518bf..00000000 --- a/integration/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - jsonld-java-parent - com.github.jsonld-java - 0.6.1-SNAPSHOT - - 4.0.0 - jsonld-java-integration - JSONLD Java :: Integration Modules Parent - Json-LD integration with other java RDF frameworks - pom - - - - clerezza - rdf2go - - diff --git a/integration/rdf2go/README.md b/integration/rdf2go/README.md deleted file mode 100644 index 48a067e0..00000000 --- a/integration/rdf2go/README.md +++ /dev/null @@ -1,34 +0,0 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.3/integration/rdf2go/README.md) - -JSONLD-Java RDF2Go Integration module -===================================== - -USAGE -===== - -From Maven ----------- - - - com.github.jsonld-java - jsonld-java-rdf2go - 0.4-SNAPSHOT - - -(Adjust for most recent , as found in ``pom.xml``). - - -Serializing RDF into JSON-LD using RDF2GoRDFParser --------------------------------------------------- - - import com.github.jsonldjava.rdf2go.*; - - ModelSet modelSet = ...; // also works with a Model - RDF2GoRDFParser parser = new RDF2GoRDFParser(); - Object json = JSONLD.fromRDF(modelSet, parser); - -Parsing JSON-LD, and convert it into a ModelSet ------------------------------------------------ - - RDF2GoTripleCallback callback = new RDF2GoTripleCallback(); - ModelSet model = (ModelSet) JSONLD.toRDF(input, callback); diff --git a/integration/rdf2go/pom.xml b/integration/rdf2go/pom.xml deleted file mode 100644 index ee3f2bd0..00000000 --- a/integration/rdf2go/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - jsonld-java-integration - com.github.jsonld-java - 0.6.1-SNAPSHOT - - 4.0.0 - jsonld-java-rdf2go - JSONLD Java :: RDF2Go - JSON-LD Java integration module for RDF2Go - bundle - - - - ismriv - Ismael Rivera - http://ismaelrivera.es - - - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - junit - junit - test - - - org.slf4j - slf4j-log4j12 - test - - - org.semweb4j - rdf2go.api - ${rdf2go.version} - compile - - - org.slf4j - slf4j-log4j12 - - - log4j - log4j - - - - - org.semweb4j - rdf2go.impl.sesame - ${rdf2go.version} - test - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - - - org.apache.felix - maven-bundle-plugin - true - - - org.jacoco - jacoco-maven-plugin - - - - diff --git a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java deleted file mode 100644 index e8b3c27f..00000000 --- a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParser.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.github.jsonldjava.rdf2go; - -import java.util.Map; - -import org.ontoware.aifbcommons.collection.ClosableIterator; -import org.ontoware.rdf2go.model.Model; -import org.ontoware.rdf2go.model.ModelSet; -import org.ontoware.rdf2go.model.Statement; -import org.ontoware.rdf2go.model.node.DatatypeLiteral; -import org.ontoware.rdf2go.model.node.LanguageTagLiteral; -import org.ontoware.rdf2go.model.node.Literal; -import org.ontoware.rdf2go.model.node.Node; -import org.ontoware.rdf2go.model.node.Resource; -import org.ontoware.rdf2go.model.node.URI; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdError.Error; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.core.RDFParser; - -/** - * Implementation of {@link RDFParser} which serializes the contents of a - * {@link ModelSet} or {@link Model} into a JSON-LD document. - * - * @author Ismael Rivera - */ -public class RDF2GoRDFParser implements RDFParser { - - private void importModel(RDFDataset result, Model model) { - // add prefixes/namespaces - final Map nsPrefixMap = model.getNamespaces(); - for (final String prefix : nsPrefixMap.keySet()) { - result.setNamespace(prefix, nsPrefixMap.get(prefix)); - } - - // add all statements from model - final URI context = model.getContextURI(); - final ClosableIterator statements = model.iterator(); - while (statements.hasNext()) { - handleStatement(result, statements.next(), context); - } - statements.close(); - } - - private void importModelSet(RDFDataset result, ModelSet modelSet, URI... contexts) { - final ClosableIterator models = modelSet.getModels(); - while (models.hasNext()) { - importModel(result, models.next()); - } - models.close(); - } - - private void handleStatement(RDFDataset result, Statement statement, URI context) { - final Resource subject = statement.getSubject(); - final URI predicate = statement.getPredicate(); - final Node object = statement.getObject(); - - if (object instanceof DatatypeLiteral) { - final DatatypeLiteral literal = (DatatypeLiteral) object; - addStatement(result, context, subject, predicate, literal.getValue(), - literal.getDatatype()); - } else if (object instanceof LanguageTagLiteral) { - final LanguageTagLiteral literal = (LanguageTagLiteral) object; - addStatement(result, context, subject, predicate, literal.getValue(), - literal.getLanguageTag()); - } else if (object instanceof Literal) { - final Literal literal = (Literal) object; - addStatement(result, context, subject, predicate, literal.getValue()); - } else { - addStatement(result, context, subject, predicate, object.asURI()); - } - } - - private void addStatement(RDFDataset result, URI context, Resource subject, URI predicate, - URI object) { - if (context == null) { - result.addTriple(subject.toString(), predicate.toString(), object.toString()); - } else { - result.addQuad(subject.toString(), predicate.toString(), object.toString(), - context.toString()); - } - } - - private void addStatement(RDFDataset result, URI context, Resource subject, URI predicate, - String value) { - if (context == null) { - result.addTriple(subject.toString(), predicate.toString(), value, null, null); - } else { - result.addQuad(subject.toString(), predicate.toString(), value, null, null, - context.toString()); - } - } - - private void addStatement(RDFDataset result, URI context, Resource subject, URI predicate, - String value, URI datatype) { - if (context == null) { - result.addTriple(subject.toString(), predicate.toString(), value, datatype.toString(), - null); - } else { - result.addQuad(subject.toString(), predicate.toString(), value, datatype.toString(), - null, context.toString()); - } - } - - private void addStatement(RDFDataset result, URI context, Resource subject, URI predicate, - String value, String language) { - if (context == null) { - result.addTriple(subject.toString(), predicate.toString(), value, null, language); - } else { - result.addQuad(subject.toString(), predicate.toString(), value, null, language, - context.toString()); - } - } - - @Override - public RDFDataset parse(Object input) throws JsonLdError { - final RDFDataset result = new RDFDataset(); - - // empty dataset if no input given - if (input == null) { - return result; - } - - if (input instanceof ModelSet) { - importModelSet(result, (ModelSet) input); - } else if (input instanceof Model) { - importModel(result, (Model) input); - } else { - throw new JsonLdError(Error.INVALID_INPUT, - "RDF2Go parser expects a Model or ModelSet object as input"); - } - - return result; - } - -} \ No newline at end of file diff --git a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java b/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java deleted file mode 100644 index a6cfa22a..00000000 --- a/integration/rdf2go/src/main/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallback.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.github.jsonldjava.rdf2go; - -import java.util.List; - -import org.ontoware.rdf2go.RDF2Go; -import org.ontoware.rdf2go.model.ModelSet; -import org.ontoware.rdf2go.model.node.Node; -import org.ontoware.rdf2go.model.node.Resource; -import org.ontoware.rdf2go.model.node.URI; - -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; - -/** - * Implementation of {@link JsonLdTripleCallback} which serializes JSONLD - * datasets into a {@link ModelSet} object. - * - * @author Ismael Rivera - */ -public class RDF2GoTripleCallback implements JsonLdTripleCallback { - - private final ModelSet sinkModel; - - public RDF2GoTripleCallback() { - this.sinkModel = RDF2Go.getModelFactory().createModelSet(); - this.sinkModel.open(); - } - - private void triple(String s, String p, String o, String graph) { - triple(sinkModel.createURI(s), sinkModel.createURI(p), sinkModel.createURI(o), graph); - } - - private void triple(String s, String p, String value, String datatype, String language, - String graph) { - Node object = null; - if (language != null) { - object = sinkModel.createLanguageTagLiteral(value, language); - } else if (datatype != null) { - object = sinkModel.createDatatypeLiteral(value, sinkModel.createURI(datatype)); - } else { - object = sinkModel.createPlainLiteral(value); - } - - triple(sinkModel.createURI(s), sinkModel.createURI(p), object, graph); - } - - private void triple(Resource subject, URI predicate, Node object, String graph) { - final URI context = graph == null ? null : sinkModel.createURI(graph); - sinkModel.addStatement(context, subject, predicate, object); - } - - @Override - public Object call(RDFDataset dataset) { - for (String graphName : dataset.keySet()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), quad.getObject().getDatatype(), quad - .getObject().getLanguage(), graphName); - } else { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), graphName); - } - } - } - - return sinkModel; - } - -} diff --git a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java deleted file mode 100644 index c0ee196c..00000000 --- a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoRDFParserTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.github.jsonldjava.rdf2go; - -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.ontoware.rdf2go.RDF2Go; -import org.ontoware.rdf2go.model.Model; -import org.ontoware.rdf2go.model.Syntax; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.Obj; - -/** - * Unit tests for {@link RDF2GoRDFParser} containing a single test, including - * literals with datatype and language. - * - * @author Ismael Rivera - */ -public class RDF2GoRDFParserTest { - - @Test - public void testFromRDF() throws JsonLdError, IOException { - - final String turtle = "@prefix const: .\n" - + "@prefix xsd: .\n" - + " const:code \"123\" .\n" - + " const:code \"23.3364\"^^xsd:decimal .\n" - + " const:code \"ABC\"^^xsd:string .\n" - + " const:code \"English\"@en .\n"; - - final List> expected = new ArrayList>() { - { - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo1"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "123"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo2"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "23.3364"); - put("@type", "http://www.w3.org/2001/XMLSchema#decimal"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo3"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "ABC"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://localhost:8080/foo4"); - put("http://foo.com/code", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "English"); - put("@language", "en"); - } - }); - } - }); - } - }); - } - }; - - final RDF2GoRDFParser parser = new RDF2GoRDFParser(); - - final Model modelResult = RDF2Go.getModelFactory().createModel().open(); - modelResult.readFrom(new ByteArrayInputStream(turtle.getBytes()), Syntax.Turtle); - final Object json = JsonLdProcessor.fromRDF(modelResult, parser); - - assertTrue(Obj.equals(json, expected)); - } - -} diff --git a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java b/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java deleted file mode 100644 index b93b62c2..00000000 --- a/integration/rdf2go/src/test/java/com/github/jsonldjava/rdf2go/RDF2GoTripleCallbackTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.github.jsonldjava.rdf2go; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.io.IOException; - -import org.junit.Test; -import org.ontoware.aifbcommons.collection.ClosableIterator; -import org.ontoware.rdf2go.model.ModelSet; -import org.ontoware.rdf2go.model.Statement; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; - -/** - * Unit tests for {@link RDF2GoTripleCallback}. - * - * @author Ismael Rivera - */ -public class RDF2GoTripleCallbackTest { - - @Test - public void testToRDF() throws JsonLdError, IOException { - final String inputstring = "{ `@id`:`http://nonexistent.com/abox#Document1823812`, `@type`:`http://nonexistent.com/tbox#Document` }" - .replace('`', '"'); - final String expectedString = "null - http://nonexistent.com/abox#Document1823812 - http://www.w3.org/1999/02/22-rdf-syntax-ns#type - http://nonexistent.com/tbox#Document"; - final Object input = JsonUtils.fromString(inputstring); - - final RDF2GoTripleCallback callback = new RDF2GoTripleCallback(); - - final ModelSet model = (ModelSet) JsonLdProcessor.toRDF(input, callback); - - // contains only one statement (type) - final ClosableIterator statements = model.iterator(); - final Statement stmt = statements.next(); - assertEquals(expectedString, stmt.getContext() + " - " + stmt.toString()); - assertFalse("Deserialized RDF contains more triples than expected", statements.hasNext()); - } - -} diff --git a/integration/rdf2go/src/test/resources/log4j.properties b/integration/rdf2go/src/test/resources/log4j.properties deleted file mode 100644 index 136eba0c..00000000 --- a/integration/rdf2go/src/test/resources/log4j.properties +++ /dev/null @@ -1,5 +0,0 @@ -log4j.rootLogger=INFO, R - -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/jsonldplayground b/jsonldplayground deleted file mode 100755 index a838ff3a..00000000 --- a/jsonldplayground +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# This script runs the JSONLDPlayground code. -# Before running this script for the first time -# you may need to run: -# chmod +x jsonldplayground -# -# run ./jsonldplayground for the usage - -if [ ! -d "tools/target/appassembler/bin" ]; then - mvn -quiet clean install -DskipTests -fi - -chmod u+x tools/target/appassembler/bin/* -tools/target/appassembler/bin/jsonldplayground "$@" diff --git a/tools/pom.xml b/tools/pom.xml deleted file mode 100644 index 577a30ef..00000000 --- a/tools/pom.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - jsonld-java-parent - com.github.jsonld-java - 0.6.1-SNAPSHOT - - 4.0.0 - jsonld-java-tools - JSONLD Java :: Tools - JSON-LD Java tools - jar - - - 2.8.5 - - - - - ${project.groupId} - jsonld-java - ${project.version} - - - junit - junit - test - - - org.slf4j - slf4j-log4j12 - runtime - - - net.sf.jopt-simple - jopt-simple - 4.8 - - - org.openrdf.sesame - sesame-model - ${sesame.version} - - - org.openrdf.sesame - sesame-rio-api - ${sesame.version} - - - org.openrdf.sesame - sesame-rio-jsonld - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-nquads - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-turtle - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-rdfxml - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-rdfjson - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-ntriples - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-trig - ${sesame.version} - runtime - - - org.openrdf.sesame - sesame-rio-trix - ${sesame.version} - runtime - - - - - - - org.codehaus.mojo - appassembler-maven-plugin - - - package - - assemble - - - - - - - com.github.jsonldjava.tools.Playground - jsonldplayground - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - - - - - - diff --git a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java b/tools/src/main/java/com/github/jsonldjava/tools/Playground.java deleted file mode 100644 index ae2b8a07..00000000 --- a/tools/src/main/java/com/github/jsonldjava/tools/Playground.java +++ /dev/null @@ -1,309 +0,0 @@ -package com.github.jsonldjava.tools; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import joptsimple.OptionException; -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import joptsimple.OptionSpec; -import joptsimple.ValueConversionException; -import joptsimple.ValueConverter; - -import org.openrdf.model.Model; -import org.openrdf.rio.RDFFormat; -import org.openrdf.rio.RDFParserRegistry; -import org.openrdf.rio.Rio; - -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; - -public class Playground { - - private static Set getProcessingOptions() { - return new LinkedHashSet(Arrays.asList("expand", "compact", "frame", "normalize", - "flatten", "fromrdf", "tordf")); - } - - private static boolean hasContext(String opt) { - return "compact".equals(opt) || "frame".equals(opt) || "flatten".equals(opt); - } - - private static Map getOutputFormats() { - final Map outputFormats = new HashMap(); - - for (final RDFFormat format : RDFParserRegistry.getInstance().getKeys()) { - outputFormats.put(format.getName().replaceAll("-", "").replaceAll("/", "") - .toLowerCase(), format); - } - - return outputFormats; - } - - public static void main(String[] args) throws Exception { - - final Map formats = getOutputFormats(); - final Set outputForms = new LinkedHashSet(Arrays.asList("compacted", - "expanded", "flattened")); - - final OptionParser parser = new OptionParser(); - - final OptionSpec help = parser.accepts("help").forHelp(); - - final OptionSpec base = parser.accepts("base").withRequiredArg() - .ofType(String.class).defaultsTo("").describedAs("base URI"); - - final OptionSpec inputFile = parser.accepts("inputFile").withRequiredArg() - .ofType(File.class).required().describedAs("The input file"); - - final OptionSpec context = parser.accepts("context").withRequiredArg() - .ofType(File.class).describedAs("The context"); - - final OptionSpec outputFormat = parser - .accepts("format") - .withOptionalArg() - .ofType(String.class) - .withValuesConvertedBy(new ValueConverter() { - @Override - public RDFFormat convert(String arg0) { - // Normalise the name to provide alternatives - final String formatName = arg0.replaceAll("-", "").replaceAll("/", "") - .toLowerCase(); - if (formats.containsKey(formatName)) { - return formats.get(formatName); - } - throw new ValueConversionException("Format was not known: " + arg0 - + " (Valid values are: " + formats.keySet() + ")"); - } - - @Override - public String valuePattern() { - return null; - } - - @Override - public Class valueType() { - return RDFFormat.class; - } - }) - .defaultsTo(RDFFormat.NQUADS) - .describedAs( - "The output file format to use. Defaults to nquads. Valid values are: " - + formats.keySet()); - - final OptionSpec processingOption = parser - .accepts("process") - .withRequiredArg() - .ofType(String.class) - .required() - .withValuesConvertedBy(new ValueConverter() { - @Override - public String convert(String value) { - if (getProcessingOptions().contains(value.toLowerCase())) { - return value.toLowerCase(); - } - throw new ValueConversionException("Processing option was not known: " - + value + " (Valid values are: " + getProcessingOptions() + ")"); - } - - @Override - public Class valueType() { - return String.class; - } - - @Override - public String valuePattern() { - return null; - } - }) - .describedAs( - "The processing to perform. Valid values are: " - + getProcessingOptions().toString()); - - final OptionSpec outputForm = parser - .accepts("outputForm") - .withOptionalArg() - .ofType(String.class) - .defaultsTo("expanded") - .withValuesConvertedBy(new ValueConverter() { - @Override - public String convert(String value) { - if (outputForms.contains(value.toLowerCase())) { - return value.toLowerCase(); - } - throw new ValueConversionException("Output form was not known: " + value - + " (Valid values are: " + outputForms + ")"); - } - - @Override - public String valuePattern() { - return null; - } - - @Override - public Class valueType() { - return String.class; - } - }) - .describedAs( - "The way to output the results from fromRDF. Defaults to expanded. Valid values are: " - + outputForms); - - OptionSet options = null; - - try { - options = parser.parse(args); - } catch (final OptionException e) { - System.out.println(e.getMessage()); - parser.printHelpOn(System.out); - throw e; - } - - if (options.has(help)) { - parser.printHelpOn(System.out); - return; - } - - final JsonLdOptions opts = new JsonLdOptions(""); - Object inobj = null; - Object ctxobj = null; - - opts.setBase(options.valueOf(base)); - opts.outputForm = options.valueOf(outputForm); - opts.format = options.has(outputFormat) ? options.valueOf(outputFormat) - .getDefaultMIMEType() : "application/nquads"; - final RDFFormat sesameOutputFormat = options.valueOf(outputFormat); - final RDFFormat sesameInputFormat = Rio.getParserFormatForFileName( - options.valueOf(inputFile).getName(), RDFFormat.JSONLD); - - final String processingOptionValue = options.valueOf(processingOption); - - if (!options.valueOf(inputFile).exists()) { - System.out.println("Error: input file \"" + options.valueOf(inputFile) - + "\" doesn't exist"); - parser.printHelpOn(System.out); - return; - } - // if base is currently null, set it - if (opts.getBase() == null || opts.getBase().equals("")) { - opts.setBase(options.valueOf(inputFile).toURI().toASCIIString()); - } - - if ("fromrdf".equals(processingOptionValue)) { - inobj = readFile(options.valueOf(inputFile)); - } else { - inobj = JsonUtils.fromInputStream(new FileInputStream(options.valueOf(inputFile))); - } - - if (hasContext(processingOptionValue) && options.has(context)) { - if (!options.valueOf(context).exists()) { - System.out.println("Error: context file \"" + options.valueOf(context) - + "\" doesn't exist"); - parser.printHelpOn(System.out); - return; - } - ctxobj = JsonUtils.fromInputStream(new FileInputStream(options.valueOf(context))); - } - - Object outobj = null; - if ("fromrdf".equals(processingOptionValue)) { - final Model inModel = Rio.parse(new StringReader((String) inobj), opts.getBase(), - sesameInputFormat); - - outobj = JsonLdProcessor.fromRDF(inModel, opts, new SesameJSONLDRDFParser()); - } else if ("tordf".equals(processingOptionValue)) { - opts.useNamespaces = true; - outobj = JsonLdProcessor - .toRDF(inobj, - new SesameJSONLDTripleCallback(Rio.createWriter(sesameOutputFormat, - System.out)), opts); - } else if ("expand".equals(processingOptionValue)) { - outobj = JsonLdProcessor.expand(inobj, opts); - } else if ("compact".equals(processingOptionValue)) { - if (ctxobj == null) { - System.out.println("Error: The compaction context must not be null."); - parser.printHelpOn(System.out); - return; - } - outobj = JsonLdProcessor.compact(inobj, ctxobj, opts); - } else if ("normalize".equals(processingOptionValue)) { - outobj = JsonLdProcessor.normalize(inobj, opts); - } else if ("frame".equals(processingOptionValue)) { - if (ctxobj != null && !(ctxobj instanceof Map)) { - System.out - .println("Invalid JSON-LD syntax; a JSON-LD frame must be a single object."); - parser.printHelpOn(System.out); - return; - } - outobj = JsonLdProcessor.frame(inobj, ctxobj, opts); - } else if ("flatten".equals(processingOptionValue)) { - outobj = JsonLdProcessor.flatten(inobj, ctxobj, opts); - } else { - System.out - .println("Error: invalid processing option \"" + processingOptionValue + "\""); - parser.printHelpOn(System.out); - return; - } - - if ("tordf".equals(processingOptionValue)) { - // Already serialised above - } else if ("normalize".equals(processingOptionValue)) { - System.out.println((String) outobj); - } else { - System.out.println(JsonUtils.toPrettyString(outobj)); - } - } - - private static String readFile(File in) throws IOException { - final BufferedReader buf = new BufferedReader(new InputStreamReader( - new FileInputStream(in), "UTF-8")); - String inobj = ""; - try { - String line; - while ((line = buf.readLine()) != null) { - line = line.trim(); - inobj = (inobj) + line + "\n"; - } - } finally { - buf.close(); - } - return inobj; - } - - // private static void usage() { - // System.out.println("Usage: jsonldplayground "); - // System.out.println("\tinput: a filename or JsonLdUrl to the rdf input (in rdfxml or n3)"); - // System.out.println("\toptions:"); - // System.out - // .println("\t\t--ignorekeys : a (space separated) list of keys to ignore (e.g. @geojson)"); - // System.out.println("\t\t--base : base URI"); - // System.out.println("\t\t--debug: Print out stack traces when errors occur"); - // System.out.println("\t\t--expand : expand the input JSON-LD"); - // System.out - // .println("\t\t--compact : compact the input JSON-LD applying the optional context file"); - // System.out - // .println("\t\t--normalize : normalize the input JSON-LD outputting as format (defaults to nquads)"); - // System.out - // .println("\t\t--frame : frame the input JSON-LD with the optional frame file"); - // System.out - // .println("\t\t--flatten : flatten the input JSON-LD applying the optional context file"); - // System.out - // .println("\t\t--fromRDF : generate JSON-LD from the input rdf (format defaults to nquads)"); - // System.out - // .println("\t\t--toRDF : generate RDF from the input JSON-LD (format defaults to nquads)"); - // System.out - // .println("\t\t--outputForm [compacted|expanded|flattened] : the way to output the results from fromRDF (defaults to expanded)"); - // System.out.println("\t\t--simplify : simplify the input JSON-LD"); - // System.exit(1); - // } -} diff --git a/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java b/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java deleted file mode 100644 index 1645e1a5..00000000 --- a/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDRDFParser.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.github.jsonldjava.tools; - -import java.util.Set; - -import org.openrdf.model.BNode; -import org.openrdf.model.Graph; -import org.openrdf.model.Literal; -import org.openrdf.model.Model; -import org.openrdf.model.Namespace; -import org.openrdf.model.Resource; -import org.openrdf.model.Statement; -import org.openrdf.model.URI; -import org.openrdf.model.Value; -import org.openrdf.model.vocabulary.RDF; -import org.openrdf.model.vocabulary.XMLSchema; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.RDFDataset; - -/** - * Implementation of RDFParser for Sesame-2.8. - * - * @author Peter Ansell - */ -class SesameJSONLDRDFParser implements com.github.jsonldjava.core.RDFParser { - - public void setPrefix(RDFDataset result, String fullUri, String prefix) { - result.setNamespace(fullUri, prefix); - } - - public void handleStatement(RDFDataset result, Statement nextStatement) { - // TODO: from a basic look at the code it seems some of these could be - // null values for IRIs will probably break things further down the line - // and i'm not sure yet if this should be something handled later on, or - // something that should be checked here - final String subject = getResourceValue(nextStatement.getSubject()); - final String predicate = getResourceValue(nextStatement.getPredicate()); - final Value object = nextStatement.getObject(); - final String graphName = getResourceValue(nextStatement.getContext()); - - if (object instanceof Literal) { - final Literal literal = (Literal) object; - final String value = literal.getLabel(); - final String language = literal.getLanguage(); - - String datatype = getResourceValue(literal.getDatatype()); - - // In RDF-1.1, Language Literals internally have the datatype - // rdf:langString - if (language != null && datatype == null) { - datatype = RDF.LANGSTRING.stringValue(); - } - - // In RDF-1.1, RDF-1.0 Plain Literals are now Typed Literals with - // type xsd:String - if (language == null && datatype == null) { - datatype = XMLSchema.STRING.stringValue(); - } - - result.addQuad(subject, predicate, value, datatype, language, graphName); - - } else { - result.addQuad(subject, predicate, getResourceValue((Resource) object), graphName); - } - } - - private String getResourceValue(Resource subject) { - if (subject == null) { - return null; - } else if (subject instanceof URI) { - return subject.stringValue(); - } else if (subject instanceof BNode) { - return "_:" + subject.stringValue(); - } - - throw new IllegalStateException("Did not recognise resource type: " - + subject.getClass().getName()); - } - - @Override - public RDFDataset parse(Object input) throws JsonLdError { - final RDFDataset result = new RDFDataset(); - if (input instanceof Statement) { - handleStatement(result, (Statement) input); - } else if (input instanceof Graph) { - if (input instanceof Model) { - final Set namespaces = ((Model) input).getNamespaces(); - for (final Namespace nextNs : namespaces) { - result.setNamespace(nextNs.getName(), nextNs.getPrefix()); - } - } - - for (final Statement nextStatement : (Graph) input) { - handleStatement(result, nextStatement); - } - } - return result; - } - -} diff --git a/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java b/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java deleted file mode 100644 index 0029da57..00000000 --- a/tools/src/main/java/com/github/jsonldjava/tools/SesameJSONLDTripleCallback.java +++ /dev/null @@ -1,221 +0,0 @@ -package com.github.jsonldjava.tools; - -import java.util.List; -import java.util.Map.Entry; - -import org.openrdf.model.Resource; -import org.openrdf.model.Statement; -import org.openrdf.model.URI; -import org.openrdf.model.Value; -import org.openrdf.model.ValueFactory; -import org.openrdf.model.impl.LinkedHashModel; -import org.openrdf.model.impl.ValueFactoryImpl; -import org.openrdf.rio.ParseErrorListener; -import org.openrdf.rio.ParserConfig; -import org.openrdf.rio.RDFHandler; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParseException; -import org.openrdf.rio.helpers.ParseErrorLogger; -import org.openrdf.rio.helpers.RDFParserHelper; -import org.openrdf.rio.helpers.StatementCollector; - -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; - -/** - * Implementation of JsonLdTripleCallback for Sesame-2.8. - * - * @author Peter Ansell - */ -class SesameJSONLDTripleCallback implements JsonLdTripleCallback { - - private ValueFactory vf; - - private RDFHandler handler; - - private ParserConfig parserConfig; - - private final ParseErrorListener parseErrorListener; - - public SesameJSONLDTripleCallback() { - this(new StatementCollector(new LinkedHashModel())); - } - - public SesameJSONLDTripleCallback(RDFHandler nextHandler) { - this(nextHandler, ValueFactoryImpl.getInstance()); - } - - public SesameJSONLDTripleCallback(RDFHandler nextHandler, ValueFactory vf) { - this(nextHandler, vf, new ParserConfig(), new ParseErrorLogger()); - } - - public SesameJSONLDTripleCallback(RDFHandler nextHandler, ValueFactory vf, - ParserConfig parserConfig, ParseErrorListener parseErrorListener) { - this.handler = nextHandler; - this.vf = vf; - this.parserConfig = parserConfig; - this.parseErrorListener = parseErrorListener; - } - - private void triple(String s, String p, String o, String graph) { - if (s == null || p == null || o == null) { - // TODO: i don't know what to do here!!!! - return; - } - - Statement result; - // This method is always called with three Resources as subject - // predicate and object - if (graph == null) { - result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o)); - } else { - result = vf.createStatement(createResource(s), vf.createURI(p), createResource(o), - createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - private Resource createResource(String resource) { - // Blank node without any given identifier - if (resource.equals("_:")) { - return vf.createBNode(); - } else if (resource.startsWith("_:")) { - return vf.createBNode(resource.substring(2)); - } else { - return vf.createURI(resource); - } - } - - private void triple(String s, String p, String value, String datatype, String language, - String graph) { - - if (s == null || p == null || value == null) { - // TODO: i don't know what to do here!!!! - return; - } - - final Resource subject = createResource(s); - - final URI predicate = vf.createURI(p); - final URI datatypeURI = datatype == null ? null : vf.createURI(datatype); - - Value object; - try { - object = RDFParserHelper.createLiteral(value, language, datatypeURI, getParserConfig(), - getParserErrorListener(), getValueFactory()); - } catch (final RDFParseException e) { - throw new RuntimeException(e); - } - - Statement result; - if (graph == null) { - result = vf.createStatement(subject, predicate, object); - } else { - result = vf.createStatement(subject, predicate, object, createResource(graph)); - } - - if (handler != null) { - try { - handler.handleStatement(result); - } catch (final RDFHandlerException e) { - throw new RuntimeException(e); - } - } - } - - public ParseErrorListener getParserErrorListener() { - return this.parseErrorListener; - } - - /** - * @return the handler - */ - public RDFHandler getHandler() { - return handler; - } - - /** - * @param handler - * the handler to set - */ - public void setHandler(RDFHandler handler) { - this.handler = handler; - } - - /** - * @return the parserConfig - */ - public ParserConfig getParserConfig() { - return parserConfig; - } - - /** - * @param parserConfig - * the parserConfig to set - */ - public void setParserConfig(ParserConfig parserConfig) { - this.parserConfig = parserConfig; - } - - /** - * @return the vf - */ - public ValueFactory getValueFactory() { - return vf; - } - - /** - * @param vf - * the vf to set - */ - public void setValueFactory(ValueFactory vf) { - this.vf = vf; - } - - @Override - public Object call(final RDFDataset dataset) { - if (handler != null) { - try { - handler.startRDF(); - for (final Entry nextNamespace : dataset.getNamespaces().entrySet()) { - handler.handleNamespace(nextNamespace.getKey(), nextNamespace.getValue()); - } - } catch (final RDFHandlerException e) { - throw new RuntimeException("Could not handle start of RDF", e); - } - } - for (String graphName : dataset.keySet()) { - final List quads = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad quad : quads) { - if (quad.getObject().isLiteral()) { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), quad.getObject().getDatatype(), quad - .getObject().getLanguage(), graphName); - } else { - triple(quad.getSubject().getValue(), quad.getPredicate().getValue(), quad - .getObject().getValue(), graphName); - } - } - } - if (handler != null) { - try { - handler.endRDF(); - } catch (final RDFHandlerException e) { - throw new RuntimeException("Could not handle end of RDF", e); - } - } - - return getHandler(); - } - -} diff --git a/tools/src/main/resources/log4j.properties b/tools/src/main/resources/log4j.properties deleted file mode 100644 index 136eba0c..00000000 --- a/tools/src/main/resources/log4j.properties +++ /dev/null @@ -1,5 +0,0 @@ -log4j.rootLogger=INFO, R - -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n From c7a66f402a7608a0014897aa78357440b93eb448 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 14:51:53 +1000 Subject: [PATCH 125/440] Reintegrate the content from the integration/README.md file --- README.md | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6befb64c..285c6a5a 100644 --- a/README.md +++ b/README.md @@ -179,10 +179,11 @@ The implementation specific integration classes for both Sesame and Jena have be PLAYGROUND ---------- -This is a simple application which provides command line access to JSON-LD functions +The jsonld-java-tools repository contains a simple application which provides command line access to JSON-LD functions -### Initial setup +### Initial clone and setup + git clone git@github.com:jsonld-java/jsonld-java-tools.git chmod +x ./jsonldplayground ### Usage @@ -388,3 +389,150 @@ Considerations for 1.0 release / optimisations * The `Context` class is a `Map` and many of the options are stored as values of the map. These could be made into variables, whice should speed things up a bit (the same with the termDefinitions variable inside the Context). * some sort of document loader interface (with a mockup for testing) is required + +JSONLD-JAVA INTEGRATION +======================= + +This is the base package for JSONLD-Java. Integration with other Java packages are done in separate repositories. + +EXISTING INTEGRATIONS +===================== + +* [OpenRDF Sesame](https://bitbucket.org/openrdf/sesame) +* [Apache Jena](https://github.com/apache/jena/) +* [RDF2GO](https://github.com/jsonld-java/jsonld-java-rdf2go) +* [Apache Clerezza](https://github.com/jsonld-java/jsonld-java-clerezza) + +CREATING AN INTEGRATION MODULE +============================== + +### Create a repository for your module + +Create a GitHub repository for your module under your user account, or have a JSONLD-Java maintainer create one in the jsonld-java organisation. + +Create module +------------- + +### Create pom.xml for your module + +Here is the basic outline for what your module's pom.xml should look like + + + + + jsonld-java-integration + com.github.jsonld-java-parent + 0.1-SNAPSHOT + + 4.0.0 + jsonld-java-{your module} + JSONLD Java :: {your module name} + JSON-LD Java integration module for {RDF Library your module integrates} + jar + + + + {YOU} + + + + + + ${project.groupId} + jsonld-java + ${project.version} + jar + compile + + + ${project.groupId} + jsonld-java + ${project.version} + test-jar + test + + + junit + junit + test + + + org.slf4j + slf4j-jdk14 + test + + + + +Make sure you edit the following: + * `project/artifactId` : set this to `jsonld-java-{module id}`, where `{module id}` usually represents the RDF library you're integrating (e.g. `jsonld-java-jena`) + * `project/name` : set this to `JSONLD Java :: {Module Name}`, wher `{module name}` is usually the name of the RDF library you're integrating. + * `project/description` + * `project/developers/developer/...` : Give youself credit by filling in the developer field. At least put your `` in ([see here for all available options](http://maven.apache.org/pom.html#Developers)). + * `project/dependencies/...` : remember to add any dependencies your project needs + +### Import into your favorite editor + +For Example: Follow the first few steps in the section above to import the whole `jsonld-java` project or only your new module into eclipse. + +Create RDFParser Implementation +------------------------------- + +The interface `com.github.jsonldjava.core.RDFParser` is used to parse RDF from the library into the JSONLD-Java internal RDF format. See the documentation in [`RDFParser.java`](../core/src/main/java/com/github/jsonldjava/core/RDFParser.java) for details on how to implement this interface. + +Create TripleCallback Implementation +------------------------------------ + +The interface `com.github.jsonldjava.core.JSONLDTripleCallback` is used to generate a representation of the JSON-LD input in the RDF library. See the documentation in [`JSONLDTripleCallback.java`](../core/src/main/java/com/github/jsonldjava/core/JSONLDTripleCallback.java) for details on how to implement this interface. + +Using your Implementations +-------------------------- + +### RDFParser + +A JSONLD RDF parser is a class that can parse your frameworks' RDF model +and generate JSON-LD. + +There are two ways to use your `RDFParser` implementation. + +Register your parser with the `JSONLD` class and set `options.format` when you call `fromRDF` + + JSONLD.registerRDFParser("format/identifier", new YourRDFParser()); + Object jsonld = JSONLD.fromRDF(yourInput, new Options("") {{ format = "format/identifier" }}); + +or pass an instance of your `RDFParser` into the `fromRDF` function + + Object jsonld = JSONLD.fromRDF(yourInput, new YourRDFParser()); + +### JSONLDTripleCallback + +A JSONLD triple callback is a class that can populate your framework's +RDF model from JSON-LD - being called for each triple (technically quad). + +Pass an instance of your `TripleCallback` to `JSONLD.toRDF` + + Object yourOutput = JSONLD.toRDF(jsonld, new YourTripleCallback()); + +Integrate with your framework +----------------------------- +Your framework might have its own system of readers and writers, where +you should register JSON-LD as a supported format. Remember that here +the "parse" direction is opposite of above, a 'reader' in e.g. Jena will +be a class that can parse JSON-LD and populate a Jena model. + +Write Tests +----------- + +It's helpful to have a test or two for your implementations to make sure they work and continue to work with future versions. + +Write README.md +--------------- + +Write a `README.md` file with instrutions on how to use your module. + +Submit your module +------------------ + +Once you've `commit`ted your code, and `push`ed it into your github fork you can issue a [Pull Request](https://help.github.com/articles/using-pull-requests) so that we can add a reference to your module in this README file. + From 6c3f915841d388782e15d1c10f888a468f62034c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 14:56:36 +1000 Subject: [PATCH 126/440] Work on the formatting for readme --- README.md | 310 +++++++++++++++++++++++++++--------------------------- 1 file changed, 156 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index 285c6a5a..ed503709 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,22 @@ or to run only core package tests -### Implementation Reports for JSONLD-Java conformance with JSONLD-1.0 +### Code style + +The JSONLD-Java project uses custom Eclipse formatting and cleanup style guides to ensure that Pull Requests are fairly simple to merge. + +These guides can be found in the /conf directory and can be installed in Eclipse using "Properties>Java Code Style>Formatter", followed by "Properties>Java Code Style>Clean Up" for each of the modules making up the JSONLD-Java project. + +If you don't use Eclipse, then don't worry, your pull requests can be cleaned up by a repository maintainer prior to merging, but it makes the initial check easier if the modified code uses the conventions. + +### Submitting Pull Requests + +Once you have made a change to fix a bug or add a new feature, you should commit and push the change to your fork. + +Then, you can open a pull request to merge your change into the master branch of the main repository. + +Implementation Reports for JSONLD-Java conformance with JSONLD-1.0 +================================================================== The Implementation Reports documenting the conformance of JSONLD-Java with JSONLD-1.0 are available at: @@ -224,19 +239,152 @@ Implementation Reports conforming to the [JSON-LD Implementation Report](http:// Current possible values for `` include JSON-LD (`application/ld+json` or `jsonld`), NQuads (`text/plain`, `nquads`, `ntriples`, `nq` or `nt`) and Turtle (`text/turtle`, `turtle` or `ttl`). `*` can be used to generate reports in all available formats. -### Code style +Integration of JSONLD-Java with other Java packages +=================================================== -The JSONLD-Java project uses custom Eclipse formatting and cleanup style guides to ensure that Pull Requests are fairly simple to merge. +This is the base package for JSONLD-Java. Integration with other Java packages are done in separate repositories. -These guides can be found in the /conf directory and can be installed in Eclipse using "Properties>Java Code Style>Formatter", followed by "Properties>Java Code Style>Clean Up" for each of the modules making up the JSONLD-Java project. +Existing integrations +--------------------- -If you don't use Eclipse, then don't worry, your pull requests can be cleaned up by a repository maintainer prior to merging, but it makes the initial check easier if the modified code uses the conventions. +* [OpenRDF Sesame](https://bitbucket.org/openrdf/sesame) +* [Apache Jena](https://github.com/apache/jena/) +* [RDF2GO](https://github.com/jsonld-java/jsonld-java-rdf2go) +* [Apache Clerezza](https://github.com/jsonld-java/jsonld-java-clerezza) -### Submitting Pull Requests +Creating an integration module +------------------------------ -Once you have made a change to fix a bug or add a new feature, you should commit and push the change to your fork. +### Create a repository for your module + +Create a GitHub repository for your module under your user account, or have a JSONLD-Java maintainer create one in the jsonld-java organisation. + +Create maven module +------------------- + +### Create pom.xml for your module + +Here is the basic outline for what your module's pom.xml should look like + + + + + jsonld-java-integration + com.github.jsonld-java-parent + 0.1-SNAPSHOT + + 4.0.0 + jsonld-java-{your module} + JSONLD Java :: {your module name} + JSON-LD Java integration module for {RDF Library your module integrates} + jar + + + + {YOU} + + + + + + ${project.groupId} + jsonld-java + ${project.version} + jar + compile + + + ${project.groupId} + jsonld-java + ${project.version} + test-jar + test + + + junit + junit + test + + + org.slf4j + slf4j-jdk14 + test + + + + +Make sure you edit the following: + * `project/artifactId` : set this to `jsonld-java-{module id}`, where `{module id}` usually represents the RDF library you're integrating (e.g. `jsonld-java-jena`) + * `project/name` : set this to `JSONLD Java :: {Module Name}`, wher `{module name}` is usually the name of the RDF library you're integrating. + * `project/description` + * `project/developers/developer/...` : Give youself credit by filling in the developer field. At least put your `` in ([see here for all available options](http://maven.apache.org/pom.html#Developers)). + * `project/dependencies/...` : remember to add any dependencies your project needs + +### Import into your favorite editor + +For Example: Follow the first few steps in the section above to import the whole `jsonld-java` project or only your new module into eclipse. + +Create RDFParser Implementation +------------------------------- + +The interface `com.github.jsonldjava.core.RDFParser` is used to parse RDF from the library into the JSONLD-Java internal RDF format. See the documentation in [`RDFParser.java`](../core/src/main/java/com/github/jsonldjava/core/RDFParser.java) for details on how to implement this interface. + +Create TripleCallback Implementation +------------------------------------ + +The interface `com.github.jsonldjava.core.JSONLDTripleCallback` is used to generate a representation of the JSON-LD input in the RDF library. See the documentation in [`JSONLDTripleCallback.java`](../core/src/main/java/com/github/jsonldjava/core/JSONLDTripleCallback.java) for details on how to implement this interface. + +Using your Implementations +-------------------------- + +### RDFParser + +A JSONLD RDF parser is a class that can parse your frameworks' RDF model +and generate JSON-LD. + +There are two ways to use your `RDFParser` implementation. + +Register your parser with the `JSONLD` class and set `options.format` when you call `fromRDF` + + JSONLD.registerRDFParser("format/identifier", new YourRDFParser()); + Object jsonld = JSONLD.fromRDF(yourInput, new Options("") {{ format = "format/identifier" }}); + +or pass an instance of your `RDFParser` into the `fromRDF` function + + Object jsonld = JSONLD.fromRDF(yourInput, new YourRDFParser()); + +### JSONLDTripleCallback + +A JSONLD triple callback is a class that can populate your framework's +RDF model from JSON-LD - being called for each triple (technically quad). + +Pass an instance of your `TripleCallback` to `JSONLD.toRDF` + + Object yourOutput = JSONLD.toRDF(jsonld, new YourTripleCallback()); + +Integrate with your framework +----------------------------- +Your framework might have its own system of readers and writers, where +you should register JSON-LD as a supported format. Remember that here +the "parse" direction is opposite of above, a 'reader' in e.g. Jena will +be a class that can parse JSON-LD and populate a Jena model. + +Write Tests +----------- + +It's helpful to have a test or two for your implementations to make sure they work and continue to work with future versions. + +Write README.md +--------------- + +Write a `README.md` file with instrutions on how to use your module. + +Submit your module +------------------ + +Once you've `commit`ted your code, and `push`ed it into your github fork you can issue a [Pull Request](https://help.github.com/articles/using-pull-requests) so that we can add a reference to your module in this README file. -Then, you can open a pull request to merge your change into the master branch of the main repository. CHANGELOG ========= @@ -390,149 +538,3 @@ Considerations for 1.0 release / optimisations * The `Context` class is a `Map` and many of the options are stored as values of the map. These could be made into variables, whice should speed things up a bit (the same with the termDefinitions variable inside the Context). * some sort of document loader interface (with a mockup for testing) is required -JSONLD-JAVA INTEGRATION -======================= - -This is the base package for JSONLD-Java. Integration with other Java packages are done in separate repositories. - -EXISTING INTEGRATIONS -===================== - -* [OpenRDF Sesame](https://bitbucket.org/openrdf/sesame) -* [Apache Jena](https://github.com/apache/jena/) -* [RDF2GO](https://github.com/jsonld-java/jsonld-java-rdf2go) -* [Apache Clerezza](https://github.com/jsonld-java/jsonld-java-clerezza) - -CREATING AN INTEGRATION MODULE -============================== - -### Create a repository for your module - -Create a GitHub repository for your module under your user account, or have a JSONLD-Java maintainer create one in the jsonld-java organisation. - -Create module -------------- - -### Create pom.xml for your module - -Here is the basic outline for what your module's pom.xml should look like - - - - - jsonld-java-integration - com.github.jsonld-java-parent - 0.1-SNAPSHOT - - 4.0.0 - jsonld-java-{your module} - JSONLD Java :: {your module name} - JSON-LD Java integration module for {RDF Library your module integrates} - jar - - - - {YOU} - - - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - junit - junit - test - - - org.slf4j - slf4j-jdk14 - test - - - - -Make sure you edit the following: - * `project/artifactId` : set this to `jsonld-java-{module id}`, where `{module id}` usually represents the RDF library you're integrating (e.g. `jsonld-java-jena`) - * `project/name` : set this to `JSONLD Java :: {Module Name}`, wher `{module name}` is usually the name of the RDF library you're integrating. - * `project/description` - * `project/developers/developer/...` : Give youself credit by filling in the developer field. At least put your `` in ([see here for all available options](http://maven.apache.org/pom.html#Developers)). - * `project/dependencies/...` : remember to add any dependencies your project needs - -### Import into your favorite editor - -For Example: Follow the first few steps in the section above to import the whole `jsonld-java` project or only your new module into eclipse. - -Create RDFParser Implementation -------------------------------- - -The interface `com.github.jsonldjava.core.RDFParser` is used to parse RDF from the library into the JSONLD-Java internal RDF format. See the documentation in [`RDFParser.java`](../core/src/main/java/com/github/jsonldjava/core/RDFParser.java) for details on how to implement this interface. - -Create TripleCallback Implementation ------------------------------------- - -The interface `com.github.jsonldjava.core.JSONLDTripleCallback` is used to generate a representation of the JSON-LD input in the RDF library. See the documentation in [`JSONLDTripleCallback.java`](../core/src/main/java/com/github/jsonldjava/core/JSONLDTripleCallback.java) for details on how to implement this interface. - -Using your Implementations --------------------------- - -### RDFParser - -A JSONLD RDF parser is a class that can parse your frameworks' RDF model -and generate JSON-LD. - -There are two ways to use your `RDFParser` implementation. - -Register your parser with the `JSONLD` class and set `options.format` when you call `fromRDF` - - JSONLD.registerRDFParser("format/identifier", new YourRDFParser()); - Object jsonld = JSONLD.fromRDF(yourInput, new Options("") {{ format = "format/identifier" }}); - -or pass an instance of your `RDFParser` into the `fromRDF` function - - Object jsonld = JSONLD.fromRDF(yourInput, new YourRDFParser()); - -### JSONLDTripleCallback - -A JSONLD triple callback is a class that can populate your framework's -RDF model from JSON-LD - being called for each triple (technically quad). - -Pass an instance of your `TripleCallback` to `JSONLD.toRDF` - - Object yourOutput = JSONLD.toRDF(jsonld, new YourTripleCallback()); - -Integrate with your framework ------------------------------ -Your framework might have its own system of readers and writers, where -you should register JSON-LD as a supported format. Remember that here -the "parse" direction is opposite of above, a 'reader' in e.g. Jena will -be a class that can parse JSON-LD and populate a Jena model. - -Write Tests ------------ - -It's helpful to have a test or two for your implementations to make sure they work and continue to work with future versions. - -Write README.md ---------------- - -Write a `README.md` file with instrutions on how to use your module. - -Submit your module ------------------- - -Once you've `commit`ted your code, and `push`ed it into your github fork you can issue a [Pull Request](https://help.github.com/articles/using-pull-requests) so that we can add a reference to your module in this README file. - From a0d8cc3f00770b63924da162a055750e4f864ccf Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 14:58:21 +1000 Subject: [PATCH 127/440] Remove integration and tools details --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 5b771092..c8d07007 100755 --- a/pom.xml +++ b/pom.xml @@ -38,19 +38,15 @@ core - integration - tools UTF-8 UTF-8 - 0.14 4.2.5 2.3.3 4.12 - 5.0.1 1.7.9 From 0d5356d56197b3ec19fa20e16aeebccd8e4158e9 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 14:59:58 +1000 Subject: [PATCH 128/440] bump versions to reflect the new module layout --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 1f4a9e13..aa89755f 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.6.1-SNAPSHOT + 0.7.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index c8d07007..7490f5e7 100755 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.6.1-SNAPSHOT + 0.7.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From e491ccdc16c80dd216b70a8a215c4a2d1d89d78b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 15:36:21 +1000 Subject: [PATCH 129/440] Switch away from the sonatype oss parent --- pom.xml | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 7490f5e7..cd363133 100755 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,6 @@ - - oss-parent - org.sonatype.oss - 7 - 4.0.0 com.github.jsonld-java jsonld-java-parent @@ -50,7 +45,7 @@ 1.7.9 - 2.2.1 + 3.0.0 @@ -69,11 +64,6 @@ jackson-annotations ${jackson.version} - - org.apache.clerezza - rdf.core - ${clerezza.version} - junit junit @@ -262,5 +252,83 @@ + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots + + false + + + true + + + + + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus-staging + Nexus Release Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + sonatype-oss-release + + + + org.apache.maven.plugins + maven-source-plugin + 2.1.2 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.7 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.1 + + + sign-artifacts + verify + + sign + + + + + + + + From fbf14950b927f3e610367343dbe65658e503f767 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 16:38:23 +1000 Subject: [PATCH 130/440] bump version for bundle plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd363133..3801224d 100755 --- a/pom.xml +++ b/pom.xml @@ -198,7 +198,7 @@ org.apache.felix maven-bundle-plugin - 2.5.3 + 2.5.4 From cda5d28f52657b34137eb646c0603c928b9eccff Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Sep 2015 16:42:07 +1000 Subject: [PATCH 131/440] Update changelog --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index ed503709..57a459c5 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,9 @@ Once you've `commit`ted your code, and `push`ed it into your github fork you can CHANGELOG ========= +### 2015-09-27 +* Move Tools, Clerezza and RDF2GO modules out to separate repositories. The Tools repository had a circular build dependency with Sesame, while the other modules are best located and managed in separate repositories + ### 2015-08-25 * Remove Sesame-2.7 module in favour of sesame-rio-jsonld for Sesame-2.8 and 4.0 * Fix bug where parsing did not fail if content was present after the end of a full JSON top level element From da156eebe0fdd2cee34a8bb603d64979a281d389 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 30 Sep 2015 12:49:11 +1000 Subject: [PATCH 132/440] Release 0.7.0 --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index aa89755f..12e97309 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.7.0-SNAPSHOT + 0.7.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 3801224d..f5060c39 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.7.0-SNAPSHOT + 0.7.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From 8d71277e9f26073c8c6af7e9ef92b20480cef0ef Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 30 Sep 2015 12:59:03 +1000 Subject: [PATCH 133/440] Update readme --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 57a459c5..93fa01b3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Note: this is the documentation for the current unstable development branch. [For the stable release documentation see here](https://github.com/jsonld-java/jsonld-java/blob/v0.6.0/README.md) - JSONLD-JAVA =========== @@ -16,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.6.1-SNAPSHOT + 0.7.1-SNAPSHOT Code example @@ -389,6 +387,9 @@ Once you've `commit`ted your code, and `push`ed it into your github fork you can CHANGELOG ========= +### 2015-09-30 +* Release 0.7.0 + ### 2015-09-27 * Move Tools, Clerezza and RDF2GO modules out to separate repositories. The Tools repository had a circular build dependency with Sesame, while the other modules are best located and managed in separate repositories From 850166aef6d3cf1d8cf11f53889bd5ffa2d14274 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 30 Sep 2015 12:59:26 +1000 Subject: [PATCH 134/440] bump to next development versions --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 12e97309..e73b174b 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.7.0 + 0.7.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index f5060c39..4135a010 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.7.0 + 0.7.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 31e33dcb239e5b61e8ffff6d187be4e6e7d7df76 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 30 Oct 2015 10:19:15 +1100 Subject: [PATCH 135/440] Add regression test for issue #153 --- .../jsonldjava/core/LongestPrefixTest.java | 55 +++++++++++++++++++ .../resources/custom/contexttest-0003.jsonld | 9 +++ 2 files changed, 64 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java create mode 100644 core/src/test/resources/custom/contexttest-0003.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java new file mode 100644 index 00000000..65bb671a --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java @@ -0,0 +1,55 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.net.URL; +import java.util.Map; + +import org.junit.Test; + +import com.github.jsonldjava.utils.JsonUtils; + +public class LongestPrefixTest { + @Test + public void toRdfWithNamespace() throws Exception { + + final URL contextUrl = getClass().getResource("/custom/contexttest-0003.jsonld"); + assertNotNull(contextUrl); + final Object context = JsonUtils.fromURL(contextUrl); + assertNotNull(context); + + final JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(context, options); + System.out.println(rdf.getNamespaces()); + assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); + assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aat_rev")); + } + + @Test + public void fromRdfWithNamespace() throws Exception { + + RDFDataset inputRdf = new RDFDataset(); + inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); + inputRdf.setNamespace("aat_rev", "http://vocab.getty.edu/aat/rev/"); + + inputRdf.addTriple("http://vocab.getty.edu/aat/rev/5001065997", JsonLdConsts.RDF_TYPE, "http://vocab.getty.edu/aat/datatype"); + + final JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + + Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf),inputRdf.getContext(), options); + + final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); + System.out.println(rdf.getNamespaces()); + assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); + assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aat_rev")); + + String toJSONLD = JsonUtils.toPrettyString(fromRDF); + System.out.println(toJSONLD); + + assertFalse("Longest prefix was not used", toJSONLD.contains("aat:rev/")); + } +} diff --git a/core/src/test/resources/custom/contexttest-0003.jsonld b/core/src/test/resources/custom/contexttest-0003.jsonld new file mode 100644 index 00000000..8d6a3655 --- /dev/null +++ b/core/src/test/resources/custom/contexttest-0003.jsonld @@ -0,0 +1,9 @@ +{ + "@context": { + "aat" : "http://vocab.getty.edu/aat/", + "aat_rev" : "http://vocab.getty.edu/aat/rev/" + }, + "@id" : "aat_rev:5001065997", + "@type": "aat_rev:datatype", + "used" : "aat:300016954" +} From 0f4ed2304411a732b7cc45d7062f0f501478f56b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 30 Oct 2015 13:39:04 +1100 Subject: [PATCH 136/440] Extract step 5.4 to a new function to make it possible to unit test --- .../com/github/jsonldjava/core/Context.java | 2245 +++++++++-------- 1 file changed, 1127 insertions(+), 1118 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index bfcdf4f3..934ed32d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -1,1119 +1,1128 @@ -package com.github.jsonldjava.core; - -import static com.github.jsonldjava.core.JsonLdUtils.compareShortestLeast; -import static com.github.jsonldjava.utils.Obj.newMap; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.github.jsonldjava.core.JsonLdError.Error; -import com.github.jsonldjava.utils.JsonLdUrl; -import com.github.jsonldjava.utils.Obj; - -/** - * A helper class which still stores all the values in a map but gives member - * variables easily access certain keys - * - * @author tristan - * - */ -public class Context extends LinkedHashMap { - - private JsonLdOptions options; - private Map termDefinitions; - public Map inverse = null; - - public Context() { - this(new JsonLdOptions()); - } - - public Context(JsonLdOptions opts) { - super(); - init(opts); - } - - public Context(Map map, JsonLdOptions opts) { - super(map); - init(opts); - } - - public Context(Map map) { - super(map); - init(new JsonLdOptions()); - } - - public Context(Object context, JsonLdOptions opts) { - // TODO: load remote context - super(context instanceof Map ? (Map) context : null); - init(opts); - } - - private void init(JsonLdOptions options) { - this.options = options; - if (options.getBase() != null) { - this.put("@base", options.getBase()); - } - this.termDefinitions = newMap(); - } - - /** - * Value Compaction Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#value-compaction - * - * @param activeProperty - * The Active Property - * @param value - * The value to compact - * @return The compacted value - */ - public Object compactValue(String activeProperty, Map value) { - // 1) - int numberMembers = value.size(); - // 2) - if (value.containsKey("@index") && "@index".equals(this.getContainer(activeProperty))) { - numberMembers--; - } - // 3) - if (numberMembers > 2) { - return value; - } - // 4) - final String typeMapping = getTypeMapping(activeProperty); - final String languageMapping = getLanguageMapping(activeProperty); - if (value.containsKey("@id")) { - // 4.1) - if (numberMembers == 1 && "@id".equals(typeMapping)) { - return compactIri((String) value.get("@id")); - } - // 4.2) - if (numberMembers == 1 && "@vocab".equals(typeMapping)) { - return compactIri((String) value.get("@id"), true); - } - // 4.3) - return value; - } - final Object valueValue = value.get("@value"); - // 5) - if (value.containsKey("@type") && Obj.equals(value.get("@type"), typeMapping)) { - return valueValue; - } - // 6) - if (value.containsKey("@language")) { - // TODO: SPEC: doesn't specify to check default language as well - if (Obj.equals(value.get("@language"), languageMapping) - || Obj.equals(value.get("@language"), this.get("@language"))) { - return valueValue; - } - } - // 7) - if (numberMembers == 1 - && (!(valueValue instanceof String) || !this.containsKey("@language") || (termDefinitions - .containsKey(activeProperty) - && getTermDefinition(activeProperty).containsKey("@language") && languageMapping == null))) { - return valueValue; - } - // 8) - return value; - } - - /** - * Context Processing Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms - * - * @param localContext - * The Local Context object. - * @param remoteContexts - * The list of Strings denoting the remote Context URLs. - * @return The parsed and merged Context. - * @throws JsonLdError - * If there is an error parsing the contexts. - */ - public Context parse(Object localContext, List remoteContexts) throws JsonLdError { - if (remoteContexts == null) { - remoteContexts = new ArrayList(); - } - // 1. Initialize result to the result of cloning active context. - Context result = this.clone(); // TODO: clone? - // 2) - if (!(localContext instanceof List)) { - final Object temp = localContext; - localContext = new ArrayList(); - ((List) localContext).add(temp); - } - // 3) - for (Object context : ((List) localContext)) { - // 3.1) - if (context == null) { - result = new Context(this.options); - continue; - } else if (context instanceof Context) { - result = ((Context) context).clone(); - } - // 3.2) - else if (context instanceof String) { - String uri = (String) result.get("@base"); - uri = JsonLdUrl.resolve(uri, (String) context); - // 3.2.2 - if (remoteContexts.contains(uri)) { - throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, uri); - } - remoteContexts.add(uri); - - // 3.2.3: Dereference context - final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); - final Object remoteContext = rd.document; - if (!(remoteContext instanceof Map) - || !((Map) remoteContext).containsKey("@context")) { - // If the dereferenced document has no top-level JSON object - // with an @context member - throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); - } - context = ((Map) remoteContext).get("@context"); - - // 3.2.4 - result = result.parse(context, remoteContexts); - // 3.2.5 - continue; - } else if (!(context instanceof Map)) { - // 3.3 - throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); - } - - // 3.4 - if (remoteContexts.isEmpty() && ((Map) context).containsKey("@base")) { - final Object value = ((Map) context).get("@base"); - if (value == null) { - result.remove("@base"); - } else if (value instanceof String) { - if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@base", value); - } else { - final String baseUri = (String) result.get("@base"); - if (!JsonLdUtils.isAbsoluteIri(baseUri)) { - throw new JsonLdError(Error.INVALID_BASE_IRI, baseUri); - } - result.put("@base", JsonLdUrl.resolve(baseUri, (String) value)); - } - } else { - throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, - "@base must be a string"); - } - } - - // 3.5 - if (((Map) context).containsKey("@vocab")) { - final Object value = ((Map) context).get("@vocab"); - if (value == null) { - result.remove("@vocab"); - } else if (value instanceof String) { - if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@vocab", value); - } else { - throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, - "@value must be an absolute IRI"); - } - } else { - throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, - "@vocab must be a string or null"); - } - } - - // 3.6 - if (((Map) context).containsKey("@language")) { - final Object value = ((Map) context).get("@language"); - if (value == null) { - result.remove("@language"); - } else if (value instanceof String) { - result.put("@language", ((String) value).toLowerCase()); - } else { - throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); - } - } - - // 3.7 - final Map defined = new LinkedHashMap(); - for (final String key : ((Map) context).keySet()) { - if ("@base".equals(key) || "@vocab".equals(key) || "@language".equals(key)) { - continue; - } - result.createTermDefinition((Map) context, key, defined); - } - } - return result; - } - - public Context parse(Object localContext) throws JsonLdError { - return this.parse(localContext, new ArrayList()); - } - - /** - * Create Term Definition Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition - * - * @param result - * @param context - * @param key - * @param defined - * @throws JsonLdError - */ - private void createTermDefinition(Map context, String term, - Map defined) throws JsonLdError { - if (defined.containsKey(term)) { - if (Boolean.TRUE.equals(defined.get(term))) { - return; - } - throw new JsonLdError(Error.CYCLIC_IRI_MAPPING, term); - } - - defined.put(term, false); - - if (JsonLdUtils.isKeyword(term)) { - throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); - } - - this.termDefinitions.remove(term); - Object value = context.get(term); - if (value == null - || (value instanceof Map && ((Map) value).containsKey("@id") && ((Map) value) - .get("@id") == null)) { - this.termDefinitions.put(term, null); - defined.put(term, true); - return; - } - - if (value instanceof String) { - value = newMap("@id", value); - } - - if (!(value instanceof Map)) { - throw new JsonLdError(Error.INVALID_TERM_DEFINITION, value); - } - - // casting the value so it doesn't have to be done below everytime - final Map val = (Map) value; - - // 9) create a new term definition - final Map definition = newMap(); - - // 10) - if (val.containsKey("@type")) { - if (!(val.get("@type") instanceof String)) { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, val.get("@type")); - } - String type = (String) val.get("@type"); - try { - type = this.expandIri((String) val.get("@type"), false, true, context, defined); - } catch (final JsonLdError error) { - if (error.getType() != Error.INVALID_IRI_MAPPING) { - throw error; - } - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); - } - // TODO: fix check for absoluteIri (blank nodes shouldn't count, at - // least not here!) - if ("@id".equals(type) || "@vocab".equals(type) - || (!type.startsWith("_:") && JsonLdUtils.isAbsoluteIri(type))) { - definition.put("@type", type); - } else { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); - } - } - - // 11) - if (val.containsKey("@reverse")) { - if (val.containsKey("@id")) { - throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); - } - if (!(val.get("@reverse") instanceof String)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "Expected String for @reverse value. got " - + (val.get("@reverse") == null ? "null" : val.get("@reverse") - .getClass())); - } - final String reverse = this.expandIri((String) val.get("@reverse"), false, true, - context, defined); - if (!JsonLdUtils.isAbsoluteIri(reverse)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Non-absolute @reverse IRI: " - + reverse); - } - definition.put("@id", reverse); - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (container == null || "@set".equals(container) || "@index".equals(container)) { - definition.put("@container", container); - } else { - throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, - "reverse properties only support set- and index-containers"); - } - } - definition.put("@reverse", true); - this.termDefinitions.put(term, definition); - defined.put(term, true); - return; - } - - // 12) - definition.put("@reverse", false); - - // 13) - if (val.get("@id") != null && !term.equals(val.get("@id"))) { - if (!(val.get("@id") instanceof String)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "expected value of @id to be a string"); - } - - final String res = this.expandIri((String) val.get("@id"), false, true, context, - defined); - if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { - if ("@context".equals(res)) { - throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, "cannot alias @context"); - } - definition.put("@id", res); - } else { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "resulting IRI mapping should be a keyword, absolute IRI or blank node"); - } - } - - // 14) - else if (term.indexOf(":") >= 0) { - final int colIndex = term.indexOf(":"); - final String prefix = term.substring(0, colIndex); - final String suffix = term.substring(colIndex + 1); - if (context.containsKey(prefix)) { - this.createTermDefinition(context, prefix, defined); - } - if (termDefinitions.containsKey(prefix)) { - definition.put("@id", - ((Map) termDefinitions.get(prefix)).get("@id") + suffix); - } else { - definition.put("@id", term); - } - // 15) - } else if (this.containsKey("@vocab")) { - definition.put("@id", this.get("@vocab") + term); - } else { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, - "relative term definition without vocab mapping"); - } - - // 16) - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (!"@list".equals(container) && !"@set".equals(container) - && !"@index".equals(container) && !"@language".equals(container)) { - throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, - "@container must be either @list, @set, @index, or @language"); - } - definition.put("@container", container); - } - - // 17) - if (val.containsKey("@language") && !val.containsKey("@type")) { - if (val.get("@language") == null || val.get("@language") instanceof String) { - final String language = (String) val.get("@language"); - definition.put("@language", language != null ? language.toLowerCase() : null); - } else { - throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, - "@language must be a string or null"); - } - } - - // 18) - this.termDefinitions.put(term, definition); - defined.put(term, true); - } - - /** - * IRI Expansion Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion - * - * @param value - * @param relative - * @param vocab - * @param context - * @param defined - * @return - * @throws JsonLdError - */ - String expandIri(String value, boolean relative, boolean vocab, Map context, - Map defined) throws JsonLdError { - // 1) - if (value == null || JsonLdUtils.isKeyword(value)) { - return value; - } - // 2) - if (context != null && context.containsKey(value) - && !Boolean.TRUE.equals(defined.get(value))) { - this.createTermDefinition(context, value, defined); - } - // 3) - if (vocab && this.termDefinitions.containsKey(value)) { - final Map td = (LinkedHashMap) this.termDefinitions - .get(value); - if (td != null) { - return (String) td.get("@id"); - } else { - return null; - } - } - // 4) - final int colIndex = value.indexOf(":"); - if (colIndex >= 0) { - // 4.1) - final String prefix = value.substring(0, colIndex); - final String suffix = value.substring(colIndex + 1); - // 4.2) - if ("_".equals(prefix) || suffix.startsWith("//")) { - return value; - } - // 4.3) - if (context != null && context.containsKey(prefix) - && (!defined.containsKey(prefix) || defined.get(prefix) == false)) { - this.createTermDefinition(context, prefix, defined); - } - // 4.4) - if (this.termDefinitions.containsKey(prefix)) { - return (String) ((LinkedHashMap) this.termDefinitions.get(prefix)) - .get("@id") + suffix; - } - // 4.5) - return value; - } - // 5) - if (vocab && this.containsKey("@vocab")) { - return this.get("@vocab") + value; - } - // 6) - else if (relative) { - return JsonLdUrl.resolve((String) this.get("@base"), value); - } else if (context != null && JsonLdUtils.isRelativeIri(value)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, "not an absolute IRI: " + value); - } - // 7) - return value; - } - - /** - * IRI Compaction Algorithm - * - * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction - * - * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI - * has an associated value it may be passed. - * - * @param iri - * the IRI to compact. - * @param value - * the value to check or null. - * @param relativeTo - * options for how to compact IRIs: vocab: true to split after - * @vocab, false not to. - * @param reverse - * true if a reverse property is being compacted, false if not. - * - * @return the compacted term, prefix, keyword alias, or the original IRI. - */ - String compactIri(String iri, Object value, boolean relativeToVocab, boolean reverse) { - // 1) - if (iri == null) { - return null; - } - - // 2) - if (relativeToVocab && getInverse().containsKey(iri)) { - // 2.1) - String defaultLanguage = (String) this.get("@language"); - if (defaultLanguage == null) { - defaultLanguage = "@none"; - } - - // 2.2) - final List containers = new ArrayList(); - // 2.3) - String typeLanguage = "@language"; - String typeLanguageValue = "@null"; - - // 2.4) - if (value instanceof Map && ((Map) value).containsKey("@index")) { - containers.add("@index"); - } - - // 2.5) - if (reverse) { - typeLanguage = "@type"; - typeLanguageValue = "@reverse"; - containers.add("@set"); - } - // 2.6) - else if (value instanceof Map && ((Map) value).containsKey("@list")) { - // 2.6.1) - if (!((Map) value).containsKey("@index")) { - containers.add("@list"); - } - // 2.6.2) - final List list = (List) ((Map) value).get("@list"); - // 2.6.3) - String commonLanguage = (list.size() == 0) ? defaultLanguage : null; - String commonType = null; - // 2.6.4) - for (final Object item : list) { - // 2.6.4.1) - String itemLanguage = "@none"; - String itemType = "@none"; - // 2.6.4.2) - if (JsonLdUtils.isValue(item)) { - // 2.6.4.2.1) - if (((Map) item).containsKey("@language")) { - itemLanguage = (String) ((Map) item).get("@language"); - } - // 2.6.4.2.2) - else if (((Map) item).containsKey("@type")) { - itemType = (String) ((Map) item).get("@type"); - } - // 2.6.4.2.3) - else { - itemLanguage = "@null"; - } - } - // 2.6.4.3) - else { - itemType = "@id"; - } - // 2.6.4.4) - if (commonLanguage == null) { - commonLanguage = itemLanguage; - } - // 2.6.4.5) - else if (!commonLanguage.equals(itemLanguage) && JsonLdUtils.isValue(item)) { - commonLanguage = "@none"; - } - // 2.6.4.6) - if (commonType == null) { - commonType = itemType; - } - // 2.6.4.7) - else if (!commonType.equals(itemType)) { - commonType = "@none"; - } - // 2.6.4.8) - if ("@none".equals(commonLanguage) && "@none".equals(commonType)) { - break; - } - } - // 2.6.5) - commonLanguage = (commonLanguage != null) ? commonLanguage : "@none"; - // 2.6.6) - commonType = (commonType != null) ? commonType : "@none"; - // 2.6.7) - if (!"@none".equals(commonType)) { - typeLanguage = "@type"; - typeLanguageValue = commonType; - } - // 2.6.8) - else { - typeLanguageValue = commonLanguage; - } - } - // 2.7) - else { - // 2.7.1) - if (value instanceof Map && ((Map) value).containsKey("@value")) { - // 2.7.1.1) - if (((Map) value).containsKey("@language") - && !((Map) value).containsKey("@index")) { - containers.add("@language"); - typeLanguageValue = (String) ((Map) value).get("@language"); - } - // 2.7.1.2) - else if (((Map) value).containsKey("@type")) { - typeLanguage = "@type"; - typeLanguageValue = (String) ((Map) value).get("@type"); - } - } - // 2.7.2) - else { - typeLanguage = "@type"; - typeLanguageValue = "@id"; - } - // 2.7.3) - containers.add("@set"); - } - - // 2.8) - containers.add("@none"); - // 2.9) - if (typeLanguageValue == null) { - typeLanguageValue = "@null"; - } - // 2.10) - final List preferredValues = new ArrayList(); - // 2.11) - if ("@reverse".equals(typeLanguageValue)) { - preferredValues.add("@reverse"); - } - // 2.12) - if (("@reverse".equals(typeLanguageValue) || "@id".equals(typeLanguageValue)) - && (value instanceof Map) && ((Map) value).containsKey("@id")) { - // 2.12.1) - final String result = this.compactIri( - (String) ((Map) value).get("@id"), null, true, true); - if (termDefinitions.containsKey(result) - && ((Map) termDefinitions.get(result)).containsKey("@id") - && ((Map) value).get("@id").equals( - ((Map) termDefinitions.get(result)).get("@id"))) { - preferredValues.add("@vocab"); - preferredValues.add("@id"); - } - // 2.12.2) - else { - preferredValues.add("@id"); - preferredValues.add("@vocab"); - } - } - // 2.13) - else { - preferredValues.add(typeLanguageValue); - } - preferredValues.add("@none"); - - // 2.14) - final String term = selectTerm(iri, containers, typeLanguage, preferredValues); - // 2.15) - if (term != null) { - return term; - } - } - - // 3) - if (relativeToVocab && this.containsKey("@vocab")) { - // determine if vocab is a prefix of the iri - final String vocab = (String) this.get("@vocab"); - // 3.1) - if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { - // use suffix as relative iri if it is not a term in the - // active context - final String suffix = iri.substring(vocab.length()); - if (!termDefinitions.containsKey(suffix)) { - return suffix; - } - } - } - - // 4) - String compactIRI = null; - // 5) - for (final String term : termDefinitions.keySet()) { - final Map termDefinition = (Map) termDefinitions - .get(term); - // 5.1) - if (term.contains(":")) { - continue; - } - // 5.2) - if (termDefinition == null || iri.equals(termDefinition.get("@id")) - || !iri.startsWith((String) termDefinition.get("@id"))) { - continue; - } - - // 5.3) - final String candidate = term + ":" - + iri.substring(((String) termDefinition.get("@id")).length()); - // 5.4) - if ((compactIRI == null || compareShortestLeast(candidate, compactIRI) < 0) - && (!termDefinitions.containsKey(candidate) || (iri - .equals(((Map) termDefinitions.get(candidate)) - .get("@id")) && value == null))) { - compactIRI = candidate; - } - - } - - // 6) - if (compactIRI != null) { - return compactIRI; - } - - // 7) - if (!relativeToVocab) { - return JsonLdUrl.removeBase(this.get("@base"), iri); - } - - // 8) - return iri; - } - - /** - * Return a map of potential RDF prefixes based on the JSON-LD Term - * Definitions in this context. - *

- * No guarantees of the prefixes are given, beyond that it will not contain - * ":". - * - * @param onlyCommonPrefixes - * If true, the result will not include - * "not so useful" prefixes, such as "term1": - * "http://example.com/term1", e.g. all IRIs will end with "/" or - * "#". If false, all potential prefixes are - * returned. - * - * @return A map from prefix string to IRI string - */ - public Map getPrefixes(boolean onlyCommonPrefixes) { - final Map prefixes = new LinkedHashMap(); - for (final String term : termDefinitions.keySet()) { - if (term.contains(":")) { - continue; - } - final Map termDefinition = (Map) termDefinitions - .get(term); - if (termDefinition == null) { - continue; - } - final String id = (String) termDefinition.get("@id"); - if (id == null) { - continue; - } - if (term.startsWith("@") || id.startsWith("@")) { - continue; - } - if (!onlyCommonPrefixes || id.endsWith("/") || id.endsWith("#")) { - prefixes.put(term, id); - } - } - return prefixes; - } - - String compactIri(String iri, boolean relativeToVocab) { - return compactIri(iri, null, relativeToVocab, false); - } - - String compactIri(String iri) { - return compactIri(iri, null, false, false); - } - - @Override - public Context clone() { - final Context rval = (Context) super.clone(); - // TODO: is this shallow copy enough? probably not, but it passes all - // the tests! - rval.termDefinitions = new LinkedHashMap(this.termDefinitions); - return rval; - } - - /** - * Inverse Context Creation - * - * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation - * - * Generates an inverse context for use in the compaction algorithm, if not - * already generated for the given active context. - * - * @return the inverse context. - */ - public Map getInverse() { - - // lazily create inverse - if (inverse != null) { - return inverse; - } - - // 1) - inverse = newMap(); - - // 2) - String defaultLanguage = (String) this.get("@language"); - if (defaultLanguage == null) { - defaultLanguage = "@none"; - } - - // create term selections for each mapping in the context, ordererd by - // shortest and then lexicographically least - final List terms = new ArrayList(termDefinitions.keySet()); - Collections.sort(terms, new Comparator() { - @Override - public int compare(String a, String b) { - return compareShortestLeast(a, b); - } - }); - - for (final String term : terms) { - final Map definition = (Map) termDefinitions.get(term); - // 3.1) - if (definition == null) { - continue; - } - - // 3.2) - String container = (String) definition.get("@container"); - if (container == null) { - container = "@none"; - } - - // 3.3) - final String iri = (String) definition.get("@id"); - - // 3.4 + 3.5) - Map containerMap = (Map) inverse.get(iri); - if (containerMap == null) { - containerMap = newMap(); - inverse.put(iri, containerMap); - } - - // 3.6 + 3.7) - Map typeLanguageMap = (Map) containerMap.get(container); - if (typeLanguageMap == null) { - typeLanguageMap = newMap(); - typeLanguageMap.put("@language", newMap()); - typeLanguageMap.put("@type", newMap()); - containerMap.put(container, typeLanguageMap); - } - - // 3.8) - if (Boolean.TRUE.equals(definition.get("@reverse"))) { - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey("@reverse")) { - typeMap.put("@reverse", term); - } - // 3.9) - } else if (definition.containsKey("@type")) { - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey(definition.get("@type"))) { - typeMap.put((String) definition.get("@type"), term); - } - // 3.10) - } else if (definition.containsKey("@language")) { - final Map languageMap = (Map) typeLanguageMap - .get("@language"); - String language = (String) definition.get("@language"); - if (language == null) { - language = "@null"; - } - if (!languageMap.containsKey(language)) { - languageMap.put(language, term); - } - // 3.11) - } else { - // 3.11.1) - final Map languageMap = (Map) typeLanguageMap - .get("@language"); - // 3.11.2) - if (!languageMap.containsKey("@language")) { - languageMap.put("@language", term); - } - // 3.11.3) - if (!languageMap.containsKey("@none")) { - languageMap.put("@none", term); - } - // 3.11.4) - final Map typeMap = (Map) typeLanguageMap - .get("@type"); - // 3.11.5) - if (!typeMap.containsKey("@none")) { - typeMap.put("@none", term); - } - } - } - // 4) - return inverse; - } - - /** - * Term Selection - * - * http://json-ld.org/spec/latest/json-ld-api/#term-selection - * - * This algorithm, invoked via the IRI Compaction algorithm, makes use of an - * active context's inverse context to find the term that is best used to - * compact an IRI. Other information about a value associated with the IRI - * is given, including which container mappings and which type mapping or - * language mapping would be best used to express the value. - * - * @return the selected term. - */ - private String selectTerm(String iri, List containers, String typeLanguage, - List preferredValues) { - final Map inv = getInverse(); - // 1) - final Map containerMap = (Map) inv.get(iri); - // 2) - for (final String container : containers) { - // 2.1) - if (!containerMap.containsKey(container)) { - continue; - } - // 2.2) - final Map typeLanguageMap = (Map) containerMap - .get(container); - // 2.3) - final Map valueMap = (Map) typeLanguageMap - .get(typeLanguage); - // 2.4 ) - for (final String item : preferredValues) { - // 2.4.1 - if (!valueMap.containsKey(item)) { - continue; - } - // 2.4.2 - return (String) valueMap.get(item); - } - } - // 3) - return null; - } - - /** - * Retrieve container mapping. - * - * @param property - * The Property to get a container mapping for. - * @return The container mapping - */ - public String getContainer(String property) { - if ("@graph".equals(property)) { - return "@set"; - } - if (JsonLdUtils.isKeyword(property)) { - return property; - } - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return null; - } - return (String) td.get("@container"); - } - - public Boolean isReverseProperty(String property) { - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return false; - } - final Object reverse = td.get("@reverse"); - return reverse != null && (Boolean) reverse; - } - - private String getTypeMapping(String property) { - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return null; - } - return (String) td.get("@type"); - } - - private String getLanguageMapping(String property) { - final Map td = (Map) termDefinitions.get(property); - if (td == null) { - return null; - } - return (String) td.get("@language"); - } - - Map getTermDefinition(String key) { - return ((Map) termDefinitions.get(key)); - } - - public Object expandValue(String activeProperty, Object value) throws JsonLdError { - final Map rval = newMap(); - final Map td = getTermDefinition(activeProperty); - // 1) - if (td != null && "@id".equals(td.get("@type"))) { - // TODO: i'm pretty sure value should be a string if the @type is - // @id - rval.put("@id", expandIri(value.toString(), true, false, null, null)); - return rval; - } - // 2) - if (td != null && "@vocab".equals(td.get("@type"))) { - // TODO: same as above - rval.put("@id", expandIri(value.toString(), true, true, null, null)); - return rval; - } - // 3) - rval.put("@value", value); - // 4) - if (td != null && td.containsKey("@type")) { - rval.put("@type", td.get("@type")); - } - // 5) - else if (value instanceof String) { - // 5.1) - if (td != null && td.containsKey("@language")) { - final String lang = (String) td.get("@language"); - if (lang != null) { - rval.put("@language", lang); - } - } - // 5.2) - else if (this.get("@language") != null) { - rval.put("@language", this.get("@language")); - } - } - return rval; - } - - public Object getContextValue(String activeProperty, String string) throws JsonLdError { - throw new JsonLdError(Error.NOT_IMPLEMENTED, - "getContextValue is only used by old code so far and thus isn't implemented"); - } - - public Map serialize() { - final Map ctx = newMap(); - if (this.get("@base") != null && !this.get("@base").equals(options.getBase())) { - ctx.put("@base", this.get("@base")); - } - if (this.get("@language") != null) { - ctx.put("@language", this.get("@language")); - } - if (this.get("@vocab") != null) { - ctx.put("@vocab", this.get("@vocab")); - } - for (final String term : termDefinitions.keySet()) { - final Map definition = (Map) termDefinitions.get(term); - if (definition.get("@language") == null - && definition.get("@container") == null - && definition.get("@type") == null - && (definition.get("@reverse") == null || Boolean.FALSE.equals(definition - .get("@reverse")))) { - final String cid = this.compactIri((String) definition.get("@id")); - ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); - } else { - final Map defn = newMap(); - final String cid = this.compactIri((String) definition.get("@id")); - final Boolean reverseProperty = Boolean.TRUE.equals(definition.get("@reverse")); - if (!(term.equals(cid) && !reverseProperty)) { - defn.put(reverseProperty ? "@reverse" : "@id", cid); - } - final String typeMapping = (String) definition.get("@type"); - if (typeMapping != null) { - defn.put("@type", JsonLdUtils.isKeyword(typeMapping) ? typeMapping - : compactIri(typeMapping, true)); - } - if (definition.get("@container") != null) { - defn.put("@container", definition.get("@container")); - } - final Object lang = definition.get("@language"); - if (definition.get("@language") != null) { - defn.put("@language", Boolean.FALSE.equals(lang) ? null : lang); - } - ctx.put(term, defn); - } - } - - final Map rval = newMap(); - if (!(ctx == null || ctx.isEmpty())) { - rval.put("@context", ctx); - } - return rval; - } - +package com.github.jsonldjava.core; + +import static com.github.jsonldjava.core.JsonLdUtils.compareShortestLeast; +import static com.github.jsonldjava.utils.Obj.newMap; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.github.jsonldjava.core.JsonLdError.Error; +import com.github.jsonldjava.utils.JsonLdUrl; +import com.github.jsonldjava.utils.Obj; + +/** + * A helper class which still stores all the values in a map but gives member + * variables easily access certain keys + * + * @author tristan + * + */ +public class Context extends LinkedHashMap { + + private JsonLdOptions options; + private Map termDefinitions; + public Map inverse = null; + + public Context() { + this(new JsonLdOptions()); + } + + public Context(JsonLdOptions opts) { + super(); + init(opts); + } + + public Context(Map map, JsonLdOptions opts) { + super(map); + init(opts); + } + + public Context(Map map) { + super(map); + init(new JsonLdOptions()); + } + + public Context(Object context, JsonLdOptions opts) { + // TODO: load remote context + super(context instanceof Map ? (Map) context : null); + init(opts); + } + + private void init(JsonLdOptions options) { + this.options = options; + if (options.getBase() != null) { + this.put("@base", options.getBase()); + } + this.termDefinitions = newMap(); + } + + /** + * Value Compaction Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#value-compaction + * + * @param activeProperty + * The Active Property + * @param value + * The value to compact + * @return The compacted value + */ + public Object compactValue(String activeProperty, Map value) { + // 1) + int numberMembers = value.size(); + // 2) + if (value.containsKey("@index") && "@index".equals(this.getContainer(activeProperty))) { + numberMembers--; + } + // 3) + if (numberMembers > 2) { + return value; + } + // 4) + final String typeMapping = getTypeMapping(activeProperty); + final String languageMapping = getLanguageMapping(activeProperty); + if (value.containsKey("@id")) { + // 4.1) + if (numberMembers == 1 && "@id".equals(typeMapping)) { + return compactIri((String) value.get("@id")); + } + // 4.2) + if (numberMembers == 1 && "@vocab".equals(typeMapping)) { + return compactIri((String) value.get("@id"), true); + } + // 4.3) + return value; + } + final Object valueValue = value.get("@value"); + // 5) + if (value.containsKey("@type") && Obj.equals(value.get("@type"), typeMapping)) { + return valueValue; + } + // 6) + if (value.containsKey("@language")) { + // TODO: SPEC: doesn't specify to check default language as well + if (Obj.equals(value.get("@language"), languageMapping) + || Obj.equals(value.get("@language"), this.get("@language"))) { + return valueValue; + } + } + // 7) + if (numberMembers == 1 + && (!(valueValue instanceof String) || !this.containsKey("@language") || (termDefinitions + .containsKey(activeProperty) + && getTermDefinition(activeProperty).containsKey("@language") && languageMapping == null))) { + return valueValue; + } + // 8) + return value; + } + + /** + * Context Processing Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#context-processing-algorithms + * + * @param localContext + * The Local Context object. + * @param remoteContexts + * The list of Strings denoting the remote Context URLs. + * @return The parsed and merged Context. + * @throws JsonLdError + * If there is an error parsing the contexts. + */ + public Context parse(Object localContext, List remoteContexts) throws JsonLdError { + if (remoteContexts == null) { + remoteContexts = new ArrayList(); + } + // 1. Initialize result to the result of cloning active context. + Context result = this.clone(); // TODO: clone? + // 2) + if (!(localContext instanceof List)) { + final Object temp = localContext; + localContext = new ArrayList(); + ((List) localContext).add(temp); + } + // 3) + for (Object context : ((List) localContext)) { + // 3.1) + if (context == null) { + result = new Context(this.options); + continue; + } else if (context instanceof Context) { + result = ((Context) context).clone(); + } + // 3.2) + else if (context instanceof String) { + String uri = (String) result.get("@base"); + uri = JsonLdUrl.resolve(uri, (String) context); + // 3.2.2 + if (remoteContexts.contains(uri)) { + throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, uri); + } + remoteContexts.add(uri); + + // 3.2.3: Dereference context + final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); + final Object remoteContext = rd.document; + if (!(remoteContext instanceof Map) + || !((Map) remoteContext).containsKey("@context")) { + // If the dereferenced document has no top-level JSON object + // with an @context member + throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); + } + context = ((Map) remoteContext).get("@context"); + + // 3.2.4 + result = result.parse(context, remoteContexts); + // 3.2.5 + continue; + } else if (!(context instanceof Map)) { + // 3.3 + throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); + } + + // 3.4 + if (remoteContexts.isEmpty() && ((Map) context).containsKey("@base")) { + final Object value = ((Map) context).get("@base"); + if (value == null) { + result.remove("@base"); + } else if (value instanceof String) { + if (JsonLdUtils.isAbsoluteIri((String) value)) { + result.put("@base", value); + } else { + final String baseUri = (String) result.get("@base"); + if (!JsonLdUtils.isAbsoluteIri(baseUri)) { + throw new JsonLdError(Error.INVALID_BASE_IRI, baseUri); + } + result.put("@base", JsonLdUrl.resolve(baseUri, (String) value)); + } + } else { + throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, + "@base must be a string"); + } + } + + // 3.5 + if (((Map) context).containsKey("@vocab")) { + final Object value = ((Map) context).get("@vocab"); + if (value == null) { + result.remove("@vocab"); + } else if (value instanceof String) { + if (JsonLdUtils.isAbsoluteIri((String) value)) { + result.put("@vocab", value); + } else { + throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, + "@value must be an absolute IRI"); + } + } else { + throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, + "@vocab must be a string or null"); + } + } + + // 3.6 + if (((Map) context).containsKey("@language")) { + final Object value = ((Map) context).get("@language"); + if (value == null) { + result.remove("@language"); + } else if (value instanceof String) { + result.put("@language", ((String) value).toLowerCase()); + } else { + throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); + } + } + + // 3.7 + final Map defined = new LinkedHashMap(); + for (final String key : ((Map) context).keySet()) { + if ("@base".equals(key) || "@vocab".equals(key) || "@language".equals(key)) { + continue; + } + result.createTermDefinition((Map) context, key, defined); + } + } + return result; + } + + public Context parse(Object localContext) throws JsonLdError { + return this.parse(localContext, new ArrayList()); + } + + /** + * Create Term Definition Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition + * + * @param result + * @param context + * @param key + * @param defined + * @throws JsonLdError + */ + private void createTermDefinition(Map context, String term, + Map defined) throws JsonLdError { + if (defined.containsKey(term)) { + if (Boolean.TRUE.equals(defined.get(term))) { + return; + } + throw new JsonLdError(Error.CYCLIC_IRI_MAPPING, term); + } + + defined.put(term, false); + + if (JsonLdUtils.isKeyword(term)) { + throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); + } + + this.termDefinitions.remove(term); + Object value = context.get(term); + if (value == null + || (value instanceof Map && ((Map) value).containsKey("@id") && ((Map) value) + .get("@id") == null)) { + this.termDefinitions.put(term, null); + defined.put(term, true); + return; + } + + if (value instanceof String) { + value = newMap("@id", value); + } + + if (!(value instanceof Map)) { + throw new JsonLdError(Error.INVALID_TERM_DEFINITION, value); + } + + // casting the value so it doesn't have to be done below everytime + final Map val = (Map) value; + + // 9) create a new term definition + final Map definition = newMap(); + + // 10) + if (val.containsKey("@type")) { + if (!(val.get("@type") instanceof String)) { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, val.get("@type")); + } + String type = (String) val.get("@type"); + try { + type = this.expandIri((String) val.get("@type"), false, true, context, defined); + } catch (final JsonLdError error) { + if (error.getType() != Error.INVALID_IRI_MAPPING) { + throw error; + } + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + } + // TODO: fix check for absoluteIri (blank nodes shouldn't count, at + // least not here!) + if ("@id".equals(type) || "@vocab".equals(type) + || (!type.startsWith("_:") && JsonLdUtils.isAbsoluteIri(type))) { + definition.put("@type", type); + } else { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + } + } + + // 11) + if (val.containsKey("@reverse")) { + if (val.containsKey("@id")) { + throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); + } + if (!(val.get("@reverse") instanceof String)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "Expected String for @reverse value. got " + + (val.get("@reverse") == null ? "null" : val.get("@reverse") + .getClass())); + } + final String reverse = this.expandIri((String) val.get("@reverse"), false, true, + context, defined); + if (!JsonLdUtils.isAbsoluteIri(reverse)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Non-absolute @reverse IRI: " + + reverse); + } + definition.put("@id", reverse); + if (val.containsKey("@container")) { + final String container = (String) val.get("@container"); + if (container == null || "@set".equals(container) || "@index".equals(container)) { + definition.put("@container", container); + } else { + throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, + "reverse properties only support set- and index-containers"); + } + } + definition.put("@reverse", true); + this.termDefinitions.put(term, definition); + defined.put(term, true); + return; + } + + // 12) + definition.put("@reverse", false); + + // 13) + if (val.get("@id") != null && !term.equals(val.get("@id"))) { + if (!(val.get("@id") instanceof String)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "expected value of @id to be a string"); + } + + final String res = this.expandIri((String) val.get("@id"), false, true, context, + defined); + if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { + if ("@context".equals(res)) { + throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, "cannot alias @context"); + } + definition.put("@id", res); + } else { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "resulting IRI mapping should be a keyword, absolute IRI or blank node"); + } + } + + // 14) + else if (term.indexOf(":") >= 0) { + final int colIndex = term.indexOf(":"); + final String prefix = term.substring(0, colIndex); + final String suffix = term.substring(colIndex + 1); + if (context.containsKey(prefix)) { + this.createTermDefinition(context, prefix, defined); + } + if (termDefinitions.containsKey(prefix)) { + definition.put("@id", + ((Map) termDefinitions.get(prefix)).get("@id") + suffix); + } else { + definition.put("@id", term); + } + // 15) + } else if (this.containsKey("@vocab")) { + definition.put("@id", this.get("@vocab") + term); + } else { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "relative term definition without vocab mapping"); + } + + // 16) + if (val.containsKey("@container")) { + final String container = (String) val.get("@container"); + if (!"@list".equals(container) && !"@set".equals(container) + && !"@index".equals(container) && !"@language".equals(container)) { + throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, + "@container must be either @list, @set, @index, or @language"); + } + definition.put("@container", container); + } + + // 17) + if (val.containsKey("@language") && !val.containsKey("@type")) { + if (val.get("@language") == null || val.get("@language") instanceof String) { + final String language = (String) val.get("@language"); + definition.put("@language", language != null ? language.toLowerCase() : null); + } else { + throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, + "@language must be a string or null"); + } + } + + // 18) + this.termDefinitions.put(term, definition); + defined.put(term, true); + } + + /** + * IRI Expansion Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#iri-expansion + * + * @param value + * @param relative + * @param vocab + * @param context + * @param defined + * @return + * @throws JsonLdError + */ + String expandIri(String value, boolean relative, boolean vocab, Map context, + Map defined) throws JsonLdError { + // 1) + if (value == null || JsonLdUtils.isKeyword(value)) { + return value; + } + // 2) + if (context != null && context.containsKey(value) + && !Boolean.TRUE.equals(defined.get(value))) { + this.createTermDefinition(context, value, defined); + } + // 3) + if (vocab && this.termDefinitions.containsKey(value)) { + final Map td = (LinkedHashMap) this.termDefinitions + .get(value); + if (td != null) { + return (String) td.get("@id"); + } else { + return null; + } + } + // 4) + final int colIndex = value.indexOf(":"); + if (colIndex >= 0) { + // 4.1) + final String prefix = value.substring(0, colIndex); + final String suffix = value.substring(colIndex + 1); + // 4.2) + if ("_".equals(prefix) || suffix.startsWith("//")) { + return value; + } + // 4.3) + if (context != null && context.containsKey(prefix) + && (!defined.containsKey(prefix) || defined.get(prefix) == false)) { + this.createTermDefinition(context, prefix, defined); + } + // 4.4) + if (this.termDefinitions.containsKey(prefix)) { + return (String) ((LinkedHashMap) this.termDefinitions.get(prefix)) + .get("@id") + suffix; + } + // 4.5) + return value; + } + // 5) + if (vocab && this.containsKey("@vocab")) { + return this.get("@vocab") + value; + } + // 6) + else if (relative) { + return JsonLdUrl.resolve((String) this.get("@base"), value); + } else if (context != null && JsonLdUtils.isRelativeIri(value)) { + throw new JsonLdError(Error.INVALID_IRI_MAPPING, "not an absolute IRI: " + value); + } + // 7) + return value; + } + + /** + * IRI Compaction Algorithm + * + * http://json-ld.org/spec/latest/json-ld-api/#iri-compaction + * + * Compacts an IRI or keyword into a term or prefix if it can be. If the IRI + * has an associated value it may be passed. + * + * @param iri + * the IRI to compact. + * @param value + * the value to check or null. + * @param relativeTo + * options for how to compact IRIs: vocab: true to split after + * @vocab, false not to. + * @param reverse + * true if a reverse property is being compacted, false if not. + * + * @return the compacted term, prefix, keyword alias, or the original IRI. + */ + String compactIri(String iri, Object value, boolean relativeToVocab, boolean reverse) { + // 1) + if (iri == null) { + return null; + } + + // 2) + if (relativeToVocab && getInverse().containsKey(iri)) { + // 2.1) + String defaultLanguage = (String) this.get("@language"); + if (defaultLanguage == null) { + defaultLanguage = "@none"; + } + + // 2.2) + final List containers = new ArrayList(); + // 2.3) + String typeLanguage = "@language"; + String typeLanguageValue = "@null"; + + // 2.4) + if (value instanceof Map && ((Map) value).containsKey("@index")) { + containers.add("@index"); + } + + // 2.5) + if (reverse) { + typeLanguage = "@type"; + typeLanguageValue = "@reverse"; + containers.add("@set"); + } + // 2.6) + else if (value instanceof Map && ((Map) value).containsKey("@list")) { + // 2.6.1) + if (!((Map) value).containsKey("@index")) { + containers.add("@list"); + } + // 2.6.2) + final List list = (List) ((Map) value).get("@list"); + // 2.6.3) + String commonLanguage = (list.size() == 0) ? defaultLanguage : null; + String commonType = null; + // 2.6.4) + for (final Object item : list) { + // 2.6.4.1) + String itemLanguage = "@none"; + String itemType = "@none"; + // 2.6.4.2) + if (JsonLdUtils.isValue(item)) { + // 2.6.4.2.1) + if (((Map) item).containsKey("@language")) { + itemLanguage = (String) ((Map) item).get("@language"); + } + // 2.6.4.2.2) + else if (((Map) item).containsKey("@type")) { + itemType = (String) ((Map) item).get("@type"); + } + // 2.6.4.2.3) + else { + itemLanguage = "@null"; + } + } + // 2.6.4.3) + else { + itemType = "@id"; + } + // 2.6.4.4) + if (commonLanguage == null) { + commonLanguage = itemLanguage; + } + // 2.6.4.5) + else if (!commonLanguage.equals(itemLanguage) && JsonLdUtils.isValue(item)) { + commonLanguage = "@none"; + } + // 2.6.4.6) + if (commonType == null) { + commonType = itemType; + } + // 2.6.4.7) + else if (!commonType.equals(itemType)) { + commonType = "@none"; + } + // 2.6.4.8) + if ("@none".equals(commonLanguage) && "@none".equals(commonType)) { + break; + } + } + // 2.6.5) + commonLanguage = (commonLanguage != null) ? commonLanguage : "@none"; + // 2.6.6) + commonType = (commonType != null) ? commonType : "@none"; + // 2.6.7) + if (!"@none".equals(commonType)) { + typeLanguage = "@type"; + typeLanguageValue = commonType; + } + // 2.6.8) + else { + typeLanguageValue = commonLanguage; + } + } + // 2.7) + else { + // 2.7.1) + if (value instanceof Map && ((Map) value).containsKey("@value")) { + // 2.7.1.1) + if (((Map) value).containsKey("@language") + && !((Map) value).containsKey("@index")) { + containers.add("@language"); + typeLanguageValue = (String) ((Map) value).get("@language"); + } + // 2.7.1.2) + else if (((Map) value).containsKey("@type")) { + typeLanguage = "@type"; + typeLanguageValue = (String) ((Map) value).get("@type"); + } + } + // 2.7.2) + else { + typeLanguage = "@type"; + typeLanguageValue = "@id"; + } + // 2.7.3) + containers.add("@set"); + } + + // 2.8) + containers.add("@none"); + // 2.9) + if (typeLanguageValue == null) { + typeLanguageValue = "@null"; + } + // 2.10) + final List preferredValues = new ArrayList(); + // 2.11) + if ("@reverse".equals(typeLanguageValue)) { + preferredValues.add("@reverse"); + } + // 2.12) + if (("@reverse".equals(typeLanguageValue) || "@id".equals(typeLanguageValue)) + && (value instanceof Map) && ((Map) value).containsKey("@id")) { + // 2.12.1) + final String result = this.compactIri( + (String) ((Map) value).get("@id"), null, true, true); + if (termDefinitions.containsKey(result) + && ((Map) termDefinitions.get(result)).containsKey("@id") + && ((Map) value).get("@id").equals( + ((Map) termDefinitions.get(result)).get("@id"))) { + preferredValues.add("@vocab"); + preferredValues.add("@id"); + } + // 2.12.2) + else { + preferredValues.add("@id"); + preferredValues.add("@vocab"); + } + } + // 2.13) + else { + preferredValues.add(typeLanguageValue); + } + preferredValues.add("@none"); + + // 2.14) + final String term = selectTerm(iri, containers, typeLanguage, preferredValues); + // 2.15) + if (term != null) { + return term; + } + } + + // 3) + if (relativeToVocab && this.containsKey("@vocab")) { + // determine if vocab is a prefix of the iri + final String vocab = (String) this.get("@vocab"); + // 3.1) + if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { + // use suffix as relative iri if it is not a term in the + // active context + final String suffix = iri.substring(vocab.length()); + if (!termDefinitions.containsKey(suffix)) { + return suffix; + } + } + } + + // 4) + String compactIRI = null; + // 5) + for (final String term : termDefinitions.keySet()) { + final Map termDefinition = (Map) termDefinitions + .get(term); + // 5.1) + if (term.contains(":")) { + continue; + } + // 5.2) + if (termDefinition == null || iri.equals(termDefinition.get("@id")) + || !iri.startsWith((String) termDefinition.get("@id"))) { + continue; + } + + // 5.3) + final String candidate = term + ":" + + iri.substring(((String) termDefinition.get("@id")).length()); + // 5.4) + compactIRI = _iriCompactionStep5point4(iri, value, compactIRI, candidate, termDefinitions); + } + + // 6) + if (compactIRI != null) { + return compactIRI; + } + + // 7) + if (!relativeToVocab) { + return JsonLdUrl.removeBase(this.get("@base"), iri); + } + + // 8) + return iri; + } + + public static String _iriCompactionStep5point4(String iri, Object value, String compactIRI, + final String candidate, Map termDefinitions) { + + boolean condition1 = (compactIRI == null || compareShortestLeast(candidate, compactIRI) < 0); + + boolean condition2 = (!termDefinitions.containsKey(candidate) || (iri + .equals(((Map) termDefinitions.get(candidate)) + .get("@id")) && value == null)); + + if (condition1 && condition2) { + compactIRI = candidate; + } + return compactIRI; + } + + /** + * Return a map of potential RDF prefixes based on the JSON-LD Term + * Definitions in this context. + *

+ * No guarantees of the prefixes are given, beyond that it will not contain + * ":". + * + * @param onlyCommonPrefixes + * If true, the result will not include + * "not so useful" prefixes, such as "term1": + * "http://example.com/term1", e.g. all IRIs will end with "/" or + * "#". If false, all potential prefixes are + * returned. + * + * @return A map from prefix string to IRI string + */ + public Map getPrefixes(boolean onlyCommonPrefixes) { + final Map prefixes = new LinkedHashMap(); + for (final String term : termDefinitions.keySet()) { + if (term.contains(":")) { + continue; + } + final Map termDefinition = (Map) termDefinitions + .get(term); + if (termDefinition == null) { + continue; + } + final String id = (String) termDefinition.get("@id"); + if (id == null) { + continue; + } + if (term.startsWith("@") || id.startsWith("@")) { + continue; + } + if (!onlyCommonPrefixes || id.endsWith("/") || id.endsWith("#")) { + prefixes.put(term, id); + } + } + return prefixes; + } + + String compactIri(String iri, boolean relativeToVocab) { + return compactIri(iri, null, relativeToVocab, false); + } + + String compactIri(String iri) { + return compactIri(iri, null, false, false); + } + + @Override + public Context clone() { + final Context rval = (Context) super.clone(); + // TODO: is this shallow copy enough? probably not, but it passes all + // the tests! + rval.termDefinitions = new LinkedHashMap(this.termDefinitions); + return rval; + } + + /** + * Inverse Context Creation + * + * http://json-ld.org/spec/latest/json-ld-api/#inverse-context-creation + * + * Generates an inverse context for use in the compaction algorithm, if not + * already generated for the given active context. + * + * @return the inverse context. + */ + public Map getInverse() { + + // lazily create inverse + if (inverse != null) { + return inverse; + } + + // 1) + inverse = newMap(); + + // 2) + String defaultLanguage = (String) this.get("@language"); + if (defaultLanguage == null) { + defaultLanguage = "@none"; + } + + // create term selections for each mapping in the context, ordererd by + // shortest and then lexicographically least + final List terms = new ArrayList(termDefinitions.keySet()); + Collections.sort(terms, new Comparator() { + @Override + public int compare(String a, String b) { + return compareShortestLeast(a, b); + } + }); + + for (final String term : terms) { + final Map definition = (Map) termDefinitions.get(term); + // 3.1) + if (definition == null) { + continue; + } + + // 3.2) + String container = (String) definition.get("@container"); + if (container == null) { + container = "@none"; + } + + // 3.3) + final String iri = (String) definition.get("@id"); + + // 3.4 + 3.5) + Map containerMap = (Map) inverse.get(iri); + if (containerMap == null) { + containerMap = newMap(); + inverse.put(iri, containerMap); + } + + // 3.6 + 3.7) + Map typeLanguageMap = (Map) containerMap.get(container); + if (typeLanguageMap == null) { + typeLanguageMap = newMap(); + typeLanguageMap.put("@language", newMap()); + typeLanguageMap.put("@type", newMap()); + containerMap.put(container, typeLanguageMap); + } + + // 3.8) + if (Boolean.TRUE.equals(definition.get("@reverse"))) { + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + if (!typeMap.containsKey("@reverse")) { + typeMap.put("@reverse", term); + } + // 3.9) + } else if (definition.containsKey("@type")) { + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + if (!typeMap.containsKey(definition.get("@type"))) { + typeMap.put((String) definition.get("@type"), term); + } + // 3.10) + } else if (definition.containsKey("@language")) { + final Map languageMap = (Map) typeLanguageMap + .get("@language"); + String language = (String) definition.get("@language"); + if (language == null) { + language = "@null"; + } + if (!languageMap.containsKey(language)) { + languageMap.put(language, term); + } + // 3.11) + } else { + // 3.11.1) + final Map languageMap = (Map) typeLanguageMap + .get("@language"); + // 3.11.2) + if (!languageMap.containsKey("@language")) { + languageMap.put("@language", term); + } + // 3.11.3) + if (!languageMap.containsKey("@none")) { + languageMap.put("@none", term); + } + // 3.11.4) + final Map typeMap = (Map) typeLanguageMap + .get("@type"); + // 3.11.5) + if (!typeMap.containsKey("@none")) { + typeMap.put("@none", term); + } + } + } + // 4) + return inverse; + } + + /** + * Term Selection + * + * http://json-ld.org/spec/latest/json-ld-api/#term-selection + * + * This algorithm, invoked via the IRI Compaction algorithm, makes use of an + * active context's inverse context to find the term that is best used to + * compact an IRI. Other information about a value associated with the IRI + * is given, including which container mappings and which type mapping or + * language mapping would be best used to express the value. + * + * @return the selected term. + */ + private String selectTerm(String iri, List containers, String typeLanguage, + List preferredValues) { + final Map inv = getInverse(); + // 1) + final Map containerMap = (Map) inv.get(iri); + // 2) + for (final String container : containers) { + // 2.1) + if (!containerMap.containsKey(container)) { + continue; + } + // 2.2) + final Map typeLanguageMap = (Map) containerMap + .get(container); + // 2.3) + final Map valueMap = (Map) typeLanguageMap + .get(typeLanguage); + // 2.4 ) + for (final String item : preferredValues) { + // 2.4.1 + if (!valueMap.containsKey(item)) { + continue; + } + // 2.4.2 + return (String) valueMap.get(item); + } + } + // 3) + return null; + } + + /** + * Retrieve container mapping. + * + * @param property + * The Property to get a container mapping for. + * @return The container mapping + */ + public String getContainer(String property) { + if ("@graph".equals(property)) { + return "@set"; + } + if (JsonLdUtils.isKeyword(property)) { + return property; + } + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return null; + } + return (String) td.get("@container"); + } + + public Boolean isReverseProperty(String property) { + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return false; + } + final Object reverse = td.get("@reverse"); + return reverse != null && (Boolean) reverse; + } + + private String getTypeMapping(String property) { + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return null; + } + return (String) td.get("@type"); + } + + private String getLanguageMapping(String property) { + final Map td = (Map) termDefinitions.get(property); + if (td == null) { + return null; + } + return (String) td.get("@language"); + } + + Map getTermDefinition(String key) { + return ((Map) termDefinitions.get(key)); + } + + public Object expandValue(String activeProperty, Object value) throws JsonLdError { + final Map rval = newMap(); + final Map td = getTermDefinition(activeProperty); + // 1) + if (td != null && "@id".equals(td.get("@type"))) { + // TODO: i'm pretty sure value should be a string if the @type is + // @id + rval.put("@id", expandIri(value.toString(), true, false, null, null)); + return rval; + } + // 2) + if (td != null && "@vocab".equals(td.get("@type"))) { + // TODO: same as above + rval.put("@id", expandIri(value.toString(), true, true, null, null)); + return rval; + } + // 3) + rval.put("@value", value); + // 4) + if (td != null && td.containsKey("@type")) { + rval.put("@type", td.get("@type")); + } + // 5) + else if (value instanceof String) { + // 5.1) + if (td != null && td.containsKey("@language")) { + final String lang = (String) td.get("@language"); + if (lang != null) { + rval.put("@language", lang); + } + } + // 5.2) + else if (this.get("@language") != null) { + rval.put("@language", this.get("@language")); + } + } + return rval; + } + + public Object getContextValue(String activeProperty, String string) throws JsonLdError { + throw new JsonLdError(Error.NOT_IMPLEMENTED, + "getContextValue is only used by old code so far and thus isn't implemented"); + } + + public Map serialize() { + final Map ctx = newMap(); + if (this.get("@base") != null && !this.get("@base").equals(options.getBase())) { + ctx.put("@base", this.get("@base")); + } + if (this.get("@language") != null) { + ctx.put("@language", this.get("@language")); + } + if (this.get("@vocab") != null) { + ctx.put("@vocab", this.get("@vocab")); + } + for (final String term : termDefinitions.keySet()) { + final Map definition = (Map) termDefinitions.get(term); + if (definition.get("@language") == null + && definition.get("@container") == null + && definition.get("@type") == null + && (definition.get("@reverse") == null || Boolean.FALSE.equals(definition + .get("@reverse")))) { + final String cid = this.compactIri((String) definition.get("@id")); + ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); + } else { + final Map defn = newMap(); + final String cid = this.compactIri((String) definition.get("@id")); + final Boolean reverseProperty = Boolean.TRUE.equals(definition.get("@reverse")); + if (!(term.equals(cid) && !reverseProperty)) { + defn.put(reverseProperty ? "@reverse" : "@id", cid); + } + final String typeMapping = (String) definition.get("@type"); + if (typeMapping != null) { + defn.put("@type", JsonLdUtils.isKeyword(typeMapping) ? typeMapping + : compactIri(typeMapping, true)); + } + if (definition.get("@container") != null) { + defn.put("@container", definition.get("@container")); + } + final Object lang = definition.get("@language"); + if (definition.get("@language") != null) { + defn.put("@language", Boolean.FALSE.equals(lang) ? null : lang); + } + ctx.put(term, defn); + } + } + + final Map rval = newMap(); + if (!(ctx == null || ctx.isEmpty())) { + rval.put("@context", ctx); + } + return rval; + } + } \ No newline at end of file From aebe0ae8d292708feb2851713830822f5a889278 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 30 Oct 2015 13:40:57 +1100 Subject: [PATCH 137/440] Note that the method is only visible for testing --- core/src/main/java/com/github/jsonldjava/core/Context.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 934ed32d..572c385e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -745,6 +745,9 @@ else if (((Map) value).containsKey("@type")) { return iri; } + /** + * This method is only visible for testing. + */ public static String _iriCompactionStep5point4(String iri, Object value, String compactIRI, final String candidate, Map termDefinitions) { From c7c5b68c126e4553301b9dcfe7364ead0aa139b6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 30 Oct 2015 14:40:36 +1100 Subject: [PATCH 138/440] Add tests to verify the lexicographical comparison, rather than the prefix length comparison --- .../jsonldjava/core/LongestPrefixTest.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java index 65bb671a..8ff10538 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java @@ -3,9 +3,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.net.URL; -import java.util.Map; import org.junit.Test; @@ -29,7 +29,7 @@ public void toRdfWithNamespace() throws Exception { } @Test - public void fromRdfWithNamespace() throws Exception { + public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Exception { RDFDataset inputRdf = new RDFDataset(); inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); @@ -50,6 +50,31 @@ public void fromRdfWithNamespace() throws Exception { String toJSONLD = JsonUtils.toPrettyString(fromRDF); System.out.println(toJSONLD); - assertFalse("Longest prefix was not used", toJSONLD.contains("aat:rev/")); + assertTrue("The lexicographically shortest URI was not chosen", toJSONLD.contains("aat:rev/")); + } + + @Test + public void fromRdfWithNamespaceLexicographicallyShortestChosen2() throws Exception { + + RDFDataset inputRdf = new RDFDataset(); + inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); + inputRdf.setNamespace("aatrev", "http://vocab.getty.edu/aat/rev/"); + + inputRdf.addTriple("http://vocab.getty.edu/aat/rev/5001065997", JsonLdConsts.RDF_TYPE, "http://vocab.getty.edu/aat/datatype"); + + final JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + + Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf),inputRdf.getContext(), options); + + final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); + System.out.println(rdf.getNamespaces()); + assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); + assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aatrev")); + + String toJSONLD = JsonUtils.toPrettyString(fromRDF); + System.out.println(toJSONLD); + + assertFalse("The lexicographically shortest URI was not chosen", toJSONLD.contains("aat:rev/")); } } From a6c0a99fa6b7d1c20e5988195db36bab4ee4e52b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 2 Nov 2015 11:40:00 +1100 Subject: [PATCH 139/440] Change README.md to use last released version Fixes #155 Currently the README.md file uses the latest snapshot version, which is confusing for people not used to how Maven works, and should always be referencing the latest released version for simplicity. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93fa01b3..92e1bada 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.7.1-SNAPSHOT + 0.7.0 Code example From 0818539b6d7577ff9bb4374d13c04de1cd4c9982 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 10:01:11 +1100 Subject: [PATCH 140/440] bump dependency versions, and specify all httpclient dependencies to work around possible issues in particular, httpclient-osgi incorrectly has a "scope=provided" dependency on httpcore-osgi which tells maven that it should not attempt to pull in the dependency. in order to make jsonld-java work for non-osgi users, we need to specify all of the necessary dependencies ourselves to work around this. --- README.md | 3 ++ core/pom.xml | 36 ++++++++++----------- pom.xml | 88 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 104 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 92e1bada..d96603bb 100644 --- a/README.md +++ b/README.md @@ -387,6 +387,9 @@ Once you've `commit`ted your code, and `push`ed it into your github fork you can CHANGELOG ========= +### 2015-11-16 +* Bump dependencies to latest versions, particularly HTTPClient that is seeing more use on 4.5/4.4 than the 4.2 series that we have used so far + ### 2015-09-30 * Release 0.7.0 diff --git a/core/pom.xml b/core/pom.xml index e73b174b..f313aab8 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -21,10 +21,28 @@ com.fasterxml.jackson.core jackson-databind + + org.apache.httpcomponents + httpclient-osgi + + + org.apache.httpcomponents + httpcore-osgi + org.slf4j slf4j-api + + + org.slf4j + jcl-over-slf4j + + + commons-io + commons-io + junit junit @@ -40,24 +58,6 @@ mockito-core test - - org.apache.httpcomponents - httpclient-osgi - - - org.apache.httpcomponents - httpcore-osgi - - - - org.slf4j - jcl-over-slf4j - - - commons-io - commons-io - diff --git a/pom.xml b/pom.xml index 4135a010..5a71549f 100755 --- a/pom.xml +++ b/pom.xml @@ -39,10 +39,11 @@ UTF-8 UTF-8 - 4.2.5 - 2.3.3 + 4.5.1 + 4.4.4 + 2.6.3 4.12 - 1.7.9 + 1.7.13 3.0.0 @@ -106,13 +107,90 @@ org.apache.httpcomponents - httpcore-osgi + httpclient + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpclient-cache + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + fluent-hc ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpmime + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpcore-osgi + ${httpcore.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpcore + ${httpcore.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpcore-nio + ${httpcore.version} + + + commons-logging + commons-logging + + + + + commons-codec + commons-codec + 1.10 org.mockito mockito-core - 1.10.17 + 1.10.19 commons-io From a5f6a172eff52ed9d94e3b8a8f5469afb620d5be Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 11:16:05 +1100 Subject: [PATCH 141/440] Convert some string appending methods to StringBuilder Fixes #158 --- .../jsonldjava/core/NormalizeUtils.java | 1144 ++++++++--------- .../jsonldjava/core/RDFDatasetUtils.java | 1128 ++++++++-------- 2 files changed, 1153 insertions(+), 1119 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index 96382edc..a1aae971 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -1,572 +1,572 @@ -package com.github.jsonldjava.core; - -import static com.github.jsonldjava.core.RDFDatasetUtils.parseNQuads; -import static com.github.jsonldjava.core.RDFDatasetUtils.toNQuad; - -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.github.jsonldjava.utils.Obj; - -class NormalizeUtils { - - private final UniqueNamer namer; - private final Map bnodes; - private final List quads; - private final JsonLdOptions options; - - public NormalizeUtils(List quads, Map bnodes, UniqueNamer namer, - JsonLdOptions options) { - this.options = options; - this.quads = quads; - this.bnodes = bnodes; - this.namer = namer; - } - - // generates unique and duplicate hashes for bnodes - public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { - List unnamed = new ArrayList(unnamed_); - List nextUnnamed = new ArrayList(); - Map> duplicates = new LinkedHashMap>(); - Map unique = new LinkedHashMap(); - - // NOTE: not using the same structure as javascript here to avoid - // possible stack overflows - // hash quads for each unnamed bnode - for (int hui = 0;; hui++) { - if (hui == unnamed.size()) { - // done, name blank nodes - Boolean named = false; - List hashes = new ArrayList(unique.keySet()); - Collections.sort(hashes); - for (final String hash : hashes) { - final String bnode = unique.get(hash); - namer.getName(bnode); - named = true; - } - - // continue to hash bnodes if a bnode was assigned a name - if (named) { - // this resets the initial variables, so it seems like it - // has to go on the stack - // but since this is the end of the function either way, it - // might not have to - // hashBlankNodes(unnamed); - hui = -1; - unnamed = nextUnnamed; - nextUnnamed = new ArrayList(); - duplicates = new LinkedHashMap>(); - unique = new LinkedHashMap(); - continue; - } - // name the duplicate hash bnods - else { - // names duplicate hash bnodes - // enumerate duplicate hash groups in sorted order - hashes = new ArrayList(duplicates.keySet()); - Collections.sort(hashes); - - // process each group - for (int pgi = 0;; pgi++) { - if (pgi == hashes.size()) { - // done, create JSON-LD array - // return createArray(); - final List normalized = new ArrayList(); - - // Note: At this point all bnodes in the set of RDF - // quads have been - // assigned canonical names, which have been stored - // in the 'namer' object. - // Here each quad is updated by assigning each of - // its bnodes its new name - // via the 'namer' object - - // update bnode names in each quad and serialize - for (int cai = 0; cai < quads.size(); ++cai) { - final Map quad = (Map) quads - .get(cai); - for (final String attr : new String[] { "subject", "object", "name" }) { - if (quad.containsKey(attr)) { - final Map qa = (Map) quad - .get(attr); - if (qa != null - && "blank node".equals(qa.get("type")) - && ((String) qa.get("value")).indexOf("_:c14n") != 0) { - qa.put("value", - namer.getName((String) qa.get(("value")))); - } - } - } - normalized - .add(toNQuad( - (RDFDataset.Quad) quad, - quad.containsKey("name") - && quad.get("name") != null ? (String) ((Map) quad - .get("name")).get("value") : null)); - } - - // sort normalized output - Collections.sort(normalized); - - // handle output format - if (options.format != null) { - if ("application/nquads".equals(options.format)) { - String rval = ""; - for (final String n : normalized) { - rval += n; - } - return rval; - } else { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, - options.format); - } - } - String rval = ""; - for (final String n : normalized) { - rval += n; - } - return parseNQuads(rval); - } - - // name each group member - final List group = duplicates.get(hashes.get(pgi)); - final List results = new ArrayList(); - for (int n = 0;; n++) { - if (n == group.size()) { - // name bnodes in hash order - Collections.sort(results, new Comparator() { - @Override - public int compare(HashResult a, HashResult b) { - final int res = a.hash.compareTo(b.hash); - return res; - } - }); - for (final HashResult r : results) { - // name all bnodes in path namer in - // key-entry order - // Note: key-order is preserved in - // javascript - for (final String key : r.pathNamer.existing().keySet()) { - namer.getName(key); - } - } - // processGroup(i+1); - break; - } else { - // skip already-named bnodes - final String bnode = group.get(n); - if (namer.isNamed(bnode)) { - continue; - } - - // hash bnode paths - final UniqueNamer pathNamer = new UniqueNamer("_:b"); - pathNamer.getName(bnode); - - final HashResult result = hashPaths(bnode, bnodes, namer, pathNamer); - results.add(result); - } - } - } - } - } - - // hash unnamed bnode - final String bnode = unnamed.get(hui); - final String hash = hashQuads(bnode, bnodes, namer); - - // store hash as unique or a duplicate - if (duplicates.containsKey(hash)) { - duplicates.get(hash).add(bnode); - nextUnnamed.add(bnode); - } else if (unique.containsKey(hash)) { - final List tmp = new ArrayList(); - tmp.add(unique.get(hash)); - tmp.add(bnode); - duplicates.put(hash, tmp); - nextUnnamed.add(unique.get(hash)); - nextUnnamed.add(bnode); - unique.remove(hash); - } else { - unique.put(hash, bnode); - } - } - } - - private static class HashResult { - String hash; - UniqueNamer pathNamer; - } - - /** - * Produces a hash for the paths of adjacent bnodes for a bnode, - * incorporating all information about its subgraph of bnodes. This method - * will recursively pick adjacent bnode permutations that produce the - * lexicographically-least 'path' serializations. - * - * @param id - * the ID of the bnode to hash paths for. - * @param bnodes - * the map of bnode quads. - * @param namer - * the canonical bnode namer. - * @param pathNamer - * the namer used to assign names to adjacent bnodes. - * @param callback - * (err, result) called once the operation completes. - */ - private static HashResult hashPaths(String id, Map bnodes, UniqueNamer namer, - UniqueNamer pathNamer) { - try { - // create SHA-1 digest - final MessageDigest md = MessageDigest.getInstance("SHA-1"); - - final Map> groups = new LinkedHashMap>(); - List groupHashes; - final List quads = (List) ((Map) bnodes.get(id)) - .get("quads"); - - for (int hpi = 0;; hpi++) { - if (hpi == quads.size()) { - // done , hash groups - groupHashes = new ArrayList(groups.keySet()); - Collections.sort(groupHashes); - for (int hgi = 0;; hgi++) { - if (hgi == groupHashes.size()) { - final HashResult res = new HashResult(); - res.hash = encodeHex(md.digest()); - res.pathNamer = pathNamer; - return res; - } - - // digest group hash - final String groupHash = groupHashes.get(hgi); - md.update(groupHash.getBytes("UTF-8")); - - // choose a path and namer from the permutations - String chosenPath = null; - UniqueNamer chosenNamer = null; - final Permutator permutator = new Permutator(groups.get(groupHash)); - while (true) { - Boolean contPermutation = false; - Boolean breakOut = false; - final List permutation = permutator.next(); - UniqueNamer pathNamerCopy = pathNamer.clone(); - - // build adjacent path - String path = ""; - final List recurse = new ArrayList(); - for (final String bnode : permutation) { - // use canonical name if available - if (namer.isNamed(bnode)) { - path += namer.getName(bnode); - } else { - // recurse if bnode isn't named in the path - // yet - if (!pathNamerCopy.isNamed(bnode)) { - recurse.add(bnode); - } - path += pathNamerCopy.getName(bnode); - } - - // skip permutation if path is already >= chosen - // path - if (chosenPath != null && path.length() >= chosenPath.length() - && path.compareTo(chosenPath) > 0) { - // return nextPermutation(true); - if (permutator.hasNext()) { - contPermutation = true; - } else { - // digest chosen path and update namer - md.update(chosenPath.getBytes("UTF-8")); - pathNamer = chosenNamer; - // hash the nextGroup - breakOut = true; - } - break; - } - } - - // if we should do the next permutation - if (contPermutation) { - continue; - } - // if we should stop processing this group - if (breakOut) { - break; - } - - // does the next recursion - for (int nrn = 0;; nrn++) { - if (nrn == recurse.size()) { - // return nextPermutation(false); - if (chosenPath == null || path.compareTo(chosenPath) < 0) { - chosenPath = path; - chosenNamer = pathNamerCopy; - } - if (!permutator.hasNext()) { - // digest chosen path and update namer - md.update(chosenPath.getBytes("UTF-8")); - pathNamer = chosenNamer; - // hash the nextGroup - breakOut = true; - } - break; - } - - // do recursion - final String bnode = recurse.get(nrn); - final HashResult result = hashPaths(bnode, bnodes, namer, - pathNamerCopy); - path += pathNamerCopy.getName(bnode) + "<" + result.hash + ">"; - pathNamerCopy = result.pathNamer; - - // skip permutation if path is already >= chosen - // path - if (chosenPath != null && path.length() >= chosenPath.length() - && path.compareTo(chosenPath) > 0) { - // return nextPermutation(true); - if (!permutator.hasNext()) { - // digest chosen path and update namer - md.update(chosenPath.getBytes("UTF-8")); - pathNamer = chosenNamer; - // hash the nextGroup - breakOut = true; - } - break; - } - // do next recursion - } - - // if we should stop processing this group - if (breakOut) { - break; - } - } - } - } - - // get adjacent bnode - final Map quad = (Map) quads.get(hpi); - String bnode = getAdjacentBlankNodeName((Map) quad.get("subject"), - id); - String direction = null; - if (bnode != null) { - // normal property - direction = "p"; - } else { - bnode = getAdjacentBlankNodeName((Map) quad.get("object"), id); - if (bnode != null) { - // reverse property - direction = "r"; - } - } - - if (bnode != null) { - // get bnode name (try canonical, path, then hash) - String name; - if (namer.isNamed(bnode)) { - name = namer.getName(bnode); - } else if (pathNamer.isNamed(bnode)) { - name = pathNamer.getName(bnode); - } else { - name = hashQuads(bnode, bnodes, namer); - } - - // hash direction, property, end bnode name/hash - final MessageDigest md1 = MessageDigest.getInstance("SHA-1"); - // String toHash = direction + (String) ((Map) quad.get("predicate")).get("value") + name; - md1.update(direction.getBytes("UTF-8")); - md1.update(((String) ((Map) quad.get("predicate")).get("value")) - .getBytes("UTF-8")); - md1.update(name.getBytes("UTF-8")); - final String groupHash = encodeHex(md1.digest()); - if (groups.containsKey(groupHash)) { - groups.get(groupHash).add(bnode); - } else { - final List tmp = new ArrayList(); - tmp.add(bnode); - groups.put(groupHash, tmp); - } - } - } - } catch (final NoSuchAlgorithmException e) { - // TODO: i don't expect that SHA-1 is even NOT going to be - // available? - // look into this further - throw new RuntimeException(e); - } catch (final UnsupportedEncodingException e) { - // TODO: i don't expect that UTF-8 is ever not going to be available - // either - throw new RuntimeException(e); - } - } - - /** - * Hashes all of the quads about a blank node. - * - * @param id - * the ID of the bnode to hash quads for. - * @param bnodes - * the mapping of bnodes to quads. - * @param namer - * the canonical bnode namer. - * - * @return the new hash. - */ - private static String hashQuads(String id, Map bnodes, UniqueNamer namer) { - // return cached hash - if (((Map) bnodes.get(id)).containsKey("hash")) { - return (String) ((Map) bnodes.get(id)).get("hash"); - } - - // serialize all of bnode's quads - final List> quads = (List>) ((Map) bnodes - .get(id)).get("quads"); - final List nquads = new ArrayList(); - for (int i = 0; i < quads.size(); ++i) { - nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), - quads.get(i).get("name") != null ? (String) ((Map) quads.get(i) - .get("name")).get("value") : null, id)); - } - // sort serialized quads - Collections.sort(nquads); - // return hashed quads - final String hash = sha1hash(nquads); - ((Map) bnodes.get(id)).put("hash", hash); - return hash; - } - - /** - * A helper class to sha1 hash all the strings in a collection - * - * @param nquads - * @return - */ - private static String sha1hash(Collection nquads) { - try { - // create SHA-1 digest - final MessageDigest md = MessageDigest.getInstance("SHA-1"); - for (final String nquad : nquads) { - md.update(nquad.getBytes("UTF-8")); - } - return encodeHex(md.digest()); - } catch (final NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } catch (final UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - // TODO: this is something to optimize - private static String encodeHex(final byte[] data) { - String rval = ""; - for (final byte b : data) { - rval += String.format("%02x", b); - } - return rval; - } - - /** - * A helper function that gets the blank node name from an RDF quad node - * (subject or object). If the node is a blank node and its value does not - * match the given blank node ID, it will be returned. - * - * @param node - * the RDF quad node. - * @param id - * the ID of the blank node to look next to. - * - * @return the adjacent blank node name or null if none was found. - */ - private static String getAdjacentBlankNodeName(Map node, String id) { - return "blank node".equals(node.get("type")) - && (!node.containsKey("value") || !Obj.equals(node.get("value"), id)) ? (String) node - .get("value") : null; - } - - private static class Permutator { - - private final List list; - private boolean done; - private final Map left; - - public Permutator(List list) { - this.list = (List) JsonLdUtils.clone(list); - Collections.sort(this.list); - this.done = false; - this.left = new LinkedHashMap(); - for (final String i : this.list) { - this.left.put(i, true); - } - } - - /** - * Returns true if there is another permutation. - * - * @return true if there is another permutation, false if not. - */ - public boolean hasNext() { - return !this.done; - } - - /** - * Gets the next permutation. Call hasNext() to ensure there is another - * one first. - * - * @return the next permutation. - */ - public List next() { - final List rval = (List) JsonLdUtils.clone(this.list); - - // Calculate the next permutation using Steinhaus-Johnson-Trotter - // permutation algoritm - - // get largest mobile element k - // (mobile: element is grater than the one it is looking at) - String k = null; - int pos = 0; - final int length = this.list.size(); - for (int i = 0; i < length; ++i) { - final String element = this.list.get(i); - final Boolean left = this.left.get(element); - if ((k == null || element.compareTo(k) > 0) - && ((left && i > 0 && element.compareTo(this.list.get(i - 1)) > 0) || (!left - && i < (length - 1) && element.compareTo(this.list.get(i + 1)) > 0))) { - k = element; - pos = i; - } - } - - // no more permutations - if (k == null) { - this.done = true; - } else { - // swap k and the element it is looking at - final int swap = this.left.get(k) ? pos - 1 : pos + 1; - this.list.set(pos, this.list.get(swap)); - this.list.set(swap, k); - - // reverse the direction of all element larger than k - for (int i = 0; i < length; i++) { - if (this.list.get(i).compareTo(k) > 0) { - this.left.put(this.list.get(i), !this.left.get(this.list.get(i))); - } - } - } - - return rval; - } - - } - -} +package com.github.jsonldjava.core; + +import static com.github.jsonldjava.core.RDFDatasetUtils.parseNQuads; +import static com.github.jsonldjava.core.RDFDatasetUtils.toNQuad; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.github.jsonldjava.utils.Obj; + +class NormalizeUtils { + + private final UniqueNamer namer; + private final Map bnodes; + private final List quads; + private final JsonLdOptions options; + + public NormalizeUtils(List quads, Map bnodes, UniqueNamer namer, + JsonLdOptions options) { + this.options = options; + this.quads = quads; + this.bnodes = bnodes; + this.namer = namer; + } + + // generates unique and duplicate hashes for bnodes + public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { + List unnamed = new ArrayList(unnamed_); + List nextUnnamed = new ArrayList(); + Map> duplicates = new LinkedHashMap>(); + Map unique = new LinkedHashMap(); + + // NOTE: not using the same structure as javascript here to avoid + // possible stack overflows + // hash quads for each unnamed bnode + for (int hui = 0;; hui++) { + if (hui == unnamed.size()) { + // done, name blank nodes + Boolean named = false; + List hashes = new ArrayList(unique.keySet()); + Collections.sort(hashes); + for (final String hash : hashes) { + final String bnode = unique.get(hash); + namer.getName(bnode); + named = true; + } + + // continue to hash bnodes if a bnode was assigned a name + if (named) { + // this resets the initial variables, so it seems like it + // has to go on the stack + // but since this is the end of the function either way, it + // might not have to + // hashBlankNodes(unnamed); + hui = -1; + unnamed = nextUnnamed; + nextUnnamed = new ArrayList(); + duplicates = new LinkedHashMap>(); + unique = new LinkedHashMap(); + continue; + } + // name the duplicate hash bnods + else { + // names duplicate hash bnodes + // enumerate duplicate hash groups in sorted order + hashes = new ArrayList(duplicates.keySet()); + Collections.sort(hashes); + + // process each group + for (int pgi = 0;; pgi++) { + if (pgi == hashes.size()) { + // done, create JSON-LD array + // return createArray(); + final List normalized = new ArrayList(); + + // Note: At this point all bnodes in the set of RDF + // quads have been + // assigned canonical names, which have been stored + // in the 'namer' object. + // Here each quad is updated by assigning each of + // its bnodes its new name + // via the 'namer' object + + // update bnode names in each quad and serialize + for (int cai = 0; cai < quads.size(); ++cai) { + final Map quad = (Map) quads + .get(cai); + for (final String attr : new String[] { "subject", "object", "name" }) { + if (quad.containsKey(attr)) { + final Map qa = (Map) quad + .get(attr); + if (qa != null + && "blank node".equals(qa.get("type")) + && ((String) qa.get("value")).indexOf("_:c14n") != 0) { + qa.put("value", + namer.getName((String) qa.get(("value")))); + } + } + } + normalized + .add(toNQuad( + (RDFDataset.Quad) quad, + quad.containsKey("name") + && quad.get("name") != null ? (String) ((Map) quad + .get("name")).get("value") : null)); + } + + // sort normalized output + Collections.sort(normalized); + + // handle output format + if (options.format != null) { + if ("application/nquads".equals(options.format)) { + StringBuilder rval = new StringBuilder(); + for (final String n : normalized) { + rval.append(n); + } + return rval.toString(); + } else { + throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, + options.format); + } + } + StringBuilder rval = new StringBuilder(); + for (final String n : normalized) { + rval.append(n); + } + return parseNQuads(rval.toString()); + } + + // name each group member + final List group = duplicates.get(hashes.get(pgi)); + final List results = new ArrayList(); + for (int n = 0;; n++) { + if (n == group.size()) { + // name bnodes in hash order + Collections.sort(results, new Comparator() { + @Override + public int compare(HashResult a, HashResult b) { + final int res = a.hash.compareTo(b.hash); + return res; + } + }); + for (final HashResult r : results) { + // name all bnodes in path namer in + // key-entry order + // Note: key-order is preserved in + // javascript + for (final String key : r.pathNamer.existing().keySet()) { + namer.getName(key); + } + } + // processGroup(i+1); + break; + } else { + // skip already-named bnodes + final String bnode = group.get(n); + if (namer.isNamed(bnode)) { + continue; + } + + // hash bnode paths + final UniqueNamer pathNamer = new UniqueNamer("_:b"); + pathNamer.getName(bnode); + + final HashResult result = hashPaths(bnode, bnodes, namer, pathNamer); + results.add(result); + } + } + } + } + } + + // hash unnamed bnode + final String bnode = unnamed.get(hui); + final String hash = hashQuads(bnode, bnodes, namer); + + // store hash as unique or a duplicate + if (duplicates.containsKey(hash)) { + duplicates.get(hash).add(bnode); + nextUnnamed.add(bnode); + } else if (unique.containsKey(hash)) { + final List tmp = new ArrayList(); + tmp.add(unique.get(hash)); + tmp.add(bnode); + duplicates.put(hash, tmp); + nextUnnamed.add(unique.get(hash)); + nextUnnamed.add(bnode); + unique.remove(hash); + } else { + unique.put(hash, bnode); + } + } + } + + private static class HashResult { + String hash; + UniqueNamer pathNamer; + } + + /** + * Produces a hash for the paths of adjacent bnodes for a bnode, + * incorporating all information about its subgraph of bnodes. This method + * will recursively pick adjacent bnode permutations that produce the + * lexicographically-least 'path' serializations. + * + * @param id + * the ID of the bnode to hash paths for. + * @param bnodes + * the map of bnode quads. + * @param namer + * the canonical bnode namer. + * @param pathNamer + * the namer used to assign names to adjacent bnodes. + * @param callback + * (err, result) called once the operation completes. + */ + private static HashResult hashPaths(String id, Map bnodes, UniqueNamer namer, + UniqueNamer pathNamer) { + try { + // create SHA-1 digest + final MessageDigest md = MessageDigest.getInstance("SHA-1"); + + final Map> groups = new LinkedHashMap>(); + List groupHashes; + final List quads = (List) ((Map) bnodes.get(id)) + .get("quads"); + + for (int hpi = 0;; hpi++) { + if (hpi == quads.size()) { + // done , hash groups + groupHashes = new ArrayList(groups.keySet()); + Collections.sort(groupHashes); + for (int hgi = 0;; hgi++) { + if (hgi == groupHashes.size()) { + final HashResult res = new HashResult(); + res.hash = encodeHex(md.digest()); + res.pathNamer = pathNamer; + return res; + } + + // digest group hash + final String groupHash = groupHashes.get(hgi); + md.update(groupHash.getBytes("UTF-8")); + + // choose a path and namer from the permutations + String chosenPath = null; + UniqueNamer chosenNamer = null; + final Permutator permutator = new Permutator(groups.get(groupHash)); + while (true) { + Boolean contPermutation = false; + Boolean breakOut = false; + final List permutation = permutator.next(); + UniqueNamer pathNamerCopy = pathNamer.clone(); + + // build adjacent path + String path = ""; + final List recurse = new ArrayList(); + for (final String bnode : permutation) { + // use canonical name if available + if (namer.isNamed(bnode)) { + path += namer.getName(bnode); + } else { + // recurse if bnode isn't named in the path + // yet + if (!pathNamerCopy.isNamed(bnode)) { + recurse.add(bnode); + } + path += pathNamerCopy.getName(bnode); + } + + // skip permutation if path is already >= chosen + // path + if (chosenPath != null && path.length() >= chosenPath.length() + && path.compareTo(chosenPath) > 0) { + // return nextPermutation(true); + if (permutator.hasNext()) { + contPermutation = true; + } else { + // digest chosen path and update namer + md.update(chosenPath.getBytes("UTF-8")); + pathNamer = chosenNamer; + // hash the nextGroup + breakOut = true; + } + break; + } + } + + // if we should do the next permutation + if (contPermutation) { + continue; + } + // if we should stop processing this group + if (breakOut) { + break; + } + + // does the next recursion + for (int nrn = 0;; nrn++) { + if (nrn == recurse.size()) { + // return nextPermutation(false); + if (chosenPath == null || path.compareTo(chosenPath) < 0) { + chosenPath = path; + chosenNamer = pathNamerCopy; + } + if (!permutator.hasNext()) { + // digest chosen path and update namer + md.update(chosenPath.getBytes("UTF-8")); + pathNamer = chosenNamer; + // hash the nextGroup + breakOut = true; + } + break; + } + + // do recursion + final String bnode = recurse.get(nrn); + final HashResult result = hashPaths(bnode, bnodes, namer, + pathNamerCopy); + path += pathNamerCopy.getName(bnode) + "<" + result.hash + ">"; + pathNamerCopy = result.pathNamer; + + // skip permutation if path is already >= chosen + // path + if (chosenPath != null && path.length() >= chosenPath.length() + && path.compareTo(chosenPath) > 0) { + // return nextPermutation(true); + if (!permutator.hasNext()) { + // digest chosen path and update namer + md.update(chosenPath.getBytes("UTF-8")); + pathNamer = chosenNamer; + // hash the nextGroup + breakOut = true; + } + break; + } + // do next recursion + } + + // if we should stop processing this group + if (breakOut) { + break; + } + } + } + } + + // get adjacent bnode + final Map quad = (Map) quads.get(hpi); + String bnode = getAdjacentBlankNodeName((Map) quad.get("subject"), + id); + String direction = null; + if (bnode != null) { + // normal property + direction = "p"; + } else { + bnode = getAdjacentBlankNodeName((Map) quad.get("object"), id); + if (bnode != null) { + // reverse property + direction = "r"; + } + } + + if (bnode != null) { + // get bnode name (try canonical, path, then hash) + String name; + if (namer.isNamed(bnode)) { + name = namer.getName(bnode); + } else if (pathNamer.isNamed(bnode)) { + name = pathNamer.getName(bnode); + } else { + name = hashQuads(bnode, bnodes, namer); + } + + // hash direction, property, end bnode name/hash + final MessageDigest md1 = MessageDigest.getInstance("SHA-1"); + // String toHash = direction + (String) ((Map) quad.get("predicate")).get("value") + name; + md1.update(direction.getBytes("UTF-8")); + md1.update(((String) ((Map) quad.get("predicate")).get("value")) + .getBytes("UTF-8")); + md1.update(name.getBytes("UTF-8")); + final String groupHash = encodeHex(md1.digest()); + if (groups.containsKey(groupHash)) { + groups.get(groupHash).add(bnode); + } else { + final List tmp = new ArrayList(); + tmp.add(bnode); + groups.put(groupHash, tmp); + } + } + } + } catch (final NoSuchAlgorithmException e) { + // TODO: i don't expect that SHA-1 is even NOT going to be + // available? + // look into this further + throw new RuntimeException(e); + } catch (final UnsupportedEncodingException e) { + // TODO: i don't expect that UTF-8 is ever not going to be available + // either + throw new RuntimeException(e); + } + } + + /** + * Hashes all of the quads about a blank node. + * + * @param id + * the ID of the bnode to hash quads for. + * @param bnodes + * the mapping of bnodes to quads. + * @param namer + * the canonical bnode namer. + * + * @return the new hash. + */ + private static String hashQuads(String id, Map bnodes, UniqueNamer namer) { + // return cached hash + if (((Map) bnodes.get(id)).containsKey("hash")) { + return (String) ((Map) bnodes.get(id)).get("hash"); + } + + // serialize all of bnode's quads + final List> quads = (List>) ((Map) bnodes + .get(id)).get("quads"); + final List nquads = new ArrayList(); + for (int i = 0; i < quads.size(); ++i) { + nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), + quads.get(i).get("name") != null ? (String) ((Map) quads.get(i) + .get("name")).get("value") : null, id)); + } + // sort serialized quads + Collections.sort(nquads); + // return hashed quads + final String hash = sha1hash(nquads); + ((Map) bnodes.get(id)).put("hash", hash); + return hash; + } + + /** + * A helper class to sha1 hash all the strings in a collection + * + * @param nquads + * @return + */ + private static String sha1hash(Collection nquads) { + try { + // create SHA-1 digest + final MessageDigest md = MessageDigest.getInstance("SHA-1"); + for (final String nquad : nquads) { + md.update(nquad.getBytes("UTF-8")); + } + return encodeHex(md.digest()); + } catch (final NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (final UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + // TODO: this is something to optimize + private static String encodeHex(final byte[] data) { + String rval = ""; + for (final byte b : data) { + rval += String.format("%02x", b); + } + return rval; + } + + /** + * A helper function that gets the blank node name from an RDF quad node + * (subject or object). If the node is a blank node and its value does not + * match the given blank node ID, it will be returned. + * + * @param node + * the RDF quad node. + * @param id + * the ID of the blank node to look next to. + * + * @return the adjacent blank node name or null if none was found. + */ + private static String getAdjacentBlankNodeName(Map node, String id) { + return "blank node".equals(node.get("type")) + && (!node.containsKey("value") || !Obj.equals(node.get("value"), id)) ? (String) node + .get("value") : null; + } + + private static class Permutator { + + private final List list; + private boolean done; + private final Map left; + + public Permutator(List list) { + this.list = (List) JsonLdUtils.clone(list); + Collections.sort(this.list); + this.done = false; + this.left = new LinkedHashMap(); + for (final String i : this.list) { + this.left.put(i, true); + } + } + + /** + * Returns true if there is another permutation. + * + * @return true if there is another permutation, false if not. + */ + public boolean hasNext() { + return !this.done; + } + + /** + * Gets the next permutation. Call hasNext() to ensure there is another + * one first. + * + * @return the next permutation. + */ + public List next() { + final List rval = (List) JsonLdUtils.clone(this.list); + + // Calculate the next permutation using Steinhaus-Johnson-Trotter + // permutation algoritm + + // get largest mobile element k + // (mobile: element is grater than the one it is looking at) + String k = null; + int pos = 0; + final int length = this.list.size(); + for (int i = 0; i < length; ++i) { + final String element = this.list.get(i); + final Boolean left = this.left.get(element); + if ((k == null || element.compareTo(k) > 0) + && ((left && i > 0 && element.compareTo(this.list.get(i - 1)) > 0) || (!left + && i < (length - 1) && element.compareTo(this.list.get(i + 1)) > 0))) { + k = element; + pos = i; + } + } + + // no more permutations + if (k == null) { + this.done = true; + } else { + // swap k and the element it is looking at + final int swap = this.left.get(k) ? pos - 1 : pos + 1; + this.list.set(pos, this.list.get(swap)); + this.list.set(swap, k); + + // reverse the direction of all element larger than k + for (int i = 0; i < length; i++) { + if (this.list.get(i).compareTo(k) > 0) { + this.left.put(this.list.get(i), !this.left.get(this.list.get(i))); + } + } + } + + return rval; + } + + } + +} diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index c3e512b3..1672a785 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -1,547 +1,581 @@ -package com.github.jsonldjava.core; - -import static com.github.jsonldjava.core.JsonLdConsts.RDF_FIRST; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_LANGSTRING; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_NIL; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_STRING; -import static com.github.jsonldjava.core.JsonLdUtils.isKeyword; -import static com.github.jsonldjava.core.JsonLdUtils.isList; -import static com.github.jsonldjava.core.JsonLdUtils.isObject; -import static com.github.jsonldjava.core.JsonLdUtils.isValue; -import static com.github.jsonldjava.core.Regex.HEX; -import static com.github.jsonldjava.utils.Obj.newMap; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class RDFDatasetUtils { - - /** - * Creates an array of RDF triples for the given graph. - * - * @param graph - * the graph to create RDF triples for. - * @param namer - * a UniqueNamer for assigning blank node names. - * - * @return the array of RDF triples for the given graph. - * @deprecated Use {@link RDFDataset#graphToRDF(String, Map)} instead - */ - @Deprecated - static List graphToRDF(Map graph, UniqueNamer namer) { - final List rval = new ArrayList(); - for (final String id : graph.keySet()) { - final Map node = (Map) graph.get(id); - final List properties = new ArrayList(node.keySet()); - Collections.sort(properties); - for (String property : properties) { - final Object items = node.get(property); - if ("@type".equals(property)) { - property = RDF_TYPE; - } else if (isKeyword(property)) { - continue; - } - - for (final Object item : (List) items) { - // RDF subjects - final Map subject = newMap(); - if (id.indexOf("_:") == 0) { - subject.put("type", "blank node"); - subject.put("value", namer.getName(id)); - } else { - subject.put("type", "IRI"); - subject.put("value", id); - } - - // RDF predicates - final Map predicate = newMap(); - predicate.put("type", "IRI"); - predicate.put("value", property); - - // convert @list to triples - if (isList(item)) { - listToRDF((List) ((Map) item).get("@list"), namer, - subject, predicate, rval); - } - // convert value or node object to triple - else { - final Object object = objectToRDF(item, namer); - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", object); - rval.add(tmp); - } - } - } - } - - return rval; - } - - /** - * Converts a @list value into linked list of blank node RDF triples (an RDF - * collection). - * - * @param list - * the @list value. - * @param namer - * a UniqueNamer for assigning blank node names. - * @param subject - * the subject for the head of the list. - * @param predicate - * the predicate for the head of the list. - * @param triples - * the array of triples to append to. - */ - private static void listToRDF(List list, UniqueNamer namer, - Map subject, Map predicate, List triples) { - final Map first = newMap(); - first.put("type", "IRI"); - first.put("value", RDF_FIRST); - final Map rest = newMap(); - rest.put("type", "IRI"); - rest.put("value", RDF_REST); - final Map nil = newMap(); - nil.put("type", "IRI"); - nil.put("value", RDF_NIL); - - for (final Object item : list) { - final Map blankNode = newMap(); - blankNode.put("type", "blank node"); - blankNode.put("value", namer.getName()); - - { - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", blankNode); - triples.add(tmp); - } - - subject = blankNode; - predicate = first; - final Object object = objectToRDF(item, namer); - - { - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", object); - triples.add(tmp); - } - - predicate = rest; - } - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", nil); - triples.add(tmp); - } - - /** - * Converts a JSON-LD value object to an RDF literal or a JSON-LD string or - * node object to an RDF resource. - * - * @param item - * the JSON-LD value or node object. - * @param namer - * the UniqueNamer to use to assign blank node names. - * - * @return the RDF literal or RDF resource. - */ - private static Object objectToRDF(Object item, UniqueNamer namer) { - final Map object = newMap(); - - // convert value object to RDF - if (isValue(item)) { - object.put("type", "literal"); - final Object value = ((Map) item).get("@value"); - final Object datatype = ((Map) item).get("@type"); - - // convert to XSD datatypes as appropriate - if (value instanceof Boolean || value instanceof Number) { - // convert to XSD datatype - if (value instanceof Boolean) { - object.put("value", value.toString()); - object.put("datatype", datatype == null ? XSD_BOOLEAN : datatype); - } else if (value instanceof Double || value instanceof Float) { - // canonical double representation - final DecimalFormat df = new DecimalFormat("0.0###############E0"); - df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); - object.put("value", df.format(value)); - object.put("datatype", datatype == null ? XSD_DOUBLE : datatype); - } else { - final DecimalFormat df = new DecimalFormat("0"); - object.put("value", df.format(value)); - object.put("datatype", datatype == null ? XSD_INTEGER : datatype); - } - } else if (((Map) item).containsKey("@language")) { - object.put("value", value); - object.put("datatype", datatype == null ? RDF_LANGSTRING : datatype); - object.put("language", ((Map) item).get("@language")); - } else { - object.put("value", value); - object.put("datatype", datatype == null ? XSD_STRING : datatype); - } - } - // convert string/node object to RDF - else { - final String id = isObject(item) ? (String) ((Map) item).get("@id") - : (String) item; - if (id.indexOf("_:") == 0) { - object.put("type", "blank node"); - object.put("value", namer.getName(id)); - } else { - object.put("type", "IRI"); - object.put("value", id); - } - } - - return object; - } - - public static String toNQuads(RDFDataset dataset) { - final List quads = new ArrayList(); - for (String graphName : dataset.graphNames()) { - final List triples = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - for (final RDFDataset.Quad triple : triples) { - quads.add(toNQuad(triple, graphName)); - } - } - Collections.sort(quads); - String rval = ""; - for (final String quad : quads) { - rval += quad; - } - return rval; - } - - static String toNQuad(RDFDataset.Quad triple, String graphName, String bnode) { - final RDFDataset.Node s = triple.getSubject(); - final RDFDataset.Node p = triple.getPredicate(); - final RDFDataset.Node o = triple.getObject(); - - String quad = ""; - - // subject is an IRI or bnode - if (s.isIRI()) { - quad += "<" + escape(s.getValue()) + ">"; - } - // normalization mode - else if (bnode != null) { - quad += bnode.equals(s.getValue()) ? "_:a" : "_:z"; - } - // normal mode - else { - quad += s.getValue(); - } - - if (p.isIRI()) { - quad += " <" + escape(p.getValue()) + "> "; - } - // otherwise it must be a bnode (TODO: can we only allow this if the - // flag is set in options?) - else { - quad += " " + escape(p.getValue()) + " "; - } - - // object is IRI, bnode or literal - if (o.isIRI()) { - quad += "<" + escape(o.getValue()) + ">"; - } else if (o.isBlankNode()) { - // normalization mode - if (bnode != null) { - quad += bnode.equals(o.getValue()) ? "_:a" : "_:z"; - } - // normal mode - else { - quad += o.getValue(); - } - } else { - final String escaped = escape(o.getValue()); - quad += "\"" + escaped + "\""; - if (RDF_LANGSTRING.equals(o.getDatatype())) { - quad += "@" + o.getLanguage(); - } else if (!XSD_STRING.equals(o.getDatatype())) { - quad += "^^<" + escape(o.getDatatype()) + ">"; - } - } - - // graph - if (graphName != null) { - if (graphName.indexOf("_:") != 0) { - quad += " <" + escape(graphName) + ">"; - } else if (bnode != null) { - quad += " _:g"; - } else { - quad += " " + graphName; - } - } - - quad += " .\n"; - return quad; - } - - static String toNQuad(RDFDataset.Quad triple, String graphName) { - return toNQuad(triple, graphName, null); - } - - final private static Pattern UCHAR_MATCHED = Pattern.compile("\\u005C(?:([tbnrf\\\"'])|(?:u(" - + HEX + "{4}))|(?:U(" + HEX + "{8})))"); - - public static String unescape(String str) { - String rval = str; - if (str != null) { - final Matcher m = UCHAR_MATCHED.matcher(str); - while (m.find()) { - String uni = m.group(0); - if (m.group(1) == null) { - final String hex = m.group(2) != null ? m.group(2) : m.group(3); - final int v = Integer.parseInt(hex, 16);// hex = - // hex.replaceAll("^(?:00)+", - // ""); - if (v > 0xFFFF) { - // deal with UTF-32 - // Integer v = Integer.parseInt(hex, 16); - final int vt = v - 0x10000; - final int vh = vt >> 10; - final int v1 = vt & 0x3FF; - final int w1 = 0xD800 + vh; - final int w2 = 0xDC00 + v1; - - final StringBuffer b = new StringBuffer(); - b.appendCodePoint(w1); - b.appendCodePoint(w2); - uni = b.toString(); - } else { - uni = Character.toString((char) v); - } - } else { - final char c = m.group(1).charAt(0); - switch (c) { - case 'b': - uni = "\b"; - break; - case 'n': - uni = "\n"; - break; - case 't': - uni = "\t"; - break; - case 'f': - uni = "\f"; - break; - case 'r': - uni = "\r"; - break; - case '\'': - uni = "'"; - break; - case '\"': - uni = "\""; - break; - case '\\': - uni = "\\"; - break; - default: - // do nothing - continue; - } - } - final String pat = Pattern.quote(m.group(0)); - final String x = Integer.toHexString(uni.charAt(0)); - rval = rval.replaceAll(pat, uni); - } - } - return rval; - } - - public static String escape(String str) { - String rval = ""; - for (int i = 0; i < str.length(); i++) { - final char hi = str.charAt(i); - if (hi <= 0x8 || hi == 0xB || hi == 0xC || (hi >= 0xE && hi <= 0x1F) - || (hi >= 0x7F && hi <= 0xA0) || // 0xA0 is end of - // non-printable latin-1 - // supplement - // characters - ((hi >= 0x24F // 0x24F is the end of latin extensions - && !Character.isHighSurrogate(hi)) - // TODO: there's probably a lot of other characters that - // shouldn't be escaped that - // fall outside these ranges, this is one example from the - // json-ld tests - )) { - rval += String.format("\\u%04x", (int) hi); - } else if (Character.isHighSurrogate(hi)) { - final char lo = str.charAt(++i); - final int c = (hi << 10) + lo + (0x10000 - (0xD800 << 10) - 0xDC00); - rval += String.format("\\U%08x", c); - } else { - switch (hi) { - case '\b': - rval += "\\b"; - break; - case '\n': - rval += "\\n"; - break; - case '\t': - rval += "\\t"; - break; - case '\f': - rval += "\\f"; - break; - case '\r': - rval += "\\r"; - break; - // case '\'': - // rval += "\\'"; - // break; - case '\"': - rval += "\\\""; - // rval += "\\u0022"; - break; - case '\\': - rval += "\\\\"; - break; - default: - // just put the char as is - rval += hi; - break; - } - } - } - return rval; - } - - private static class Regex { - // define partial regexes - // final public static Pattern IRI = - // Pattern.compile("(?:<([^:]+:[^>]*)>)"); - final public static Pattern IRI = Pattern.compile("(?:<([^>]*)>)"); - final public static Pattern BNODE = Pattern.compile("(_:(?:[A-Za-z][A-Za-z0-9]*))"); - final public static Pattern PLAIN = Pattern.compile("\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\""); - final public static Pattern DATATYPE = Pattern.compile("(?:\\^\\^" + IRI + ")"); - final public static Pattern LANGUAGE = Pattern.compile("(?:@([a-z]+(?:-[a-zA-Z0-9]+)*))"); - final public static Pattern LITERAL = Pattern.compile("(?:" + PLAIN + "(?:" + DATATYPE - + "|" + LANGUAGE + ")?)"); - final public static Pattern WS = Pattern.compile("[ \\t]+"); - final public static Pattern WSO = Pattern.compile("[ \\t]*"); - final public static Pattern EOLN = Pattern.compile("(?:\r\n)|(?:\n)|(?:\r)"); - final public static Pattern EMPTY = Pattern.compile("^" + WSO + "$"); - - // define quad part regexes - final public static Pattern SUBJECT = Pattern.compile("(?:" + IRI + "|" + BNODE + ")" + WS); - final public static Pattern PROPERTY = Pattern.compile(IRI.pattern() + WS.pattern()); - final public static Pattern OBJECT = Pattern.compile("(?:" + IRI + "|" + BNODE + "|" - + LITERAL + ")" + WSO); - final public static Pattern GRAPH = Pattern.compile("(?:\\.|(?:(?:" + IRI + "|" + BNODE - + ")" + WSO + "\\.))"); - - // full quad regex - final public static Pattern QUAD = Pattern.compile("^" + WSO + SUBJECT + PROPERTY + OBJECT - + GRAPH + WSO + "$"); - } - - /** - * Parses RDF in the form of N-Quads. - * - * @param input - * the N-Quads input to parse. - * - * @return an RDF dataset. - * @throws JsonLdError - * If there was an error parsing the N-Quads document. - */ - public static RDFDataset parseNQuads(String input) throws JsonLdError { - // build RDF dataset - final RDFDataset dataset = new RDFDataset(); - - // split N-Quad input into lines - final String[] lines = Regex.EOLN.split(input); - int lineNumber = 0; - for (final String line : lines) { - lineNumber++; - - // skip empty lines - if (Regex.EMPTY.matcher(line).matches()) { - continue; - } - - // parse quad - final Matcher match = Regex.QUAD.matcher(line); - if (!match.matches()) { - throw new JsonLdError(JsonLdError.Error.SYNTAX_ERROR, - "Error while parsing N-Quads; invalid quad. line:" + lineNumber); - } - - // get subject - RDFDataset.Node subject; - if (match.group(1) != null) { - subject = new RDFDataset.IRI(unescape(match.group(1))); - } else { - subject = new RDFDataset.BlankNode(unescape(match.group(2))); - } - - // get predicate - final RDFDataset.Node predicate = new RDFDataset.IRI(unescape(match.group(3))); - - // get object - RDFDataset.Node object; - if (match.group(4) != null) { - object = new RDFDataset.IRI(unescape(match.group(4))); - } else if (match.group(5) != null) { - object = new RDFDataset.BlankNode(unescape(match.group(5))); - } else { - final String language = unescape(match.group(8)); - final String datatype = match.group(7) != null ? unescape(match.group(7)) : match - .group(8) != null ? RDF_LANGSTRING : XSD_STRING; - final String unescaped = unescape(match.group(6)); - object = new RDFDataset.Literal(unescaped, datatype, language); - } - - // get graph name ('@default' is used for the default graph) - String name = "@default"; - if (match.group(9) != null) { - name = unescape(match.group(9)); - } else if (match.group(10) != null) { - name = unescape(match.group(10)); - } - - final RDFDataset.Quad triple = new RDFDataset.Quad(subject, predicate, object, name); - - // initialise graph in dataset - if (!dataset.containsKey(name)) { - final List tmp = new ArrayList(); - tmp.add(triple); - dataset.put(name, tmp); - } - // add triple if unique to its graph - else { - final List triples = (List) dataset.get(name); - if (!triples.contains(triple)) { - triples.add(triple); - } - } - } - - return dataset; - } -} +package com.github.jsonldjava.core; + +import static com.github.jsonldjava.core.JsonLdConsts.RDF_FIRST; +import static com.github.jsonldjava.core.JsonLdConsts.RDF_LANGSTRING; +import static com.github.jsonldjava.core.JsonLdConsts.RDF_NIL; +import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; +import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE; +import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN; +import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE; +import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER; +import static com.github.jsonldjava.core.JsonLdConsts.XSD_STRING; +import static com.github.jsonldjava.core.JsonLdUtils.isKeyword; +import static com.github.jsonldjava.core.JsonLdUtils.isList; +import static com.github.jsonldjava.core.JsonLdUtils.isObject; +import static com.github.jsonldjava.core.JsonLdUtils.isValue; +import static com.github.jsonldjava.core.Regex.HEX; +import static com.github.jsonldjava.utils.Obj.newMap; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RDFDatasetUtils { + + /** + * Creates an array of RDF triples for the given graph. + * + * @param graph + * the graph to create RDF triples for. + * @param namer + * a UniqueNamer for assigning blank node names. + * + * @return the array of RDF triples for the given graph. + * @deprecated Use {@link RDFDataset#graphToRDF(String, Map)} instead + */ + @Deprecated + static List graphToRDF(Map graph, UniqueNamer namer) { + final List rval = new ArrayList(); + for (final String id : graph.keySet()) { + final Map node = (Map) graph.get(id); + final List properties = new ArrayList(node.keySet()); + Collections.sort(properties); + for (String property : properties) { + final Object items = node.get(property); + if ("@type".equals(property)) { + property = RDF_TYPE; + } else if (isKeyword(property)) { + continue; + } + + for (final Object item : (List) items) { + // RDF subjects + final Map subject = newMap(); + if (id.indexOf("_:") == 0) { + subject.put("type", "blank node"); + subject.put("value", namer.getName(id)); + } else { + subject.put("type", "IRI"); + subject.put("value", id); + } + + // RDF predicates + final Map predicate = newMap(); + predicate.put("type", "IRI"); + predicate.put("value", property); + + // convert @list to triples + if (isList(item)) { + listToRDF((List) ((Map) item).get("@list"), namer, + subject, predicate, rval); + } + // convert value or node object to triple + else { + final Object object = objectToRDF(item, namer); + final Map tmp = newMap(); + tmp.put("subject", subject); + tmp.put("predicate", predicate); + tmp.put("object", object); + rval.add(tmp); + } + } + } + } + + return rval; + } + + /** + * Converts a @list value into linked list of blank node RDF triples (an RDF + * collection). + * + * @param list + * the @list value. + * @param namer + * a UniqueNamer for assigning blank node names. + * @param subject + * the subject for the head of the list. + * @param predicate + * the predicate for the head of the list. + * @param triples + * the array of triples to append to. + */ + private static void listToRDF(List list, UniqueNamer namer, + Map subject, Map predicate, List triples) { + final Map first = newMap(); + first.put("type", "IRI"); + first.put("value", RDF_FIRST); + final Map rest = newMap(); + rest.put("type", "IRI"); + rest.put("value", RDF_REST); + final Map nil = newMap(); + nil.put("type", "IRI"); + nil.put("value", RDF_NIL); + + for (final Object item : list) { + final Map blankNode = newMap(); + blankNode.put("type", "blank node"); + blankNode.put("value", namer.getName()); + + { + final Map tmp = newMap(); + tmp.put("subject", subject); + tmp.put("predicate", predicate); + tmp.put("object", blankNode); + triples.add(tmp); + } + + subject = blankNode; + predicate = first; + final Object object = objectToRDF(item, namer); + + { + final Map tmp = newMap(); + tmp.put("subject", subject); + tmp.put("predicate", predicate); + tmp.put("object", object); + triples.add(tmp); + } + + predicate = rest; + } + final Map tmp = newMap(); + tmp.put("subject", subject); + tmp.put("predicate", predicate); + tmp.put("object", nil); + triples.add(tmp); + } + + /** + * Converts a JSON-LD value object to an RDF literal or a JSON-LD string or + * node object to an RDF resource. + * + * @param item + * the JSON-LD value or node object. + * @param namer + * the UniqueNamer to use to assign blank node names. + * + * @return the RDF literal or RDF resource. + */ + private static Object objectToRDF(Object item, UniqueNamer namer) { + final Map object = newMap(); + + // convert value object to RDF + if (isValue(item)) { + object.put("type", "literal"); + final Object value = ((Map) item).get("@value"); + final Object datatype = ((Map) item).get("@type"); + + // convert to XSD datatypes as appropriate + if (value instanceof Boolean || value instanceof Number) { + // convert to XSD datatype + if (value instanceof Boolean) { + object.put("value", value.toString()); + object.put("datatype", datatype == null ? XSD_BOOLEAN : datatype); + } else if (value instanceof Double || value instanceof Float) { + // canonical double representation + final DecimalFormat df = new DecimalFormat("0.0###############E0"); + df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); + object.put("value", df.format(value)); + object.put("datatype", datatype == null ? XSD_DOUBLE : datatype); + } else { + final DecimalFormat df = new DecimalFormat("0"); + object.put("value", df.format(value)); + object.put("datatype", datatype == null ? XSD_INTEGER : datatype); + } + } else if (((Map) item).containsKey("@language")) { + object.put("value", value); + object.put("datatype", datatype == null ? RDF_LANGSTRING : datatype); + object.put("language", ((Map) item).get("@language")); + } else { + object.put("value", value); + object.put("datatype", datatype == null ? XSD_STRING : datatype); + } + } + // convert string/node object to RDF + else { + final String id = isObject(item) ? (String) ((Map) item).get("@id") + : (String) item; + if (id.indexOf("_:") == 0) { + object.put("type", "blank node"); + object.put("value", namer.getName(id)); + } else { + object.put("type", "IRI"); + object.put("value", id); + } + } + + return object; + } + + public static String toNQuads(RDFDataset dataset) { + StringBuilder output = new StringBuilder(256); + toNQuads(dataset, output); + return output.toString(); + } + public static void toNQuads(RDFDataset dataset, StringBuilder output) { + final List quads = new ArrayList(); + for (String graphName : dataset.graphNames()) { + final List triples = dataset.getQuads(graphName); + if ("@default".equals(graphName)) { + graphName = null; + } + for (final RDFDataset.Quad triple : triples) { + quads.add(toNQuad(triple, graphName)); + } + } + Collections.sort(quads); + for (final String quad : quads) { + output.append(quad); + } + } + + static String toNQuad(RDFDataset.Quad triple, String graphName, String bnode) { + StringBuilder output = new StringBuilder(256); + toNQuad(triple, graphName, bnode, output); + return output.toString(); + } + static void toNQuad(RDFDataset.Quad triple, String graphName, String bnode, StringBuilder output) { + final RDFDataset.Node s = triple.getSubject(); + final RDFDataset.Node p = triple.getPredicate(); + final RDFDataset.Node o = triple.getObject(); + + // subject is an IRI or bnode + if (s.isIRI()) { + output.append("<"); + escape(s.getValue(), output); + output.append(">"); + } + // normalization mode + else if (bnode != null) { + output.append(bnode.equals(s.getValue()) ? "_:a" : "_:z"); + } + // normal mode + else { + output.append(s.getValue()); + } + + if (p.isIRI()) { + output.append(" <"); + escape(p.getValue(), output); + output.append("> "); + } + // otherwise it must be a bnode (TODO: can we only allow this if the + // flag is set in options?) + else { + output.append(" "); + escape(p.getValue(), output); + output.append(" "); + } + + // object is IRI, bnode or literal + if (o.isIRI()) { + output.append("<"); + escape(o.getValue(), output); + output.append(">"); + } else if (o.isBlankNode()) { + // normalization mode + if (bnode != null) { + output.append(bnode.equals(o.getValue()) ? "_:a" : "_:z"); + } + // normal mode + else { + output.append(o.getValue()); + } + } else { + output.append("\""); + escape(o.getValue(), output); + output.append("\""); + if (RDF_LANGSTRING.equals(o.getDatatype())) { + output.append("@").append(o.getLanguage()); + } else if (!XSD_STRING.equals(o.getDatatype())) { + output.append("^^<"); + escape(o.getDatatype(), output); + output.append(">"); + } + } + + // graph + if (graphName != null) { + if (graphName.indexOf("_:") != 0) { + output.append(" <"); + escape(graphName, output); + output.append(">"); + } else if (bnode != null) { + output.append(" _:g"); + } else { + output.append(" ").append(graphName); + } + } + + output.append(" .\n"); + } + + static String toNQuad(RDFDataset.Quad triple, String graphName) { + return toNQuad(triple, graphName, null); + } + + final private static Pattern UCHAR_MATCHED = Pattern.compile("\\u005C(?:([tbnrf\\\"'])|(?:u(" + + HEX + "{4}))|(?:U(" + HEX + "{8})))"); + + public static String unescape(String str) { + String rval = str; + if (str != null) { + final Matcher m = UCHAR_MATCHED.matcher(str); + while (m.find()) { + String uni = m.group(0); + if (m.group(1) == null) { + final String hex = m.group(2) != null ? m.group(2) : m.group(3); + final int v = Integer.parseInt(hex, 16);// hex = + // hex.replaceAll("^(?:00)+", + // ""); + if (v > 0xFFFF) { + // deal with UTF-32 + // Integer v = Integer.parseInt(hex, 16); + final int vt = v - 0x10000; + final int vh = vt >> 10; + final int v1 = vt & 0x3FF; + final int w1 = 0xD800 + vh; + final int w2 = 0xDC00 + v1; + + final StringBuffer b = new StringBuffer(); + b.appendCodePoint(w1); + b.appendCodePoint(w2); + uni = b.toString(); + } else { + uni = Character.toString((char) v); + } + } else { + final char c = m.group(1).charAt(0); + switch (c) { + case 'b': + uni = "\b"; + break; + case 'n': + uni = "\n"; + break; + case 't': + uni = "\t"; + break; + case 'f': + uni = "\f"; + break; + case 'r': + uni = "\r"; + break; + case '\'': + uni = "'"; + break; + case '\"': + uni = "\""; + break; + case '\\': + uni = "\\"; + break; + default: + // do nothing + continue; + } + } + final String pat = Pattern.quote(m.group(0)); + final String x = Integer.toHexString(uni.charAt(0)); + rval = rval.replaceAll(pat, uni); + } + } + return rval; + } + + /** + * Escapes the given string according to the N-Quads escape rules + * @param str The string to escape + * @return The escaped string + * @deprecated Use {@link #escape(String, StringBuilder)} instead. + */ + public static String escape(String str) { + StringBuilder rval = new StringBuilder(); + escape(str, rval); + return rval.toString(); + } + + /** + * Escapes the given string according to the N-Quads escape rules + * @param str The string to escape + * @param rval The {@link StringBuilder} to append to. + */ + public static void escape(String str, StringBuilder rval) { + for (int i = 0; i < str.length(); i++) { + final char hi = str.charAt(i); + if (hi <= 0x8 || hi == 0xB || hi == 0xC || (hi >= 0xE && hi <= 0x1F) + || (hi >= 0x7F && hi <= 0xA0) || // 0xA0 is end of + // non-printable latin-1 + // supplement + // characters + ((hi >= 0x24F // 0x24F is the end of latin extensions + && !Character.isHighSurrogate(hi)) + // TODO: there's probably a lot of other characters that + // shouldn't be escaped that + // fall outside these ranges, this is one example from the + // json-ld tests + )) { + rval.append(String.format("\\u%04x", (int) hi)); + } else if (Character.isHighSurrogate(hi)) { + final char lo = str.charAt(++i); + final int c = (hi << 10) + lo + (0x10000 - (0xD800 << 10) - 0xDC00); + rval.append(String.format("\\U%08x", c)); + } else { + switch (hi) { + case '\b': + rval.append("\\b"); + break; + case '\n': + rval.append("\\n"); + break; + case '\t': + rval.append("\\t"); + break; + case '\f': + rval.append("\\f"); + break; + case '\r': + rval.append("\\r"); + break; + // case '\'': + // rval += "\\'"; + // break; + case '\"': + rval.append("\\\""); + // rval += "\\u0022"; + break; + case '\\': + rval.append("\\\\"); + break; + default: + // just put the char as is + rval.append(hi); + break; + } + } + } + //return rval; + } + + private static class Regex { + // define partial regexes + // final public static Pattern IRI = + // Pattern.compile("(?:<([^:]+:[^>]*)>)"); + final public static Pattern IRI = Pattern.compile("(?:<([^>]*)>)"); + final public static Pattern BNODE = Pattern.compile("(_:(?:[A-Za-z][A-Za-z0-9]*))"); + final public static Pattern PLAIN = Pattern.compile("\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\""); + final public static Pattern DATATYPE = Pattern.compile("(?:\\^\\^" + IRI + ")"); + final public static Pattern LANGUAGE = Pattern.compile("(?:@([a-z]+(?:-[a-zA-Z0-9]+)*))"); + final public static Pattern LITERAL = Pattern.compile("(?:" + PLAIN + "(?:" + DATATYPE + + "|" + LANGUAGE + ")?)"); + final public static Pattern WS = Pattern.compile("[ \\t]+"); + final public static Pattern WSO = Pattern.compile("[ \\t]*"); + final public static Pattern EOLN = Pattern.compile("(?:\r\n)|(?:\n)|(?:\r)"); + final public static Pattern EMPTY = Pattern.compile("^" + WSO + "$"); + + // define quad part regexes + final public static Pattern SUBJECT = Pattern.compile("(?:" + IRI + "|" + BNODE + ")" + WS); + final public static Pattern PROPERTY = Pattern.compile(IRI.pattern() + WS.pattern()); + final public static Pattern OBJECT = Pattern.compile("(?:" + IRI + "|" + BNODE + "|" + + LITERAL + ")" + WSO); + final public static Pattern GRAPH = Pattern.compile("(?:\\.|(?:(?:" + IRI + "|" + BNODE + + ")" + WSO + "\\.))"); + + // full quad regex + final public static Pattern QUAD = Pattern.compile("^" + WSO + SUBJECT + PROPERTY + OBJECT + + GRAPH + WSO + "$"); + } + + /** + * Parses RDF in the form of N-Quads. + * + * @param input + * the N-Quads input to parse. + * + * @return an RDF dataset. + * @throws JsonLdError + * If there was an error parsing the N-Quads document. + */ + public static RDFDataset parseNQuads(String input) throws JsonLdError { + // build RDF dataset + final RDFDataset dataset = new RDFDataset(); + + // split N-Quad input into lines + final String[] lines = Regex.EOLN.split(input); + int lineNumber = 0; + for (final String line : lines) { + lineNumber++; + + // skip empty lines + if (Regex.EMPTY.matcher(line).matches()) { + continue; + } + + // parse quad + final Matcher match = Regex.QUAD.matcher(line); + if (!match.matches()) { + throw new JsonLdError(JsonLdError.Error.SYNTAX_ERROR, + "Error while parsing N-Quads; invalid quad. line:" + lineNumber); + } + + // get subject + RDFDataset.Node subject; + if (match.group(1) != null) { + subject = new RDFDataset.IRI(unescape(match.group(1))); + } else { + subject = new RDFDataset.BlankNode(unescape(match.group(2))); + } + + // get predicate + final RDFDataset.Node predicate = new RDFDataset.IRI(unescape(match.group(3))); + + // get object + RDFDataset.Node object; + if (match.group(4) != null) { + object = new RDFDataset.IRI(unescape(match.group(4))); + } else if (match.group(5) != null) { + object = new RDFDataset.BlankNode(unescape(match.group(5))); + } else { + final String language = unescape(match.group(8)); + final String datatype = match.group(7) != null ? unescape(match.group(7)) : match + .group(8) != null ? RDF_LANGSTRING : XSD_STRING; + final String unescaped = unescape(match.group(6)); + object = new RDFDataset.Literal(unescaped, datatype, language); + } + + // get graph name ('@default' is used for the default graph) + String name = "@default"; + if (match.group(9) != null) { + name = unescape(match.group(9)); + } else if (match.group(10) != null) { + name = unescape(match.group(10)); + } + + final RDFDataset.Quad triple = new RDFDataset.Quad(subject, predicate, object, name); + + // initialise graph in dataset + if (!dataset.containsKey(name)) { + final List tmp = new ArrayList(); + tmp.add(triple); + dataset.put(name, tmp); + } + // add triple if unique to its graph + else { + final List triples = (List) dataset.get(name); + if (!triples.contains(triple)) { + triples.add(triple); + } + } + } + + return dataset; + } +} From 859353b195df456687a384c8b91b8a2edbaa13d4 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 11:17:05 +1100 Subject: [PATCH 142/440] Update README.md with note about performance improvements --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d96603bb..8a521c3e 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,7 @@ CHANGELOG ### 2015-11-16 * Bump dependencies to latest versions, particularly HTTPClient that is seeing more use on 4.5/4.4 than the 4.2 series that we have used so far +* Performance improvements for serialisation to N-Quads by replacing string append and replace with StringBuilder ### 2015-09-30 * Release 0.7.0 From 1ed92423ae21e3ad40c45f7cff5c2e9b9fd882d4 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 11:20:17 +1100 Subject: [PATCH 143/440] Attempt to fix CRLF/LF issues --- .../main/java/com/github/jsonldjava/core/NormalizeUtils.java | 2 +- .../main/java/com/github/jsonldjava/core/RDFDatasetUtils.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index a1aae971..6aab6e46 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -31,7 +31,7 @@ public NormalizeUtils(List quads, Map bnodes, UniqueName this.namer = namer; } - // generates unique and duplicate hashes for bnodes + // generates unique and duplicate hashes for bnodes public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { List unnamed = new ArrayList(unnamed_); List nextUnnamed = new ArrayList(); diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 1672a785..4961752a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -252,7 +252,7 @@ static void toNQuad(RDFDataset.Quad triple, String graphName, String bnode, Stri escape(s.getValue(), output); output.append(">"); } - // normalization mode + // normalization mode else if (bnode != null) { output.append(bnode.equals(s.getValue()) ? "_:a" : "_:z"); } From 83e8fd5e68cbc939a390c0dd49bdb2ad98aefade Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 11:37:30 +1100 Subject: [PATCH 144/440] change the code strategy for getDefaultHttpClient --- .../jsonldjava/core/DocumentLoader.java | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 8da04c24..dec20576 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -115,34 +115,34 @@ public InputStream openStreamFromURL(java.net.URL url) throws IOException { } protected static HttpClient getDefaultHttpClient() { - final HttpClient result = defaultHttpClient; - if (result != null) { - return result; - } - synchronized (DocumentLoader.class) { - if (defaultHttpClient == null) { - // Uses Apache SystemDefaultHttpClient rather than - // DefaultHttpClient, thus the normal proxy settings for the - // JVM will be used - - final DefaultHttpClient client = new SystemDefaultHttpClient(); - // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 - client.addRequestInterceptor(new RequestAcceptEncoding()); - client.addResponseInterceptor(new ResponseContentEncoding()); - final CacheConfig cacheConfig = new CacheConfig(); - cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB - cacheConfig.setMaxCacheEntries(1000); - // and allow caching - final CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); - - // Wrap again with JAR cache - final JarCacheStorage jarCache = new JarCacheStorage(); - defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, - jarCache.getCacheConfig()); + HttpClient result = defaultHttpClient; + if (result == null) { + synchronized (DocumentLoader.class) { + result = defaultHttpClient; + if (result == null) { + // Uses Apache SystemDefaultHttpClient rather than + // DefaultHttpClient, thus the normal proxy settings for the + // JVM will be used + + final DefaultHttpClient client = new SystemDefaultHttpClient(); + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + client.addRequestInterceptor(new RequestAcceptEncoding()); + client.addResponseInterceptor(new ResponseContentEncoding()); + final CacheConfig cacheConfig = new CacheConfig(); + cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB + cacheConfig.setMaxCacheEntries(1000); + // and allow caching + final CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); + + // Wrap again with JAR cache + final JarCacheStorage jarCache = new JarCacheStorage(); + result = defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, + jarCache.getCacheConfig()); + } } - return defaultHttpClient; } + return result; } public HttpClient getHttpClient() { From 2655d21c30d16d3a62d363683ed3e50e7e0d696a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 13:54:04 +1100 Subject: [PATCH 145/440] Add option to disable loading of remote documents, fixes #159 The system property to use is com.github.jsonldjava.disallowRemoteContextLoading and the value to set it to is the string "true". --- .../jsonldjava/core/DocumentLoader.java | 21 +++- .../github/jsonldjava/core/JsonLdError.java | 108 +++++++++++++----- .../jsonldjava/core/DocumentLoaderTest.java | 28 ++++- 3 files changed, 125 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index dec20576..46308b0d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -25,12 +25,24 @@ public class DocumentLoader { + /** + * Identifies a system property that can be set to "true" in order to + * disallow remote context loading. + */ + public static final String DISALLOW_REMOTE_CONTEXT_LOADING = "com.github.jsonldjava.disallowRemoteContextLoading"; + public RemoteDocument loadDocument(String url) throws JsonLdError { + String disallowRemote = System.getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); + + if ("true".equalsIgnoreCase(disallowRemote)) { + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); + } + final RemoteDocument doc = new RemoteDocument(url, null); try { doc.setDocument(fromURL(new URL(url))); } catch (final Exception e) { - new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); } return doc; } @@ -123,7 +135,7 @@ protected static HttpClient getDefaultHttpClient() { // Uses Apache SystemDefaultHttpClient rather than // DefaultHttpClient, thus the normal proxy settings for the // JVM will be used - + final DefaultHttpClient client = new SystemDefaultHttpClient(); // Support compressed data // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 @@ -133,8 +145,9 @@ protected static HttpClient getDefaultHttpClient() { cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB cacheConfig.setMaxCacheEntries(1000); // and allow caching - final CachingHttpClient cachingClient = new CachingHttpClient(client, cacheConfig); - + final CachingHttpClient cachingClient = new CachingHttpClient(client, + cacheConfig); + // Wrap again with JAR cache final JarCacheStorage jarCache = new JarCacheStorage(); result = defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java index 64d3e16e..9bdccf41 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java @@ -19,32 +19,88 @@ public JsonLdError(Error type) { } public enum Error { - LOADING_DOCUMENT_FAILED("loading document failed"), LIST_OF_LISTS("list of lists"), INVALID_INDEX_VALUE( - "invalid @index value"), CONFLICTING_INDEXES("conflicting indexes"), INVALID_ID_VALUE( - "invalid @id value"), INVALID_LOCAL_CONTEXT("invalid local context"), MULTIPLE_CONTEXT_LINK_HEADERS( - "multiple context link headers"), LOADING_REMOTE_CONTEXT_FAILED( - "loading remote context failed"), INVALID_REMOTE_CONTEXT("invalid remote context"), RECURSIVE_CONTEXT_INCLUSION( - "recursive context inclusion"), INVALID_BASE_IRI("invalid base IRI"), INVALID_VOCAB_MAPPING( - "invalid vocab mapping"), INVALID_DEFAULT_LANGUAGE("invalid default language"), KEYWORD_REDEFINITION( - "keyword redefinition"), INVALID_TERM_DEFINITION("invalid term definition"), INVALID_REVERSE_PROPERTY( - "invalid reverse property"), INVALID_IRI_MAPPING("invalid IRI mapping"), CYCLIC_IRI_MAPPING( - "cyclic IRI mapping"), INVALID_KEYWORD_ALIAS("invalid keyword alias"), INVALID_TYPE_MAPPING( - "invalid type mapping"), INVALID_LANGUAGE_MAPPING("invalid language mapping"), COLLIDING_KEYWORDS( - "colliding keywords"), INVALID_CONTAINER_MAPPING("invalid container mapping"), INVALID_TYPE_VALUE( - "invalid type value"), INVALID_VALUE_OBJECT("invalid value object"), INVALID_VALUE_OBJECT_VALUE( - "invalid value object value"), INVALID_LANGUAGE_TAGGED_STRING( - "invalid language-tagged string"), INVALID_LANGUAGE_TAGGED_VALUE( - "invalid language-tagged value"), INVALID_TYPED_VALUE("invalid typed value"), INVALID_SET_OR_LIST_OBJECT( - "invalid set or list object"), INVALID_LANGUAGE_MAP_VALUE( - "invalid language map value"), COMPACTION_TO_LIST_OF_LISTS( - "compaction to list of lists"), INVALID_REVERSE_PROPERTY_MAP( - "invalid reverse property map"), INVALID_REVERSE_VALUE("invalid @reverse value"), INVALID_REVERSE_PROPERTY_VALUE( - "invalid reverse property value"), - - // non spec related errors - SYNTAX_ERROR("syntax error"), NOT_IMPLEMENTED("not implemnted"), UNKNOWN_FORMAT( - "unknown format"), INVALID_INPUT("invalid input"), PARSE_ERROR("parse error"), UNKNOWN_ERROR( - "unknown error"); + LOADING_DOCUMENT_FAILED("loading document failed"), + + LIST_OF_LISTS("list of lists"), + + INVALID_INDEX_VALUE("invalid @index value"), + + CONFLICTING_INDEXES("conflicting indexes"), + + INVALID_ID_VALUE("invalid @id value"), + + INVALID_LOCAL_CONTEXT("invalid local context"), + + MULTIPLE_CONTEXT_LINK_HEADERS("multiple context link headers"), + + LOADING_REMOTE_CONTEXT_FAILED("loading remote context failed"), + + INVALID_REMOTE_CONTEXT("invalid remote context"), + + RECURSIVE_CONTEXT_INCLUSION("recursive context inclusion"), + + INVALID_BASE_IRI("invalid base IRI"), + + INVALID_VOCAB_MAPPING("invalid vocab mapping"), + + INVALID_DEFAULT_LANGUAGE("invalid default language"), + + KEYWORD_REDEFINITION("keyword redefinition"), + + INVALID_TERM_DEFINITION("invalid term definition"), + + INVALID_REVERSE_PROPERTY("invalid reverse property"), + + INVALID_IRI_MAPPING("invalid IRI mapping"), + + CYCLIC_IRI_MAPPING("cyclic IRI mapping"), + + INVALID_KEYWORD_ALIAS("invalid keyword alias"), + + INVALID_TYPE_MAPPING("invalid type mapping"), + + INVALID_LANGUAGE_MAPPING("invalid language mapping"), + + COLLIDING_KEYWORDS("colliding keywords"), + + INVALID_CONTAINER_MAPPING("invalid container mapping"), + + INVALID_TYPE_VALUE("invalid type value"), + + INVALID_VALUE_OBJECT("invalid value object"), + + INVALID_VALUE_OBJECT_VALUE("invalid value object value"), + + INVALID_LANGUAGE_TAGGED_STRING("invalid language-tagged string"), + + INVALID_LANGUAGE_TAGGED_VALUE("invalid language-tagged value"), + + INVALID_TYPED_VALUE("invalid typed value"), + + INVALID_SET_OR_LIST_OBJECT("invalid set or list object"), + + INVALID_LANGUAGE_MAP_VALUE("invalid language map value"), + + COMPACTION_TO_LIST_OF_LISTS("compaction to list of lists"), + + INVALID_REVERSE_PROPERTY_MAP("invalid reverse property map"), + + INVALID_REVERSE_VALUE("invalid @reverse value"), + + INVALID_REVERSE_PROPERTY_VALUE("invalid reverse property value"), + + // non spec related errors + SYNTAX_ERROR("syntax error"), + + NOT_IMPLEMENTED("not implemnted"), + + UNKNOWN_FORMAT("unknown format"), + + INVALID_INPUT("invalid input"), + + PARSE_ERROR("parse error"), + + UNKNOWN_ERROR("unknown error"); private final String error; diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 23f99997..7bcde81e 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -38,11 +38,11 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +@SuppressWarnings("unchecked") public class DocumentLoaderTest { DocumentLoader documentLoader = new DocumentLoader(); - @SuppressWarnings("unchecked") @Test public void fromURLTest0001() throws Exception { final URL contexttest = getClass().getResource("/custom/contexttest-0001.jsonld"); @@ -58,7 +58,6 @@ public void fromURLTest0001() throws Exception { assertEquals("ex:term1", term1.get("@id")); } - @SuppressWarnings("unchecked") @Test public void fromURLTest0002() throws Exception { final URL contexttest = getClass().getResource("/custom/contexttest-0002.jsonld"); @@ -281,4 +280,29 @@ public void differentHttpClient() throws Exception { assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); } + @Test + public void testDisallowRemoteContexts() throws Exception { + String testUrl = "http://json-ld.org/contexts/person.jsonld"; + Object test = documentLoader.loadDocument(testUrl); + + assertNotNull( + "Was not able to fetch from URL before testing disallow remote contexts loading", + test); + + String disallowProperty = System + .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); + try { + System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true"); + documentLoader.loadDocument(testUrl); + fail("Expected exception to occur"); + } catch (JsonLdError e) { + assertEquals(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, e.getType()); + } finally { + if (disallowProperty == null) { + System.clearProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); + } else { + System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, disallowProperty); + } + } + } } From e27acd7e855a31857f55d106f073e42bfd28a8f9 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 14:00:00 +1100 Subject: [PATCH 146/440] Update readme with details of how to disable remote context loading --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 8a521c3e..f7e774be 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,16 @@ normally be set correctly. If not, try: Thread.currentThread().setContextClassLoader(oldContextCL); } +To disable all remote document fetching, when using the default DocumentLoader, set the +following Java System Property to "true" using: + System.setProperty("com.github.jsonldjava.disallowRemoteContextLoading", "true"); + +You can also use the constant provided in DocumentLoader for the same purpose: + + System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true"); + +Note that if you override DocumentLoader you should also support this setting for consistency. ### Customizing the Apache HttpClient @@ -390,6 +399,7 @@ CHANGELOG ### 2015-11-16 * Bump dependencies to latest versions, particularly HTTPClient that is seeing more use on 4.5/4.4 than the 4.2 series that we have used so far * Performance improvements for serialisation to N-Quads by replacing string append and replace with StringBuilder +* Support setting a system property, com.github.jsonldjava.disallowRemoteContextLoading, to "true" to disable remote context loading. ### 2015-09-30 * Release 0.7.0 From b2dcff1fb48cb62a8546348372fc4590a633c720 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 16 Nov 2015 14:18:36 +1100 Subject: [PATCH 147/440] Add test to verify that the RDFDataset API is not the key to the IRI appearing in the context in expanded form for issue #140 Seems to be setup manually in the Jena code: https://github.com/apache/jena/blob/d480bd1fc36d4f7a9b286a607dbc66ea4988b64d/jena-arq/src/main/java/org/apache/jena/riot/out/JsonLDWriter.java#L147 --- .../jsonldjava/core/LongestPrefixTest.java | 67 +++++++++++++------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java index 8ff10538..0190eed7 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java @@ -30,51 +30,78 @@ public void toRdfWithNamespace() throws Exception { @Test public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Exception { - + RDFDataset inputRdf = new RDFDataset(); inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); inputRdf.setNamespace("aat_rev", "http://vocab.getty.edu/aat/rev/"); - - inputRdf.addTriple("http://vocab.getty.edu/aat/rev/5001065997", JsonLdConsts.RDF_TYPE, "http://vocab.getty.edu/aat/datatype"); - + + inputRdf.addTriple("http://vocab.getty.edu/aat/rev/5001065997", JsonLdConsts.RDF_TYPE, + "http://vocab.getty.edu/aat/datatype"); + final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; - - Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf),inputRdf.getContext(), options); - + + Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + inputRdf.getContext(), options); + final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); System.out.println(rdf.getNamespaces()); assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aat_rev")); - + String toJSONLD = JsonUtils.toPrettyString(fromRDF); System.out.println(toJSONLD); - - assertTrue("The lexicographically shortest URI was not chosen", toJSONLD.contains("aat:rev/")); + + assertTrue("The lexicographically shortest URI was not chosen", + toJSONLD.contains("aat:rev/")); } @Test public void fromRdfWithNamespaceLexicographicallyShortestChosen2() throws Exception { - + RDFDataset inputRdf = new RDFDataset(); inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); inputRdf.setNamespace("aatrev", "http://vocab.getty.edu/aat/rev/"); - - inputRdf.addTriple("http://vocab.getty.edu/aat/rev/5001065997", JsonLdConsts.RDF_TYPE, "http://vocab.getty.edu/aat/datatype"); - + + inputRdf.addTriple("http://vocab.getty.edu/aat/rev/5001065997", JsonLdConsts.RDF_TYPE, + "http://vocab.getty.edu/aat/datatype"); + final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; - - Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf),inputRdf.getContext(), options); - + + Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + inputRdf.getContext(), options); + final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); System.out.println(rdf.getNamespaces()); assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aatrev")); - + String toJSONLD = JsonUtils.toPrettyString(fromRDF); System.out.println(toJSONLD); - - assertFalse("The lexicographically shortest URI was not chosen", toJSONLD.contains("aat:rev/")); + + assertFalse("The lexicographically shortest URI was not chosen", + toJSONLD.contains("aat:rev/")); + } + + @Test + public void prefixUsedToShortenPredicate() throws Exception { + final RDFDataset inputRdf = new RDFDataset(); + inputRdf.setNamespace("ex", "http://www.a.com/foo/"); + inputRdf.addTriple("http://www.a.com/foo/s", "http://www.a.com/foo/p", + "http://www.a.com/foo/o"); + assertEquals("http://www.a.com/foo/", inputRdf.getNamespace("ex")); + + final JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + + Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + inputRdf.getContext(), options); + String toJSONLD = JsonUtils.toPrettyString(fromRDF); + System.out.println(toJSONLD); + + assertFalse("The lexicographically shortest URI was not chosen", + toJSONLD.contains("http://www.a.com/foo/p")); } + } From a986877c78f398e514dfa53b2b13d07f687041f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=A4fer?= Date: Tue, 17 Nov 2015 20:16:26 +0100 Subject: [PATCH 148/440] fixes #160 --- .../jsonldjava/core/DocumentLoader.java | 63 +++++++++---------- .../jsonldjava/core/DocumentLoaderTest.java | 19 +++--- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 46308b0d..df22da27 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -6,16 +6,14 @@ import java.util.List; import java.util.Map; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.client.SystemDefaultHttpClient; +import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.cache.CacheConfig; -import org.apache.http.impl.client.cache.CachingHttpClient; +import org.apache.http.impl.client.cache.CachingHttpClientBuilder; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; @@ -52,8 +50,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { */ public static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; - protected static volatile CachingHttpClient defaultHttpClient; - private volatile HttpClient httpClient; + protected static volatile CloseableHttpClient defaultHttpClient; + private volatile CloseableHttpClient httpClient; /** * Returns a Map, List, or String containing the contents of the JSON @@ -118,54 +116,55 @@ public InputStream openStreamFromURL(java.net.URL url) throws IOException { // or whatever is available request.addHeader("Accept", ACCEPT_HEADER); - final HttpResponse response = getHttpClient().execute(request); + final CloseableHttpResponse response = getHttpClient().execute(request); final int status = response.getStatusLine().getStatusCode(); if (status != 200 && status != 203) { + response.close(); throw new IOException("Can't retrieve " + url + ", status code: " + status); } return response.getEntity().getContent(); } - protected static HttpClient getDefaultHttpClient() { - HttpClient result = defaultHttpClient; + protected static CloseableHttpClient getDefaultHttpClient() { + CloseableHttpClient result = defaultHttpClient; if (result == null) { synchronized (DocumentLoader.class) { result = defaultHttpClient; if (result == null) { - // Uses Apache SystemDefaultHttpClient rather than - // DefaultHttpClient, thus the normal proxy settings for the - // JVM will be used - - final DefaultHttpClient client = new SystemDefaultHttpClient(); - // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 - client.addRequestInterceptor(new RequestAcceptEncoding()); - client.addResponseInterceptor(new ResponseContentEncoding()); - final CacheConfig cacheConfig = new CacheConfig(); - cacheConfig.setMaxObjectSize(1024 * 128); // 128 kB - cacheConfig.setMaxCacheEntries(1000); - // and allow caching - final CachingHttpClient cachingClient = new CachingHttpClient(client, - cacheConfig); - - // Wrap again with JAR cache - final JarCacheStorage jarCache = new JarCacheStorage(); - result = defaultHttpClient = new CachingHttpClient(cachingClient, jarCache, - jarCache.getCacheConfig()); + result = defaultHttpClient = createDefaultHttpClient(); } } } return result; } - public HttpClient getHttpClient() { + protected static CloseableHttpClient createDefaultHttpClient() { + return CachingHttpClientBuilder + .create() + // allow caching + .setCacheConfig( + CacheConfig + .custom() + .setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build()) + // TODO: enable wrapping with JAR cache: .setHttpCacheStorage(new JarCacheStorage()) + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + .addInterceptorFirst(new RequestAcceptEncoding()) + .addInterceptorFirst(new ResponseContentEncoding()) + // use system defaults for proxy etc. + .useSystemProperties() + .build(); + } + + public CloseableHttpClient getHttpClient() { if (httpClient == null) { return getDefaultHttpClient(); } return httpClient; } - public void setHttpClient(HttpClient nextHttpClient) { + public void setHttpClient(CloseableHttpClient nextHttpClient) { httpClient = nextHttpClient; } } diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 7bcde81e..b81ecc97 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -27,12 +27,12 @@ import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.cache.CacheResponseStatus; +import org.apache.http.client.cache.HttpCacheContext; +import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.SystemDefaultHttpClient; -import org.apache.http.impl.client.cache.CachingHttpClient; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.junit.After; import org.junit.Test; @@ -110,17 +110,16 @@ public void fromURLCache() throws Exception { // Now try to get it again and ensure it is // cached - final HttpClient client = new CachingHttpClient(documentLoader.getHttpClient()); + final HttpClient client = documentLoader.getHttpClient(); final HttpUriRequest get = new HttpGet(url.toURI()); get.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); - final HttpContext localContext = new BasicHttpContext(); + final HttpCacheContext localContext = HttpCacheContext.create(); final HttpResponse respo = client.execute(get, localContext); EntityUtils.consume(respo.getEntity()); // Check cache status // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/caching.html - final CacheResponseStatus responseStatus = (CacheResponseStatus) localContext - .getAttribute(CachingHttpClient.CACHE_RESPONSE_STATUS); + final CacheResponseStatus responseStatus = localContext.getCacheResponseStatus(); assertFalse(CacheResponseStatus.CACHE_MISS.equals(responseStatus)); } @@ -152,10 +151,10 @@ public InputStream getInputStream() throws IOException { assertFalse(((Map) context).isEmpty()); } - protected HttpClient fakeHttpClient(ArgumentCaptor httpRequest) + protected CloseableHttpClient fakeHttpClient(ArgumentCaptor httpRequest) throws IllegalStateException, IOException { - final HttpClient httpClient = mock(HttpClient.class); - final HttpResponse fakeResponse = mock(HttpResponse.class); + final CloseableHttpClient httpClient = mock(CloseableHttpClient.class); + final CloseableHttpResponse fakeResponse = mock(CloseableHttpResponse.class); final StatusLine statusCode = mock(StatusLine.class); when(statusCode.getStatusCode()).thenReturn(200); when(fakeResponse.getStatusLine()).thenReturn(statusCode); From f2b74ae8b9f87b3d56d27b3a8cfffec92b150d82 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 19 Nov 2015 09:00:50 +1100 Subject: [PATCH 149/440] Always close response in a finally block --- .../jsonldjava/core/DocumentLoader.java | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index df22da27..5a94ca82 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -117,12 +117,17 @@ public InputStream openStreamFromURL(java.net.URL url) throws IOException { request.addHeader("Accept", ACCEPT_HEADER); final CloseableHttpResponse response = getHttpClient().execute(request); - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - response.close(); - throw new IOException("Can't retrieve " + url + ", status code: " + status); + try { + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + return response.getEntity().getContent(); + } finally { + if (response != null) { + response.close(); + } } - return response.getEntity().getContent(); } protected static CloseableHttpClient getDefaultHttpClient() { @@ -143,18 +148,16 @@ protected static CloseableHttpClient createDefaultHttpClient() { .create() // allow caching .setCacheConfig( - CacheConfig - .custom() - .setMaxCacheEntries(1000) - .setMaxObjectSize(1024 * 128).build()) - // TODO: enable wrapping with JAR cache: .setHttpCacheStorage(new JarCacheStorage()) + CacheConfig.custom().setMaxCacheEntries(1000).setMaxObjectSize(1024 * 128) + .build()) + // TODO: enable wrapping with JAR cache: + .setHttpCacheStorage(new JarCacheStorage()) // Support compressed data // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 .addInterceptorFirst(new RequestAcceptEncoding()) .addInterceptorFirst(new ResponseContentEncoding()) // use system defaults for proxy etc. - .useSystemProperties() - .build(); + .useSystemProperties().build(); } public CloseableHttpClient getHttpClient() { From 9e162eaffc4ec4baec012789c40662d730d1fef5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 19 Nov 2015 09:43:20 +1100 Subject: [PATCH 150/440] Support delegates in JarCacheStorage In 4.2.5, it was simple to construct chained CachedHttpClient instances. In the new versions it does not appear simple or possible in general Hence, we are chaining the HttpCacheStorage objects together to replicate the behaviour we had previously. --- .../jsonldjava/core/DocumentLoader.java | 20 +++++-- .../jsonldjava/utils/JarCacheStorage.java | 58 ++++++++++++++----- .../jsonldjava/core/DocumentLoaderTest.java | 18 +++--- 3 files changed, 69 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 5a94ca82..6ecf406c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -12,6 +12,7 @@ import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; @@ -144,20 +145,27 @@ protected static CloseableHttpClient getDefaultHttpClient() { } protected static CloseableHttpClient createDefaultHttpClient() { - return CachingHttpClientBuilder + // Common CacheConfig for both the JarCacheStorage and the underlying + // BasicHttpCacheStorage + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + + CloseableHttpClient result = CachingHttpClientBuilder .create() // allow caching - .setCacheConfig( - CacheConfig.custom().setMaxCacheEntries(1000).setMaxObjectSize(1024 * 128) - .build()) - // TODO: enable wrapping with JAR cache: - .setHttpCacheStorage(new JarCacheStorage()) + .setCacheConfig(cacheConfig) + // Wrap the local JarCacheStorage around a BasicHttpCacheStorage + .setHttpCacheStorage( + new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( + cacheConfig))) // Support compressed data // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 .addInterceptorFirst(new RequestAcceptEncoding()) .addInterceptorFirst(new ResponseContentEncoding()) // use system defaults for proxy etc. .useSystemProperties().build(); + + return result; } public CloseableHttpClient getHttpClient() { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 04977867..51f93017 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -22,6 +22,7 @@ import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.client.cache.Resource; +import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.cookie.DateUtils; import org.apache.http.message.BasicHeader; @@ -40,9 +41,16 @@ public class JarCacheStorage implements HttpCacheStorage { private final Logger log = LoggerFactory.getLogger(getClass()); - private final CacheConfig cacheConfig = new CacheConfig(); + private final CacheConfig cacheConfig; + // private final CacheConfig cacheConfig = new CacheConfig(); private ClassLoader classLoader; + /** + * All live caching that is not found locally is delegated to this + * implementation. + */ + private HttpCacheStorage delegate; + public ClassLoader getClassLoader() { if (classLoader != null) { return classLoader; @@ -54,22 +62,44 @@ public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } + /** + * @deprecated Use + * {@link JarCacheStorage#JarCacheStorage(ClassLoader, CacheConfig)} + * instead. + */ + @Deprecated public JarCacheStorage() { - this(null); + this(null, CacheConfig.DEFAULT); } + /** + * + * @param classLoader + * The ClassLoader to use to locate JAR files and resources, or + * null to use the Thread context class loader in each case. + * @deprecated Use + * {@link JarCacheStorage#JarCacheStorage(ClassLoader, CacheConfig)} + * instead. + */ + @Deprecated public JarCacheStorage(ClassLoader classLoader) { + this(classLoader, CacheConfig.DEFAULT); + } + + public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig) { + this(classLoader, cacheConfig, new BasicHttpCacheStorage(cacheConfig)); + } + + public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig, + HttpCacheStorage delegate) { setClassLoader(classLoader); - cacheConfig.setMaxObjectSize(0); - cacheConfig.setMaxCacheEntries(0); - cacheConfig.setMaxUpdateRetries(0); - cacheConfig.getMaxCacheEntries(); + this.cacheConfig = cacheConfig; + this.delegate = delegate; } @Override public void putEntry(String key, HttpCacheEntry entry) throws IOException { - // ignored - + delegate.putEntry(key, entry); } ObjectMapper mapper = new ObjectMapper(); @@ -107,7 +137,9 @@ public HttpCacheEntry getEntry(String key) throws IOException { } } } - return null; + // If we didn't find it in our cache, then attempt to find it in the + // chained delegate + return delegate.getEntry(key); } private Enumeration getResources() throws IOException { @@ -176,7 +208,7 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach final List
responseHeaders = new ArrayList
(); if (!cacheNode.has(HTTP.DATE_HEADER)) { responseHeaders - .add(new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()))); + .add(new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date()))); } if (!cacheNode.has(HeaderConstants.CACHE_CONTROL)) { responseHeaders.add(new BasicHeader(HeaderConstants.CACHE_CONTROL, @@ -197,13 +229,13 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach @Override public void removeEntry(String key) throws IOException { - // Ignored + delegate.removeEntry(key); } @Override public void updateEntry(String key, HttpCacheUpdateCallback callback) throws IOException, - HttpCacheUpdateException { - // ignored + HttpCacheUpdateException { + delegate.updateEntry(key, callback); } public CacheConfig getCacheConfig() { diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index b81ecc97..d3ef225f 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; @@ -110,17 +111,18 @@ public void fromURLCache() throws Exception { // Now try to get it again and ensure it is // cached - final HttpClient client = documentLoader.getHttpClient(); - final HttpUriRequest get = new HttpGet(url.toURI()); - get.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); - final HttpCacheContext localContext = HttpCacheContext.create(); - final HttpResponse respo = client.execute(get, localContext); - EntityUtils.consume(respo.getEntity()); + final HttpClient clientCached = documentLoader.getHttpClient(); + final HttpUriRequest getCached = new HttpGet(url.toURI()); + getCached.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); + final HttpCacheContext localContextCached = HttpCacheContext.create(); + final HttpResponse respoCached = clientCached.execute(getCached, localContextCached); + EntityUtils.consume(respoCached.getEntity()); // Check cache status // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/caching.html - final CacheResponseStatus responseStatus = localContext.getCacheResponseStatus(); - assertFalse(CacheResponseStatus.CACHE_MISS.equals(responseStatus)); + final CacheResponseStatus responseStatusCached = localContextCached + .getCacheResponseStatus(); + assertNotEquals(CacheResponseStatus.CACHE_MISS, responseStatusCached); } @Test From 33a48bb26f151d1c2055113cc985f60477442ba3 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 19 Nov 2015 09:49:53 +1100 Subject: [PATCH 151/440] Move field declarations to the top of JarCacheStorage --- .../jsonldjava/utils/JarCacheStorage.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 51f93017..35ecce90 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -51,6 +51,16 @@ public class JarCacheStorage implements HttpCacheStorage { */ private HttpCacheStorage delegate; + ObjectMapper mapper = new ObjectMapper(); + + /** + * Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) to a + * SoftReference to its content as JsonNode. + * + * @see #getJarCache(URL) + */ + protected ConcurrentMap> jarCaches = new ConcurrentHashMap>(); + public ClassLoader getClassLoader() { if (classLoader != null) { return classLoader; @@ -102,8 +112,6 @@ public void putEntry(String key, HttpCacheEntry entry) throws IOException { delegate.putEntry(key, entry); } - ObjectMapper mapper = new ObjectMapper(); - @Override public HttpCacheEntry getEntry(String key) throws IOException { log.trace("Requesting " + key); @@ -151,14 +159,6 @@ private Enumeration getResources() throws IOException { } } - /** - * Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) to a - * SoftReference to its content as JsonNode. - * - * @see #getJarCache(URL) - */ - protected ConcurrentMap> jarCaches = new ConcurrentHashMap>(); - protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingException { URI uri; From ba332582a2a9e357c2f56747e9336b59d2aec857 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 19 Nov 2015 10:06:44 +1100 Subject: [PATCH 152/440] bump to 0.8.0 in view of the change in the way DocumentLoader needs to be configured --- README.md | 35 ++++++++++++++++++++++++----------- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f7e774be..c450422a 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ Note that if you override DocumentLoader you should also support this setting fo To customize the HTTP behaviour (e.g. to disable the cache or provide [authentication credentials)](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html), -you may want to create and configure your own `HttpClient` instance, which can +you may want to create and configure your own `CloseableHttpClient` instance, which can be passed to a `DocumentLoader` instance using `setHttpClient()`. This document loader can then be inserted into `JsonLdOptions` using `setDocumentLoader()` and passed as an argument to `JsonLdProcessor` arguments. @@ -158,8 +158,24 @@ by HTTP Basic Auth): new AuthScope("localhost", 443), new UsernamePasswordCredentials("username", "password")); - DefaultHttpClient httpClient = new SystemDefaultHttpClient(); - httpClient.setCredentialsProvider(credsProvider); + CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + + CloseableHttpClient httpClient = CachingHttpClientBuilder + .create() + // allow caching + .setCacheConfig(cacheConfig) + // Wrap the local JarCacheStorage around a BasicHttpCacheStorage + .setHttpCacheStorage( + new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( + cacheConfig))).... + + // Add in the credentials provider + .setDefaultCredentialsProvider(credsProvider); + + + // When you are finished setting the properties, call build + .build(); documentLoader.setHttpClient(httpClient); @@ -168,14 +184,6 @@ by HTTP Basic Auth): // .. and any other options Object rdf = JsonLdProcessor.toRDF(input, options); -Note that if you override the DocumentLoader HTTP Client, this would also -disable the JAR Cache (see above), unless reinitiated: - - JarCacheStorage jarCache = new JarCacheStorage(); - httpClient = new CachingHttpClient(httpClient, jarCache, jarCache.getCacheConfig()); - documentLoader.setHttpClient(httpClient); - - RDF implementation specific code -------------------------------- @@ -396,6 +404,11 @@ Once you've `commit`ted your code, and `push`ed it into your github fork you can CHANGELOG ========= +### 2015-11-19 +* Replace deprecated HTTPClient code with the new builder pattern +* Chain JarCacheStorage to any other HttpCacheStorage to simplify the way local caching is performed +* Bump version to 0.8.0-SNAPSHOT as some interface method parameters changed, particularly, DocumentLoader.setHttpClient changed to require CloseableHttpClient that was introduced in HttpClient-4.3 + ### 2015-11-16 * Bump dependencies to latest versions, particularly HTTPClient that is seeing more use on 4.5/4.4 than the 4.2 series that we have used so far * Performance improvements for serialisation to N-Quads by replacing string append and replace with StringBuilder diff --git a/core/pom.xml b/core/pom.xml index f313aab8..9bda0eb7 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.7.1-SNAPSHOT + 0.8.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 5a71549f..6e556efa 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.7.1-SNAPSHOT + 0.8.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 4cf0aa17e23e01286a79e2b353acfc23fd16e47f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 27 Dec 2015 13:09:48 +1100 Subject: [PATCH 153/440] Update plugin versions --- pom.xml | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 6e556efa..42b8f148 100755 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 1.7.13 - 3.0.0 + 3.0.5 @@ -206,16 +206,46 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 + 3.2 1.6 1.6 + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.1 + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + + org.apache.maven.plugins + maven-resources-plugin + 2.7 + + + org.apache.maven.plugins + maven-install-plugin + 2.5.2 + + + org.apache.maven.plugins + maven-clean-plugin + 2.6.1 + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + org.apache.maven.plugins maven-jar-plugin - 2.4 + 2.5 @@ -227,7 +257,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + 2.4 attach-source @@ -246,12 +276,12 @@ org.apache.maven.plugins maven-surefire-plugin - 2.17 + 2.18.1 org.codehaus.mojo animal-sniffer-maven-plugin - 1.13 + 1.14 test @@ -271,7 +301,7 @@ org.codehaus.mojo appassembler-maven-plugin - 1.9 + 1.10 org.apache.felix @@ -287,7 +317,7 @@ org.jacoco jacoco-maven-plugin - 0.7.2.201409121644 + 0.7.4.201502262128 prepare-agent From a0aa567826f97342fa880ae9890611504eddde00 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 24 Jan 2016 10:16:47 +1100 Subject: [PATCH 154/440] Remove out of date information about integrations, there is another section that already links to them --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index c450422a..864f159f 100644 --- a/README.md +++ b/README.md @@ -184,13 +184,6 @@ by HTTP Basic Auth): // .. and any other options Object rdf = JsonLdProcessor.toRDF(input, options); -RDF implementation specific code --------------------------------- - -All code specific to various RDF implementations are stored in the [integration modules](./integration). Readmes for how to use these modules should be present in their respective folders. - -The implementation specific integration classes for both Sesame and Jena have been moved into their respective codebases. - PLAYGROUND ---------- From 8bf1ba86ca77041973b506d8ff225a034a2cf341 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 24 Jan 2016 10:21:17 +1100 Subject: [PATCH 155/440] improve the instructions for people generating their own links to other systems --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 864f159f..a5bb968f 100644 --- a/README.md +++ b/README.md @@ -280,7 +280,7 @@ Here is the basic outline for what your module's pom.xml should look like jsonld-java-integration com.github.jsonld-java-parent - 0.1-SNAPSHOT + 0.8.0-SNAPSHOT 4.0.0 jsonld-java-{your module} @@ -291,6 +291,7 @@ Here is the basic outline for what your module's pom.xml should look like {YOU} + {YOUR EMAIL ADDRESS} @@ -300,7 +301,7 @@ Here is the basic outline for what your module's pom.xml should look like jsonld-java ${project.version} jar - compile + compile ${project.groupId} @@ -320,7 +321,7 @@ Here is the basic outline for what your module's pom.xml should look like test - + Make sure you edit the following: * `project/artifactId` : set this to `jsonld-java-{module id}`, where `{module id}` usually represents the RDF library you're integrating (e.g. `jsonld-java-jena`) @@ -375,8 +376,8 @@ Integrate with your framework ----------------------------- Your framework might have its own system of readers and writers, where you should register JSON-LD as a supported format. Remember that here -the "parse" direction is opposite of above, a 'reader' in e.g. Jena will -be a class that can parse JSON-LD and populate a Jena model. +the "parse" direction is opposite of above, a 'reader' may be a class +that can parse JSON-LD and populate an RDF Graph. Write Tests ----------- @@ -393,6 +394,7 @@ Submit your module Once you've `commit`ted your code, and `push`ed it into your github fork you can issue a [Pull Request](https://help.github.com/articles/using-pull-requests) so that we can add a reference to your module in this README file. +Alternatively, we can also host your repository in the jsonld-java organisation to give it more visibility. CHANGELOG ========= From 61fa62db51a3c78bd26320c00d1b5e11bb649499 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 24 Jan 2016 10:33:28 +1100 Subject: [PATCH 156/440] bump surefire and other plugin versions to see if they fix the travis openjdk7 error --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 42b8f148..fe1eb3b7 100755 --- a/pom.xml +++ b/pom.xml @@ -206,7 +206,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.2 + 3.5 1.6 1.6 @@ -215,7 +215,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.1 + 2.10.3 org.apache.maven.plugins @@ -276,7 +276,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.18.1 + 2.19.1 org.codehaus.mojo @@ -397,7 +397,7 @@ org.apache.maven.plugins maven-source-plugin - 2.1.2 + 2.4 attach-sources @@ -410,7 +410,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.7 + 2.10.3 attach-javadocs @@ -423,7 +423,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.1 + 1.6 sign-artifacts From 8c9e6e9b973a7d897ff069e5bd44bbb74e242771 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 24 Jan 2016 10:52:31 +1100 Subject: [PATCH 157/440] OpenJDK-7 on Travis has issues that appeared since the last successful build without any code changes Hence, turning openjdk 7 off. Still have oracle jdk 7 enabled until the upgrade to Java-8 happens --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2ee09394..36aa3a3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: java jdk: - - openjdk7 - oraclejdk7 - oraclejdk8 notifications: From 9ec4010472ec7bcb7f7d914ea9f4955e5548a13e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 9 Feb 2016 11:48:36 +1100 Subject: [PATCH 158/440] Add hyperlink to tools repository --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5bb968f..77c6bb57 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ by HTTP Basic Auth): PLAYGROUND ---------- -The jsonld-java-tools repository contains a simple application which provides command line access to JSON-LD functions +The [jsonld-java-tools](https://github.com/jsonld-java/jsonld-java-tools) repository contains a simple application which provides command line access to JSON-LD functions ### Initial clone and setup From d161da06704a55bac069f2948acd5110dc410506 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 9 Feb 2016 17:41:16 -0500 Subject: [PATCH 159/440] release 0.8.0 --- README.md | 7 +++++-- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 77c6bb57..90b18d84 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.7.0 + 0.8.0 Code example @@ -280,7 +280,7 @@ Here is the basic outline for what your module's pom.xml should look like jsonld-java-integration com.github.jsonld-java-parent - 0.8.0-SNAPSHOT + 0.8.1-SNAPSHOT 4.0.0 jsonld-java-{your module} @@ -399,6 +399,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2016-02-10 +* Release version 0.8.0 + ### 2015-11-19 * Replace deprecated HTTPClient code with the new builder pattern * Chain JarCacheStorage to any other HttpCacheStorage to simplify the way local caching is performed diff --git a/core/pom.xml b/core/pom.xml index 9bda0eb7..74afd320 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.0-SNAPSHOT + 0.8.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index fe1eb3b7..83b5cda8 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.0-SNAPSHOT + 0.8.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From 4232512d9524376dc8cc8247bd5ff8ae02e1e3dd Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 9 Feb 2016 18:00:49 -0500 Subject: [PATCH 160/440] Bump to next snapshot version --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 74afd320..18233579 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.0 + 0.8.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 83b5cda8..81445f15 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.0 + 0.8.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 15bb55e1586efe585f4ba8ec8cb3f268b13e3ce5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 13 Feb 2016 15:26:27 +1100 Subject: [PATCH 161/440] Remove circular dependency between DocumentLoader and JsonUtils The public API for DocumentLoader is unchanged, but the protected static API for DocumentLoader has been modified to move all of the implementation methods and fields into JsonUtils --- .../jsonldjava/core/DocumentLoader.java | 115 +++--------------- .../github/jsonldjava/utils/JsonUtils.java | 90 +++++++++++++- 2 files changed, 100 insertions(+), 105 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 6ecf406c..de9f4199 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -3,24 +3,11 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.util.List; -import java.util.Map; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.RequestAcceptEncoding; -import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.cache.BasicHttpCacheStorage; -import org.apache.http.impl.client.cache.CacheConfig; -import org.apache.http.impl.client.cache.CachingHttpClientBuilder; import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.MappingJsonFactory; -import com.github.jsonldjava.utils.JarCacheStorage; +import com.github.jsonldjava.utils.JsonUtils; public class DocumentLoader { @@ -48,10 +35,11 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { /** * An HTTP Accept header that prefers JSONLD. + * @deprecated Use {@link JsonUtils#ACCEPT_HEADER} instead. */ - public static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; + @Deprecated + public static final String ACCEPT_HEADER = JsonUtils.ACCEPT_HEADER; - protected static volatile CloseableHttpClient defaultHttpClient; private volatile CloseableHttpClient httpClient; /** @@ -68,30 +56,9 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { * If there was an error resolving the resource. */ public Object fromURL(java.net.URL url) throws JsonParseException, IOException { - - final MappingJsonFactory jsonFactory = new MappingJsonFactory(); - final InputStream in = openStreamFromURL(url); - try { - final JsonParser parser = jsonFactory.createParser(in); - try { - final JsonToken token = parser.nextToken(); - Class type; - if (token == JsonToken.START_OBJECT) { - type = Map.class; - } else if (token == JsonToken.START_ARRAY) { - type = List.class; - } else { - type = String.class; - } - return parser.readValueAs(type); - } finally { - parser.close(); - } - } finally { - in.close(); - } + return JsonUtils.fromURL(url, getHttpClient()); } - + /** * Opens an {@link InputStream} for the given {@link java.net.URL}, * including support for http and https URLs that are requested using @@ -105,76 +72,22 @@ public Object fromURL(java.net.URL url) throws JsonParseException, IOException { * If there was an error resolving the {@link java.net.URL}. */ public InputStream openStreamFromURL(java.net.URL url) throws IOException { - final String protocol = url.getProtocol(); - if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { - // Can't use the HTTP client for those! - // Fallback to Java's built-in JsonLdUrl handler. No need for - // Accept headers as it's likely to be file: or jar: - return url.openStream(); - } - final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to application/json - // or whatever is available - request.addHeader("Accept", ACCEPT_HEADER); - - final CloseableHttpResponse response = getHttpClient().execute(request); - try { - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - return response.getEntity().getContent(); - } finally { - if (response != null) { - response.close(); - } - } + return JsonUtils.openStreamForURL(url, getHttpClient()); } - - protected static CloseableHttpClient getDefaultHttpClient() { - CloseableHttpClient result = defaultHttpClient; + + public CloseableHttpClient getHttpClient() { + CloseableHttpClient result = httpClient; if (result == null) { - synchronized (DocumentLoader.class) { - result = defaultHttpClient; - if (result == null) { - result = defaultHttpClient = createDefaultHttpClient(); + synchronized(DocumentLoader.class) { + result = httpClient; + if(result == null) { + result = httpClient = JsonUtils.getDefaultHttpClient(); } } } return result; } - protected static CloseableHttpClient createDefaultHttpClient() { - // Common CacheConfig for both the JarCacheStorage and the underlying - // BasicHttpCacheStorage - final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) - .setMaxObjectSize(1024 * 128).build(); - - CloseableHttpClient result = CachingHttpClientBuilder - .create() - // allow caching - .setCacheConfig(cacheConfig) - // Wrap the local JarCacheStorage around a BasicHttpCacheStorage - .setHttpCacheStorage( - new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( - cacheConfig))) - // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 - .addInterceptorFirst(new RequestAcceptEncoding()) - .addInterceptorFirst(new ResponseContentEncoding()) - // use system defaults for proxy etc. - .useSystemProperties().build(); - - return result; - } - - public CloseableHttpClient getHttpClient() { - if (httpClient == null) { - return getDefaultHttpClient(); - } - return httpClient; - } - public void setHttpClient(CloseableHttpClient nextHttpClient) { httpClient = nextHttpClient; } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index a6734c86..cf2042c4 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -11,6 +11,16 @@ import java.util.List; import java.util.Map; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.protocol.RequestAcceptEncoding; +import org.apache.http.client.protocol.ResponseContentEncoding; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.cache.BasicHttpCacheStorage; +import org.apache.http.impl.client.cache.CacheConfig; +import org.apache.http.impl.client.cache.CachingHttpClientBuilder; + import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; @@ -18,7 +28,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.jsonldjava.core.DocumentLoader; import com.github.jsonldjava.core.JsonLdApi; import com.github.jsonldjava.core.JsonLdProcessor; @@ -33,10 +42,10 @@ public class JsonUtils { /** * An HTTP Accept header that prefers JSONLD. */ - protected static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; + public static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); private static final JsonFactory JSON_FACTORY = new JsonFactory(JSON_MAPPER); - private static DocumentLoader DOCUMENT_LOADER = new DocumentLoader(); + private static volatile CloseableHttpClient DEFAULT_HTTP_CLIENT; static { // Disable default Jackson behaviour to close @@ -166,7 +175,7 @@ public static Object fromString(String jsonString) throws JsonParseException, IO * If there was an IO error during parsing. */ public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { - return DOCUMENT_LOADER.fromURL(url); + return fromURL(url, getDefaultHttpClient()); } /** @@ -242,4 +251,77 @@ public static void writePrettyPrint(Writer writer, Object jsonObject) jw.useDefaultPrettyPrinter(); jw.writeObject(jsonObject); } + + public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) throws IOException { + final String protocol = url.getProtocol(); + if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { + // Can't use the HTTP client for those! + // Fallback to Java's built-in JsonLdUrl handler. No need for + // Accept headers as it's likely to be file: or jar: + return url.openStream(); + } + final HttpUriRequest request = new HttpGet(url.toExternalForm()); + // We prefer application/ld+json, but fallback to application/json + // or whatever is available + request.addHeader("Accept", ACCEPT_HEADER); + + final CloseableHttpResponse response = httpClient.execute(request); + try { + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + return response.getEntity().getContent(); + } finally { + if (response != null) { + response.close(); + } + } + } + + public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) throws JsonParseException, IOException { + final InputStream in = openStreamForURL(url, httpClient); + try { + return fromInputStream(in); + } finally { + in.close(); + } + } + + public static CloseableHttpClient getDefaultHttpClient() { + CloseableHttpClient result = DEFAULT_HTTP_CLIENT; + if (result == null) { + synchronized (JsonUtils.class) { + result = DEFAULT_HTTP_CLIENT; + if (result == null) { + result = DEFAULT_HTTP_CLIENT = JsonUtils.createDefaultHttpClient(); + } + } + } + return result; + } + + private static CloseableHttpClient createDefaultHttpClient() { + // Common CacheConfig for both the JarCacheStorage and the underlying + // BasicHttpCacheStorage + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + + CloseableHttpClient result = CachingHttpClientBuilder + .create() + // allow caching + .setCacheConfig(cacheConfig) + // Wrap the local JarCacheStorage around a BasicHttpCacheStorage + .setHttpCacheStorage( + new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( + cacheConfig))) + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + .addInterceptorFirst(new RequestAcceptEncoding()) + .addInterceptorFirst(new ResponseContentEncoding()) + // use system defaults for proxy etc. + .useSystemProperties().build(); + + return result; + } } From d2e89458158a7dd22a568aa243503ec8ebacc98c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 13 Feb 2016 15:44:50 +1100 Subject: [PATCH 162/440] Deprecate methods that do not supply their own CloseableHttpClient This way, in the future, we can fully hide the JsonUtils internal API. --- .../com/github/jsonldjava/utils/JsonUtils.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index cf2042c4..13aa63c0 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -173,7 +173,9 @@ public static Object fromString(String jsonString) throws JsonParseException, IO * If there was a JSON related error during parsing. * @throws IOException * If there was an IO error during parsing. + * @deprecated Use {@link #fromURL(java.net.URL, CloseableHttpClient)} instead. */ + @Deprecated public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { return fromURL(url, getDefaultHttpClient()); } @@ -279,6 +281,21 @@ public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient } } + /** + * Parses a JSON-LD document, from the contents of the JSON resource + * resolved from the JsonLdUrl, to an object that can be used as input for + * the {@link JsonLdApi} and {@link JsonLdProcessor} methods. + * + * @param url + * The JsonLdUrl to resolve + * @param httpClient + * The {@link CloseableHttpClient} to use to resolve the URL. + * @return A JSON Object. + * @throws JsonParseException + * If there was a JSON related error during parsing. + * @throws IOException + * If there was an IO error during parsing. + */ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) throws JsonParseException, IOException { final InputStream in = openStreamForURL(url, httpClient); try { From 6877ca065883dfe0fea5d01e647cdc58ffdec89a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 13 Feb 2016 15:53:20 +1100 Subject: [PATCH 163/440] Javadoc --- .../main/java/com/github/jsonldjava/utils/JsonUtils.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 13aa63c0..3fa8021a 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -254,6 +254,15 @@ public static void writePrettyPrint(Writer writer, Object jsonObject) jw.writeObject(jsonObject); } + /** + * Attempts to open an {@link InputStream} that will contain the content of the URL, as resolved by the given HTTP Client. + * + * If the URL is not an HTTP or HTTPS URL it is resolved using the default {@link java.net.URL#openStream()} method. + * @param url The URL to resolve. + * @param httpClient The CloseableHttpClient to use to resolve the URL. + * @return An InputStream containing the contents of the resolved URL. + * @throws IOException If there are any IO exceptions while resolving the URL. + */ public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) throws IOException { final String protocol = url.getProtocol(); if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { From de7c22019ffb071fd2b29447095509bf8f568e20 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 13 Feb 2016 15:56:53 +1100 Subject: [PATCH 164/440] Fix calls to deprecated method --- .../com/github/jsonldjava/core/ArrayContextToRDFTest.java | 4 ++-- .../java/com/github/jsonldjava/core/LongestPrefixTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index 8c287a6c..2283d5cb 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -16,12 +16,12 @@ public void toRdfWithNamespace() throws Exception { final URL contextUrl = getClass().getResource("/custom/contexttest-0001.jsonld"); assertNotNull(contextUrl); - final Object context = JsonUtils.fromURL(contextUrl); + final Object context = JsonUtils.fromURL(contextUrl, JsonUtils.getDefaultHttpClient()); assertNotNull(context); final URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); assertNotNull(arrayContextUrl); - final Object arrayContext = JsonUtils.fromURL(arrayContextUrl); + final Object arrayContext = JsonUtils.fromURL(arrayContextUrl, JsonUtils.getDefaultHttpClient()); assertNotNull(arrayContext); final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; diff --git a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java index 0190eed7..1471feaf 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java @@ -17,7 +17,7 @@ public void toRdfWithNamespace() throws Exception { final URL contextUrl = getClass().getResource("/custom/contexttest-0003.jsonld"); assertNotNull(contextUrl); - final Object context = JsonUtils.fromURL(contextUrl); + final Object context = JsonUtils.fromURL(contextUrl, JsonUtils.getDefaultHttpClient()); assertNotNull(context); final JsonLdOptions options = new JsonLdOptions(); From 766c20cc01d8a1b33d81b369e501ac6a8351c035 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 17 Feb 2016 17:34:34 -0500 Subject: [PATCH 165/440] Release 0.8.1 --- README.md | 6 +++++- pom.xml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 90b18d84..8a0b9f59 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.8.0 + 0.8.1 Code example @@ -399,6 +399,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2016-02-17 +* Release version 0.8.1 +* Refactor JSONUtils and DocumentLoader to move most of the static logic into JSONUtils, and deprecate the DocumentLoader versions + ### 2016-02-10 * Release version 0.8.0 diff --git a/pom.xml b/pom.xml index 81445f15..83b1b60d 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.1-SNAPSHOT + 0.8.1 JSONLD Java :: Parent Json-LD Java Parent POM pom From 789909530429dd51a72cd534756a2f5edb967f45 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 17 Feb 2016 17:41:43 -0500 Subject: [PATCH 166/440] Release core 0.8.1 --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 18233579..07335ed7 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.1-SNAPSHOT + 0.8.1 4.0.0 jsonld-java From 70c19add6b2c59734cc8ba9a5d0088008c0a0933 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 17 Feb 2016 17:51:51 -0500 Subject: [PATCH 167/440] Bump to next development version --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 07335ed7..05c5b593 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.1 + 0.9.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 83b1b60d..59aefe9c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.1 + 0.9.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 868798d024c460ca30a3ef4a3924e7ae8a602510 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 17 Feb 2016 18:19:34 -0500 Subject: [PATCH 168/440] Release 0.8.2 --- README.md | 3 ++- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8a0b9f59..bfbba189 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.8.1 + 0.8.2 Code example @@ -400,6 +400,7 @@ CHANGELOG ========= ### 2016-02-17 +* Re-release version 0.8.2 with the refactoring work actually in it. 0.8.1 is identical in functionality to 0.8.0 * Release version 0.8.1 * Refactor JSONUtils and DocumentLoader to move most of the static logic into JSONUtils, and deprecate the DocumentLoader versions diff --git a/core/pom.xml b/core/pom.xml index 05c5b593..c34a90f6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.9.0-SNAPSHOT + 0.8.2 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 59aefe9c..7145a063 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.9.0-SNAPSHOT + 0.8.2 JSONLD Java :: Parent Json-LD Java Parent POM pom From 7702833a810c21168f2b23a01024089cd1a0e764 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 17 Feb 2016 18:31:51 -0500 Subject: [PATCH 169/440] bump to next development version --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index c34a90f6..e317d19e 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.2 + 0.8.3-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 7145a063..0be7af1c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.2 + 0.8.3-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From e00b8a2eca5a965a0caceb68cdadf82c9b275cb8 Mon Sep 17 00:00:00 2001 From: Maxim Kolchin Date: Fri, 26 Feb 2016 21:00:32 +0300 Subject: [PATCH 170/440] Added test reproducing ConcurrentModificationException --- .../jsonldjava/core/JsonLdFramingTest.java | 26 +++++++++++++++++++ .../resources/custom/frame-0001-frame.jsonld | 10 +++++++ .../resources/custom/frame-0001-in.jsonld | 19 ++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java create mode 100644 core/src/test/resources/custom/frame-0001-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0001-in.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java new file mode 100644 index 00000000..c82f343d --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -0,0 +1,26 @@ +package com.github.jsonldjava.core; + +import com.github.jsonldjava.utils.JsonUtils; +import java.io.IOException; +import org.junit.Test; +import static org.junit.Assert.*; + +public class JsonLdFramingTest { + + @Test + public void testFrame0001() throws IOException, JsonLdError { + try { + Object frame = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/custom/frame-0001-frame.jsonld")); + Object in = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/custom/frame-0001-in.jsonld")); + + JsonLdProcessor.frame(in, frame, new JsonLdOptions()); + } catch (Throwable t) { + t.printStackTrace(); + + fail(); + } + } + +} diff --git a/core/src/test/resources/custom/frame-0001-frame.jsonld b/core/src/test/resources/custom/frame-0001-frame.jsonld new file mode 100644 index 00000000..8c5731c1 --- /dev/null +++ b/core/src/test/resources/custom/frame-0001-frame.jsonld @@ -0,0 +1,10 @@ +{ + "@context": { + "net": "http://www.example.net/", + "org": "http://example.org/", + "com": "http://example.com/", + + "org:p3": { "@type": "@id" } + }, + "com:p1": {} +} \ No newline at end of file diff --git a/core/src/test/resources/custom/frame-0001-in.jsonld b/core/src/test/resources/custom/frame-0001-in.jsonld new file mode 100644 index 00000000..d8b9a61c --- /dev/null +++ b/core/src/test/resources/custom/frame-0001-in.jsonld @@ -0,0 +1,19 @@ +{ + "@context": { + "net": "http://www.example.net/", + "org": "http://example.org/", + "com": "http://example.com/", + + "org:p3": { "@type": "@id" } + }, + "com:p1":[ + { + "org:p3": "_:b2", + "net:p2": {} + }, + { + "@id": "_:b2", + "net:p2": {} + } + ] +} \ No newline at end of file From 339c3f76cd8cab33734b0f5aad9713cf0140ce57 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 28 Feb 2016 17:14:38 -0500 Subject: [PATCH 171/440] Add positive test for completion in the framing test --- .../jsonldjava/core/JsonLdFramingTest.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index c82f343d..882b5d5e 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -2,6 +2,8 @@ import com.github.jsonldjava.utils.JsonUtils; import java.io.IOException; +import java.util.Map; + import org.junit.Test; import static org.junit.Assert.*; @@ -9,18 +11,14 @@ public class JsonLdFramingTest { @Test public void testFrame0001() throws IOException, JsonLdError { - try { - Object frame = JsonUtils.fromInputStream( - getClass().getResourceAsStream("/custom/frame-0001-frame.jsonld")); - Object in = JsonUtils.fromInputStream( - getClass().getResourceAsStream("/custom/frame-0001-in.jsonld")); + Object frame = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/custom/frame-0001-frame.jsonld")); + Object in = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/custom/frame-0001-in.jsonld")); - JsonLdProcessor.frame(in, frame, new JsonLdOptions()); - } catch (Throwable t) { - t.printStackTrace(); - - fail(); - } + Map frame2 = JsonLdProcessor.frame(in, frame, new JsonLdOptions()); + + assertEquals(2, frame2.size()); } } From 17ec4ba48fc393974f96f8c964ba80499d44fe31 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 28 Feb 2016 17:16:02 -0500 Subject: [PATCH 172/440] Take a defensive copy of the keyset to avoid CME. Fixes #166 ConcurrenModificationException occurs because the map and therefore the keyset is being modified in some cases while the iteration on it is occurring. Fix this by copying the keyset to a new temporary set for iteration. --- core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 770687e8..c6efade5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1551,7 +1551,7 @@ private static void removeEmbed(FramingContext state, String id) { private static void removeDependents(Map embeds, String id) { // get embed keys as a separate array to enable deleting keys in map - for (final String id_dep : embeds.keySet()) { + for (final String id_dep : new HashSet(embeds.keySet())) { final EmbedNode e = embeds.get(id_dep); final Object p = e.parent != null ? e.parent : newMap(); if (!(p instanceof Map)) { From a124ac1951022cabbc35c8850dddfc12b79fb39c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 28 Feb 2016 17:27:53 -0500 Subject: [PATCH 173/440] Update changelog with CME fix --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index bfbba189..9e028ea8 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2016-02-29 +* Fix ConcurrentModificationException in the implementation of the Framing API + ### 2016-02-17 * Re-release version 0.8.2 with the refactoring work actually in it. 0.8.1 is identical in functionality to 0.8.0 * Release version 0.8.1 From 2f1763ebbdeb525b3b744ee6b329130f799f7ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Fri, 11 Mar 2016 15:59:38 +0100 Subject: [PATCH 174/440] added a test for issue #167 --- .../json-ld.org/frame-0022-frame.jsonld | 12 +++++++++ .../json-ld.org/frame-0022-in.jsonld | 24 +++++++++++++++++ .../json-ld.org/frame-0022-out.jsonld | 26 +++++++++++++++++++ .../json-ld.org/frame-manifest.jsonld | 10 ++++++- 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/json-ld.org/frame-0022-frame.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-0022-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-0022-out.jsonld diff --git a/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld b/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld new file mode 100644 index 00000000..1f6d39e7 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld @@ -0,0 +1,12 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@type": "ex:Library", + "ex:contains": { + "@explicit":true, + "dc:title":{"@default":"Title missing"}, + "dc:creator":{} + } +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0022-in.jsonld b/core/src/test/resources/json-ld.org/frame-0022-in.jsonld new file mode 100644 index 00000000..6c0feddb --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0022-in.jsonld @@ -0,0 +1,24 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@graph": [ + { + "@id": "http://example.org/library", + "@type": "ex:Library", + "ex:contains": [{"@id":"http://example.org/library/the-republic#introduction"},{"@id":"http://example.org/library/the-republic"}] + }, + { + "@id": "http://example.org/library/the-republic", + "@type": "ex:Book", + "dc:creator": "Plato", + "dc:title": "The Republic" + }, + { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Book", + "dc:creator": "Plato" + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0022-out.jsonld b/core/src/test/resources/json-ld.org/frame-0022-out.jsonld new file mode 100644 index 00000000..42836207 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0022-out.jsonld @@ -0,0 +1,26 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@graph": [ + { + "@id": "http://example.org/library", + "@type": "ex:Library", + "ex:contains": [ + { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Book", + "dc:creator": "Plato", + "dc:title": "Title missing" + }, + { + "@id": "http://example.org/library/the-republic", + "@type": "ex:Book", + "dc:creator": "Plato", + "dc:title": "The Republic" + } + ] + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index 016f9f3a..d476dbac 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -152,5 +152,13 @@ "input": "frame-0021-in.jsonld", "frame": "frame-0021-frame.jsonld", "expect": "frame-0021-out.jsonld" - }] + } + , { + "@id": "#t0022", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Default inside sets", + "input": "frame-0022-in.jsonld", + "frame": "frame-0022-frame.jsonld", + "expect": "frame-0022-out.jsonld" + }] } From 59185f79e9178286d715e3c978701e0ddbbdca12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Fri, 11 Mar 2016 16:01:05 +0100 Subject: [PATCH 175/440] Inside filterNode() check if nodes have an @default in the frame, if they do, then don't filter them out. --- .../com/github/jsonldjava/core/JsonLdApi.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index c6efade5..e2afcc0f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1606,7 +1606,23 @@ private boolean filterNode(FramingContext state, Map node, } else { for (final String key : frame.keySet()) { if ("@id".equals(key) || !isKeyword(key) && !(node.containsKey(key))) { - return false; + + Object frameObject = frame.get(key); + if(frameObject instanceof ArrayList) { + ArrayList o = (ArrayList) frame.get(key); + + boolean _default = false; + for (Object oo : o) { + if(oo instanceof Map){ + if (((Map) oo).containsKey("@default")) { + _default = true; + } + } + } + if(_default) continue; + } + + return false; } } return true; From 02b7d75892f10037f27604c61a2011f19eb890a1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 23 Apr 2016 11:59:44 +1000 Subject: [PATCH 176/440] Cleanup --- .../com/github/jsonldjava/core/JsonLdApi.java | 95 ++++++++++--------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index e2afcc0f..6911ca37 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -266,7 +266,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, } if (value instanceof List) { ((List) result.get(property)) - .addAll((List) value); + .addAll((List) value); } else { ((List) result.get(property)).add(value); } @@ -414,7 +414,7 @@ else if (result.containsKey(itemActiveProperty)) { // 7.6.6.1) final Boolean check = (!compactArrays || "@set".equals(container) || "@list".equals(container) || "@list".equals(expandedProperty) || "@graph" - .equals(expandedProperty)) + .equals(expandedProperty)) && (!(compactedItem instanceof List)); if (check) { final List tmp = new ArrayList(); @@ -431,7 +431,7 @@ else if (result.containsKey(itemActiveProperty)) { } if (compactedItem instanceof List) { ((List) result.get(itemActiveProperty)) - .addAll((List) compactedItem); + .addAll((List) compactedItem); } else { ((List) result.get(itemActiveProperty)).add(compactedItem); } @@ -683,7 +683,7 @@ else if ("@reverse".equals(expandedProperty)) { // 7.4.11.2.2) if (item instanceof List) { ((List) result.get(property)) - .addAll((List) item); + .addAll((List) item); } else { ((List) result.get(property)).add(item); } @@ -850,7 +850,7 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.10.4.3) if (item instanceof List) { ((List) reverseMap.get(expandedProperty)) - .addAll((List) item); + .addAll((List) item); } else { ((List) reverseMap.get(expandedProperty)).add(item); } @@ -865,7 +865,7 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.11.2) if (expandedValue instanceof List) { ((List) result.get(expandedProperty)) - .addAll((List) expandedValue); + .addAll((List) expandedValue); } else { ((List) result.get(expandedProperty)).add(expandedValue); } @@ -943,7 +943,7 @@ else if (result.containsKey("@set") || result.containsKey("@list")) { // 12.1) if (result != null && (result.size() == 0 || result.containsKey("@value") || result - .containsKey("@list"))) { + .containsKey("@list"))) { result = null; } // 12.2) @@ -1000,7 +1000,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG void generateNodeMap(Object element, Map nodeMap, String activeGraph, Object activeSubject, String activeProperty, Map list) - throws JsonLdError { + throws JsonLdError { // 1) if (element instanceof List) { // 1.1) @@ -1429,7 +1429,7 @@ private void frame(FramingContext state, Map nodes, Map) ((List) frame.get(prop)) - .get(0), list, "@list"); + .get(0), list, "@list"); } else { // include other values automatcially (TODO: // may need JsonLdUtils.clone(n)) @@ -1468,26 +1468,26 @@ else if (JsonLdUtils.isNodeReference(item)) { final List pf = (List) frame.get(prop); Map propertyFrame = pf.size() > 0 ? (Map) pf .get(0) : null; - if (propertyFrame == null) { - propertyFrame = newMap(); - } - final boolean omitDefaultOn = getFrameFlag(propertyFrame, "@omitDefault", - state.omitDefault); - if (!omitDefaultOn && !output.containsKey(prop)) { - Object def = "@null"; - if (propertyFrame.containsKey("@default")) { - def = JsonLdUtils.clone(propertyFrame.get("@default")); - } - if (!(def instanceof List)) { - final List tmp = new ArrayList(); - tmp.add(def); - def = tmp; - } - final Map tmp1 = newMap("@preserve", def); - final List tmp2 = new ArrayList(); - tmp2.add(tmp1); - output.put(prop, tmp2); - } + if (propertyFrame == null) { + propertyFrame = newMap(); + } + final boolean omitDefaultOn = getFrameFlag(propertyFrame, "@omitDefault", + state.omitDefault); + if (!omitDefaultOn && !output.containsKey(prop)) { + Object def = "@null"; + if (propertyFrame.containsKey("@default")) { + def = JsonLdUtils.clone(propertyFrame.get("@default")); + } + if (!(def instanceof List)) { + final List tmp = new ArrayList(); + tmp.add(def); + def = tmp; + } + final Map tmp1 = newMap("@preserve", def); + final List tmp2 = new ArrayList(); + tmp2.add(tmp1); + output.put(prop, tmp2); + } } // add output to parent @@ -1607,22 +1607,23 @@ private boolean filterNode(FramingContext state, Map node, for (final String key : frame.keySet()) { if ("@id".equals(key) || !isKeyword(key) && !(node.containsKey(key))) { - Object frameObject = frame.get(key); - if(frameObject instanceof ArrayList) { - ArrayList o = (ArrayList) frame.get(key); - - boolean _default = false; - for (Object oo : o) { - if(oo instanceof Map){ - if (((Map) oo).containsKey("@default")) { - _default = true; - } - } - } - if(_default) continue; - } - - return false; + Object frameObject = frame.get(key); + if (frameObject instanceof ArrayList) { + ArrayList o = (ArrayList) frame.get(key); + + boolean _default = false; + for (Object oo : o) { + if (oo instanceof Map) { + if (((Map) oo).containsKey("@default")) { + _default = true; + } + } + } + if (_default) + continue; + } + + return false; } } return true; @@ -1859,7 +1860,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { if (object.isBlankNode() || object.isIRI()) { // 3.5.8.1-3) nodeMap.get(object.getValue()).usages - .add(new UsagesNode(node, predicate, value)); + .add(new UsagesNode(node, predicate, value)); } } } @@ -2060,7 +2061,7 @@ public Object normalize(Map dataset) throws JsonLdError { }); } ((List) ((Map) bnodes.get(id)).get("quads")) - .add(quad); + .add(quad); } } } From 161c05f2940b94fd6b646ddba29cc32261172936 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 23 Apr 2016 13:07:23 +1000 Subject: [PATCH 177/440] Add performance test for JsonLdApi.fromRDF(RDFDataset) --- .../core/JsonLdPerformanceTest.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index baa72e88..ab580f2b 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -5,11 +5,18 @@ import java.io.File; import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.DoubleSummaryStatistics; +import java.util.List; +import java.util.LongSummaryStatistics; +import java.util.Random; import java.util.zip.GZIPInputStream; import org.junit.Ignore; import org.junit.Test; +import com.github.jsonldjava.core.RDFDataset.Quad; import com.github.jsonldjava.utils.JsonUtils; /** @@ -41,4 +48,110 @@ public final void test() throws Exception { System.out.printf("Compaction time: %d", (compactEnd - compactStart)); } + @Test + public final void testSerialisationPerformance() throws Exception { + Random prng = new Random(); + + String exNs = "http://example.org/"; + + String bnode = "_:anon"; + String uri1 = exNs + "a1"; + String uri2 = exNs + "b2"; + String uri3 = exNs + "c3"; + List potentialSubjects = new ArrayList(); + potentialSubjects.add(bnode); + potentialSubjects.add(uri1); + potentialSubjects.add(uri2); + potentialSubjects.add(uri3); + for (int i = 0; i < 50; i++) { + potentialSubjects.add("_:" + i); + } + for (int i = 1; i < 50; i++) { + potentialSubjects.add("_:a" + Integer.toHexString(i).toUpperCase()); + } + for (int i = 0; i < 200; i++) { + potentialSubjects.add(exNs + Integer.toHexString(i) + "/z" + + Integer.toOctalString(i % 20)); + } + Collections.shuffle(potentialSubjects, prng); + + List potentialObjects = new ArrayList(); + potentialObjects.addAll(potentialSubjects); + Collections.shuffle(potentialObjects, prng); + + List potentialPredicates = new ArrayList(); + potentialPredicates.add(JsonLdConsts.RDF_TYPE); + potentialPredicates.add(JsonLdConsts.RDF_LIST); + potentialPredicates.add(JsonLdConsts.RDF_NIL); + potentialPredicates.add(JsonLdConsts.RDF_FIRST); + potentialPredicates.add(JsonLdConsts.RDF_OBJECT); + potentialPredicates.add(JsonLdConsts.XSD_STRING); + Collections.shuffle(potentialPredicates, prng); + + RDFDataset testData = new RDFDataset(); + + for (int i = 0; i < 8000; i++) { + String nextObject = potentialObjects.get(prng.nextInt(potentialObjects.size())); + boolean isLiteral = true; + if (nextObject.startsWith("_:") || nextObject.startsWith("http://")) { + isLiteral = false; + } + if (isLiteral) { + if (i % 2 == 0) { + testData.addQuad(potentialSubjects.get(prng.nextInt(potentialSubjects.size())), + potentialPredicates.get(prng.nextInt(potentialPredicates.size())), + nextObject, JsonLdConsts.XSD_STRING, + potentialSubjects.get(prng.nextInt(potentialSubjects.size())), null); + } else if (i % 5 == 0) { + testData.addTriple( + potentialSubjects.get(prng.nextInt(potentialSubjects.size())), + potentialPredicates.get(prng.nextInt(potentialPredicates.size())), + nextObject, JsonLdConsts.RDF_LANGSTRING, "en"); + } + } else { + if (i % 2 == 0) { + testData.addQuad(potentialSubjects.get(prng.nextInt(potentialSubjects.size())), + potentialPredicates.get(prng.nextInt(potentialPredicates.size())), + nextObject, + potentialSubjects.get(prng.nextInt(potentialSubjects.size()))); + } else if (i % 5 == 0) { + testData.addTriple( + potentialSubjects.get(prng.nextInt(potentialSubjects.size())), + potentialPredicates.get(prng.nextInt(potentialPredicates.size())), + nextObject); + } + } + } + + JsonLdOptions options = new JsonLdOptions(); + JsonLdApi jsonLdApi = new JsonLdApi(options); + int rounds = 10000; + int[] hashCodes = new int[rounds]; + LongSummaryStatistics statsFirst5000 = new LongSummaryStatistics(); + LongSummaryStatistics stats = new LongSummaryStatistics(); + for (int i = 0; i < rounds; i++) { + long start = System.nanoTime(); + Object fromRDF = jsonLdApi.fromRDF(testData); + if (i < 5000) { + statsFirst5000.accept(System.nanoTime() - start); + } else { + stats.accept(System.nanoTime() - start); + } + hashCodes[i] = fromRDF.hashCode(); + fromRDF = null; + } + System.out.println("First 5000 out of " + rounds); + System.out.println("Average: " + statsFirst5000.getAverage() / 100000); + System.out.println("Sum: " + statsFirst5000.getSum() / 100000); + System.out.println("Maximum: " + statsFirst5000.getMax() / 100000); + System.out.println("Minimum: " + statsFirst5000.getMin() / 100000); + System.out.println("Count: " + statsFirst5000.getCount()); + + System.out.println("Post 5000 out of " + rounds); + System.out.println("Average: " + stats.getAverage() / 100000); + System.out.println("Sum: " + stats.getSum() / 100000); + System.out.println("Maximum: " + stats.getMax() / 100000); + System.out.println("Minimum: " + stats.getMin() / 100000); + System.out.println("Count: " + stats.getCount()); + } } From 104f3bb340dcdfc5ef2932037d8f83772e497fb8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 23 Apr 2016 13:33:46 +1000 Subject: [PATCH 178/440] Minimum reasonable map size should be 4, not 2 --- core/src/main/java/com/github/jsonldjava/utils/Obj.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/Obj.java b/core/src/main/java/com/github/jsonldjava/utils/Obj.java index a7f371de..4e7e36bb 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/Obj.java +++ b/core/src/main/java/com/github/jsonldjava/utils/Obj.java @@ -11,7 +11,7 @@ public class Obj { * @return A new {@link Map} instance. */ public static Map newMap() { - return new LinkedHashMap(2, 0.75f); + return new LinkedHashMap(4, 0.75f); } /** From 52e4c05fc78f053003b24d4901ee429d7811e437 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 23 Apr 2016 13:34:25 +1000 Subject: [PATCH 179/440] start array lists by default at size 4 --- .../com/github/jsonldjava/core/JsonLdApi.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 6911ca37..fe134e3d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1029,7 +1029,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG if (elem.get("@type") instanceof List) { oldTypes = (List) elem.get("@type"); } else { - oldTypes = new ArrayList(); + oldTypes = new ArrayList(4); oldTypes.add((String) elem.get("@type")); } for (final String item : oldTypes) { @@ -1061,7 +1061,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG // 5) else if (elem.containsKey("@list")) { // 5.1) - final Map result = newMap("@list", new ArrayList()); + final Map result = newMap("@list", new ArrayList(4)); // 5.2) // for (final Object item : (List) elem.get("@list")) { // generateNodeMap(item, nodeMap, activeGraph, activeSubject, @@ -1166,7 +1166,7 @@ else if (activeProperty != null) { } // 6.11.2) if (!node.containsKey(property)) { - node.put(property, new ArrayList()); + node.put(property, new ArrayList(4)); } // 6.11.3) generateNodeMap(value, nodeMap, activeGraph, id, property, null); @@ -1739,7 +1739,7 @@ public UsagesNode(NodeMapNode node, String property, Map value) } private class NodeMapNode extends LinkedHashMap { - public List usages = new ArrayList(); + public List usages = new ArrayList(4); public NodeMapNode(String id) { super(); @@ -1798,9 +1798,9 @@ public Map serialize() { */ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 1) - final Map defaultGraph = new LinkedHashMap(); + final Map defaultGraph = new LinkedHashMap(4); // 2) - final Map> graphMap = new LinkedHashMap>(); + final Map> graphMap = new LinkedHashMap>(4); graphMap.put("@default", defaultGraph); // 3/3.1) @@ -1883,8 +1883,8 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { String property = usage.property; Map head = usage.value; // 4.3.2) - final List list = new ArrayList(); - final List listNodes = new ArrayList(); + final List list = new ArrayList(4); + final List listNodes = new ArrayList(4); // 4.3.3) while (RDF_REST.equals(property) && node.isWellFormedListNode()) { // 4.3.3.1) @@ -1931,7 +1931,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { } // 5) - final List result = new ArrayList(); + final List result = new ArrayList(4); // 6) final List ids = new ArrayList(defaultGraph.keySet()); Collections.sort(ids); @@ -1940,7 +1940,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 6.1) if (graphMap.containsKey(subject)) { // 6.1.1) - node.put("@graph", new ArrayList()); + node.put("@graph", new ArrayList(4)); // 6.1.2) final List keys = new ArrayList(graphMap.get(subject).keySet()); Collections.sort(keys); From 261e20b5b4e01afe4c1639bcc255cc94ac66118a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 23 Apr 2016 14:23:28 +1000 Subject: [PATCH 180/440] Add tests for various algorithms --- .../core/JsonLdPerformanceTest.java | 94 ++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index ab580f2b..74b7d4fb 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -49,8 +49,9 @@ public final void test() throws Exception { } @Test - public final void testSerialisationPerformance() throws Exception { + public final void testPerformance() throws Exception { Random prng = new Random(); + int rounds = 2000; String exNs = "http://example.org/"; @@ -123,9 +124,10 @@ public final void testSerialisationPerformance() throws Exception { } } + System.out + .println("RDF triples to JSON-LD (internal objects, not parsed from a document)..."); JsonLdOptions options = new JsonLdOptions(); JsonLdApi jsonLdApi = new JsonLdApi(options); - int rounds = 10000; int[] hashCodes = new int[rounds]; LongSummaryStatistics statsFirst5000 = new LongSummaryStatistics(); LongSummaryStatistics stats = new LongSummaryStatistics(); @@ -153,5 +155,93 @@ public final void testSerialisationPerformance() throws Exception { System.out.println("Maximum: " + stats.getMax() / 100000); System.out.println("Minimum: " + stats.getMin() / 100000); System.out.println("Count: " + stats.getCount()); + + System.out.println("Non-pretty print benchmarking..."); + JsonLdOptions options2 = new JsonLdOptions(); + JsonLdApi jsonLdApi2 = new JsonLdApi(options2); + LongSummaryStatistics statsFirst5000Part2 = new LongSummaryStatistics(); + LongSummaryStatistics statsPart2 = new LongSummaryStatistics(); + Object fromRDF2 = jsonLdApi2.fromRDF(testData); + for (int i = 0; i < rounds; i++) { + long start = System.nanoTime(); + JsonUtils.toString(fromRDF2); + if (i < 5000) { + statsFirst5000Part2.accept(System.nanoTime() - start); + } else { + statsPart2.accept(System.nanoTime() - start); + } + } + System.out.println("First 5000 out of " + rounds); + System.out.println("Average: " + statsFirst5000Part2.getAverage() / 100000); + System.out.println("Sum: " + statsFirst5000Part2.getSum() / 100000); + System.out.println("Maximum: " + statsFirst5000Part2.getMax() / 100000); + System.out.println("Minimum: " + statsFirst5000Part2.getMin() / 100000); + System.out.println("Count: " + statsFirst5000Part2.getCount()); + + System.out.println("Post 5000 out of " + rounds); + System.out.println("Average: " + statsPart2.getAverage() / 100000); + System.out.println("Sum: " + statsPart2.getSum() / 100000); + System.out.println("Maximum: " + statsPart2.getMax() / 100000); + System.out.println("Minimum: " + statsPart2.getMin() / 100000); + System.out.println("Count: " + statsPart2.getCount()); + + System.out.println("Pretty print benchmarking..."); + JsonLdOptions options3 = new JsonLdOptions(); + JsonLdApi jsonLdApi3 = new JsonLdApi(options3); + LongSummaryStatistics statsFirst5000Part3 = new LongSummaryStatistics(); + LongSummaryStatistics statsPart3 = new LongSummaryStatistics(); + Object fromRDF3 = jsonLdApi3.fromRDF(testData); + for (int i = 0; i < rounds; i++) { + long start = System.nanoTime(); + JsonUtils.toPrettyString(fromRDF3); + if (i < 5000) { + statsFirst5000Part3.accept(System.nanoTime() - start); + } else { + statsPart3.accept(System.nanoTime() - start); + } + } + System.out.println("First 5000 out of " + rounds); + System.out.println("Average: " + statsFirst5000Part3.getAverage() / 100000); + System.out.println("Sum: " + statsFirst5000Part3.getSum() / 100000); + System.out.println("Maximum: " + statsFirst5000Part3.getMax() / 100000); + System.out.println("Minimum: " + statsFirst5000Part3.getMin() / 100000); + System.out.println("Count: " + statsFirst5000Part3.getCount()); + + System.out.println("Post 5000 out of " + rounds); + System.out.println("Average: " + statsPart3.getAverage() / 100000); + System.out.println("Sum: " + statsPart3.getSum() / 100000); + System.out.println("Maximum: " + statsPart3.getMax() / 100000); + System.out.println("Minimum: " + statsPart3.getMin() / 100000); + System.out.println("Count: " + statsPart3.getCount()); + + System.out.println("Expansion benchmarking..."); + JsonLdOptions options4 = new JsonLdOptions(); + JsonLdApi jsonLdApi4 = new JsonLdApi(options4); + LongSummaryStatistics statsFirst5000Part4 = new LongSummaryStatistics(); + LongSummaryStatistics statsPart4 = new LongSummaryStatistics(); + Object fromRDF4 = jsonLdApi4.fromRDF(testData); + for (int i = 0; i < rounds; i++) { + long start = System.nanoTime(); + JsonLdProcessor.expand(fromRDF4, options4); + if (i < 5000) { + statsFirst5000Part4.accept(System.nanoTime() - start); + } else { + statsPart4.accept(System.nanoTime() - start); + } + } + System.out.println("First 5000 out of " + rounds); + System.out.println("Average: " + statsFirst5000Part4.getAverage() / 100000); + System.out.println("Sum: " + statsFirst5000Part4.getSum() / 100000); + System.out.println("Maximum: " + statsFirst5000Part4.getMax() / 100000); + System.out.println("Minimum: " + statsFirst5000Part4.getMin() / 100000); + System.out.println("Count: " + statsFirst5000Part4.getCount()); + + System.out.println("Post 5000 out of " + rounds); + System.out.println("Average: " + statsPart4.getAverage() / 100000); + System.out.println("Sum: " + statsPart4.getSum() / 100000); + System.out.println("Maximum: " + statsPart4.getMax() / 100000); + System.out.println("Minimum: " + statsPart4.getMin() / 100000); + System.out.println("Count: " + statsPart4.getCount()); + } } From 0c6a20ea96ff1aab0233a60f20726814fa02ca5f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 23 Apr 2016 14:24:30 +1000 Subject: [PATCH 181/440] Ignore performance test by default --- .../java/com/github/jsonldjava/core/JsonLdPerformanceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 74b7d4fb..929b11e2 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -48,6 +48,7 @@ public final void test() throws Exception { System.out.printf("Compaction time: %d", (compactEnd - compactStart)); } + @Ignore("Disable performance tests by default") @Test public final void testPerformance() throws Exception { Random prng = new Random(); From f8d663d451e3e4df3658214490909f1f14ba6624 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 May 2016 09:47:27 +1000 Subject: [PATCH 182/440] Add laxMergeValue option to possibly streamline parsing in future --- .../com/github/jsonldjava/core/JsonLdApi.java | 3 +- .../github/jsonldjava/core/JsonLdUtils.java | 17 ++++ .../core/JsonLdPerformanceTest.java | 99 +++++++++++++++---- 3 files changed, 101 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index fe134e3d..4d2bc69d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1855,7 +1855,8 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 3.5.6+7) JsonLdUtils.mergeValue(node, predicate, value); - + // JsonLdUtils.laxMergeValue(node, predicate, value); + // 3.5.8) if (object.isBlankNode() || object.isIRI()) { // 3.5.8.1-3) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 890f8751..10310001 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -118,6 +118,23 @@ static void mergeValue(Map obj, String key, Object value) { } } + static void laxMergeValue(Map obj, String key, Object value) { + if (obj == null) { + return; + } + List values = (List) obj.get(key); + if (values == null) { + values = new ArrayList(); + obj.put(key, values); + } + if ("@list".equals(key) + || (value instanceof Map && ((Map) value).containsKey("@list")) + //|| !deepContains(values, value) + ) { + values.add(value); + } + } + static void mergeCompactedValue(Map obj, String key, Object value) { if (obj == null) { return; diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 929b11e2..e7b8e4f0 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -3,8 +3,12 @@ */ package com.github.jsonldjava.core; +import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.DoubleSummaryStatistics; @@ -13,8 +17,12 @@ import java.util.Random; import java.util.zip.GZIPInputStream; +import org.apache.commons.io.FileUtils; +import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import com.github.jsonldjava.core.RDFDataset.Quad; import com.github.jsonldjava.utils.JsonUtils; @@ -25,6 +33,16 @@ */ public class JsonLdPerformanceTest { + @Rule + public TemporaryFolder tempDir = new TemporaryFolder(); + + private File testDir; + + @Before + public void setUp() throws Exception { + testDir = tempDir.newFolder("jsonld-perf-tests-"); + } + /** * Test performance parsing using test data from: * @@ -34,23 +52,70 @@ public class JsonLdPerformanceTest { */ @Ignore("Enable as necessary for manual testing, particularly to test that it fails due to irregular URIs") @Test - public final void test() throws Exception { - final long parseStart = System.currentTimeMillis(); - final Object inputObject = JsonUtils.fromInputStream(new GZIPInputStream( - new FileInputStream(new File("/home/ans025/Downloads/2000007922.jsonld.gz")))); - final long parseEnd = System.currentTimeMillis(); - System.out.printf("Parse time: %d", (parseEnd - parseStart)); - final JsonLdOptions opts = new JsonLdOptions("urn:test:"); - - final long compactStart = System.currentTimeMillis(); - JsonLdProcessor.compact(inputObject, null, opts); - final long compactEnd = System.currentTimeMillis(); - System.out.printf("Compaction time: %d", (compactEnd - compactStart)); + public final void testPerformance1() throws Exception { + testCompaction("Long", new GZIPInputStream( + new FileInputStream(new File("/home/peter/Downloads/2000007922.jsonld.gz")))); + } + + /** + * Test performance parsing using test data from: + * + * https://github.com/jsonld-java/jsonld-java/files/245372/jsonldperfs.zip + * + * @throws Exception + */ + @Ignore("Enable as necessary to test performance") + @Test + public final void testLaxMergeValuesPerfFast() throws Exception { + testCompaction("Fast", + new FileInputStream(new File("/home/peter/Downloads/jsonldperfs/fast.jsonld"))); + } + + /** + * Test performance parsing using test data from: + * + * https://github.com/jsonld-java/jsonld-java/files/245372/jsonldperfs.zip + * + * @throws Exception + */ + @Ignore("Enable as necessary to test performance") + @Test + public final void testLaxMergeValuesPerfSlow() throws Exception { + testCompaction("Slow", + new FileInputStream(new File("/home/peter/Downloads/jsonldperfs/slow.jsonld"))); + } + + private void testCompaction(String label, InputStream nextInputStream) + throws IOException, FileNotFoundException, JsonLdError { + File testFile = File.createTempFile("jsonld-perf-source-", ".jsonld", testDir); + FileUtils.copyInputStreamToFile(nextInputStream, testFile); + + LongSummaryStatistics parseStats = new LongSummaryStatistics(); + LongSummaryStatistics compactStats = new LongSummaryStatistics(); + + for (int i = 0; i < 1000; i++) { + InputStream testInput = new BufferedInputStream(new FileInputStream(testFile)); + try { + final long parseStart = System.currentTimeMillis(); + final Object inputObject = JsonUtils.fromInputStream(testInput); + parseStats.accept(System.currentTimeMillis() - parseStart); + final JsonLdOptions opts = new JsonLdOptions("urn:test:"); + + final long compactStart = System.currentTimeMillis(); + JsonLdProcessor.compact(inputObject, null, opts); + compactStats.accept(System.currentTimeMillis() - compactStart); + } finally { + testInput.close(); + } + } + + System.out.println("(" + label + ") Parse average : " + parseStats.getAverage()); + System.out.println("(" + label + ") Compact average : " + compactStats.getAverage()); } @Ignore("Disable performance tests by default") @Test - public final void testPerformance() throws Exception { + public final void testPerformanceRandom() throws Exception { Random prng = new Random(); int rounds = 2000; @@ -72,8 +137,8 @@ public final void testPerformance() throws Exception { potentialSubjects.add("_:a" + Integer.toHexString(i).toUpperCase()); } for (int i = 0; i < 200; i++) { - potentialSubjects.add(exNs + Integer.toHexString(i) + "/z" - + Integer.toOctalString(i % 20)); + potentialSubjects + .add(exNs + Integer.toHexString(i) + "/z" + Integer.toOctalString(i % 20)); } Collections.shuffle(potentialSubjects, prng); @@ -125,8 +190,8 @@ public final void testPerformance() throws Exception { } } - System.out - .println("RDF triples to JSON-LD (internal objects, not parsed from a document)..."); + System.out.println( + "RDF triples to JSON-LD (internal objects, not parsed from a document)..."); JsonLdOptions options = new JsonLdOptions(); JsonLdApi jsonLdApi = new JsonLdApi(options); int[] hashCodes = new int[rounds]; From ea5e779ef7138872f876da9de8bd8baafcfba89a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 19:32:14 -0400 Subject: [PATCH 183/440] Extract constants to JsonLdConsts --- .../com/github/jsonldjava/core/Context.java | 420 +++++++++--------- .../com/github/jsonldjava/core/JsonLdApi.java | 346 +++++++-------- .../github/jsonldjava/core/JsonLdConsts.java | 30 ++ .../jsonldjava/core/JsonLdProcessor.java | 64 +-- 4 files changed, 445 insertions(+), 415 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 572c385e..e1e0a59f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -55,7 +55,7 @@ public Context(Object context, JsonLdOptions opts) { private void init(JsonLdOptions options) { this.options = options; if (options.getBase() != null) { - this.put("@base", options.getBase()); + this.put(JsonLdConsts.BASE, options.getBase()); } this.termDefinitions = newMap(); } @@ -75,7 +75,7 @@ public Object compactValue(String activeProperty, Map value) { // 1) int numberMembers = value.size(); // 2) - if (value.containsKey("@index") && "@index".equals(this.getContainer(activeProperty))) { + if (value.containsKey(JsonLdConsts.INDEX) && JsonLdConsts.INDEX.equals(this.getContainer(activeProperty))) { numberMembers--; } // 3) @@ -85,36 +85,36 @@ public Object compactValue(String activeProperty, Map value) { // 4) final String typeMapping = getTypeMapping(activeProperty); final String languageMapping = getLanguageMapping(activeProperty); - if (value.containsKey("@id")) { + if (value.containsKey(JsonLdConsts.ID)) { // 4.1) - if (numberMembers == 1 && "@id".equals(typeMapping)) { - return compactIri((String) value.get("@id")); + if (numberMembers == 1 && JsonLdConsts.ID.equals(typeMapping)) { + return compactIri((String) value.get(JsonLdConsts.ID)); } // 4.2) - if (numberMembers == 1 && "@vocab".equals(typeMapping)) { - return compactIri((String) value.get("@id"), true); + if (numberMembers == 1 && JsonLdConsts.VOCAB.equals(typeMapping)) { + return compactIri((String) value.get(JsonLdConsts.ID), true); } // 4.3) return value; } - final Object valueValue = value.get("@value"); + final Object valueValue = value.get(JsonLdConsts.VALUE); // 5) - if (value.containsKey("@type") && Obj.equals(value.get("@type"), typeMapping)) { + if (value.containsKey(JsonLdConsts.TYPE) && Obj.equals(value.get(JsonLdConsts.TYPE), typeMapping)) { return valueValue; } // 6) - if (value.containsKey("@language")) { + if (value.containsKey(JsonLdConsts.LANGUAGE)) { // TODO: SPEC: doesn't specify to check default language as well - if (Obj.equals(value.get("@language"), languageMapping) - || Obj.equals(value.get("@language"), this.get("@language"))) { + if (Obj.equals(value.get(JsonLdConsts.LANGUAGE), languageMapping) + || Obj.equals(value.get(JsonLdConsts.LANGUAGE), this.get(JsonLdConsts.LANGUAGE))) { return valueValue; } } // 7) if (numberMembers == 1 - && (!(valueValue instanceof String) || !this.containsKey("@language") || (termDefinitions + && (!(valueValue instanceof String) || !this.containsKey(JsonLdConsts.LANGUAGE) || (termDefinitions .containsKey(activeProperty) - && getTermDefinition(activeProperty).containsKey("@language") && languageMapping == null))) { + && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) && languageMapping == null))) { return valueValue; } // 8) @@ -157,7 +157,7 @@ public Context parse(Object localContext, List remoteContexts) throws Js } // 3.2) else if (context instanceof String) { - String uri = (String) result.get("@base"); + String uri = (String) result.get(JsonLdConsts.BASE); uri = JsonLdUrl.resolve(uri, (String) context); // 3.2.2 if (remoteContexts.contains(uri)) { @@ -169,12 +169,12 @@ else if (context instanceof String) { final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); final Object remoteContext = rd.document; if (!(remoteContext instanceof Map) - || !((Map) remoteContext).containsKey("@context")) { + || !((Map) remoteContext).containsKey(JsonLdConsts.CONTEXT)) { // If the dereferenced document has no top-level JSON object // with an @context member throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); } - context = ((Map) remoteContext).get("@context"); + context = ((Map) remoteContext).get(JsonLdConsts.CONTEXT); // 3.2.4 result = result.parse(context, remoteContexts); @@ -186,19 +186,19 @@ else if (context instanceof String) { } // 3.4 - if (remoteContexts.isEmpty() && ((Map) context).containsKey("@base")) { - final Object value = ((Map) context).get("@base"); + if (remoteContexts.isEmpty() && ((Map) context).containsKey(JsonLdConsts.BASE)) { + final Object value = ((Map) context).get(JsonLdConsts.BASE); if (value == null) { - result.remove("@base"); + result.remove(JsonLdConsts.BASE); } else if (value instanceof String) { if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@base", value); + result.put(JsonLdConsts.BASE, value); } else { - final String baseUri = (String) result.get("@base"); + final String baseUri = (String) result.get(JsonLdConsts.BASE); if (!JsonLdUtils.isAbsoluteIri(baseUri)) { throw new JsonLdError(Error.INVALID_BASE_IRI, baseUri); } - result.put("@base", JsonLdUrl.resolve(baseUri, (String) value)); + result.put(JsonLdConsts.BASE, JsonLdUrl.resolve(baseUri, (String) value)); } } else { throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, @@ -207,13 +207,13 @@ else if (context instanceof String) { } // 3.5 - if (((Map) context).containsKey("@vocab")) { - final Object value = ((Map) context).get("@vocab"); + if (((Map) context).containsKey(JsonLdConsts.VOCAB)) { + final Object value = ((Map) context).get(JsonLdConsts.VOCAB); if (value == null) { - result.remove("@vocab"); + result.remove(JsonLdConsts.VOCAB); } else if (value instanceof String) { if (JsonLdUtils.isAbsoluteIri((String) value)) { - result.put("@vocab", value); + result.put(JsonLdConsts.VOCAB, value); } else { throw new JsonLdError(Error.INVALID_VOCAB_MAPPING, "@value must be an absolute IRI"); @@ -225,12 +225,12 @@ else if (context instanceof String) { } // 3.6 - if (((Map) context).containsKey("@language")) { - final Object value = ((Map) context).get("@language"); + if (((Map) context).containsKey(JsonLdConsts.LANGUAGE)) { + final Object value = ((Map) context).get(JsonLdConsts.LANGUAGE); if (value == null) { - result.remove("@language"); + result.remove(JsonLdConsts.LANGUAGE); } else if (value instanceof String) { - result.put("@language", ((String) value).toLowerCase()); + result.put(JsonLdConsts.LANGUAGE, ((String) value).toLowerCase()); } else { throw new JsonLdError(Error.INVALID_DEFAULT_LANGUAGE, value); } @@ -239,7 +239,7 @@ else if (context instanceof String) { // 3.7 final Map defined = new LinkedHashMap(); for (final String key : ((Map) context).keySet()) { - if ("@base".equals(key) || "@vocab".equals(key) || "@language".equals(key)) { + if (JsonLdConsts.BASE.equals(key) || JsonLdConsts.VOCAB.equals(key) || JsonLdConsts.LANGUAGE.equals(key)) { continue; } result.createTermDefinition((Map) context, key, defined); @@ -281,15 +281,15 @@ private void createTermDefinition(Map context, String term, this.termDefinitions.remove(term); Object value = context.get(term); if (value == null - || (value instanceof Map && ((Map) value).containsKey("@id") && ((Map) value) - .get("@id") == null)) { + || (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.ID) && ((Map) value) + .get(JsonLdConsts.ID) == null)) { this.termDefinitions.put(term, null); defined.put(term, true); return; } if (value instanceof String) { - value = newMap("@id", value); + value = newMap(JsonLdConsts.ID, value); } if (!(value instanceof Map)) { @@ -303,13 +303,13 @@ private void createTermDefinition(Map context, String term, final Map definition = newMap(); // 10) - if (val.containsKey("@type")) { - if (!(val.get("@type") instanceof String)) { - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, val.get("@type")); + if (val.containsKey(JsonLdConsts.TYPE)) { + if (!(val.get(JsonLdConsts.TYPE) instanceof String)) { + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, val.get(JsonLdConsts.TYPE)); } - String type = (String) val.get("@type"); + String type = (String) val.get(JsonLdConsts.TYPE); try { - type = this.expandIri((String) val.get("@type"), false, true, context, defined); + type = this.expandIri((String) val.get(JsonLdConsts.TYPE), false, true, context, defined); } catch (final JsonLdError error) { if (error.getType() != Error.INVALID_IRI_MAPPING) { throw error; @@ -318,64 +318,64 @@ private void createTermDefinition(Map context, String term, } // TODO: fix check for absoluteIri (blank nodes shouldn't count, at // least not here!) - if ("@id".equals(type) || "@vocab".equals(type) - || (!type.startsWith("_:") && JsonLdUtils.isAbsoluteIri(type))) { - definition.put("@type", type); + if (JsonLdConsts.ID.equals(type) || JsonLdConsts.VOCAB.equals(type) + || (!type.startsWith(JsonLdConsts.BLANK_NODE_PREFIX) && JsonLdUtils.isAbsoluteIri(type))) { + definition.put(JsonLdConsts.TYPE, type); } else { throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); } } // 11) - if (val.containsKey("@reverse")) { - if (val.containsKey("@id")) { + if (val.containsKey(JsonLdConsts.REVERSE)) { + if (val.containsKey(JsonLdConsts.ID)) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, val); } - if (!(val.get("@reverse") instanceof String)) { + if (!(val.get(JsonLdConsts.REVERSE) instanceof String)) { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Expected String for @reverse value. got " - + (val.get("@reverse") == null ? "null" : val.get("@reverse") + + (val.get(JsonLdConsts.REVERSE) == null ? "null" : val.get(JsonLdConsts.REVERSE) .getClass())); } - final String reverse = this.expandIri((String) val.get("@reverse"), false, true, + final String reverse = this.expandIri((String) val.get(JsonLdConsts.REVERSE), false, true, context, defined); if (!JsonLdUtils.isAbsoluteIri(reverse)) { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Non-absolute @reverse IRI: " + reverse); } - definition.put("@id", reverse); - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (container == null || "@set".equals(container) || "@index".equals(container)) { - definition.put("@container", container); + definition.put(JsonLdConsts.ID, reverse); + if (val.containsKey(JsonLdConsts.CONTAINER)) { + final String container = (String) val.get(JsonLdConsts.CONTAINER); + if (container == null || JsonLdConsts.SET.equals(container) || JsonLdConsts.INDEX.equals(container)) { + definition.put(JsonLdConsts.CONTAINER, container); } else { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, "reverse properties only support set- and index-containers"); } } - definition.put("@reverse", true); + definition.put(JsonLdConsts.REVERSE, true); this.termDefinitions.put(term, definition); defined.put(term, true); return; } // 12) - definition.put("@reverse", false); + definition.put(JsonLdConsts.REVERSE, false); // 13) - if (val.get("@id") != null && !term.equals(val.get("@id"))) { - if (!(val.get("@id") instanceof String)) { + if (val.get(JsonLdConsts.ID) != null && !term.equals(val.get(JsonLdConsts.ID))) { + if (!(val.get(JsonLdConsts.ID) instanceof String)) { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "expected value of @id to be a string"); } - final String res = this.expandIri((String) val.get("@id"), false, true, context, + final String res = this.expandIri((String) val.get(JsonLdConsts.ID), false, true, context, defined); if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { - if ("@context".equals(res)) { + if (JsonLdConsts.CONTEXT.equals(res)) { throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, "cannot alias @context"); } - definition.put("@id", res); + definition.put(JsonLdConsts.ID, res); } else { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "resulting IRI mapping should be a keyword, absolute IRI or blank node"); @@ -391,35 +391,35 @@ else if (term.indexOf(":") >= 0) { this.createTermDefinition(context, prefix, defined); } if (termDefinitions.containsKey(prefix)) { - definition.put("@id", - ((Map) termDefinitions.get(prefix)).get("@id") + suffix); + definition.put(JsonLdConsts.ID, + ((Map) termDefinitions.get(prefix)).get(JsonLdConsts.ID) + suffix); } else { - definition.put("@id", term); + definition.put(JsonLdConsts.ID, term); } // 15) - } else if (this.containsKey("@vocab")) { - definition.put("@id", this.get("@vocab") + term); + } else if (this.containsKey(JsonLdConsts.VOCAB)) { + definition.put(JsonLdConsts.ID, this.get(JsonLdConsts.VOCAB) + term); } else { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "relative term definition without vocab mapping"); } // 16) - if (val.containsKey("@container")) { - final String container = (String) val.get("@container"); - if (!"@list".equals(container) && !"@set".equals(container) - && !"@index".equals(container) && !"@language".equals(container)) { + if (val.containsKey(JsonLdConsts.CONTAINER)) { + final String container = (String) val.get(JsonLdConsts.CONTAINER); + if (!JsonLdConsts.LIST.equals(container) && !JsonLdConsts.SET.equals(container) + && !JsonLdConsts.INDEX.equals(container) && !JsonLdConsts.LANGUAGE.equals(container)) { throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, "@container must be either @list, @set, @index, or @language"); } - definition.put("@container", container); + definition.put(JsonLdConsts.CONTAINER, container); } // 17) - if (val.containsKey("@language") && !val.containsKey("@type")) { - if (val.get("@language") == null || val.get("@language") instanceof String) { - final String language = (String) val.get("@language"); - definition.put("@language", language != null ? language.toLowerCase() : null); + if (val.containsKey(JsonLdConsts.LANGUAGE) && !val.containsKey(JsonLdConsts.TYPE)) { + if (val.get(JsonLdConsts.LANGUAGE) == null || val.get(JsonLdConsts.LANGUAGE) instanceof String) { + final String language = (String) val.get(JsonLdConsts.LANGUAGE); + definition.put(JsonLdConsts.LANGUAGE, language != null ? language.toLowerCase() : null); } else { throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, "@language must be a string or null"); @@ -460,7 +460,7 @@ String expandIri(String value, boolean relative, boolean vocab, Map td = (LinkedHashMap) this.termDefinitions .get(value); if (td != null) { - return (String) td.get("@id"); + return (String) td.get(JsonLdConsts.ID); } else { return null; } @@ -483,18 +483,18 @@ String expandIri(String value, boolean relative, boolean vocab, Map) this.termDefinitions.get(prefix)) - .get("@id") + suffix; + .get(JsonLdConsts.ID) + suffix; } // 4.5) return value; } // 5) - if (vocab && this.containsKey("@vocab")) { - return this.get("@vocab") + value; + if (vocab && this.containsKey(JsonLdConsts.VOCAB)) { + return this.get(JsonLdConsts.VOCAB) + value; } // 6) else if (relative) { - return JsonLdUrl.resolve((String) this.get("@base"), value); + return JsonLdUrl.resolve((String) this.get(JsonLdConsts.BASE), value); } else if (context != null && JsonLdUtils.isRelativeIri(value)) { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "not an absolute IRI: " + value); } @@ -531,62 +531,62 @@ String compactIri(String iri, Object value, boolean relativeToVocab, boolean rev // 2) if (relativeToVocab && getInverse().containsKey(iri)) { // 2.1) - String defaultLanguage = (String) this.get("@language"); + String defaultLanguage = (String) this.get(JsonLdConsts.LANGUAGE); if (defaultLanguage == null) { - defaultLanguage = "@none"; + defaultLanguage = JsonLdConsts.NONE; } // 2.2) final List containers = new ArrayList(); // 2.3) - String typeLanguage = "@language"; - String typeLanguageValue = "@null"; + String typeLanguage = JsonLdConsts.LANGUAGE; + String typeLanguageValue = JsonLdConsts.NULL; // 2.4) - if (value instanceof Map && ((Map) value).containsKey("@index")) { - containers.add("@index"); + if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.INDEX)) { + containers.add(JsonLdConsts.INDEX); } // 2.5) if (reverse) { - typeLanguage = "@type"; - typeLanguageValue = "@reverse"; - containers.add("@set"); + typeLanguage = JsonLdConsts.TYPE; + typeLanguageValue = JsonLdConsts.REVERSE; + containers.add(JsonLdConsts.SET); } // 2.6) - else if (value instanceof Map && ((Map) value).containsKey("@list")) { + else if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.LIST)) { // 2.6.1) - if (!((Map) value).containsKey("@index")) { - containers.add("@list"); + if (!((Map) value).containsKey(JsonLdConsts.INDEX)) { + containers.add(JsonLdConsts.LIST); } // 2.6.2) - final List list = (List) ((Map) value).get("@list"); + final List list = (List) ((Map) value).get(JsonLdConsts.LIST); // 2.6.3) String commonLanguage = (list.size() == 0) ? defaultLanguage : null; String commonType = null; // 2.6.4) for (final Object item : list) { // 2.6.4.1) - String itemLanguage = "@none"; - String itemType = "@none"; + String itemLanguage = JsonLdConsts.NONE; + String itemType = JsonLdConsts.NONE; // 2.6.4.2) if (JsonLdUtils.isValue(item)) { // 2.6.4.2.1) - if (((Map) item).containsKey("@language")) { - itemLanguage = (String) ((Map) item).get("@language"); + if (((Map) item).containsKey(JsonLdConsts.LANGUAGE)) { + itemLanguage = (String) ((Map) item).get(JsonLdConsts.LANGUAGE); } // 2.6.4.2.2) - else if (((Map) item).containsKey("@type")) { - itemType = (String) ((Map) item).get("@type"); + else if (((Map) item).containsKey(JsonLdConsts.TYPE)) { + itemType = (String) ((Map) item).get(JsonLdConsts.TYPE); } // 2.6.4.2.3) else { - itemLanguage = "@null"; + itemLanguage = JsonLdConsts.NULL; } } // 2.6.4.3) else { - itemType = "@id"; + itemType = JsonLdConsts.ID; } // 2.6.4.4) if (commonLanguage == null) { @@ -594,7 +594,7 @@ else if (((Map) item).containsKey("@type")) { } // 2.6.4.5) else if (!commonLanguage.equals(itemLanguage) && JsonLdUtils.isValue(item)) { - commonLanguage = "@none"; + commonLanguage = JsonLdConsts.NONE; } // 2.6.4.6) if (commonType == null) { @@ -602,20 +602,20 @@ else if (!commonLanguage.equals(itemLanguage) && JsonLdUtils.isValue(item)) { } // 2.6.4.7) else if (!commonType.equals(itemType)) { - commonType = "@none"; + commonType = JsonLdConsts.NONE; } // 2.6.4.8) - if ("@none".equals(commonLanguage) && "@none".equals(commonType)) { + if (JsonLdConsts.NONE.equals(commonLanguage) && JsonLdConsts.NONE.equals(commonType)) { break; } } // 2.6.5) - commonLanguage = (commonLanguage != null) ? commonLanguage : "@none"; + commonLanguage = (commonLanguage != null) ? commonLanguage : JsonLdConsts.NONE; // 2.6.6) - commonType = (commonType != null) ? commonType : "@none"; + commonType = (commonType != null) ? commonType : JsonLdConsts.NONE; // 2.6.7) - if (!"@none".equals(commonType)) { - typeLanguage = "@type"; + if (!JsonLdConsts.NONE.equals(commonType)) { + typeLanguage = JsonLdConsts.TYPE; typeLanguageValue = commonType; } // 2.6.8) @@ -626,64 +626,64 @@ else if (!commonType.equals(itemType)) { // 2.7) else { // 2.7.1) - if (value instanceof Map && ((Map) value).containsKey("@value")) { + if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.VALUE)) { // 2.7.1.1) - if (((Map) value).containsKey("@language") - && !((Map) value).containsKey("@index")) { - containers.add("@language"); - typeLanguageValue = (String) ((Map) value).get("@language"); + if (((Map) value).containsKey(JsonLdConsts.LANGUAGE) + && !((Map) value).containsKey(JsonLdConsts.INDEX)) { + containers.add(JsonLdConsts.LANGUAGE); + typeLanguageValue = (String) ((Map) value).get(JsonLdConsts.LANGUAGE); } // 2.7.1.2) - else if (((Map) value).containsKey("@type")) { - typeLanguage = "@type"; - typeLanguageValue = (String) ((Map) value).get("@type"); + else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { + typeLanguage = JsonLdConsts.TYPE; + typeLanguageValue = (String) ((Map) value).get(JsonLdConsts.TYPE); } } // 2.7.2) else { - typeLanguage = "@type"; - typeLanguageValue = "@id"; + typeLanguage = JsonLdConsts.TYPE; + typeLanguageValue = JsonLdConsts.ID; } // 2.7.3) - containers.add("@set"); + containers.add(JsonLdConsts.SET); } // 2.8) - containers.add("@none"); + containers.add(JsonLdConsts.NONE); // 2.9) if (typeLanguageValue == null) { - typeLanguageValue = "@null"; + typeLanguageValue = JsonLdConsts.NULL; } // 2.10) final List preferredValues = new ArrayList(); // 2.11) - if ("@reverse".equals(typeLanguageValue)) { - preferredValues.add("@reverse"); + if (JsonLdConsts.REVERSE.equals(typeLanguageValue)) { + preferredValues.add(JsonLdConsts.REVERSE); } // 2.12) - if (("@reverse".equals(typeLanguageValue) || "@id".equals(typeLanguageValue)) - && (value instanceof Map) && ((Map) value).containsKey("@id")) { + if ((JsonLdConsts.REVERSE.equals(typeLanguageValue) || JsonLdConsts.ID.equals(typeLanguageValue)) + && (value instanceof Map) && ((Map) value).containsKey(JsonLdConsts.ID)) { // 2.12.1) final String result = this.compactIri( - (String) ((Map) value).get("@id"), null, true, true); + (String) ((Map) value).get(JsonLdConsts.ID), null, true, true); if (termDefinitions.containsKey(result) - && ((Map) termDefinitions.get(result)).containsKey("@id") - && ((Map) value).get("@id").equals( - ((Map) termDefinitions.get(result)).get("@id"))) { - preferredValues.add("@vocab"); - preferredValues.add("@id"); + && ((Map) termDefinitions.get(result)).containsKey(JsonLdConsts.ID) + && ((Map) value).get(JsonLdConsts.ID).equals( + ((Map) termDefinitions.get(result)).get(JsonLdConsts.ID))) { + preferredValues.add(JsonLdConsts.VOCAB); + preferredValues.add(JsonLdConsts.ID); } // 2.12.2) else { - preferredValues.add("@id"); - preferredValues.add("@vocab"); + preferredValues.add(JsonLdConsts.ID); + preferredValues.add(JsonLdConsts.VOCAB); } } // 2.13) else { preferredValues.add(typeLanguageValue); } - preferredValues.add("@none"); + preferredValues.add(JsonLdConsts.NONE); // 2.14) final String term = selectTerm(iri, containers, typeLanguage, preferredValues); @@ -694,9 +694,9 @@ else if (((Map) value).containsKey("@type")) { } // 3) - if (relativeToVocab && this.containsKey("@vocab")) { + if (relativeToVocab && this.containsKey(JsonLdConsts.VOCAB)) { // determine if vocab is a prefix of the iri - final String vocab = (String) this.get("@vocab"); + final String vocab = (String) this.get(JsonLdConsts.VOCAB); // 3.1) if (iri.indexOf(vocab) == 0 && !iri.equals(vocab)) { // use suffix as relative iri if it is not a term in the @@ -719,14 +719,14 @@ else if (((Map) value).containsKey("@type")) { continue; } // 5.2) - if (termDefinition == null || iri.equals(termDefinition.get("@id")) - || !iri.startsWith((String) termDefinition.get("@id"))) { + if (termDefinition == null || iri.equals(termDefinition.get(JsonLdConsts.ID)) + || !iri.startsWith((String) termDefinition.get(JsonLdConsts.ID))) { continue; } // 5.3) final String candidate = term + ":" - + iri.substring(((String) termDefinition.get("@id")).length()); + + iri.substring(((String) termDefinition.get(JsonLdConsts.ID)).length()); // 5.4) compactIRI = _iriCompactionStep5point4(iri, value, compactIRI, candidate, termDefinitions); } @@ -738,7 +738,7 @@ else if (((Map) value).containsKey("@type")) { // 7) if (!relativeToVocab) { - return JsonLdUrl.removeBase(this.get("@base"), iri); + return JsonLdUrl.removeBase(this.get(JsonLdConsts.BASE), iri); } // 8) @@ -755,7 +755,7 @@ public static String _iriCompactionStep5point4(String iri, Object value, String boolean condition2 = (!termDefinitions.containsKey(candidate) || (iri .equals(((Map) termDefinitions.get(candidate)) - .get("@id")) && value == null)); + .get(JsonLdConsts.ID)) && value == null)); if (condition1 && condition2) { compactIRI = candidate; @@ -790,7 +790,7 @@ public Map getPrefixes(boolean onlyCommonPrefixes) { if (termDefinition == null) { continue; } - final String id = (String) termDefinition.get("@id"); + final String id = (String) termDefinition.get(JsonLdConsts.ID); if (id == null) { continue; } @@ -842,9 +842,9 @@ public Map getInverse() { inverse = newMap(); // 2) - String defaultLanguage = (String) this.get("@language"); + String defaultLanguage = (String) this.get(JsonLdConsts.LANGUAGE); if (defaultLanguage == null) { - defaultLanguage = "@none"; + defaultLanguage = JsonLdConsts.NONE; } // create term selections for each mapping in the context, ordererd by @@ -865,13 +865,13 @@ public int compare(String a, String b) { } // 3.2) - String container = (String) definition.get("@container"); + String container = (String) definition.get(JsonLdConsts.CONTAINER); if (container == null) { - container = "@none"; + container = JsonLdConsts.NONE; } // 3.3) - final String iri = (String) definition.get("@id"); + final String iri = (String) definition.get(JsonLdConsts.ID); // 3.4 + 3.5) Map containerMap = (Map) inverse.get(iri); @@ -884,32 +884,32 @@ public int compare(String a, String b) { Map typeLanguageMap = (Map) containerMap.get(container); if (typeLanguageMap == null) { typeLanguageMap = newMap(); - typeLanguageMap.put("@language", newMap()); - typeLanguageMap.put("@type", newMap()); + typeLanguageMap.put(JsonLdConsts.LANGUAGE, newMap()); + typeLanguageMap.put(JsonLdConsts.TYPE, newMap()); containerMap.put(container, typeLanguageMap); } // 3.8) - if (Boolean.TRUE.equals(definition.get("@reverse"))) { + if (Boolean.TRUE.equals(definition.get(JsonLdConsts.REVERSE))) { final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey("@reverse")) { - typeMap.put("@reverse", term); + .get(JsonLdConsts.TYPE); + if (!typeMap.containsKey(JsonLdConsts.REVERSE)) { + typeMap.put(JsonLdConsts.REVERSE, term); } // 3.9) - } else if (definition.containsKey("@type")) { + } else if (definition.containsKey(JsonLdConsts.TYPE)) { final Map typeMap = (Map) typeLanguageMap - .get("@type"); - if (!typeMap.containsKey(definition.get("@type"))) { - typeMap.put((String) definition.get("@type"), term); + .get(JsonLdConsts.TYPE); + if (!typeMap.containsKey(definition.get(JsonLdConsts.TYPE))) { + typeMap.put((String) definition.get(JsonLdConsts.TYPE), term); } // 3.10) - } else if (definition.containsKey("@language")) { + } else if (definition.containsKey(JsonLdConsts.LANGUAGE)) { final Map languageMap = (Map) typeLanguageMap - .get("@language"); - String language = (String) definition.get("@language"); + .get(JsonLdConsts.LANGUAGE); + String language = (String) definition.get(JsonLdConsts.LANGUAGE); if (language == null) { - language = "@null"; + language = JsonLdConsts.NULL; } if (!languageMap.containsKey(language)) { languageMap.put(language, term); @@ -918,21 +918,21 @@ public int compare(String a, String b) { } else { // 3.11.1) final Map languageMap = (Map) typeLanguageMap - .get("@language"); + .get(JsonLdConsts.LANGUAGE); // 3.11.2) - if (!languageMap.containsKey("@language")) { - languageMap.put("@language", term); + if (!languageMap.containsKey(JsonLdConsts.LANGUAGE)) { + languageMap.put(JsonLdConsts.LANGUAGE, term); } // 3.11.3) - if (!languageMap.containsKey("@none")) { - languageMap.put("@none", term); + if (!languageMap.containsKey(JsonLdConsts.NONE)) { + languageMap.put(JsonLdConsts.NONE, term); } // 3.11.4) final Map typeMap = (Map) typeLanguageMap - .get("@type"); + .get(JsonLdConsts.TYPE); // 3.11.5) - if (!typeMap.containsKey("@none")) { - typeMap.put("@none", term); + if (!typeMap.containsKey(JsonLdConsts.NONE)) { + typeMap.put(JsonLdConsts.NONE, term); } } } @@ -992,8 +992,8 @@ private String selectTerm(String iri, List containers, String typeLangua * @return The container mapping */ public String getContainer(String property) { - if ("@graph".equals(property)) { - return "@set"; + if (JsonLdConsts.GRAPH.equals(property)) { + return JsonLdConsts.SET; } if (JsonLdUtils.isKeyword(property)) { return property; @@ -1002,7 +1002,7 @@ public String getContainer(String property) { if (td == null) { return null; } - return (String) td.get("@container"); + return (String) td.get(JsonLdConsts.CONTAINER); } public Boolean isReverseProperty(String property) { @@ -1010,7 +1010,7 @@ public Boolean isReverseProperty(String property) { if (td == null) { return false; } - final Object reverse = td.get("@reverse"); + final Object reverse = td.get(JsonLdConsts.REVERSE); return reverse != null && (Boolean) reverse; } @@ -1019,7 +1019,7 @@ private String getTypeMapping(String property) { if (td == null) { return null; } - return (String) td.get("@type"); + return (String) td.get(JsonLdConsts.TYPE); } private String getLanguageMapping(String property) { @@ -1027,7 +1027,7 @@ private String getLanguageMapping(String property) { if (td == null) { return null; } - return (String) td.get("@language"); + return (String) td.get(JsonLdConsts.LANGUAGE); } Map getTermDefinition(String key) { @@ -1038,36 +1038,36 @@ public Object expandValue(String activeProperty, Object value) throws JsonLdErro final Map rval = newMap(); final Map td = getTermDefinition(activeProperty); // 1) - if (td != null && "@id".equals(td.get("@type"))) { + if (td != null && JsonLdConsts.ID.equals(td.get(JsonLdConsts.TYPE))) { // TODO: i'm pretty sure value should be a string if the @type is // @id - rval.put("@id", expandIri(value.toString(), true, false, null, null)); + rval.put(JsonLdConsts.ID, expandIri(value.toString(), true, false, null, null)); return rval; } // 2) - if (td != null && "@vocab".equals(td.get("@type"))) { + if (td != null && JsonLdConsts.VOCAB.equals(td.get(JsonLdConsts.TYPE))) { // TODO: same as above - rval.put("@id", expandIri(value.toString(), true, true, null, null)); + rval.put(JsonLdConsts.ID, expandIri(value.toString(), true, true, null, null)); return rval; } // 3) - rval.put("@value", value); + rval.put(JsonLdConsts.VALUE, value); // 4) - if (td != null && td.containsKey("@type")) { - rval.put("@type", td.get("@type")); + if (td != null && td.containsKey(JsonLdConsts.TYPE)) { + rval.put(JsonLdConsts.TYPE, td.get(JsonLdConsts.TYPE)); } // 5) else if (value instanceof String) { // 5.1) - if (td != null && td.containsKey("@language")) { - final String lang = (String) td.get("@language"); + if (td != null && td.containsKey(JsonLdConsts.LANGUAGE)) { + final String lang = (String) td.get(JsonLdConsts.LANGUAGE); if (lang != null) { - rval.put("@language", lang); + rval.put(JsonLdConsts.LANGUAGE, lang); } } // 5.2) - else if (this.get("@language") != null) { - rval.put("@language", this.get("@language")); + else if (this.get(JsonLdConsts.LANGUAGE) != null) { + rval.put(JsonLdConsts.LANGUAGE, this.get(JsonLdConsts.LANGUAGE)); } } return rval; @@ -1080,42 +1080,42 @@ public Object getContextValue(String activeProperty, String string) throws JsonL public Map serialize() { final Map ctx = newMap(); - if (this.get("@base") != null && !this.get("@base").equals(options.getBase())) { - ctx.put("@base", this.get("@base")); + if (this.get(JsonLdConsts.BASE) != null && !this.get(JsonLdConsts.BASE).equals(options.getBase())) { + ctx.put(JsonLdConsts.BASE, this.get(JsonLdConsts.BASE)); } - if (this.get("@language") != null) { - ctx.put("@language", this.get("@language")); + if (this.get(JsonLdConsts.LANGUAGE) != null) { + ctx.put(JsonLdConsts.LANGUAGE, this.get(JsonLdConsts.LANGUAGE)); } - if (this.get("@vocab") != null) { - ctx.put("@vocab", this.get("@vocab")); + if (this.get(JsonLdConsts.VOCAB) != null) { + ctx.put(JsonLdConsts.VOCAB, this.get(JsonLdConsts.VOCAB)); } for (final String term : termDefinitions.keySet()) { final Map definition = (Map) termDefinitions.get(term); - if (definition.get("@language") == null - && definition.get("@container") == null - && definition.get("@type") == null - && (definition.get("@reverse") == null || Boolean.FALSE.equals(definition - .get("@reverse")))) { - final String cid = this.compactIri((String) definition.get("@id")); - ctx.put(term, term.equals(cid) ? definition.get("@id") : cid); + if (definition.get(JsonLdConsts.LANGUAGE) == null + && definition.get(JsonLdConsts.CONTAINER) == null + && definition.get(JsonLdConsts.TYPE) == null + && (definition.get(JsonLdConsts.REVERSE) == null || Boolean.FALSE.equals(definition + .get(JsonLdConsts.REVERSE)))) { + final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); + ctx.put(term, term.equals(cid) ? definition.get(JsonLdConsts.ID) : cid); } else { final Map defn = newMap(); - final String cid = this.compactIri((String) definition.get("@id")); - final Boolean reverseProperty = Boolean.TRUE.equals(definition.get("@reverse")); + final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); + final Boolean reverseProperty = Boolean.TRUE.equals(definition.get(JsonLdConsts.REVERSE)); if (!(term.equals(cid) && !reverseProperty)) { - defn.put(reverseProperty ? "@reverse" : "@id", cid); + defn.put(reverseProperty ? JsonLdConsts.REVERSE : JsonLdConsts.ID, cid); } - final String typeMapping = (String) definition.get("@type"); + final String typeMapping = (String) definition.get(JsonLdConsts.TYPE); if (typeMapping != null) { - defn.put("@type", JsonLdUtils.isKeyword(typeMapping) ? typeMapping + defn.put(JsonLdConsts.TYPE, JsonLdUtils.isKeyword(typeMapping) ? typeMapping : compactIri(typeMapping, true)); } - if (definition.get("@container") != null) { - defn.put("@container", definition.get("@container")); + if (definition.get(JsonLdConsts.CONTAINER) != null) { + defn.put(JsonLdConsts.CONTAINER, definition.get(JsonLdConsts.CONTAINER)); } - final Object lang = definition.get("@language"); - if (definition.get("@language") != null) { - defn.put("@language", Boolean.FALSE.equals(lang) ? null : lang); + final Object lang = definition.get(JsonLdConsts.LANGUAGE); + if (definition.get(JsonLdConsts.LANGUAGE) != null) { + defn.put(JsonLdConsts.LANGUAGE, Boolean.FALSE.equals(lang) ? null : lang); } ctx.put(term, defn); } @@ -1123,7 +1123,7 @@ public Map serialize() { final Map rval = newMap(); if (!(ctx == null || ctx.isEmpty())) { - rval.put("@context", ctx); + rval.put(JsonLdConsts.CONTEXT, ctx); } return rval; } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 6911ca37..612ebaef 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -182,14 +182,14 @@ public Object compact(Context activeCtx, String activeProperty, Object element, final Map elem = (Map) element; // 4 - if (elem.containsKey("@value") || elem.containsKey("@id")) { + if (elem.containsKey(JsonLdConsts.VALUE) || elem.containsKey(JsonLdConsts.ID)) { final Object compactedValue = activeCtx.compactValue(activeProperty, elem); if (!(compactedValue instanceof Map || compactedValue instanceof List)) { return compactedValue; } } // 5) - final boolean insideReverse = ("@reverse".equals(activeProperty)); + final boolean insideReverse = (JsonLdConsts.REVERSE.equals(activeProperty)); // 6) final Map result = newMap(); @@ -200,13 +200,13 @@ public Object compact(Context activeCtx, String activeProperty, Object element, final Object expandedValue = elem.get(expandedProperty); // 7.1) - if ("@id".equals(expandedProperty) || "@type".equals(expandedProperty)) { + if (JsonLdConsts.ID.equals(expandedProperty) || JsonLdConsts.TYPE.equals(expandedProperty)) { Object compactedValue; // 7.1.1) if (expandedValue instanceof String) { compactedValue = activeCtx.compactIri((String) expandedValue, - "@type".equals(expandedProperty)); + JsonLdConsts.TYPE.equals(expandedProperty)); } // 7.1.2) else { @@ -235,10 +235,10 @@ public Object compact(Context activeCtx, String activeProperty, Object element, } // 7.2) - if ("@reverse".equals(expandedProperty)) { + if (JsonLdConsts.REVERSE.equals(expandedProperty)) { // 7.2.1) final Map compactedValue = (Map) compact( - activeCtx, "@reverse", expandedValue, compactArrays); + activeCtx, JsonLdConsts.REVERSE, expandedValue, compactArrays); // 7.2.2) // Note: Must create a new set to avoid modifying the set we @@ -248,7 +248,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, // 7.2.2.1) if (activeCtx.isReverseProperty(property)) { // 7.2.2.1.1) - if (("@set".equals(activeCtx.getContainer(property)) || !compactArrays) + if ((JsonLdConsts.SET.equals(activeCtx.getContainer(property)) || !compactArrays) && !(value instanceof List)) { final List tmp = new ArrayList(); tmp.add(value); @@ -278,7 +278,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, // 7.2.3) if (!compactedValue.isEmpty()) { // 7.2.3.1) - final String alias = activeCtx.compactIri("@reverse", true); + final String alias = activeCtx.compactIri(JsonLdConsts.REVERSE, true); // 7.2.3.2) result.put(alias, compactedValue); } @@ -287,13 +287,13 @@ public Object compact(Context activeCtx, String activeProperty, Object element, } // 7.3) - if ("@index".equals(expandedProperty) - && "@index".equals(activeCtx.getContainer(activeProperty))) { + if (JsonLdConsts.INDEX.equals(expandedProperty) + && JsonLdConsts.INDEX.equals(activeCtx.getContainer(activeProperty))) { continue; } // 7.4) - else if ("@index".equals(expandedProperty) || "@value".equals(expandedProperty) - || "@language".equals(expandedProperty)) { + else if (JsonLdConsts.INDEX.equals(expandedProperty) || JsonLdConsts.VALUE.equals(expandedProperty) + || JsonLdConsts.LANGUAGE.equals(expandedProperty)) { // 7.4.1) final String alias = activeCtx.compactIri(expandedProperty, true); // 7.4.2) @@ -332,10 +332,10 @@ else if ("@index".equals(expandedProperty) || "@value".equals(expandedProperty) // get @list value if appropriate final boolean isList = (expandedItem instanceof Map && ((Map) expandedItem) - .containsKey("@list")); + .containsKey(JsonLdConsts.LIST)); Object list = null; if (isList) { - list = ((Map) expandedItem).get("@list"); + list = ((Map) expandedItem).get(JsonLdConsts.LIST); } // 7.6.3) @@ -351,20 +351,20 @@ else if ("@index".equals(expandedProperty) || "@value".equals(expandedProperty) compactedItem = tmp; } // 7.6.4.2) - if (!"@list".equals(container)) { + if (!JsonLdConsts.LIST.equals(container)) { // 7.6.4.2.1) final Map wrapper = newMap(); // TODO: SPEC: no mention of vocab = true - wrapper.put(activeCtx.compactIri("@list", true), compactedItem); + wrapper.put(activeCtx.compactIri(JsonLdConsts.LIST, true), compactedItem); compactedItem = wrapper; // 7.6.4.2.2) - if (((Map) expandedItem).containsKey("@index")) { + if (((Map) expandedItem).containsKey(JsonLdConsts.INDEX)) { ((Map) compactedItem).put( // TODO: SPEC: no mention of vocab = // true - activeCtx.compactIri("@index", true), - ((Map) expandedItem).get("@index")); + activeCtx.compactIri(JsonLdConsts.INDEX, true), + ((Map) expandedItem).get(JsonLdConsts.INDEX)); } } // 7.6.4.3) @@ -375,7 +375,7 @@ else if (result.containsKey(itemActiveProperty)) { } // 7.6.5) - if ("@language".equals(container) || "@index".equals(container)) { + if (JsonLdConsts.LANGUAGE.equals(container) || JsonLdConsts.INDEX.equals(container)) { // 7.6.5.1) Map mapObject; if (result.containsKey(itemActiveProperty)) { @@ -386,10 +386,10 @@ else if (result.containsKey(itemActiveProperty)) { } // 7.6.5.2) - if ("@language".equals(container) + if (JsonLdConsts.LANGUAGE.equals(container) && (compactedItem instanceof Map && ((Map) compactedItem) - .containsKey("@value"))) { - compactedItem = ((Map) compactedItem).get("@value"); + .containsKey(JsonLdConsts.VALUE))) { + compactedItem = ((Map) compactedItem).get(JsonLdConsts.VALUE); } // 7.6.5.3) @@ -412,8 +412,8 @@ else if (result.containsKey(itemActiveProperty)) { // 7.6.6) else { // 7.6.6.1) - final Boolean check = (!compactArrays || "@set".equals(container) - || "@list".equals(container) || "@list".equals(expandedProperty) || "@graph" + final Boolean check = (!compactArrays || JsonLdConsts.SET.equals(container) + || JsonLdConsts.LIST.equals(container) || JsonLdConsts.LIST.equals(expandedProperty) || JsonLdConsts.GRAPH .equals(expandedProperty)) && (!(compactedItem instanceof List)); if (check) { @@ -507,10 +507,10 @@ public Object expand(Context activeCtx, String activeProperty, Object element) // 3.2.1) final Object v = expand(activeCtx, activeProperty, item); // 3.2.2) - if (("@list".equals(activeProperty) || "@list".equals(activeCtx + if ((JsonLdConsts.LIST.equals(activeProperty) || JsonLdConsts.LIST.equals(activeCtx .getContainer(activeProperty))) && (v instanceof List || (v instanceof Map && ((Map) v) - .containsKey("@list")))) { + .containsKey(JsonLdConsts.LIST)))) { throw new JsonLdError(Error.LIST_OF_LISTS, "lists of lists are not permitted."); } // 3.2.3) @@ -530,8 +530,8 @@ else if (element instanceof Map) { // access helper final Map elem = (Map) element; // 5) - if (elem.containsKey("@context")) { - activeCtx = activeCtx.parse(elem.get("@context")); + if (elem.containsKey(JsonLdConsts.CONTEXT)) { + activeCtx = activeCtx.parse(elem.get(JsonLdConsts.CONTEXT)); } // 6) Map result = newMap(); @@ -541,7 +541,7 @@ else if (element instanceof Map) { for (final String key : keys) { final Object value = elem.get(key); // 7.1) - if (key.equals("@context")) { + if (key.equals(JsonLdConsts.CONTEXT)) { continue; } // 7.2) @@ -555,7 +555,7 @@ else if (element instanceof Map) { // 7.4) if (isKeyword(expandedProperty)) { // 7.4.1) - if ("@reverse".equals(activeProperty)) { + if (JsonLdConsts.REVERSE.equals(activeProperty)) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_MAP, "a keyword cannot be used as a @reverse propery"); } @@ -565,7 +565,7 @@ else if (element instanceof Map) { + " already exists in result"); } // 7.4.3) - if ("@id".equals(expandedProperty)) { + if (JsonLdConsts.ID.equals(expandedProperty)) { if (!(value instanceof String)) { throw new JsonLdError(Error.INVALID_ID_VALUE, "value of @id must be a string"); @@ -574,7 +574,7 @@ else if (element instanceof Map) { .expandIri((String) value, true, false, null, null); } // 7.4.4) - else if ("@type".equals(expandedProperty)) { + else if (JsonLdConsts.TYPE.equals(expandedProperty)) { if (value instanceof List) { expandedValue = new ArrayList(); for (final Object v : (List) value) { @@ -602,23 +602,23 @@ else if (value instanceof Map) { } } // 7.4.5) - else if ("@graph".equals(expandedProperty)) { - expandedValue = expand(activeCtx, "@graph", value); + else if (JsonLdConsts.GRAPH.equals(expandedProperty)) { + expandedValue = expand(activeCtx, JsonLdConsts.GRAPH, value); } // 7.4.6) - else if ("@value".equals(expandedProperty)) { + else if (JsonLdConsts.VALUE.equals(expandedProperty)) { if (value != null && (value instanceof Map || value instanceof List)) { throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE, "value of " + expandedProperty + " must be a scalar or null"); } expandedValue = value; if (expandedValue == null) { - result.put("@value", null); + result.put(JsonLdConsts.VALUE, null); continue; } } // 7.4.7) - else if ("@language".equals(expandedProperty)) { + else if (JsonLdConsts.LANGUAGE.equals(expandedProperty)) { if (!(value instanceof String)) { throw new JsonLdError(Error.INVALID_LANGUAGE_TAGGED_STRING, "Value of " + expandedProperty + " must be a string"); @@ -626,7 +626,7 @@ else if ("@language".equals(expandedProperty)) { expandedValue = ((String) value).toLowerCase(); } // 7.4.8) - else if ("@index".equals(expandedProperty)) { + else if (JsonLdConsts.INDEX.equals(expandedProperty)) { if (!(value instanceof String)) { throw new JsonLdError(Error.INVALID_INDEX_VALUE, "Value of " + expandedProperty + " must be a string"); @@ -634,9 +634,9 @@ else if ("@index".equals(expandedProperty)) { expandedValue = value; } // 7.4.9) - else if ("@list".equals(expandedProperty)) { + else if (JsonLdConsts.LIST.equals(expandedProperty)) { // 7.4.9.1) - if (activeProperty == null || "@graph".equals(activeProperty)) { + if (activeProperty == null || JsonLdConsts.GRAPH.equals(activeProperty)) { continue; } // 7.4.9.2) @@ -651,29 +651,29 @@ else if ("@list".equals(expandedProperty)) { // 7.4.9.3) for (final Object o : (List) expandedValue) { - if (o instanceof Map && ((Map) o).containsKey("@list")) { + if (o instanceof Map && ((Map) o).containsKey(JsonLdConsts.LIST)) { throw new JsonLdError(Error.LIST_OF_LISTS, "A list may not contain another list"); } } } // 7.4.10) - else if ("@set".equals(expandedProperty)) { + else if (JsonLdConsts.SET.equals(expandedProperty)) { expandedValue = expand(activeCtx, activeProperty, value); } // 7.4.11) - else if ("@reverse".equals(expandedProperty)) { + else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { if (!(value instanceof Map)) { throw new JsonLdError(Error.INVALID_REVERSE_VALUE, "@reverse value must be an object"); } // 7.4.11.1) - expandedValue = expand(activeCtx, "@reverse", value); + expandedValue = expand(activeCtx, JsonLdConsts.REVERSE, value); // NOTE: algorithm assumes the result is a map // 7.4.11.2) - if (((Map) expandedValue).containsKey("@reverse")) { + if (((Map) expandedValue).containsKey(JsonLdConsts.REVERSE)) { final Map reverse = (Map) ((Map) expandedValue) - .get("@reverse"); + .get(JsonLdConsts.REVERSE); for (final String property : reverse.keySet()) { final Object item = reverse.get(property); // 7.4.11.2.1) @@ -691,18 +691,18 @@ else if ("@reverse".equals(expandedProperty)) { } // 7.4.11.3) if (((Map) expandedValue).size() > (((Map) expandedValue) - .containsKey("@reverse") ? 1 : 0)) { + .containsKey(JsonLdConsts.REVERSE) ? 1 : 0)) { // 7.4.11.3.1) - if (!result.containsKey("@reverse")) { - result.put("@reverse", newMap()); + if (!result.containsKey(JsonLdConsts.REVERSE)) { + result.put(JsonLdConsts.REVERSE, newMap()); } // 7.4.11.3.2) final Map reverseMap = (Map) result - .get("@reverse"); + .get(JsonLdConsts.REVERSE); // 7.4.11.3.3) for (final String property : ((Map) expandedValue) .keySet()) { - if ("@reverse".equals(property)) { + if (JsonLdConsts.REVERSE.equals(property)) { continue; } // 7.4.11.3.3.1) @@ -711,8 +711,8 @@ else if ("@reverse".equals(expandedProperty)) { for (final Object item : items) { // 7.4.11.3.3.1.1) if (item instanceof Map - && (((Map) item).containsKey("@value") || ((Map) item) - .containsKey("@list"))) { + && (((Map) item).containsKey(JsonLdConsts.VALUE) || ((Map) item) + .containsKey(JsonLdConsts.LIST))) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_VALUE); } // 7.4.11.3.3.1.2) @@ -728,11 +728,11 @@ else if ("@reverse".equals(expandedProperty)) { continue; } // TODO: SPEC no mention of @explicit etc in spec - else if ("@explicit".equals(expandedProperty) - || "@default".equals(expandedProperty) - || "@embed".equals(expandedProperty) - || "@embedChildren".equals(expandedProperty) - || "@omitDefault".equals(expandedProperty)) { + else if (JsonLdConsts.EXPLICIT.equals(expandedProperty) + || JsonLdConsts.DEFAULT.equals(expandedProperty) + || JsonLdConsts.EMBED.equals(expandedProperty) + || JsonLdConsts.EMBED_CHILDREN.equals(expandedProperty) + || JsonLdConsts.OMIT_DEFAULT.equals(expandedProperty)) { expandedValue = expand(activeCtx, expandedProperty, value); } // 7.4.12) @@ -743,7 +743,7 @@ else if ("@explicit".equals(expandedProperty) continue; } // 7.5 - else if ("@language".equals(activeCtx.getContainer(key)) && value instanceof Map) { + else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.5.1) expandedValue = new ArrayList(); // 7.5.2) @@ -764,14 +764,14 @@ else if ("@language".equals(activeCtx.getContainer(key)) && value instanceof Map } // 7.5.2.2.2) final Map tmp = newMap(); - tmp.put("@value", item); - tmp.put("@language", language.toLowerCase()); + tmp.put(JsonLdConsts.VALUE, item); + tmp.put(JsonLdConsts.LANGUAGE, language.toLowerCase()); ((List) expandedValue).add(tmp); } } } // 7.6) - else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { + else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.6.1) expandedValue = new ArrayList(); // 7.6.2) @@ -791,8 +791,8 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { // 7.6.2.3) for (final Map item : (List>) indexValue) { // 7.6.2.3.1) - if (!item.containsKey("@index")) { - item.put("@index", index); + if (!item.containsKey(JsonLdConsts.INDEX)) { + item.put(JsonLdConsts.INDEX, index); } // 7.6.2.3.2) ((List) expandedValue).add(item); @@ -808,27 +808,27 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { continue; } // 7.9) - if ("@list".equals(activeCtx.getContainer(key))) { + if (JsonLdConsts.LIST.equals(activeCtx.getContainer(key))) { if (!(expandedValue instanceof Map) - || !((Map) expandedValue).containsKey("@list")) { + || !((Map) expandedValue).containsKey(JsonLdConsts.LIST)) { Object tmp = expandedValue; if (!(tmp instanceof List)) { tmp = new ArrayList(); ((List) tmp).add(expandedValue); } expandedValue = newMap(); - ((Map) expandedValue).put("@list", tmp); + ((Map) expandedValue).put(JsonLdConsts.LIST, tmp); } } // 7.10) if (activeCtx.isReverseProperty(key)) { // 7.10.1) - if (!result.containsKey("@reverse")) { - result.put("@reverse", newMap()); + if (!result.containsKey(JsonLdConsts.REVERSE)) { + result.put(JsonLdConsts.REVERSE, newMap()); } // 7.10.2) final Map reverseMap = (Map) result - .get("@reverse"); + .get(JsonLdConsts.REVERSE); // 7.10.3) if (!(expandedValue instanceof List)) { final Object tmp = expandedValue; @@ -839,8 +839,8 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { for (final Object item : (List) expandedValue) { // 7.10.4.1) if (item instanceof Map - && (((Map) item).containsKey("@value") || ((Map) item) - .containsKey("@list"))) { + && (((Map) item).containsKey(JsonLdConsts.VALUE) || ((Map) item) + .containsKey(JsonLdConsts.LIST))) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_VALUE); } // 7.10.4.2) @@ -872,82 +872,82 @@ else if ("@index".equals(activeCtx.getContainer(key)) && value instanceof Map) { } } // 8) - if (result.containsKey("@value")) { + if (result.containsKey(JsonLdConsts.VALUE)) { // 8.1) // TODO: is this method faster than just using containsKey for // each? final Set keySet = new HashSet(result.keySet()); - keySet.remove("@value"); - keySet.remove("@index"); - final boolean langremoved = keySet.remove("@language"); - final boolean typeremoved = keySet.remove("@type"); + keySet.remove(JsonLdConsts.VALUE); + keySet.remove(JsonLdConsts.INDEX); + final boolean langremoved = keySet.remove(JsonLdConsts.LANGUAGE); + final boolean typeremoved = keySet.remove(JsonLdConsts.TYPE); if ((langremoved && typeremoved) || !keySet.isEmpty()) { throw new JsonLdError(Error.INVALID_VALUE_OBJECT, "value object has unknown keys"); } // 8.2) - final Object rval = result.get("@value"); + final Object rval = result.get(JsonLdConsts.VALUE); if (rval == null) { // nothing else is possible with result if we set it to // null, so simply return it return null; } // 8.3) - if (!(rval instanceof String) && result.containsKey("@language")) { + if (!(rval instanceof String) && result.containsKey(JsonLdConsts.LANGUAGE)) { throw new JsonLdError(Error.INVALID_LANGUAGE_TAGGED_VALUE, "when @language is used, @value must be a string"); } // 8.4) - else if (result.containsKey("@type")) { + else if (result.containsKey(JsonLdConsts.TYPE)) { // TODO: is this enough for "is an IRI" - if (!(result.get("@type") instanceof String) - || ((String) result.get("@type")).startsWith("_:") - || !((String) result.get("@type")).contains(":")) { + if (!(result.get(JsonLdConsts.TYPE) instanceof String) + || ((String) result.get(JsonLdConsts.TYPE)).startsWith("_:") + || !((String) result.get(JsonLdConsts.TYPE)).contains(":")) { throw new JsonLdError(Error.INVALID_TYPED_VALUE, "value of @type must be an IRI"); } } } // 9) - else if (result.containsKey("@type")) { - final Object rtype = result.get("@type"); + else if (result.containsKey(JsonLdConsts.TYPE)) { + final Object rtype = result.get(JsonLdConsts.TYPE); if (!(rtype instanceof List)) { final List tmp = new ArrayList(); tmp.add(rtype); - result.put("@type", tmp); + result.put(JsonLdConsts.TYPE, tmp); } } // 10) - else if (result.containsKey("@set") || result.containsKey("@list")) { + else if (result.containsKey(JsonLdConsts.SET) || result.containsKey(JsonLdConsts.LIST)) { // 10.1) - if (result.size() > (result.containsKey("@index") ? 2 : 1)) { + if (result.size() > (result.containsKey(JsonLdConsts.INDEX) ? 2 : 1)) { throw new JsonLdError(Error.INVALID_SET_OR_LIST_OBJECT, "@set or @list may only contain @index"); } // 10.2) - if (result.containsKey("@set")) { + if (result.containsKey(JsonLdConsts.SET)) { // result becomes an array here, thus the remaining checks // will never be true from here on // so simply return the value rather than have to make // result an object and cast it with every // other use in the function. - return result.get("@set"); + return result.get(JsonLdConsts.SET); } } // 11) - if (result.containsKey("@language") && result.size() == 1) { + if (result.containsKey(JsonLdConsts.LANGUAGE) && result.size() == 1) { result = null; } // 12) - if (activeProperty == null || "@graph".equals(activeProperty)) { + if (activeProperty == null || JsonLdConsts.GRAPH.equals(activeProperty)) { // 12.1) if (result != null - && (result.size() == 0 || result.containsKey("@value") || result - .containsKey("@list"))) { + && (result.size() == 0 || result.containsKey(JsonLdConsts.VALUE) || result + .containsKey(JsonLdConsts.LIST))) { result = null; } // 12.2) - else if (result != null && result.containsKey("@id") && result.size() == 1) { + else if (result != null && result.containsKey(JsonLdConsts.ID) && result.size() == 1) { result = null; } } @@ -957,7 +957,7 @@ else if (result != null && result.containsKey("@id") && result.size() == 1) { // 2) If element is a scalar else { // 2.1) - if (activeProperty == null || "@graph".equals(activeProperty)) { + if (activeProperty == null || JsonLdConsts.GRAPH.equals(activeProperty)) { return null; } return activeCtx.expandValue(activeProperty, element); @@ -990,7 +990,7 @@ public Object expand(Context activeCtx, Object element) throws JsonLdError { */ void generateNodeMap(Object element, Map nodeMap) throws JsonLdError { - generateNodeMap(element, nodeMap, "@default", null, null, null); + generateNodeMap(element, nodeMap, JsonLdConsts.DEFAULT, null, null, null); } void generateNodeMap(Object element, Map nodeMap, String activeGraph) @@ -1022,15 +1022,15 @@ void generateNodeMap(Object element, Map nodeMap, String activeG .get(activeSubject)); // 3) - if (elem.containsKey("@type")) { + if (elem.containsKey(JsonLdConsts.TYPE)) { // 3.1) List oldTypes; final List newTypes = new ArrayList(); - if (elem.get("@type") instanceof List) { - oldTypes = (List) elem.get("@type"); + if (elem.get(JsonLdConsts.TYPE) instanceof List) { + oldTypes = (List) elem.get(JsonLdConsts.TYPE); } else { oldTypes = new ArrayList(); - oldTypes.add((String) elem.get("@type")); + oldTypes.add((String) elem.get(JsonLdConsts.TYPE)); } for (final String item : oldTypes) { if (item.startsWith("_:")) { @@ -1039,35 +1039,35 @@ void generateNodeMap(Object element, Map nodeMap, String activeG newTypes.add(item); } } - if (elem.get("@type") instanceof List) { - elem.put("@type", newTypes); + if (elem.get(JsonLdConsts.TYPE) instanceof List) { + elem.put(JsonLdConsts.TYPE, newTypes); } else { - elem.put("@type", newTypes.get(0)); + elem.put(JsonLdConsts.TYPE, newTypes.get(0)); } } // 4) - if (elem.containsKey("@value")) { + if (elem.containsKey(JsonLdConsts.VALUE)) { // 4.1) if (list == null) { JsonLdUtils.mergeValue(node, activeProperty, elem); } // 4.2) else { - JsonLdUtils.mergeValue(list, "@list", elem); + JsonLdUtils.mergeValue(list, JsonLdConsts.LIST, elem); } } // 5) - else if (elem.containsKey("@list")) { + else if (elem.containsKey(JsonLdConsts.LIST)) { // 5.1) - final Map result = newMap("@list", new ArrayList()); + final Map result = newMap(JsonLdConsts.LIST, new ArrayList()); // 5.2) // for (final Object item : (List) elem.get("@list")) { // generateNodeMap(item, nodeMap, activeGraph, activeSubject, // activeProperty, result); // } - generateNodeMap(elem.get("@list"), nodeMap, activeGraph, activeSubject, activeProperty, + generateNodeMap(elem.get(JsonLdConsts.LIST), nodeMap, activeGraph, activeSubject, activeProperty, result); // 5.3) JsonLdUtils.mergeValue(node, activeProperty, result); @@ -1076,7 +1076,7 @@ else if (elem.containsKey("@list")) { // 6) else { // 6.1) - String id = (String) elem.remove("@id"); + String id = (String) elem.remove(JsonLdConsts.ID); if (id != null) { if (id.startsWith("_:")) { id = generateBlankNodeIdentifier(id); @@ -1088,7 +1088,7 @@ else if (elem.containsKey("@list")) { } // 6.3) if (!graph.containsKey(id)) { - final Map tmp = newMap("@id", id); + final Map tmp = newMap(JsonLdConsts.ID, id); graph.put(id, tmp); } // 6.4) TODO: SPEC this line is asked for by the spec, but it breaks @@ -1102,7 +1102,7 @@ else if (elem.containsKey("@list")) { } // 6.6) else if (activeProperty != null) { - final Map reference = newMap("@id", id); + final Map reference = newMap(JsonLdConsts.ID, id); // 6.6.2) if (list == null) { // 6.6.2.1+2) @@ -1111,36 +1111,36 @@ else if (activeProperty != null) { // 6.6.3) TODO: SPEC says to add ELEMENT to @list member, should // be REFERENCE else { - JsonLdUtils.mergeValue(list, "@list", reference); + JsonLdUtils.mergeValue(list, JsonLdConsts.LIST, reference); } } // TODO: SPEC this is removed in the spec now, but it's still needed // (see 6.4) node = (Map) graph.get(id); // 6.7) - if (elem.containsKey("@type")) { - for (final Object type : (List) elem.remove("@type")) { - JsonLdUtils.mergeValue(node, "@type", type); + if (elem.containsKey(JsonLdConsts.TYPE)) { + for (final Object type : (List) elem.remove(JsonLdConsts.TYPE)) { + JsonLdUtils.mergeValue(node, JsonLdConsts.TYPE, type); } } // 6.8) - if (elem.containsKey("@index")) { - final Object elemIndex = elem.remove("@index"); - if (node.containsKey("@index")) { - if (!JsonLdUtils.deepCompare(node.get("@index"), elemIndex)) { + if (elem.containsKey(JsonLdConsts.INDEX)) { + final Object elemIndex = elem.remove(JsonLdConsts.INDEX); + if (node.containsKey(JsonLdConsts.INDEX)) { + if (!JsonLdUtils.deepCompare(node.get(JsonLdConsts.INDEX), elemIndex)) { throw new JsonLdError(Error.CONFLICTING_INDEXES); } } else { - node.put("@index", elemIndex); + node.put(JsonLdConsts.INDEX, elemIndex); } } // 6.9) - if (elem.containsKey("@reverse")) { + if (elem.containsKey(JsonLdConsts.REVERSE)) { // 6.9.1) - final Map referencedNode = newMap("@id", id); + final Map referencedNode = newMap(JsonLdConsts.ID, id); // 6.9.2+6.9.4) final Map reverseMap = (Map) elem - .remove("@reverse"); + .remove(JsonLdConsts.REVERSE); // 6.9.3) for (final String property : reverseMap.keySet()) { final List values = (List) reverseMap.get(property); @@ -1152,8 +1152,8 @@ else if (activeProperty != null) { } } // 6.10) - if (elem.containsKey("@graph")) { - generateNodeMap(elem.remove("@graph"), nodeMap, id, null, null, null); + if (elem.containsKey(JsonLdConsts.GRAPH)) { + generateNodeMap(elem.remove(JsonLdConsts.GRAPH), nodeMap, id, null, null, null); } // 6.11) final List keys = new ArrayList(elem.keySet()); @@ -1286,7 +1286,7 @@ public List frame(Object input, List frame) throws JsonLdError { // use tree map so keys are sotred by default final Map nodes = new TreeMap(); generateNodeMap(input, nodes); - this.nodeMap = (Map) nodes.get("@default"); + this.nodeMap = (Map) nodes.get(JsonLdConsts.DEFAULT); final List framed = new ArrayList(); // NOTE: frame validation is done by the function not allowing anything @@ -1322,8 +1322,8 @@ private void frame(FramingContext state, Map nodes, Map matches = filterNodes(state, nodes, frame); // get flags for current frame - Boolean embedOn = getFrameFlag(frame, "@embed", state.embed); - final Boolean explicicOn = getFrameFlag(frame, "@explicit", state.explicit); + Boolean embedOn = getFrameFlag(frame, JsonLdConsts.EMBED, state.embed); + final Boolean explicicOn = getFrameFlag(frame, JsonLdConsts.EXPLICIT, state.explicit); // add matches to output final List ids = new ArrayList(matches.keySet()); @@ -1335,7 +1335,7 @@ private void frame(FramingContext state, Map nodes, Map output = newMap(); - output.put("@id", id); + output.put(JsonLdConsts.ID, id); // prepare embed meta info final EmbedNode embeddedNode = new EmbedNode(); @@ -1361,7 +1361,7 @@ private void frame(FramingContext state, Map nodes, Map) ((Map) existing.parent) .get(existing.property)) { if (v instanceof Map - && Obj.equals(id, ((Map) v).get("@id"))) { + && Obj.equals(id, ((Map) v).get(JsonLdConsts.ID))) { embedOn = true; break; } @@ -1410,30 +1410,30 @@ private void frame(FramingContext state, Map nodes, Map) item).containsKey("@list")) { + && ((Map) item).containsKey(JsonLdConsts.LIST)) { // add empty list final Map list = newMap(); - list.put("@list", new ArrayList()); + list.put(JsonLdConsts.LIST, new ArrayList()); addFrameOutput(state, output, prop, list); // add list objects for (final Object listitem : (List) ((Map) item) - .get("@list")) { + .get(JsonLdConsts.LIST)) { // recurse into subject reference if (JsonLdUtils.isNodeReference(listitem)) { final Map tmp = newMap(); final String itemid = (String) ((Map) listitem) - .get("@id"); + .get(JsonLdConsts.ID); // TODO: nodes may need to be node_map, // which is global tmp.put(itemid, this.nodeMap.get(itemid)); frame(state, tmp, (Map) ((List) frame.get(prop)) - .get(0), list, "@list"); + .get(0), list, JsonLdConsts.LIST); } else { // include other values automatcially (TODO: // may need JsonLdUtils.clone(n)) - addFrameOutput(state, list, "@list", listitem); + addFrameOutput(state, list, JsonLdConsts.LIST, listitem); } } } @@ -1441,7 +1441,7 @@ private void frame(FramingContext state, Map nodes, Map tmp = newMap(); - final String itemid = (String) ((Map) item).get("@id"); + final String itemid = (String) ((Map) item).get(JsonLdConsts.ID); // TODO: nodes may need to be node_map, which is // global tmp.put(itemid, this.nodeMap.get(itemid)); @@ -1471,19 +1471,19 @@ else if (JsonLdUtils.isNodeReference(item)) { if (propertyFrame == null) { propertyFrame = newMap(); } - final boolean omitDefaultOn = getFrameFlag(propertyFrame, "@omitDefault", + final boolean omitDefaultOn = getFrameFlag(propertyFrame, JsonLdConsts.OMIT_DEFAULT, state.omitDefault); if (!omitDefaultOn && !output.containsKey(prop)) { Object def = "@null"; - if (propertyFrame.containsKey("@default")) { - def = JsonLdUtils.clone(propertyFrame.get("@default")); + if (propertyFrame.containsKey(JsonLdConsts.DEFAULT)) { + def = JsonLdUtils.clone(propertyFrame.get(JsonLdConsts.DEFAULT)); } if (!(def instanceof List)) { final List tmp = new ArrayList(); tmp.add(def); def = tmp; } - final Map tmp1 = newMap("@preserve", def); + final Map tmp1 = newMap(JsonLdConsts.PRESERVE, def); final List tmp2 = new ArrayList(); tmp2.add(tmp1); output.put(prop, tmp2); @@ -1503,8 +1503,8 @@ private Boolean getFrameFlag(Map frame, String name, boolean the value = ((List) value).get(0); } } - if (value instanceof Map && ((Map) value).containsKey("@value")) { - value = ((Map) value).get("@value"); + if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.VALUE)) { + value = ((Map) value).get(JsonLdConsts.VALUE); } if (value instanceof Boolean) { return (Boolean) value; @@ -1528,7 +1528,7 @@ private static void removeEmbed(FramingContext state, String id) { final String property = embed.property; // create reference to replace embed - final Map node = newMap("@id", id); + final Map node = newMap(JsonLdConsts.ID, id); // remove existing embed if (JsonLdUtils.isNode(parent)) { @@ -1537,7 +1537,7 @@ private static void removeEmbed(FramingContext state, String id) { final List oldvals = (List) ((Map) parent) .get(property); for (final Object v : oldvals) { - if (v instanceof Map && Obj.equals(((Map) v).get("@id"), id)) { + if (v instanceof Map && Obj.equals(((Map) v).get(JsonLdConsts.ID), id)) { newvals.add(node); } else { newvals.add(v); @@ -1557,7 +1557,7 @@ private static void removeDependents(Map embeds, String id) { if (!(p instanceof Map)) { continue; } - final String pid = (String) ((Map) p).get("@id"); + final String pid = (String) ((Map) p).get(JsonLdConsts.ID); if (Obj.equals(id, pid)) { embeds.remove(id_dep); removeDependents(embeds, id_dep); @@ -1579,12 +1579,12 @@ private Map filterNodes(FramingContext state, Map node, Map frame) throws JsonLdError { - final Object types = frame.get("@type"); + final Object types = frame.get(JsonLdConsts.TYPE); if (types != null) { if (!(types instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "frame @type must be an array"); } - Object nodeTypes = node.get("@type"); + Object nodeTypes = node.get(JsonLdConsts.TYPE); if (nodeTypes == null) { nodeTypes = new ArrayList(); } else if (!(nodeTypes instanceof List)) { @@ -1605,7 +1605,7 @@ private boolean filterNode(FramingContext state, Map node, } } else { for (final String key : frame.keySet()) { - if ("@id".equals(key) || !isKeyword(key) && !(node.containsKey(key))) { + if (JsonLdConsts.ID.equals(key) || !isKeyword(key) && !(node.containsKey(key))) { Object frameObject = frame.get(key); if (frameObject instanceof ArrayList) { @@ -1614,7 +1614,7 @@ private boolean filterNode(FramingContext state, Map node, boolean _default = false; for (Object oo : o) { if (oo instanceof Map) { - if (((Map) oo).containsKey("@default")) { + if (((Map) oo).containsKey(JsonLdConsts.DEFAULT)) { _default = true; } } @@ -1676,7 +1676,7 @@ private void embedValues(FramingContext state, Map element, Stri for (Object o : objects) { // handle subject reference if (JsonLdUtils.isNodeReference(o)) { - final String sid = (String) ((Map) o).get("@id"); + final String sid = (String) ((Map) o).get(JsonLdConsts.ID); // embed full subject if isn't already embedded if (!state.embeds.containsKey(sid)) { @@ -1690,7 +1690,7 @@ private void embedValues(FramingContext state, Map element, Stri o = newMap(); Map s = (Map) this.nodeMap.get(sid); if (s == null) { - s = newMap("@id", sid); + s = newMap(JsonLdConsts.ID, sid); } for (final String prop : s.keySet()) { // copy keywords @@ -1743,7 +1743,7 @@ private class NodeMapNode extends LinkedHashMap { public NodeMapNode(String id) { super(); - this.put("@id", id); + this.put(JsonLdConsts.ID, id); } // helper fucntion for 4.3.3 @@ -1764,15 +1764,15 @@ public boolean isWellFormedListNode() { return false; } } - if (containsKey("@type")) { + if (containsKey(JsonLdConsts.TYPE)) { keys++; - if (!(get("@type") instanceof List && ((List) get("@type")).size() == 1) - && RDF_LIST.equals(((List) get("@type")).get(0))) { + if (!(get(JsonLdConsts.TYPE) instanceof List && ((List) get(JsonLdConsts.TYPE)).size() == 1) + && RDF_LIST.equals(((List) get(JsonLdConsts.TYPE)).get(0))) { return false; } } // TODO: SPEC: 4.3.3 has no mention of @id - if (containsKey("@id")) { + if (containsKey(JsonLdConsts.ID)) { keys++; } if (keys < size()) { @@ -1801,7 +1801,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { final Map defaultGraph = new LinkedHashMap(); // 2) final Map> graphMap = new LinkedHashMap>(); - graphMap.put("@default", defaultGraph); + graphMap.put(JsonLdConsts.DEFAULT, defaultGraph); // 3/3.1) for (final String name : dataset.graphNames()) { @@ -1818,7 +1818,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { } // 3.3) - if (!"@default".equals(name) && !Obj.contains(defaultGraph, name)) { + if (!JsonLdConsts.DEFAULT.equals(name) && !Obj.contains(defaultGraph, name)) { defaultGraph.put(name, new NodeMapNode(name)); } @@ -1846,7 +1846,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 3.5.4) if (RDF_TYPE.equals(predicate) && (object.isIRI() || object.isBlankNode()) && !opts.getUseRdfType()) { - JsonLdUtils.mergeValue(node, "@type", object.getValue()); + JsonLdUtils.mergeValue(node, JsonLdConsts.TYPE, object.getValue()); continue; } @@ -1890,7 +1890,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 4.3.3.1) list.add(((List) node.get(RDF_FIRST)).get(0)); // 4.3.3.2) - listNodes.add((String) node.get("@id")); + listNodes.add((String) node.get(JsonLdConsts.ID)); // 4.3.3.3) final UsagesNode nodeUsage = node.usages.get(0); // 4.3.3.4) @@ -1905,11 +1905,11 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 4.3.4) if (RDF_FIRST.equals(property)) { // 4.3.4.1) - if (RDF_NIL.equals(node.get("@id"))) { + if (RDF_NIL.equals(node.get(JsonLdConsts.ID))) { continue; } // 4.3.4.3) - final String headId = (String) head.get("@id"); + final String headId = (String) head.get(JsonLdConsts.ID); // 4.3.4.4-5) head = (Map) ((List) graph.get(headId).get(RDF_REST)) .get(0); @@ -1918,11 +1918,11 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { listNodes.remove(listNodes.size() - 1); } // 4.3.5) - head.remove("@id"); + head.remove(JsonLdConsts.ID); // 4.3.6) Collections.reverse(list); // 4.3.7) - head.put("@list", list); + head.put(JsonLdConsts.LIST, list); // 4.3.8) for (final String nodeId : listNodes) { graph.remove(nodeId); @@ -1940,20 +1940,20 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { // 6.1) if (graphMap.containsKey(subject)) { // 6.1.1) - node.put("@graph", new ArrayList()); + node.put(JsonLdConsts.GRAPH, new ArrayList()); // 6.1.2) final List keys = new ArrayList(graphMap.get(subject).keySet()); Collections.sort(keys); for (final String s : keys) { final NodeMapNode n = graphMap.get(subject).get(s); - if (n.size() == 1 && n.containsKey("@id")) { + if (n.size() == 1 && n.containsKey(JsonLdConsts.ID)) { continue; } - ((List) node.get("@graph")).add(n.serialize()); + ((List) node.get(JsonLdConsts.GRAPH)).add(n.serialize()); } } // 6.2) - if (node.size() == 1 && node.containsKey("@id")) { + if (node.size() == 1 && node.containsKey(JsonLdConsts.ID)) { continue; } result.add(node.serialize()); @@ -1984,7 +1984,7 @@ public RDFDataset toRDF() throws JsonLdError { // TODO: make the default generateNodeMap call (i.e. without a // graphName) create and return the nodeMap final Map nodeMap = newMap(); - nodeMap.put("@default", newMap()); + nodeMap.put(JsonLdConsts.DEFAULT, newMap()); generateNodeMap(this.value, nodeMap); final RDFDataset dataset = new RDFDataset(this); @@ -2027,7 +2027,7 @@ public Object normalize(Map dataset) throws JsonLdError { for (String graphName : dataset.keySet()) { final List> triples = (List>) dataset .get(graphName); - if ("@default".equals(graphName)) { + if (JsonLdConsts.DEFAULT.equals(graphName)) { graphName = null; } for (final Map quad : triples) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java index b68c4cd4..0e311c67 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java @@ -27,4 +27,34 @@ public final class JsonLdConsts { public static final String RDF_OBJECT = RDF_SYNTAX_NS + "object"; public static final String RDF_LANGSTRING = RDF_SYNTAX_NS + "langString"; public static final String RDF_LIST = RDF_SYNTAX_NS + "List"; + + public static final String TEXT_TURTLE = "text/turtle"; + public static final String APPLICATION_NQUADS = "application/nquads"; + + public static final String FLATTENED = "flattened"; + public static final String COMPACTED = "compacted"; + public static final String EXPANDED = "expanded"; + + public static final String ID = "@id"; + public static final String DEFAULT = "@default"; + public static final String GRAPH = "@graph"; + public static final String CONTEXT = "@context"; + public static final String PRESERVE = "@preserve"; + public static final String EXPLICIT = "@explicit"; + public static final String OMIT_DEFAULT = "@omitDefault"; + public static final String EMBED_CHILDREN = "@embedChildren"; + public static final String EMBED = "@embed"; + public static final String LIST = "@list"; + public static final String LANGUAGE = "@language"; + public static final String INDEX = "@index"; + public static final String SET = "@set"; + public static final String TYPE = "@type"; + public static final String REVERSE = "@reverse"; + public static final String VALUE = "@value"; + public static final String NULL = "@null"; + public static final String NONE = "@none"; + public static final String CONTAINER = "@container"; + public static final String BLANK_NODE_PREFIX = "_:"; + public static final String VOCAB = "@vocab"; + public static final String BASE = "@base"; } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 8ea35f59..7bad0938 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -50,8 +50,8 @@ public static Map compact(Object input, Object context, JsonLdOp // 2-6) NOTE: these are all the same steps as in expand final Object expanded = expand(input, opts); // 7) - if (context instanceof Map && ((Map) context).containsKey("@context")) { - context = ((Map) context).get("@context"); + if (context instanceof Map && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { + context = ((Map) context).get(JsonLdConsts.CONTEXT); } Context activeCtx = new Context(opts); activeCtx = activeCtx.parse(context); @@ -67,7 +67,7 @@ public static Map compact(Object input, Object context, JsonLdOp } else { final Map tmp = newMap(); // TODO: SPEC: doesn't specify to use vocab = true here - tmp.put(activeCtx.compactIri("@graph", true), compacted); + tmp.put(activeCtx.compactIri(JsonLdConsts.GRAPH, true), compacted); compacted = tmp; } } @@ -79,10 +79,10 @@ public static Map compact(Object input, Object context, JsonLdOp if (context instanceof List && ((List) context).size() == 1 && opts.getCompactArrays()) { - ((Map) compacted).put("@context", + ((Map) compacted).put(JsonLdConsts.CONTEXT, ((List) context).get(0)); } else { - ((Map) compacted).put("@context", context); + ((Map) compacted).put(JsonLdConsts.CONTEXT, context); } } } @@ -132,8 +132,8 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL // 4) if (opts.getExpandContext() != null) { Object exCtx = opts.getExpandContext(); - if (exCtx instanceof Map && ((Map) exCtx).containsKey("@context")) { - exCtx = ((Map) exCtx).get("@context"); + if (exCtx instanceof Map && ((Map) exCtx).containsKey(JsonLdConsts.CONTEXT)) { + exCtx = ((Map) exCtx).get(JsonLdConsts.CONTEXT); } activeCtx = activeCtx.parse(exCtx); } @@ -146,9 +146,9 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL Object expanded = new JsonLdApi(opts).expand(activeCtx, input); // final step of Expansion Algorithm - if (expanded instanceof Map && ((Map) expanded).containsKey("@graph") + if (expanded instanceof Map && ((Map) expanded).containsKey(JsonLdConsts.GRAPH) && ((Map) expanded).size() == 1) { - expanded = ((Map) expanded).get("@graph"); + expanded = ((Map) expanded).get(JsonLdConsts.GRAPH); } else if (expanded == null) { expanded = new ArrayList(); } @@ -182,8 +182,8 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // 2-6) NOTE: these are all the same steps as in expand final Object expanded = expand(input, opts); // 7) - if (context instanceof Map && ((Map) context).containsKey("@context")) { - context = ((Map) context).get("@context"); + if (context instanceof Map && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { + context = ((Map) context).get(JsonLdConsts.CONTEXT); } // 8) NOTE: blank node generation variables are members of JsonLdApi // 9) NOTE: the next block is the Flattening Algorithm described in @@ -191,11 +191,11 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // 1) final Map nodeMap = newMap(); - nodeMap.put("@default", newMap()); + nodeMap.put(JsonLdConsts.DEFAULT, newMap()); // 2) new JsonLdApi(opts).generateNodeMap(expanded, nodeMap); // 3) - final Map defaultGraph = (Map) nodeMap.remove("@default"); + final Map defaultGraph = (Map) nodeMap.remove(JsonLdConsts.DEFAULT); // 4) for (final String graphName : nodeMap.keySet()) { final Map graph = (Map) nodeMap.get(graphName); @@ -203,7 +203,7 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) Map entry; if (!defaultGraph.containsKey(graphName)) { entry = newMap(); - entry.put("@id", graphName); + entry.put(JsonLdConsts.ID, graphName); defaultGraph.put(graphName, entry); } else { entry = (Map) defaultGraph.get(graphName); @@ -211,15 +211,15 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // 4.3) // TODO: SPEC doesn't specify that this should only be added if it // doesn't exists - if (!entry.containsKey("@graph")) { - entry.put("@graph", new ArrayList()); + if (!entry.containsKey(JsonLdConsts.GRAPH)) { + entry.put(JsonLdConsts.GRAPH, new ArrayList()); } final List keys = new ArrayList(graph.keySet()); Collections.sort(keys); for (final String id : keys) { final Map node = (Map) graph.get(id); - if (!(node.containsKey("@id") && node.size() == 1)) { - ((List) entry.get("@graph")).add(node); + if (!(node.containsKey(JsonLdConsts.ID) && node.size() == 1)) { + ((List) entry.get(JsonLdConsts.GRAPH)).add(node); } } @@ -231,7 +231,7 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) Collections.sort(keys); for (final String id : keys) { final Map node = (Map) defaultGraph.get(id); - if (!(node.containsKey("@id") && node.size() == 1)) { + if (!(node.containsKey(JsonLdConsts.ID) && node.size() == 1)) { flattened.add(node); } } @@ -247,7 +247,7 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) tmp.add(compacted); compacted = tmp; } - final String alias = activeCtx.compactIri("@graph"); + final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); final Map rval = activeCtx.serialize(); rval.put(alias, compacted); return rval; @@ -304,7 +304,7 @@ public static Map frame(Object input, Object frame, JsonLdOption final JsonLdApi api = new JsonLdApi(expandedInput, opts); final List framed = api.frame(expandedInput, expandedFrame); - final Context activeCtx = api.context.parse(((Map) frame).get("@context")); + final Context activeCtx = api.context.parse(((Map) frame).get(JsonLdConsts.CONTEXT)); Object compacted = api.compact(activeCtx, null, framed); if (!(compacted instanceof List)) { @@ -312,7 +312,7 @@ public static Map frame(Object input, Object frame, JsonLdOption tmp.add(compacted); compacted = tmp; } - final String alias = activeCtx.compactIri("@graph"); + final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); final Map rval = activeCtx.serialize(); rval.put(alias, compacted); JsonLdUtils.removePreserve(activeCtx, rval, opts); @@ -328,8 +328,8 @@ public static Map frame(Object input, Object frame, JsonLdOption private static Map rdfParsers = new LinkedHashMap() { { // automatically register nquad serializer - put("application/nquads", new NQuadRDFParser()); - put("text/turtle", new TurtleRDFParser()); + put(JsonLdConsts.APPLICATION_NQUADS, new NQuadRDFParser()); + put(JsonLdConsts.TEXT_TURTLE, new TurtleRDFParser()); } }; @@ -365,7 +365,7 @@ public static Object fromRDF(Object dataset, JsonLdOptions options) throws JsonL if (options.format == null && dataset instanceof String) { // attempt to parse the input as nquads - options.format = "application/nquads"; + options.format = JsonLdConsts.APPLICATION_NQUADS; } if (rdfParsers.containsKey(options.format)) { @@ -424,11 +424,11 @@ public static Object fromRDF(Object input, JsonLdOptions options, RDFParser pars // re-process using the generated context if outputForm is set if (options.outputForm != null) { - if ("expanded".equals(options.outputForm)) { + if (JsonLdConsts.EXPANDED.equals(options.outputForm)) { return rval; - } else if ("compacted".equals(options.outputForm)) { + } else if (JsonLdConsts.COMPACTED.equals(options.outputForm)) { return compact(rval, dataset.getContext(), options); - } else if ("flattened".equals(options.outputForm)) { + } else if (JsonLdConsts.FLATTENED.equals(options.outputForm)) { return flatten(rval, dataset.getContext(), options); } else { throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, "Output form was unknown: " @@ -494,8 +494,8 @@ public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOp _input.add((Map) input); } for (final Map e : _input) { - if (e.containsKey("@context")) { - dataset.parseContext(e.get("@context")); + if (e.containsKey(JsonLdConsts.CONTEXT)) { + dataset.parseContext(e.get(JsonLdConsts.CONTEXT)); } } } @@ -505,9 +505,9 @@ public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOp } if (options.format != null) { - if ("application/nquads".equals(options.format)) { + if (JsonLdConsts.APPLICATION_NQUADS.equals(options.format)) { return new NQuadTripleCallback().call(dataset); - } else if ("text/turtle".equals(options.format)) { + } else if (JsonLdConsts.TEXT_TURTLE.equals(options.format)) { return new TurtleTripleCallback().call(dataset); } else { throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, options.format); From 906ec5fecdfbc06f8ba7a4f537c9d1eb24017204 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 20:13:52 -0400 Subject: [PATCH 184/440] Add regression test for both versions of the issue Ie, local and remote function differently if they are first or last --- .../github/jsonldjava/core/LocalBaseTest.java | 61 +++++++++++++++++++ .../test/resources/custom/base-0001-in.jsonld | 16 +++++ .../resources/custom/base-0001-out.jsonld | 10 +++ .../test/resources/custom/base-0002-in.jsonld | 16 +++++ .../resources/custom/base-0002-out.jsonld | 10 +++ 5 files changed, 113 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java create mode 100644 core/src/test/resources/custom/base-0001-in.jsonld create mode 100644 core/src/test/resources/custom/base-0001-out.jsonld create mode 100644 core/src/test/resources/custom/base-0002-in.jsonld create mode 100644 core/src/test/resources/custom/base-0002-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java new file mode 100644 index 00000000..4e975b56 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java @@ -0,0 +1,61 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.nio.charset.Charset; + +import org.junit.Test; + +import com.github.jsonldjava.utils.JsonUtils; + +public class LocalBaseTest { + @Test + public void testMixedLocalRemoteBaseRemoteContextFirst() throws Exception { + + final Reader reader = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/custom/base-0001-in.jsonld"), + Charset.forName("UTF-8"))); + final Object context = JsonUtils.fromReader(reader); + assertNotNull(context); + + final JsonLdOptions options = new JsonLdOptions(); + final Object expanded = JsonLdProcessor.expand(context, options); + System.out.println(JsonUtils.toPrettyString(expanded)); + + final Reader outReader = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/custom/base-0001-out.jsonld"), + Charset.forName("UTF-8"))); + final Object output = JsonUtils.fromReader(outReader); + assertNotNull(output); + assertEquals(expanded, output); + } + + @Test + public void testMixedLocalRemoteBaseLocalContextFirst() throws Exception { + + final Reader reader = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/custom/base-0002-in.jsonld"), + Charset.forName("UTF-8"))); + final Object context = JsonUtils.fromReader(reader); + assertNotNull(context); + + final JsonLdOptions options = new JsonLdOptions(); + final Object expanded = JsonLdProcessor.expand(context, options); + System.out.println(JsonUtils.toPrettyString(expanded)); + + final Reader outReader = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/custom/base-0002-out.jsonld"), + Charset.forName("UTF-8"))); + final Object output = JsonUtils.fromReader(outReader); + assertNotNull(output); + assertEquals(expanded, output); + } + +} diff --git a/core/src/test/resources/custom/base-0001-in.jsonld b/core/src/test/resources/custom/base-0001-in.jsonld new file mode 100644 index 00000000..f9bd58fd --- /dev/null +++ b/core/src/test/resources/custom/base-0001-in.jsonld @@ -0,0 +1,16 @@ +{ + "@context": [ +"https://raw.githubusercontent.com/monarch-initiative/monarch-app/master/conf/monarch-context.jsonld", + { + "@base": "http://example.org/base/", + "ex": "http://example.org/", + "ex:friendOf": { + "@type": "@id" + } + } + ], + "@id": "3456", + "ex:name": "Jim", + "ex:friendOf": "1234", + "@type": "Person" +} \ No newline at end of file diff --git a/core/src/test/resources/custom/base-0001-out.jsonld b/core/src/test/resources/custom/base-0001-out.jsonld new file mode 100644 index 00000000..5d522f30 --- /dev/null +++ b/core/src/test/resources/custom/base-0001-out.jsonld @@ -0,0 +1,10 @@ +[ { + "@id" : "http://example.org/base/3456", + "@type" : [ "http://example.org/base/Person" ], + "http://example.org/friendOf" : [ { + "@id" : "http://example.org/base/1234" + } ], + "http://example.org/name" : [ { + "@value" : "Jim" + } ] +} ] \ No newline at end of file diff --git a/core/src/test/resources/custom/base-0002-in.jsonld b/core/src/test/resources/custom/base-0002-in.jsonld new file mode 100644 index 00000000..4b2e3848 --- /dev/null +++ b/core/src/test/resources/custom/base-0002-in.jsonld @@ -0,0 +1,16 @@ +{ + "@context": [ + { + "@base": "http://example.org/base/", + "ex": "http://example.org/", + "ex:friendOf": { + "@type": "@id" + } + }, + "https://raw.githubusercontent.com/monarch-initiative/monarch-app/master/conf/monarch-context.jsonld" + ], + "@id": "3456", + "ex:name": "Jim", + "ex:friendOf": "1234", + "@type": "Person" +} \ No newline at end of file diff --git a/core/src/test/resources/custom/base-0002-out.jsonld b/core/src/test/resources/custom/base-0002-out.jsonld new file mode 100644 index 00000000..5d522f30 --- /dev/null +++ b/core/src/test/resources/custom/base-0002-out.jsonld @@ -0,0 +1,10 @@ +[ { + "@id" : "http://example.org/base/3456", + "@type" : [ "http://example.org/base/Person" ], + "http://example.org/friendOf" : [ { + "@id" : "http://example.org/base/1234" + } ], + "http://example.org/name" : [ { + "@value" : "Jim" + } ] +} ] \ No newline at end of file From 24b2e904cea8a74a7cb447208527f4c4984be965 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 20:14:33 -0400 Subject: [PATCH 185/440] Annotate the inner 3.4 loop with step numbers --- core/src/main/java/com/github/jsonldjava/core/Context.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index e1e0a59f..e2feec44 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -134,6 +134,7 @@ && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) && langu * @throws JsonLdError * If there is an error parsing the contexts. */ + @SuppressWarnings("unchecked") public Context parse(Object localContext, List remoteContexts) throws JsonLdError { if (remoteContexts == null) { remoteContexts = new ArrayList(); @@ -187,13 +188,17 @@ else if (context instanceof String) { // 3.4 if (remoteContexts.isEmpty() && ((Map) context).containsKey(JsonLdConsts.BASE)) { + // 3.4.1 final Object value = ((Map) context).get(JsonLdConsts.BASE); + // 3.4.2 if (value == null) { result.remove(JsonLdConsts.BASE); } else if (value instanceof String) { + // 3.4.3 if (JsonLdUtils.isAbsoluteIri((String) value)) { result.put(JsonLdConsts.BASE, value); } else { + // 3.4.4 final String baseUri = (String) result.get(JsonLdConsts.BASE); if (!JsonLdUtils.isAbsoluteIri(baseUri)) { throw new JsonLdError(Error.INVALID_BASE_IRI, baseUri); @@ -201,6 +206,7 @@ else if (context instanceof String) { result.put(JsonLdConsts.BASE, JsonLdUrl.resolve(baseUri, (String) value)); } } else { + // 3.4.5 throw new JsonLdError(JsonLdError.Error.INVALID_BASE_IRI, "@base must be a string"); } From 007ffbdaba4eaff06331641c9710f8c438d7b0e6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 20:25:21 -0400 Subject: [PATCH 186/440] Fix issue #175 using a hack for recursive context processing --- .../com/github/jsonldjava/core/Context.java | 171 ++++++++++++------ 1 file changed, 111 insertions(+), 60 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index e2feec44..c98749f7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -75,7 +75,8 @@ public Object compactValue(String activeProperty, Map value) { // 1) int numberMembers = value.size(); // 2) - if (value.containsKey(JsonLdConsts.INDEX) && JsonLdConsts.INDEX.equals(this.getContainer(activeProperty))) { + if (value.containsKey(JsonLdConsts.INDEX) + && JsonLdConsts.INDEX.equals(this.getContainer(activeProperty))) { numberMembers--; } // 3) @@ -99,22 +100,24 @@ public Object compactValue(String activeProperty, Map value) { } final Object valueValue = value.get(JsonLdConsts.VALUE); // 5) - if (value.containsKey(JsonLdConsts.TYPE) && Obj.equals(value.get(JsonLdConsts.TYPE), typeMapping)) { + if (value.containsKey(JsonLdConsts.TYPE) + && Obj.equals(value.get(JsonLdConsts.TYPE), typeMapping)) { return valueValue; } // 6) if (value.containsKey(JsonLdConsts.LANGUAGE)) { // TODO: SPEC: doesn't specify to check default language as well - if (Obj.equals(value.get(JsonLdConsts.LANGUAGE), languageMapping) - || Obj.equals(value.get(JsonLdConsts.LANGUAGE), this.get(JsonLdConsts.LANGUAGE))) { + if (Obj.equals(value.get(JsonLdConsts.LANGUAGE), languageMapping) || Obj + .equals(value.get(JsonLdConsts.LANGUAGE), this.get(JsonLdConsts.LANGUAGE))) { return valueValue; } } // 7) - if (numberMembers == 1 - && (!(valueValue instanceof String) || !this.containsKey(JsonLdConsts.LANGUAGE) || (termDefinitions - .containsKey(activeProperty) - && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) && languageMapping == null))) { + if (numberMembers == 1 && (!(valueValue instanceof String) + || !this.containsKey(JsonLdConsts.LANGUAGE) + || (termDefinitions.containsKey(activeProperty) + && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) + && languageMapping == null))) { return valueValue; } // 8) @@ -136,6 +139,28 @@ && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) && langu */ @SuppressWarnings("unchecked") public Context parse(Object localContext, List remoteContexts) throws JsonLdError { + return parse(localContext, remoteContexts, false); + } + + /** + * Helper method used to work around logic errors related to the recursive + * nature of the JSONLD-API Context Processing Algorithm. + * + * @param localContext + * The Local Context object. + * @param remoteContexts + * The list of Strings denoting the remote Context URLs. + * @param parsingARemoteContext + * True if localContext represents a remote context that has been + * parsed and sent into this method and false otherwise. This + * must be set to know whether to propagate the @code{@base} key + * from the context to the result. + * @return The parsed and merged Context. + * @throws JsonLdError + * If there is an error parsing the contexts. + */ + private Context parse(Object localContext, List remoteContexts, + boolean parsingARemoteContext) throws JsonLdError { if (remoteContexts == null) { remoteContexts = new ArrayList(); } @@ -148,7 +173,7 @@ public Context parse(Object localContext, List remoteContexts) throws Js ((List) localContext).add(temp); } // 3) - for (Object context : ((List) localContext)) { + for (final Object context : ((List) localContext)) { // 3.1) if (context == null) { result = new Context(this.options); @@ -169,16 +194,17 @@ else if (context instanceof String) { // 3.2.3: Dereference context final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); final Object remoteContext = rd.document; - if (!(remoteContext instanceof Map) - || !((Map) remoteContext).containsKey(JsonLdConsts.CONTEXT)) { + if (!(remoteContext instanceof Map) || !((Map) remoteContext) + .containsKey(JsonLdConsts.CONTEXT)) { // If the dereferenced document has no top-level JSON object // with an @context member throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); } - context = ((Map) remoteContext).get(JsonLdConsts.CONTEXT); + Object tempContext = ((Map) remoteContext) + .get(JsonLdConsts.CONTEXT); // 3.2.4 - result = result.parse(context, remoteContexts); + result = result.parse(tempContext, remoteContexts, true); // 3.2.5 continue; } else if (!(context instanceof Map)) { @@ -187,7 +213,8 @@ else if (context instanceof String) { } // 3.4 - if (remoteContexts.isEmpty() && ((Map) context).containsKey(JsonLdConsts.BASE)) { + if (!parsingARemoteContext + && ((Map) context).containsKey(JsonLdConsts.BASE)) { // 3.4.1 final Object value = ((Map) context).get(JsonLdConsts.BASE); // 3.4.2 @@ -245,7 +272,8 @@ else if (context instanceof String) { // 3.7 final Map defined = new LinkedHashMap(); for (final String key : ((Map) context).keySet()) { - if (JsonLdConsts.BASE.equals(key) || JsonLdConsts.VOCAB.equals(key) || JsonLdConsts.LANGUAGE.equals(key)) { + if (JsonLdConsts.BASE.equals(key) || JsonLdConsts.VOCAB.equals(key) + || JsonLdConsts.LANGUAGE.equals(key)) { continue; } result.createTermDefinition((Map) context, key, defined); @@ -286,9 +314,9 @@ private void createTermDefinition(Map context, String term, this.termDefinitions.remove(term); Object value = context.get(term); - if (value == null - || (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.ID) && ((Map) value) - .get(JsonLdConsts.ID) == null)) { + if (value == null || (value instanceof Map + && ((Map) value).containsKey(JsonLdConsts.ID) + && ((Map) value).get(JsonLdConsts.ID) == null)) { this.termDefinitions.put(term, null); defined.put(term, true); return; @@ -315,7 +343,8 @@ private void createTermDefinition(Map context, String term, } String type = (String) val.get(JsonLdConsts.TYPE); try { - type = this.expandIri((String) val.get(JsonLdConsts.TYPE), false, true, context, defined); + type = this.expandIri((String) val.get(JsonLdConsts.TYPE), false, true, context, + defined); } catch (final JsonLdError error) { if (error.getType() != Error.INVALID_IRI_MAPPING) { throw error; @@ -325,7 +354,8 @@ private void createTermDefinition(Map context, String term, // TODO: fix check for absoluteIri (blank nodes shouldn't count, at // least not here!) if (JsonLdConsts.ID.equals(type) || JsonLdConsts.VOCAB.equals(type) - || (!type.startsWith(JsonLdConsts.BLANK_NODE_PREFIX) && JsonLdUtils.isAbsoluteIri(type))) { + || (!type.startsWith(JsonLdConsts.BLANK_NODE_PREFIX) + && JsonLdUtils.isAbsoluteIri(type))) { definition.put(JsonLdConsts.TYPE, type); } else { throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); @@ -340,19 +370,20 @@ private void createTermDefinition(Map context, String term, if (!(val.get(JsonLdConsts.REVERSE) instanceof String)) { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Expected String for @reverse value. got " - + (val.get(JsonLdConsts.REVERSE) == null ? "null" : val.get(JsonLdConsts.REVERSE) - .getClass())); + + (val.get(JsonLdConsts.REVERSE) == null ? "null" + : val.get(JsonLdConsts.REVERSE).getClass())); } - final String reverse = this.expandIri((String) val.get(JsonLdConsts.REVERSE), false, true, - context, defined); + final String reverse = this.expandIri((String) val.get(JsonLdConsts.REVERSE), false, + true, context, defined); if (!JsonLdUtils.isAbsoluteIri(reverse)) { - throw new JsonLdError(Error.INVALID_IRI_MAPPING, "Non-absolute @reverse IRI: " - + reverse); + throw new JsonLdError(Error.INVALID_IRI_MAPPING, + "Non-absolute @reverse IRI: " + reverse); } definition.put(JsonLdConsts.ID, reverse); if (val.containsKey(JsonLdConsts.CONTAINER)) { final String container = (String) val.get(JsonLdConsts.CONTAINER); - if (container == null || JsonLdConsts.SET.equals(container) || JsonLdConsts.INDEX.equals(container)) { + if (container == null || JsonLdConsts.SET.equals(container) + || JsonLdConsts.INDEX.equals(container)) { definition.put(JsonLdConsts.CONTAINER, container); } else { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY, @@ -375,8 +406,8 @@ private void createTermDefinition(Map context, String term, "expected value of @id to be a string"); } - final String res = this.expandIri((String) val.get(JsonLdConsts.ID), false, true, context, - defined); + final String res = this.expandIri((String) val.get(JsonLdConsts.ID), false, true, + context, defined); if (JsonLdUtils.isKeyword(res) || JsonLdUtils.isAbsoluteIri(res)) { if (JsonLdConsts.CONTEXT.equals(res)) { throw new JsonLdError(Error.INVALID_KEYWORD_ALIAS, "cannot alias @context"); @@ -398,7 +429,8 @@ else if (term.indexOf(":") >= 0) { } if (termDefinitions.containsKey(prefix)) { definition.put(JsonLdConsts.ID, - ((Map) termDefinitions.get(prefix)).get(JsonLdConsts.ID) + suffix); + ((Map) termDefinitions.get(prefix)).get(JsonLdConsts.ID) + + suffix); } else { definition.put(JsonLdConsts.ID, term); } @@ -414,7 +446,8 @@ else if (term.indexOf(":") >= 0) { if (val.containsKey(JsonLdConsts.CONTAINER)) { final String container = (String) val.get(JsonLdConsts.CONTAINER); if (!JsonLdConsts.LIST.equals(container) && !JsonLdConsts.SET.equals(container) - && !JsonLdConsts.INDEX.equals(container) && !JsonLdConsts.LANGUAGE.equals(container)) { + && !JsonLdConsts.INDEX.equals(container) + && !JsonLdConsts.LANGUAGE.equals(container)) { throw new JsonLdError(Error.INVALID_CONTAINER_MAPPING, "@container must be either @list, @set, @index, or @language"); } @@ -423,9 +456,11 @@ else if (term.indexOf(":") >= 0) { // 17) if (val.containsKey(JsonLdConsts.LANGUAGE) && !val.containsKey(JsonLdConsts.TYPE)) { - if (val.get(JsonLdConsts.LANGUAGE) == null || val.get(JsonLdConsts.LANGUAGE) instanceof String) { + if (val.get(JsonLdConsts.LANGUAGE) == null + || val.get(JsonLdConsts.LANGUAGE) instanceof String) { final String language = (String) val.get(JsonLdConsts.LANGUAGE); - definition.put(JsonLdConsts.LANGUAGE, language != null ? language.toLowerCase() : null); + definition.put(JsonLdConsts.LANGUAGE, + language != null ? language.toLowerCase() : null); } else { throw new JsonLdError(Error.INVALID_LANGUAGE_MAPPING, "@language must be a string or null"); @@ -521,8 +556,8 @@ else if (relative) { * @param value * the value to check or null. * @param relativeTo - * options for how to compact IRIs: vocab: true to split after - * @vocab, false not to. + * options for how to compact IRIs: vocab: true to split + * after @vocab, false not to. * @param reverse * true if a reverse property is being compacted, false if not. * @@ -549,7 +584,8 @@ String compactIri(String iri, Object value, boolean relativeToVocab, boolean rev String typeLanguageValue = JsonLdConsts.NULL; // 2.4) - if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.INDEX)) { + if (value instanceof Map + && ((Map) value).containsKey(JsonLdConsts.INDEX)) { containers.add(JsonLdConsts.INDEX); } @@ -560,13 +596,15 @@ String compactIri(String iri, Object value, boolean relativeToVocab, boolean rev containers.add(JsonLdConsts.SET); } // 2.6) - else if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.LIST)) { + else if (value instanceof Map + && ((Map) value).containsKey(JsonLdConsts.LIST)) { // 2.6.1) if (!((Map) value).containsKey(JsonLdConsts.INDEX)) { containers.add(JsonLdConsts.LIST); } // 2.6.2) - final List list = (List) ((Map) value).get(JsonLdConsts.LIST); + final List list = (List) ((Map) value) + .get(JsonLdConsts.LIST); // 2.6.3) String commonLanguage = (list.size() == 0) ? defaultLanguage : null; String commonType = null; @@ -579,7 +617,8 @@ else if (value instanceof Map && ((Map) value).containsKey(JsonL if (JsonLdUtils.isValue(item)) { // 2.6.4.2.1) if (((Map) item).containsKey(JsonLdConsts.LANGUAGE)) { - itemLanguage = (String) ((Map) item).get(JsonLdConsts.LANGUAGE); + itemLanguage = (String) ((Map) item) + .get(JsonLdConsts.LANGUAGE); } // 2.6.4.2.2) else if (((Map) item).containsKey(JsonLdConsts.TYPE)) { @@ -611,7 +650,8 @@ else if (!commonType.equals(itemType)) { commonType = JsonLdConsts.NONE; } // 2.6.4.8) - if (JsonLdConsts.NONE.equals(commonLanguage) && JsonLdConsts.NONE.equals(commonType)) { + if (JsonLdConsts.NONE.equals(commonLanguage) + && JsonLdConsts.NONE.equals(commonType)) { break; } } @@ -632,17 +672,20 @@ else if (!commonType.equals(itemType)) { // 2.7) else { // 2.7.1) - if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.VALUE)) { + if (value instanceof Map + && ((Map) value).containsKey(JsonLdConsts.VALUE)) { // 2.7.1.1) if (((Map) value).containsKey(JsonLdConsts.LANGUAGE) && !((Map) value).containsKey(JsonLdConsts.INDEX)) { containers.add(JsonLdConsts.LANGUAGE); - typeLanguageValue = (String) ((Map) value).get(JsonLdConsts.LANGUAGE); + typeLanguageValue = (String) ((Map) value) + .get(JsonLdConsts.LANGUAGE); } // 2.7.1.2) else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { typeLanguage = JsonLdConsts.TYPE; - typeLanguageValue = (String) ((Map) value).get(JsonLdConsts.TYPE); + typeLanguageValue = (String) ((Map) value) + .get(JsonLdConsts.TYPE); } } // 2.7.2) @@ -667,15 +710,19 @@ else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { preferredValues.add(JsonLdConsts.REVERSE); } // 2.12) - if ((JsonLdConsts.REVERSE.equals(typeLanguageValue) || JsonLdConsts.ID.equals(typeLanguageValue)) - && (value instanceof Map) && ((Map) value).containsKey(JsonLdConsts.ID)) { + if ((JsonLdConsts.REVERSE.equals(typeLanguageValue) + || JsonLdConsts.ID.equals(typeLanguageValue)) && (value instanceof Map) + && ((Map) value).containsKey(JsonLdConsts.ID)) { // 2.12.1) final String result = this.compactIri( - (String) ((Map) value).get(JsonLdConsts.ID), null, true, true); + (String) ((Map) value).get(JsonLdConsts.ID), null, true, + true); if (termDefinitions.containsKey(result) - && ((Map) termDefinitions.get(result)).containsKey(JsonLdConsts.ID) - && ((Map) value).get(JsonLdConsts.ID).equals( - ((Map) termDefinitions.get(result)).get(JsonLdConsts.ID))) { + && ((Map) termDefinitions.get(result)) + .containsKey(JsonLdConsts.ID) + && ((Map) value).get(JsonLdConsts.ID) + .equals(((Map) termDefinitions.get(result)) + .get(JsonLdConsts.ID))) { preferredValues.add(JsonLdConsts.VOCAB); preferredValues.add(JsonLdConsts.ID); } @@ -734,7 +781,8 @@ else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { final String candidate = term + ":" + iri.substring(((String) termDefinition.get(JsonLdConsts.ID)).length()); // 5.4) - compactIRI = _iriCompactionStep5point4(iri, value, compactIRI, candidate, termDefinitions); + compactIRI = _iriCompactionStep5point4(iri, value, compactIRI, candidate, + termDefinitions); } // 6) @@ -756,13 +804,14 @@ else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { */ public static String _iriCompactionStep5point4(String iri, Object value, String compactIRI, final String candidate, Map termDefinitions) { - - boolean condition1 = (compactIRI == null || compareShortestLeast(candidate, compactIRI) < 0); - + + boolean condition1 = (compactIRI == null + || compareShortestLeast(candidate, compactIRI) < 0); + boolean condition2 = (!termDefinitions.containsKey(candidate) || (iri - .equals(((Map) termDefinitions.get(candidate)) - .get(JsonLdConsts.ID)) && value == null)); - + .equals(((Map) termDefinitions.get(candidate)).get(JsonLdConsts.ID)) + && value == null)); + if (condition1 && condition2) { compactIRI = candidate; } @@ -1086,7 +1135,8 @@ public Object getContextValue(String activeProperty, String string) throws JsonL public Map serialize() { final Map ctx = newMap(); - if (this.get(JsonLdConsts.BASE) != null && !this.get(JsonLdConsts.BASE).equals(options.getBase())) { + if (this.get(JsonLdConsts.BASE) != null + && !this.get(JsonLdConsts.BASE).equals(options.getBase())) { ctx.put(JsonLdConsts.BASE, this.get(JsonLdConsts.BASE)); } if (this.get(JsonLdConsts.LANGUAGE) != null) { @@ -1100,14 +1150,15 @@ public Map serialize() { if (definition.get(JsonLdConsts.LANGUAGE) == null && definition.get(JsonLdConsts.CONTAINER) == null && definition.get(JsonLdConsts.TYPE) == null - && (definition.get(JsonLdConsts.REVERSE) == null || Boolean.FALSE.equals(definition - .get(JsonLdConsts.REVERSE)))) { + && (definition.get(JsonLdConsts.REVERSE) == null + || Boolean.FALSE.equals(definition.get(JsonLdConsts.REVERSE)))) { final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); ctx.put(term, term.equals(cid) ? definition.get(JsonLdConsts.ID) : cid); } else { final Map defn = newMap(); final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); - final Boolean reverseProperty = Boolean.TRUE.equals(definition.get(JsonLdConsts.REVERSE)); + final Boolean reverseProperty = Boolean.TRUE + .equals(definition.get(JsonLdConsts.REVERSE)); if (!(term.equals(cid) && !reverseProperty)) { defn.put(reverseProperty ? JsonLdConsts.REVERSE : JsonLdConsts.ID, cid); } From ed676e753adcf93bbf1a8a9b231f88192a9f4503 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 21:05:07 -0400 Subject: [PATCH 187/440] Update dependency versions --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0be7af1c..fdadde92 100755 --- a/pom.xml +++ b/pom.xml @@ -39,11 +39,11 @@ UTF-8 UTF-8 - 4.5.1 + 4.5.2 4.4.4 - 2.6.3 + 2.7.4 4.12 - 1.7.13 + 1.7.21 3.0.5 @@ -195,7 +195,7 @@ commons-io commons-io - 2.4 + 2.5 From eeb58b2e2cba8faa43e81640d1fab4feebf1f6b8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 21:09:15 -0400 Subject: [PATCH 188/440] Bump plugin versions --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index fdadde92..b3f6baa8 100755 --- a/pom.xml +++ b/pom.xml @@ -206,7 +206,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5 + 3.5.1 1.6 1.6 @@ -235,7 +235,7 @@ org.apache.maven.plugins maven-clean-plugin - 2.6.1 + 3.0.0 org.apache.maven.plugins @@ -245,7 +245,7 @@ org.apache.maven.plugins maven-jar-plugin - 2.5 + 2.6 @@ -281,7 +281,7 @@ org.codehaus.mojo animal-sniffer-maven-plugin - 1.14 + 1.15 test @@ -306,18 +306,18 @@ org.apache.felix maven-bundle-plugin - 2.5.4 + 3.0.1 org.eluder.coveralls coveralls-maven-plugin - 3.0.1 + 4.1.0 org.jacoco jacoco-maven-plugin - 0.7.4.201502262128 + 0.7.5.201505241946 prepare-agent From 782e251a68a3535d3ed552133ff7e42a8dea2bdb Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 21:29:51 -0400 Subject: [PATCH 189/440] Add to changelog --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9e028ea8..33585b0d 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2016-05-18 +* Fix @base in remote contexts corrupting the local context + ### 2016-02-29 * Fix ConcurrentModificationException in the implementation of the Framing API From 3b4200cf7271de77d62d8aca97f89bc3eed59d2e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 17 May 2016 21:59:06 -0400 Subject: [PATCH 190/440] Note that need to use Java-8 to build this branch due to the use of Java-8 classes in tests. However, the rest of the codebase is still compatible with Java-6. --- .travis.yml | 1 - README.md | 1 + pom.xml | 33 +++++++++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36aa3a3e..312621f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: java jdk: - - oraclejdk7 - oraclejdk8 notifications: email: diff --git a/README.md b/README.md index 33585b0d..2fa376d0 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,7 @@ For Developers `jsonld-java` uses maven to compile. From the base `jsonld-java` module run `mvn clean install` to install the jar into your local maven repository. +The tests require Java-8 to compile, while the rest of the codebase is still compatible and built using the Java-6 APIs. ### Running tests diff --git a/pom.xml b/pom.xml index b3f6baa8..aba0cb75 100755 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,11 @@ 2.7.4 4.12 1.7.21 + + 1.6 + 1.6 + 1.8 + 1.8 3.0.5 @@ -207,10 +212,30 @@ org.apache.maven.plugins maven-compiler-plugin 3.5.1 - - 1.6 - 1.6 - + + + default-compile + + true + true + + ${maven.compiler.target} + ${maven.compiler.source} + + + + + default-testCompile + + true + true + + ${maven.compiler.testTarget} + ${maven.compiler.testSource} + + + + org.apache.maven.plugins From 157d6ffa440e3e3c3d6ab93e19a9dc9e77813705 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 00:35:56 -0400 Subject: [PATCH 191/440] Add ide profile to allow Eclipse to use Java-8 for test compilation --- pom.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pom.xml b/pom.xml index aba0cb75..7b0908d5 100755 --- a/pom.xml +++ b/pom.xml @@ -462,6 +462,24 @@ + + ide + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.testSource} + ${maven.compiler.testTarget} + + + + + From 5cc8c382921796d40e5644bbdf9cd0abb0d29327 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 00:36:48 -0400 Subject: [PATCH 192/440] Add support for laxMergeValues --- .../com/github/jsonldjava/core/JsonLdApi.java | 210 +++++++++++------- .../github/jsonldjava/core/JsonLdUtils.java | 8 +- 2 files changed, 130 insertions(+), 88 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index b3f1befb..a7f5d548 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -161,7 +161,8 @@ public Object compact(Context activeCtx, String activeProperty, Object element, // 2.2) for (final Object item : (List) element) { // 2.2.1) - final Object compactedItem = compact(activeCtx, activeProperty, item, compactArrays); + final Object compactedItem = compact(activeCtx, activeProperty, item, + compactArrays); // 2.2.2) if (compactedItem != null) { result.add(compactedItem); @@ -200,7 +201,8 @@ public Object compact(Context activeCtx, String activeProperty, Object element, final Object expandedValue = elem.get(expandedProperty); // 7.1) - if (JsonLdConsts.ID.equals(expandedProperty) || JsonLdConsts.TYPE.equals(expandedProperty)) { + if (JsonLdConsts.ID.equals(expandedProperty) + || JsonLdConsts.TYPE.equals(expandedProperty)) { Object compactedValue; // 7.1.1) @@ -248,8 +250,8 @@ public Object compact(Context activeCtx, String activeProperty, Object element, // 7.2.2.1) if (activeCtx.isReverseProperty(property)) { // 7.2.2.1.1) - if ((JsonLdConsts.SET.equals(activeCtx.getContainer(property)) || !compactArrays) - && !(value instanceof List)) { + if ((JsonLdConsts.SET.equals(activeCtx.getContainer(property)) + || !compactArrays) && !(value instanceof List)) { final List tmp = new ArrayList(); tmp.add(value); result.put(property, tmp); @@ -292,7 +294,8 @@ public Object compact(Context activeCtx, String activeProperty, Object element, continue; } // 7.4) - else if (JsonLdConsts.INDEX.equals(expandedProperty) || JsonLdConsts.VALUE.equals(expandedProperty) + else if (JsonLdConsts.INDEX.equals(expandedProperty) + || JsonLdConsts.VALUE.equals(expandedProperty) || JsonLdConsts.LANGUAGE.equals(expandedProperty)) { // 7.4.1) final String alias = activeCtx.compactIri(expandedProperty, true); @@ -331,16 +334,16 @@ else if (JsonLdConsts.INDEX.equals(expandedProperty) || JsonLdConsts.VALUE.equal final String container = activeCtx.getContainer(itemActiveProperty); // get @list value if appropriate - final boolean isList = (expandedItem instanceof Map && ((Map) expandedItem) - .containsKey(JsonLdConsts.LIST)); + final boolean isList = (expandedItem instanceof Map + && ((Map) expandedItem).containsKey(JsonLdConsts.LIST)); Object list = null; if (isList) { list = ((Map) expandedItem).get(JsonLdConsts.LIST); } // 7.6.3) - Object compactedItem = compact(activeCtx, itemActiveProperty, isList ? list - : expandedItem, compactArrays); + Object compactedItem = compact(activeCtx, itemActiveProperty, + isList ? list : expandedItem, compactArrays); // 7.6.4) if (isList) { @@ -355,16 +358,19 @@ else if (JsonLdConsts.INDEX.equals(expandedProperty) || JsonLdConsts.VALUE.equal // 7.6.4.2.1) final Map wrapper = newMap(); // TODO: SPEC: no mention of vocab = true - wrapper.put(activeCtx.compactIri(JsonLdConsts.LIST, true), compactedItem); + wrapper.put(activeCtx.compactIri(JsonLdConsts.LIST, true), + compactedItem); compactedItem = wrapper; // 7.6.4.2.2) - if (((Map) expandedItem).containsKey(JsonLdConsts.INDEX)) { + if (((Map) expandedItem) + .containsKey(JsonLdConsts.INDEX)) { ((Map) compactedItem).put( // TODO: SPEC: no mention of vocab = // true activeCtx.compactIri(JsonLdConsts.INDEX, true), - ((Map) expandedItem).get(JsonLdConsts.INDEX)); + ((Map) expandedItem) + .get(JsonLdConsts.INDEX)); } } // 7.6.4.3) @@ -375,7 +381,8 @@ else if (result.containsKey(itemActiveProperty)) { } // 7.6.5) - if (JsonLdConsts.LANGUAGE.equals(container) || JsonLdConsts.INDEX.equals(container)) { + if (JsonLdConsts.LANGUAGE.equals(container) + || JsonLdConsts.INDEX.equals(container)) { // 7.6.5.1) Map mapObject; if (result.containsKey(itemActiveProperty)) { @@ -386,10 +393,11 @@ else if (result.containsKey(itemActiveProperty)) { } // 7.6.5.2) - if (JsonLdConsts.LANGUAGE.equals(container) - && (compactedItem instanceof Map && ((Map) compactedItem) + if (JsonLdConsts.LANGUAGE.equals(container) && (compactedItem instanceof Map + && ((Map) compactedItem) .containsKey(JsonLdConsts.VALUE))) { - compactedItem = ((Map) compactedItem).get(JsonLdConsts.VALUE); + compactedItem = ((Map) compactedItem) + .get(JsonLdConsts.VALUE); } // 7.6.5.3) @@ -413,8 +421,9 @@ else if (result.containsKey(itemActiveProperty)) { else { // 7.6.6.1) final Boolean check = (!compactArrays || JsonLdConsts.SET.equals(container) - || JsonLdConsts.LIST.equals(container) || JsonLdConsts.LIST.equals(expandedProperty) || JsonLdConsts.GRAPH - .equals(expandedProperty)) + || JsonLdConsts.LIST.equals(container) + || JsonLdConsts.LIST.equals(expandedProperty) + || JsonLdConsts.GRAPH.equals(expandedProperty)) && (!(compactedItem instanceof List)); if (check) { final List tmp = new ArrayList(); @@ -507,10 +516,10 @@ public Object expand(Context activeCtx, String activeProperty, Object element) // 3.2.1) final Object v = expand(activeCtx, activeProperty, item); // 3.2.2) - if ((JsonLdConsts.LIST.equals(activeProperty) || JsonLdConsts.LIST.equals(activeCtx - .getContainer(activeProperty))) - && (v instanceof List || (v instanceof Map && ((Map) v) - .containsKey(JsonLdConsts.LIST)))) { + if ((JsonLdConsts.LIST.equals(activeProperty) + || JsonLdConsts.LIST.equals(activeCtx.getContainer(activeProperty))) + && (v instanceof List || (v instanceof Map + && ((Map) v).containsKey(JsonLdConsts.LIST)))) { throw new JsonLdError(Error.LIST_OF_LISTS, "lists of lists are not permitted."); } // 3.2.3) @@ -561,8 +570,8 @@ else if (element instanceof Map) { } // 7.4.2) if (result.containsKey(expandedProperty)) { - throw new JsonLdError(Error.COLLIDING_KEYWORDS, expandedProperty - + " already exists in result"); + throw new JsonLdError(Error.COLLIDING_KEYWORDS, + expandedProperty + " already exists in result"); } // 7.4.3) if (JsonLdConsts.ID.equals(expandedProperty)) { @@ -570,8 +579,8 @@ else if (element instanceof Map) { throw new JsonLdError(Error.INVALID_ID_VALUE, "value of @id must be a string"); } - expandedValue = activeCtx - .expandIri((String) value, true, false, null, null); + expandedValue = activeCtx.expandIri((String) value, true, false, null, + null); } // 7.4.4) else if (JsonLdConsts.TYPE.equals(expandedProperty)) { @@ -582,8 +591,8 @@ else if (JsonLdConsts.TYPE.equals(expandedProperty)) { throw new JsonLdError(Error.INVALID_TYPE_VALUE, "@type value must be a string or array of strings"); } - ((List) expandedValue).add(activeCtx.expandIri((String) v, - true, true, null, null)); + ((List) expandedValue).add( + activeCtx.expandIri((String) v, true, true, null, null)); } } else if (value instanceof String) { expandedValue = activeCtx.expandIri((String) value, true, true, null, @@ -608,8 +617,8 @@ else if (JsonLdConsts.GRAPH.equals(expandedProperty)) { // 7.4.6) else if (JsonLdConsts.VALUE.equals(expandedProperty)) { if (value != null && (value instanceof Map || value instanceof List)) { - throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE, "value of " - + expandedProperty + " must be a scalar or null"); + throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE, + "value of " + expandedProperty + " must be a scalar or null"); } expandedValue = value; if (expandedValue == null) { @@ -620,16 +629,16 @@ else if (JsonLdConsts.VALUE.equals(expandedProperty)) { // 7.4.7) else if (JsonLdConsts.LANGUAGE.equals(expandedProperty)) { if (!(value instanceof String)) { - throw new JsonLdError(Error.INVALID_LANGUAGE_TAGGED_STRING, "Value of " - + expandedProperty + " must be a string"); + throw new JsonLdError(Error.INVALID_LANGUAGE_TAGGED_STRING, + "Value of " + expandedProperty + " must be a string"); } expandedValue = ((String) value).toLowerCase(); } // 7.4.8) else if (JsonLdConsts.INDEX.equals(expandedProperty)) { if (!(value instanceof String)) { - throw new JsonLdError(Error.INVALID_INDEX_VALUE, "Value of " - + expandedProperty + " must be a string"); + throw new JsonLdError(Error.INVALID_INDEX_VALUE, + "Value of " + expandedProperty + " must be a string"); } expandedValue = value; } @@ -651,7 +660,8 @@ else if (JsonLdConsts.LIST.equals(expandedProperty)) { // 7.4.9.3) for (final Object o : (List) expandedValue) { - if (o instanceof Map && ((Map) o).containsKey(JsonLdConsts.LIST)) { + if (o instanceof Map + && ((Map) o).containsKey(JsonLdConsts.LIST)) { throw new JsonLdError(Error.LIST_OF_LISTS, "A list may not contain another list"); } @@ -671,7 +681,8 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { expandedValue = expand(activeCtx, JsonLdConsts.REVERSE, value); // NOTE: algorithm assumes the result is a map // 7.4.11.2) - if (((Map) expandedValue).containsKey(JsonLdConsts.REVERSE)) { + if (((Map) expandedValue) + .containsKey(JsonLdConsts.REVERSE)) { final Map reverse = (Map) ((Map) expandedValue) .get(JsonLdConsts.REVERSE); for (final String property : reverse.keySet()) { @@ -690,8 +701,9 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { } } // 7.4.11.3) - if (((Map) expandedValue).size() > (((Map) expandedValue) - .containsKey(JsonLdConsts.REVERSE) ? 1 : 0)) { + if (((Map) expandedValue) + .size() > (((Map) expandedValue) + .containsKey(JsonLdConsts.REVERSE) ? 1 : 0)) { // 7.4.11.3.1) if (!result.containsKey(JsonLdConsts.REVERSE)) { result.put(JsonLdConsts.REVERSE, newMap()); @@ -710,8 +722,9 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { .get(property); for (final Object item : items) { // 7.4.11.3.3.1.1) - if (item instanceof Map - && (((Map) item).containsKey(JsonLdConsts.VALUE) || ((Map) item) + if (item instanceof Map && (((Map) item) + .containsKey(JsonLdConsts.VALUE) + || ((Map) item) .containsKey(JsonLdConsts.LIST))) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_VALUE); } @@ -743,7 +756,8 @@ else if (JsonLdConsts.EXPLICIT.equals(expandedProperty) continue; } // 7.5 - else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key)) && value instanceof Map) { + else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key)) + && value instanceof Map) { // 7.5.1) expandedValue = new ArrayList(); // 7.5.2) @@ -759,8 +773,8 @@ else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key)) && value inst for (final Object item : (List) languageValue) { // 7.5.2.2.1) if (!(item instanceof String)) { - throw new JsonLdError(Error.INVALID_LANGUAGE_MAP_VALUE, "Expected " - + item.toString() + " to be a string"); + throw new JsonLdError(Error.INVALID_LANGUAGE_MAP_VALUE, + "Expected " + item.toString() + " to be a string"); } // 7.5.2.2.2) final Map tmp = newMap(); @@ -771,7 +785,8 @@ else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key)) && value inst } } // 7.6) - else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) && value instanceof Map) { + else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) + && value instanceof Map) { // 7.6.1) expandedValue = new ArrayList(); // 7.6.2) @@ -809,8 +824,8 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) && value instanc } // 7.9) if (JsonLdConsts.LIST.equals(activeCtx.getContainer(key))) { - if (!(expandedValue instanceof Map) - || !((Map) expandedValue).containsKey(JsonLdConsts.LIST)) { + if (!(expandedValue instanceof Map) || !((Map) expandedValue) + .containsKey(JsonLdConsts.LIST)) { Object tmp = expandedValue; if (!(tmp instanceof List)) { tmp = new ArrayList(); @@ -838,9 +853,9 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) && value instanc // 7.10.4) for (final Object item : (List) expandedValue) { // 7.10.4.1) - if (item instanceof Map - && (((Map) item).containsKey(JsonLdConsts.VALUE) || ((Map) item) - .containsKey(JsonLdConsts.LIST))) { + if (item instanceof Map && (((Map) item) + .containsKey(JsonLdConsts.VALUE) + || ((Map) item).containsKey(JsonLdConsts.LIST))) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_VALUE); } // 7.10.4.2) @@ -918,7 +933,8 @@ else if (result.containsKey(JsonLdConsts.TYPE)) { } } // 10) - else if (result.containsKey(JsonLdConsts.SET) || result.containsKey(JsonLdConsts.LIST)) { + else if (result.containsKey(JsonLdConsts.SET) + || result.containsKey(JsonLdConsts.LIST)) { // 10.1) if (result.size() > (result.containsKey(JsonLdConsts.INDEX) ? 2 : 1)) { throw new JsonLdError(Error.INVALID_SET_OR_LIST_OBJECT, @@ -941,13 +957,13 @@ else if (result.containsKey(JsonLdConsts.SET) || result.containsKey(JsonLdConsts // 12) if (activeProperty == null || JsonLdConsts.GRAPH.equals(activeProperty)) { // 12.1) - if (result != null - && (result.size() == 0 || result.containsKey(JsonLdConsts.VALUE) || result - .containsKey(JsonLdConsts.LIST))) { + if (result != null && (result.size() == 0 || result.containsKey(JsonLdConsts.VALUE) + || result.containsKey(JsonLdConsts.LIST))) { result = null; } // 12.2) - else if (result != null && result.containsKey(JsonLdConsts.ID) && result.size() == 1) { + else if (result != null && result.containsKey(JsonLdConsts.ID) + && result.size() == 1) { result = null; } } @@ -1018,8 +1034,8 @@ void generateNodeMap(Object element, Map nodeMap, String activeG nodeMap.put(activeGraph, newMap()); } final Map graph = (Map) nodeMap.get(activeGraph); - Map node = (Map) (activeSubject == null ? null : graph - .get(activeSubject)); + Map node = (Map) (activeSubject == null ? null + : graph.get(activeSubject)); // 3) if (elem.containsKey(JsonLdConsts.TYPE)) { @@ -1067,8 +1083,8 @@ else if (elem.containsKey(JsonLdConsts.LIST)) { // generateNodeMap(item, nodeMap, activeGraph, activeSubject, // activeProperty, result); // } - generateNodeMap(elem.get(JsonLdConsts.LIST), nodeMap, activeGraph, activeSubject, activeProperty, - result); + generateNodeMap(elem.get(JsonLdConsts.LIST), nodeMap, activeGraph, activeSubject, + activeProperty, result); // 5.3) JsonLdUtils.mergeValue(node, activeProperty, result); } @@ -1147,7 +1163,8 @@ else if (activeProperty != null) { // 6.9.3.1) for (final Object value : values) { // 6.9.3.1.1) - generateNodeMap(value, nodeMap, activeGraph, referencedNode, property, null); + generateNodeMap(value, nodeMap, activeGraph, referencedNode, property, + null); } } } @@ -1268,8 +1285,8 @@ private class EmbedNode { private Map nodeMap; /** - * Performs JSON-LD framing. + * Performs JSON-LD + * framing. * * @param input * the expanded JSON-LD to frame. @@ -1291,8 +1308,7 @@ public List frame(Object input, List frame) throws JsonLdError { final List framed = new ArrayList(); // NOTE: frame validation is done by the function not allowing anything // other than list to me passed - frame(state, - this.nodeMap, + frame(state, this.nodeMap, (frame != null && frame.size() > 0 ? (Map) frame.get(0) : newMap()), framed, null); @@ -1360,8 +1376,8 @@ private void frame(FramingContext state, Map nodes, Map) existing.parent).containsKey(existing.property)) { for (final Object v : (List) ((Map) existing.parent) .get(existing.property)) { - if (v instanceof Map - && Obj.equals(id, ((Map) v).get(JsonLdConsts.ID))) { + if (v instanceof Map && Obj.equals(id, + ((Map) v).get(JsonLdConsts.ID))) { embedOn = true; break; } @@ -1429,7 +1445,8 @@ private void frame(FramingContext state, Map nodes, Map) ((List) frame.get(prop)) - .get(0), list, JsonLdConsts.LIST); + .get(0), + list, JsonLdConsts.LIST); } else { // include other values automatcially (TODO: // may need JsonLdUtils.clone(n)) @@ -1441,7 +1458,8 @@ private void frame(FramingContext state, Map nodes, Map tmp = newMap(); - final String itemid = (String) ((Map) item).get(JsonLdConsts.ID); + final String itemid = (String) ((Map) item) + .get(JsonLdConsts.ID); // TODO: nodes may need to be node_map, which is // global tmp.put(itemid, this.nodeMap.get(itemid)); @@ -1466,13 +1484,13 @@ else if (JsonLdUtils.isNodeReference(item)) { } final List pf = (List) frame.get(prop); - Map propertyFrame = pf.size() > 0 ? (Map) pf - .get(0) : null; + Map propertyFrame = pf.size() > 0 + ? (Map) pf.get(0) : null; if (propertyFrame == null) { propertyFrame = newMap(); } - final boolean omitDefaultOn = getFrameFlag(propertyFrame, JsonLdConsts.OMIT_DEFAULT, - state.omitDefault); + final boolean omitDefaultOn = getFrameFlag(propertyFrame, + JsonLdConsts.OMIT_DEFAULT, state.omitDefault); if (!omitDefaultOn && !output.containsKey(prop)) { Object def = "@null"; if (propertyFrame.containsKey(JsonLdConsts.DEFAULT)) { @@ -1537,7 +1555,8 @@ private static void removeEmbed(FramingContext state, String id) { final List oldvals = (List) ((Map) parent) .get(property); for (final Object v : oldvals) { - if (v instanceof Map && Obj.equals(((Map) v).get(JsonLdConsts.ID), id)) { + if (v instanceof Map + && Obj.equals(((Map) v).get(JsonLdConsts.ID), id)) { newvals.add(node); } else { newvals.add(v); @@ -1754,19 +1773,22 @@ public boolean isWellFormedListNode() { int keys = 0; if (containsKey(RDF_FIRST)) { keys++; - if (!(get(RDF_FIRST) instanceof List && ((List) get(RDF_FIRST)).size() == 1)) { + if (!(get(RDF_FIRST) instanceof List + && ((List) get(RDF_FIRST)).size() == 1)) { return false; } } if (containsKey(RDF_REST)) { keys++; - if (!(get(RDF_REST) instanceof List && ((List) get(RDF_REST)).size() == 1)) { + if (!(get(RDF_REST) instanceof List + && ((List) get(RDF_REST)).size() == 1)) { return false; } } if (containsKey(JsonLdConsts.TYPE)) { keys++; - if (!(get(JsonLdConsts.TYPE) instanceof List && ((List) get(JsonLdConsts.TYPE)).size() == 1) + if (!(get(JsonLdConsts.TYPE) instanceof List + && ((List) get(JsonLdConsts.TYPE)).size() == 1) && RDF_LIST.equals(((List) get(JsonLdConsts.TYPE)).get(0))) { return false; } @@ -1797,10 +1819,28 @@ public Map serialize() { * If there was an error during conversion from RDF to JSON-LD. */ public List fromRDF(final RDFDataset dataset) throws JsonLdError { + return fromRDF(dataset, false); + } + + /** + * Converts RDF statements into JSON-LD, presuming that there are no duplicates in the dataset. + * + * @param dataset + * the RDF statements. + * @param noDuplicatesInDataset + * True if there are no duplicates in the dataset and false otherwise. + * @return A list of JSON-LD objects found in the given dataset. + * @throws JsonLdError + * If there was an error during conversion from RDF to JSON-LD. + * @deprecated Experimental method, only use if you are sure you need to use this method. Most users will need to use {@link #fromRDF(RDFDataset)}. + */ + @Deprecated + public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInDataset) throws JsonLdError { // 1) final Map defaultGraph = new LinkedHashMap(4); // 2) - final Map> graphMap = new LinkedHashMap>(4); + final Map> graphMap = new LinkedHashMap>( + 4); graphMap.put(JsonLdConsts.DEFAULT, defaultGraph); // 3/3.1) @@ -1854,9 +1894,12 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { final Map value = object.toObject(opts.getUseNativeTypes()); // 3.5.6+7) - JsonLdUtils.mergeValue(node, predicate, value); - // JsonLdUtils.laxMergeValue(node, predicate, value); - + if(noDuplicatesInDataset) { + JsonLdUtils.laxMergeValue(node, predicate, value); + } else { + JsonLdUtils.mergeValue(node, predicate, value); + } + // 3.5.8) if (object.isBlankNode() || object.isIRI()) { // 3.5.8.1-3) @@ -2049,9 +2092,8 @@ public Object normalize(Map dataset) throws JsonLdError { final String[] attrs = new String[] { "subject", "object", "name" }; for (final String attr : attrs) { - if (quad.containsKey(attr) - && "blank node".equals(((Map) quad.get(attr)) - .get("type"))) { + if (quad.containsKey(attr) && "blank node" + .equals(((Map) quad.get(attr)).get("type"))) { final String id = (String) ((Map) quad.get(attr)) .get("value"); if (!bnodes.containsKey(id)) { @@ -2069,8 +2111,8 @@ public Object normalize(Map dataset) throws JsonLdError { } // mapping complete, start canonical naming - final NormalizeUtils normalizeUtils = new NormalizeUtils(quads, bnodes, new UniqueNamer( - "_:c14n"), opts); + final NormalizeUtils normalizeUtils = new NormalizeUtils(quads, bnodes, + new UniqueNamer("_:c14n"), opts); return normalizeUtils.hashBlankNodes(bnodes.keySet()); } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 10310001..10955298 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -127,12 +127,12 @@ static void laxMergeValue(Map obj, String key, Object value) { values = new ArrayList(); obj.put(key, values); } - if ("@list".equals(key) - || (value instanceof Map && ((Map) value).containsKey("@list")) + //if ("@list".equals(key) + // || (value instanceof Map && ((Map) value).containsKey("@list")) //|| !deepContains(values, value) - ) { + // ) { values.add(value); - } + //} } static void mergeCompactedValue(Map obj, String key, Object value) { From 0d19da22087a47d83ed29462cbce1c932d014265 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 00:37:14 -0400 Subject: [PATCH 193/440] Add performance tests for the rdf parsing methods --- .../core/JsonLdPerformanceTest.java | 249 +++++++++++++++++- 1 file changed, 246 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index e7b8e4f0..7fa4ec20 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.LongSummaryStatistics; import java.util.Random; +import java.util.function.Function; import java.util.zip.GZIPInputStream; import org.apache.commons.io.FileUtils; @@ -113,11 +114,11 @@ private void testCompaction(String label, InputStream nextInputStream) System.out.println("(" + label + ") Compact average : " + compactStats.getAverage()); } - @Ignore("Disable performance tests by default") + // @Ignore("Disable performance tests by default") @Test public final void testPerformanceRandom() throws Exception { Random prng = new Random(); - int rounds = 2000; + int rounds = 10000; String exNs = "http://example.org/"; @@ -157,7 +158,7 @@ public final void testPerformanceRandom() throws Exception { RDFDataset testData = new RDFDataset(); - for (int i = 0; i < 8000; i++) { + for (int i = 0; i < 2000; i++) { String nextObject = potentialObjects.get(prng.nextInt(potentialObjects.size())); boolean isLiteral = true; if (nextObject.startsWith("_:") || nextObject.startsWith("http://")) { @@ -222,6 +223,38 @@ public final void testPerformanceRandom() throws Exception { System.out.println("Minimum: " + stats.getMin() / 100000); System.out.println("Count: " + stats.getCount()); + System.out.println( + "RDF triples to JSON-LD (internal objects, not parsed from a document), using laxMergeValue..."); + JsonLdOptions optionsLax = new JsonLdOptions(); + JsonLdApi jsonLdApiLax = new JsonLdApi(optionsLax); + int[] hashCodesLax = new int[rounds]; + LongSummaryStatistics statsLaxFirst5000 = new LongSummaryStatistics(); + LongSummaryStatistics statsLax = new LongSummaryStatistics(); + for (int i = 0; i < rounds; i++) { + long start = System.nanoTime(); + Object fromRDF = jsonLdApiLax.fromRDF(testData, true); + if (i < 5000) { + statsLaxFirst5000.accept(System.nanoTime() - start); + } else { + statsLax.accept(System.nanoTime() - start); + } + hashCodesLax[i] = fromRDF.hashCode(); + fromRDF = null; + } + System.out.println("First 5000 out of " + rounds); + System.out.println("Average: " + statsLaxFirst5000.getAverage() / 100000); + System.out.println("Sum: " + statsLaxFirst5000.getSum() / 100000); + System.out.println("Maximum: " + statsLaxFirst5000.getMax() / 100000); + System.out.println("Minimum: " + statsLaxFirst5000.getMin() / 100000); + System.out.println("Count: " + statsLaxFirst5000.getCount()); + + System.out.println("Post 5000 out of " + rounds); + System.out.println("Average: " + statsLax.getAverage() / 100000); + System.out.println("Sum: " + statsLax.getSum() / 100000); + System.out.println("Maximum: " + statsLax.getMax() / 100000); + System.out.println("Minimum: " + statsLax.getMin() / 100000); + System.out.println("Count: " + statsLax.getCount()); + System.out.println("Non-pretty print benchmarking..."); JsonLdOptions options2 = new JsonLdOptions(); JsonLdApi jsonLdApi2 = new JsonLdApi(options2); @@ -310,4 +343,214 @@ public final void testPerformanceRandom() throws Exception { System.out.println("Count: " + statsPart4.getCount()); } + + /** + * many triples with same subject and prop: current implementation is slow + * + * @author fpservant + */ + @Test + public final void slowVsFast5Predicates() throws Exception { + + final String ns = "http://www.example.com/foo/"; + + Function subjectGenerator = new Function() { + public String apply(Integer index) { + return ns + "s"; + } + }; + Function predicateGenerator = new Function() { + public String apply(Integer index) { + return ns + "p" + Integer.toString(index % 5); + } + }; + Function objectGenerator = new Function() { + public String apply(Integer index) { + return ns + "o" + Integer.toString(index); + } + }; + int tripleCount = 2000; + int warmingRounds = 200; + int rounds = 1000; + + runLaxVersusSlowToRDFTest("5 predicates", ns, subjectGenerator, predicateGenerator, + objectGenerator, tripleCount, warmingRounds, rounds); + + } + + /** + * many triples with same subject and prop: current implementation is slow + * + * @author fpservant + */ + @Test + public final void slowVsFast2Predicates() throws Exception { + + final String ns = "http://www.example.com/foo/"; + + Function subjectGenerator = new Function() { + public String apply(Integer index) { + return ns + "s"; + } + }; + Function predicateGenerator = new Function() { + public String apply(Integer index) { + return ns + "p" + Integer.toString(index % 2); + } + }; + Function objectGenerator = new Function() { + public String apply(Integer index) { + return ns + "o" + Integer.toString(index); + } + }; + int tripleCount = 2000; + int warmingRounds = 200; + int rounds = 1000; + + runLaxVersusSlowToRDFTest("2 predicates", ns, subjectGenerator, predicateGenerator, + objectGenerator, tripleCount, warmingRounds, rounds); + + } + + /** + * many triples with same subject and prop: current implementation is slow + * + * @author fpservant + */ + @Test + public final void slowVsFast1Predicate() throws Exception { + + final String ns = "http://www.example.com/foo/"; + + Function subjectGenerator = new Function() { + public String apply(Integer index) { + return ns + "s"; + } + }; + Function predicateGenerator = new Function() { + public String apply(Integer index) { + return ns + "p"; + } + }; + Function objectGenerator = new Function() { + public String apply(Integer index) { + return ns + "o" + Integer.toString(index); + } + }; + int tripleCount = 2000; + int warmingRounds = 200; + int rounds = 1000; + + runLaxVersusSlowToRDFTest("1 predicate", ns, subjectGenerator, predicateGenerator, + objectGenerator, tripleCount, warmingRounds, rounds); + + } + + /** + * Run a test on lax versus slow methods for toRDF. + * + * @param ns + * The namespace to assign + * @param subjectGenerator + * A {@link Function} used to generate the subject IRIs + * @param predicateGenerator + * A {@link Function} used to generate the predicate IRIs + * @param objectGenerator + * A {@link Function} used to generate the object IRIs + * @param tripleCount + * The number of triples to create for the dataset + * @param warmingRounds + * The number of warming rounds to use + * @param rounds + * The number of test rounds to use + * @throws JsonLdError + * If there is an error with the JSONLD processing. + */ + public void runLaxVersusSlowToRDFTest(final String label, final String ns, + Function subjectGenerator, + Function predicateGenerator, Function objectGenerator, + int tripleCount, int warmingRounds, int rounds) throws JsonLdError { + + System.out.println("Running test for lax versus slow for " + label); + + RDFDataset inputRdf = new RDFDataset(); + inputRdf.setNamespace("ex", ns); + + for (int i = 0; i < tripleCount; i++) { + inputRdf.addTriple(subjectGenerator.apply(i), predicateGenerator.apply(i), + objectGenerator.apply(i)); + } + + final JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + + // warming + for (int i = 0; i < warmingRounds; i++) { + new JsonLdApi(options).fromRDF(inputRdf); + // JsonLdProcessor.expand(new JsonLdApi(options).fromRDF(inputRdf)); + } + + for (int i = 0; i < warmingRounds; i++) { + new JsonLdApi(options).fromRDF(inputRdf, true); + // JsonLdProcessor.expand(new JsonLdApi(options).fromRDF(inputRdf, + // true)); + } + + System.out.println("Average time to parse a dataset containing one subject with " + + tripleCount + " different triples:"); + long startLax = System.currentTimeMillis(); + for (int i = 0; i < rounds; i++) { + new JsonLdApi(options).fromRDF(inputRdf, true); + // JsonLdProcessor.expand(new JsonLdApi(options).fromRDF(inputRdf, + // true)); + } + System.out.println("\t- Assuming no duplicates: " + + (((System.currentTimeMillis() - startLax)) / rounds)); + + long start = System.currentTimeMillis(); + for (int i = 0; i < rounds; i++) { + new JsonLdApi(options).fromRDF(inputRdf); + // JsonLdProcessor.expand(new JsonLdApi(options).fromRDF(inputRdf)); + } + System.out.println( + "\t- Assuming duplicates: " + (((System.currentTimeMillis() - start)) / rounds)); + } + + /** + * @author fpservant + */ + @Test + public final void duplicatedTriplesInAnRDFDataset() throws Exception { + RDFDataset inputRdf = new RDFDataset(); + String ns = "http://www.example.com/foo/"; + inputRdf.setNamespace("ex", ns); + inputRdf.addTriple(ns + "s", ns + "p", ns + "o"); + inputRdf.addTriple(ns + "s", ns + "p", ns + "o"); + + System.out.println("Twice the same triple in RDFDataset:/n"); + for (Quad quad : inputRdf.getQuads("@default")) { + System.out.println(quad); + } + + final JsonLdOptions options = new JsonLdOptions(); + options.useNamespaces = true; + + Object fromRDF; + String jsonld; + + System.out.println("\nJSON-LD output is OK:\n"); + fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + inputRdf.getContext(), options); + + jsonld = JsonUtils.toPrettyString(fromRDF); + System.out.println(jsonld); + + System.out.println( + "\nWouldn't be the case assuming there is no duplicated triple in RDFDataset:\n"); + fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf, true), + inputRdf.getContext(), options); + jsonld = JsonUtils.toPrettyString(fromRDF); + System.out.println(jsonld); + + } } From 462d4aaceaeab197ad7eac7ff2ddf2f467fccc17 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 00:54:00 -0400 Subject: [PATCH 194/440] Add some more tests of the lax versus full merge situation --- .../core/JsonLdPerformanceTest.java | 79 ++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 7fa4ec20..7fdd527a 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -114,7 +114,7 @@ private void testCompaction(String label, InputStream nextInputStream) System.out.println("(" + label + ") Compact average : " + compactStats.getAverage()); } - // @Ignore("Disable performance tests by default") + @Ignore("Disable performance tests by default") @Test public final void testPerformanceRandom() throws Exception { Random prng = new Random(); @@ -349,6 +349,7 @@ public final void testPerformanceRandom() throws Exception { * * @author fpservant */ + @Ignore("Disable performance tests by default") @Test public final void slowVsFast5Predicates() throws Exception { @@ -383,6 +384,7 @@ public String apply(Integer index) { * * @author fpservant */ + @Ignore("Disable performance tests by default") @Test public final void slowVsFast2Predicates() throws Exception { @@ -417,6 +419,7 @@ public String apply(Integer index) { * * @author fpservant */ + @Ignore("Disable performance tests by default") @Test public final void slowVsFast1Predicate() throws Exception { @@ -446,6 +449,76 @@ public String apply(Integer index) { } + /** + * many triples with same subject and prop: current implementation is slow + * + * @author fpservant + */ + @Ignore("Disable performance tests by default") + @Test + public final void slowVsFastMultipleSubjects1Predicate() throws Exception { + + final String ns = "http://www.example.com/foo/"; + + Function subjectGenerator = new Function() { + public String apply(Integer index) { + return ns + "s" + Integer.toString(index % 100); + } + }; + Function predicateGenerator = new Function() { + public String apply(Integer index) { + return ns + "p"; + } + }; + Function objectGenerator = new Function() { + public String apply(Integer index) { + return ns + "o" + Integer.toString(index); + } + }; + int tripleCount = 2000; + int warmingRounds = 200; + int rounds = 1000; + + runLaxVersusSlowToRDFTest("100 subjects and 1 predicate", ns, subjectGenerator, predicateGenerator, + objectGenerator, tripleCount, warmingRounds, rounds); + + } + + /** + * many triples with same subject and prop: current implementation is slow + * + * @author fpservant + */ + @Ignore("Disable performance tests by default") + @Test + public final void slowVsFastMultipleSubjects5Predicates() throws Exception { + + final String ns = "http://www.example.com/foo/"; + + Function subjectGenerator = new Function() { + public String apply(Integer index) { + return ns + "s" + Integer.toString(index % 1000); + } + }; + Function predicateGenerator = new Function() { + public String apply(Integer index) { + return ns + "p" + Integer.toString(index % 5); + } + }; + Function objectGenerator = new Function() { + public String apply(Integer index) { + return ns + "o" + Integer.toString(index); + } + }; + int tripleCount = 2000; + int warmingRounds = 200; + int rounds = 1000; + + runLaxVersusSlowToRDFTest("1000 subjects and 5 predicates", ns, subjectGenerator, predicateGenerator, + objectGenerator, tripleCount, warmingRounds, rounds); + + } + /** * Run a test on lax versus slow methods for toRDF. * @@ -466,7 +539,7 @@ public String apply(Integer index) { * @throws JsonLdError * If there is an error with the JSONLD processing. */ - public void runLaxVersusSlowToRDFTest(final String label, final String ns, + private void runLaxVersusSlowToRDFTest(final String label, final String ns, Function subjectGenerator, Function predicateGenerator, Function objectGenerator, int tripleCount, int warmingRounds, int rounds) throws JsonLdError { @@ -496,7 +569,7 @@ public void runLaxVersusSlowToRDFTest(final String label, final String ns, // true)); } - System.out.println("Average time to parse a dataset containing one subject with " + System.out.println("Average time to parse a dataset containing " + tripleCount + " different triples:"); long startLax = System.currentTimeMillis(); for (int i = 0; i < rounds; i++) { From e682f28d785b065d4bd8089ab0dad28f79512583 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 01:03:16 -0400 Subject: [PATCH 195/440] Add note to changelog about allowing default inside of sets --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2fa376d0..023a2788 100644 --- a/README.md +++ b/README.md @@ -403,6 +403,9 @@ CHANGELOG ### 2016-05-18 * Fix @base in remote contexts corrupting the local context +### 2016-04-23 +* Support @default inside of sets for framing + ### 2016-02-29 * Fix ConcurrentModificationException in the implementation of the Framing API From 08333f8b1e41227cc2eb1560d23996c962213e0c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 01:04:04 -0400 Subject: [PATCH 196/440] Release 0.8.3 --- README.md | 3 ++- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 023a2788..380ea8ca 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.8.2 + 0.8.3 Code example @@ -401,6 +401,7 @@ CHANGELOG ========= ### 2016-05-18 +* Release 0.8.3 * Fix @base in remote contexts corrupting the local context ### 2016-04-23 diff --git a/core/pom.xml b/core/pom.xml index e317d19e..8f8bf294 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.3-SNAPSHOT + 0.8.3 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 7b0908d5..b9636df2 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.3-SNAPSHOT + 0.8.3 JSONLD Java :: Parent Json-LD Java Parent POM pom From 0451364de9dd7c4d4bcb1a2413309aed8a679f3c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 01:08:35 -0400 Subject: [PATCH 197/440] Bump to next snapshot --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 8f8bf294..01f5512c 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.3 + 0.8.4-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index b9636df2..b85a7c2a 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.3 + 0.8.4-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 86366a4de1e1876d5236d246acce69dacdd2df07 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 18 May 2016 19:28:02 -0400 Subject: [PATCH 198/440] Cache maven files on Travis --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 312621f2..f39b7428 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,8 @@ language: java +sudo: false +cache: + directories: + - $HOME/.m2 jdk: - oraclejdk8 notifications: From 74b2c9339fac3306674bf676f89b56f1a728578b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 19 May 2016 19:03:49 -0400 Subject: [PATCH 199/440] Avoid creating a new map to do a get that will always be null Also add a sanity check on the actual node that may have been deleted by one of the recursive calls Fixes #179 --- .../com/github/jsonldjava/core/JsonLdApi.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index a7f5d548..0928ea03 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1572,11 +1572,10 @@ private static void removeDependents(Map embeds, String id) { // get embed keys as a separate array to enable deleting keys in map for (final String id_dep : new HashSet(embeds.keySet())) { final EmbedNode e = embeds.get(id_dep); - final Object p = e.parent != null ? e.parent : newMap(); - if (!(p instanceof Map)) { + if (e == null || e.parent == null || !(e.parent instanceof Map)) { continue; } - final String pid = (String) ((Map) p).get(JsonLdConsts.ID); + final String pid = (String) ((Map) e.parent).get(JsonLdConsts.ID); if (Obj.equals(id, pid)) { embeds.remove(id_dep); removeDependents(embeds, id_dep); @@ -1823,19 +1822,24 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { } /** - * Converts RDF statements into JSON-LD, presuming that there are no duplicates in the dataset. + * Converts RDF statements into JSON-LD, presuming that there are no + * duplicates in the dataset. * * @param dataset * the RDF statements. - * @param noDuplicatesInDataset - * True if there are no duplicates in the dataset and false otherwise. + * @param noDuplicatesInDataset + * True if there are no duplicates in the dataset and false + * otherwise. * @return A list of JSON-LD objects found in the given dataset. * @throws JsonLdError * If there was an error during conversion from RDF to JSON-LD. - * @deprecated Experimental method, only use if you are sure you need to use this method. Most users will need to use {@link #fromRDF(RDFDataset)}. + * @deprecated Experimental method, only use if you are sure you need to use + * this method. Most users will need to use + * {@link #fromRDF(RDFDataset)}. */ @Deprecated - public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInDataset) throws JsonLdError { + public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInDataset) + throws JsonLdError { // 1) final Map defaultGraph = new LinkedHashMap(4); // 2) @@ -1894,7 +1898,7 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData final Map value = object.toObject(opts.getUseNativeTypes()); // 3.5.6+7) - if(noDuplicatesInDataset) { + if (noDuplicatesInDataset) { JsonLdUtils.laxMergeValue(node, predicate, value); } else { JsonLdUtils.mergeValue(node, predicate, value); From b779efa73a3bfaa1b6bd50b3f05eff67d780978e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 19 May 2016 19:10:23 -0400 Subject: [PATCH 200/440] Add changelog entry for issue #179 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 380ea8ca..02941c36 100644 --- a/README.md +++ b/README.md @@ -400,6 +400,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2016-05-20 +* Fix reported NPE in JsonLdApi.removeDependents + ### 2016-05-18 * Release 0.8.3 * Fix @base in remote contexts corrupting the local context From 6edf852f25014d6e3a442d6b7f0147a27c225800 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 4 Aug 2016 19:15:43 -0400 Subject: [PATCH 201/440] issue#180 : Add disabled regression tests for schema.org Doesn't seem to be an issue locally with jsonld-java, so disabling the regression tests. --- .../jsonldjava/core/DocumentLoaderTest.java | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index d3ef225f..4d11a7dd 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -36,13 +36,19 @@ import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.util.EntityUtils; import org.junit.After; +import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; @SuppressWarnings("unchecked") public class DocumentLoaderTest { - DocumentLoader documentLoader = new DocumentLoader(); + private DocumentLoader documentLoader = new DocumentLoader(); + + @After + public void setContextClassLoader() { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + } @Test public void fromURLTest0001() throws Exception { @@ -104,6 +110,33 @@ public void fromURLredirect() throws Exception { assertFalse(((Map) context).isEmpty()); } + // @Ignore("Integration test") + @Test + public void loadDocumentWf4ever() throws Exception { + final RemoteDocument document = documentLoader.loadDocument("http://purl.org/wf4ever/ro-bundle/context.json"); + Object context = document.getDocument(); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + + @Ignore("Integration test") + @Test + public void fromURLSchemaOrg() throws Exception { + final URL url = new URL("http://schema.org/"); + final Object context = documentLoader.fromURL(url); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + + @Ignore("Integration test") + @Test + public void loadDocumentSchemaOrg() throws Exception { + final RemoteDocument document = documentLoader.loadDocument("http://schema.org/"); + Object context = document.getDocument(); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + @Test public void fromURLCache() throws Exception { final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); @@ -233,11 +266,6 @@ public void jarCacheMiss404() throws Exception { .fromURL(new URL("http://nonexisting.example.com/miss")); } - @After - public void setContextClassLoader() { - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - } - @Test(expected = IOException.class) public void jarCacheMissThreadCtx() throws Exception { final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); From e53dbb0f50a1feddb28c0602b5e969d42084a1e2 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 4 Aug 2016 19:27:50 -0400 Subject: [PATCH 202/440] Disable another test that requires schema.org until google fix it --- .../java/com/github/jsonldjava/core/ContextCompactionTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index fb08bee7..44d0679b 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -10,6 +10,7 @@ import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import com.fasterxml.jackson.core.JsonGenerationException; @@ -17,6 +18,7 @@ public class ContextCompactionTest { + @Ignore("Disable until schema.org is fixed") @Test public void testCompaction() throws Exception { From 59eb810d30db10cf1016e8bc7928a1d3edb7ed62 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 4 Aug 2016 22:35:58 -0400 Subject: [PATCH 203/440] Add test for schema.org that does work, showing they broke compatibility with httpclient specifically --- .../jsonldjava/core/DocumentLoaderTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 4d11a7dd..01f3b101 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -13,14 +13,19 @@ import java.io.IOException; import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.HttpURLConnection; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.net.URLStreamHandler; +import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; @@ -40,6 +45,8 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import com.github.jsonldjava.utils.JsonUtils; + @SuppressWarnings("unchecked") public class DocumentLoaderTest { @@ -128,6 +135,28 @@ public void fromURLSchemaOrg() throws Exception { assertFalse(((Map) context).isEmpty()); } + //@Ignore("Integration test") + @Test + public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { + final URL url = new URL("http://schema.org/"); + + HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); + urlConn.addRequestProperty("Accept", "application/ld+json"); + + InputStream directStream = urlConn.getInputStream(); + + StringWriter output = new StringWriter(); + try { + IOUtils.copy(directStream, output, Charset.forName("UTF-8")); + } + finally { + directStream.close(); + } + Object context = JsonUtils.fromReader(new StringReader(output.toString())); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + @Ignore("Integration test") @Test public void loadDocumentSchemaOrg() throws Exception { From 2d53ddd45d4c0a69b9f3120e871699b0c3c4879f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 4 Aug 2016 22:49:11 -0400 Subject: [PATCH 204/440] Deprecate some methods in DocumentLoader that don't need to be present --- .../java/com/github/jsonldjava/core/DocumentLoader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index de9f4199..6b98b426 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -26,7 +26,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { final RemoteDocument doc = new RemoteDocument(url, null); try { - doc.setDocument(fromURL(new URL(url))); + doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); } catch (final Exception e) { throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); } @@ -54,7 +54,9 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { * If the JSON was not valid. * @throws IOException * If there was an error resolving the resource. + * @deprecated Since 0.8.4, use {@link #loadDocument(String)} instead. */ + @Deprecated public Object fromURL(java.net.URL url) throws JsonParseException, IOException { return JsonUtils.fromURL(url, getHttpClient()); } @@ -70,7 +72,9 @@ public Object fromURL(java.net.URL url) throws JsonParseException, IOException { * @return An InputStream containing the contents of the source. * @throws IOException * If there was an error resolving the {@link java.net.URL}. + * @deprecated Since 0.8.4, use {@link #loadDocument(String)} instead. */ + @Deprecated public InputStream openStreamFromURL(java.net.URL url) throws IOException { return JsonUtils.openStreamForURL(url, getHttpClient()); } From 5ae9c89e27e958f92a1e48ed36d10e2e7c49855b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 4 Aug 2016 22:54:05 -0400 Subject: [PATCH 205/440] Add hack to make schema.org accessible by using HttpURLConnection schema.org has broken compatibility somehow with Apache HttpClient, resulting in failed requests. Fixes #180 Signed-off-by: Peter Ansell --- .../jsonldjava/core/DocumentLoader.java | 6 +++- .../github/jsonldjava/utils/JsonUtils.java | 36 +++++++++++++++++-- .../core/ContextCompactionTest.java | 2 +- .../jsonldjava/core/DocumentLoaderTest.java | 4 +-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 6b98b426..b5e34d49 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -26,7 +26,11 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { final RemoteDocument doc = new RemoteDocument(url, null); try { - doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); + if(url.equalsIgnoreCase("http://schema.org/")) { + doc.setDocument(JsonUtils.fromURLJavaNet(new URL(url))); + } else { + doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); + } } catch (final Exception e) { throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 3fa8021a..2cb7ac3f 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -8,9 +8,13 @@ import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.Charset; import java.util.List; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; @@ -129,18 +133,18 @@ public static Object fromReader(Reader reader) throws IOException { } else if (initialToken == JsonToken.VALUE_NULL) { rval = null; } else { - throw new JsonParseException("document doesn't start with a valid json element : " + throw new JsonParseException(jp, "document doesn't start with a valid json element : " + initialToken, jp.getCurrentLocation()); } JsonToken t ; try { t = jp.nextToken(); } catch (JsonParseException ex) { - throw new JsonParseException("Document contains more content after json-ld element - (possible mismatched {}?)", + throw new JsonParseException(jp, "Document contains more content after json-ld element - (possible mismatched {}?)", jp.getCurrentLocation()); } if ( t != null ) - throw new JsonParseException("Document contains possible json content after the json-ld element - (possible mismatched {}?)", + throw new JsonParseException(jp, "Document contains possible json content after the json-ld element - (possible mismatched {}?)", jp.getCurrentLocation()); return rval; } @@ -314,6 +318,32 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) t } } + /** + * Fallback method directly using the {@link java.net.HttpURLConnection} class for cases where servers do not interoperate correctly with Apache HTTPClient. + * @param url The URL to access. + * @return The result, after conversion from JSON to a Java Object. + * @throws JsonParseException + * If there was a JSON related error during parsing. + * @throws IOException + * If there was an IO error during parsing. + */ + public static Object fromURLJavaNet(java.net.URL url) throws JsonParseException, IOException { + HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); + urlConn.addRequestProperty("Accept", ACCEPT_HEADER); + + InputStream directStream = urlConn.getInputStream(); + + StringWriter output = new StringWriter(); + try { + IOUtils.copy(directStream, output, Charset.forName("UTF-8")); + } + finally { + directStream.close(); + } + Object context = JsonUtils.fromReader(new StringReader(output.toString())); + return context; + } + public static CloseableHttpClient getDefaultHttpClient() { CloseableHttpClient result = DEFAULT_HTTP_CLIENT; if (result == null) { diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index 44d0679b..9861ed32 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -18,7 +18,7 @@ public class ContextCompactionTest { - @Ignore("Disable until schema.org is fixed") + //@Ignore("Disable until schema.org is fixed") @Test public void testCompaction() throws Exception { diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 01f3b101..8f0cfc76 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -126,7 +126,7 @@ public void loadDocumentWf4ever() throws Exception { assertFalse(((Map) context).isEmpty()); } - @Ignore("Integration test") + @Ignore("Broken at server side") @Test public void fromURLSchemaOrg() throws Exception { final URL url = new URL("http://schema.org/"); @@ -157,7 +157,7 @@ public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { assertFalse(((Map) context).isEmpty()); } - @Ignore("Integration test") + //@Ignore("Integration test") @Test public void loadDocumentSchemaOrg() throws Exception { final RemoteDocument document = documentLoader.loadDocument("http://schema.org/"); From edf859b4ce5156fc4d1664a1ff6b087f6a2300ba Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 4 Aug 2016 23:07:44 -0400 Subject: [PATCH 206/440] Start on a minimal regression test for schema.org Signed-off-by: Peter Ansell --- .../github/jsonldjava/utils/JsonUtils.java | 1 + .../core/MinimalSchemaOrgRegressionTest.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 2cb7ac3f..25ed4a94 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -339,6 +339,7 @@ public static Object fromURLJavaNet(java.net.URL url) throws JsonParseException, } finally { directStream.close(); + output.flush(); } Object context = JsonUtils.fromReader(new StringReader(output.toString())); return context; diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java new file mode 100644 index 00000000..9469568e --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -0,0 +1,38 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.*; + +import java.io.InputStream; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.Charset; + +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +public class MinimalSchemaOrgRegressionTest { + + @Test + public void testHttpURLConnection() throws Exception { + URL url = new URL("http://schema.org/"); + HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); + urlConn.addRequestProperty("Accept", + "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"); + + InputStream directStream = urlConn.getInputStream(); + StringWriter output = new StringWriter(); + try { + IOUtils.copy(directStream, output, Charset.forName("UTF-8")); + } finally { + directStream.close(); + output.flush(); + } + String outputString = output.toString(); + // Test for some basic conditions without including the JSON/JSON-LD + // parsing code here + assertTrue(outputString.endsWith("}\n")); + assertTrue(outputString.length() > 100000); + } + +} From e4c9fca097dee692faecff506f0fd92e60f9d579 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 00:19:08 -0400 Subject: [PATCH 207/440] Add test that apparently succeeds with Apache HTTP Client Signed-off-by: Peter Ansell --- .../core/MinimalSchemaOrgRegressionTest.java | 65 ++++++++++++++++++- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index 9469568e..cd8c03e2 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.*; +import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.net.HttpURLConnection; @@ -9,18 +10,34 @@ import java.nio.charset.Charset; import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.protocol.RequestAcceptEncoding; +import org.apache.http.client.protocol.ResponseContentEncoding; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.cache.BasicHttpCacheStorage; +import org.apache.http.impl.client.cache.CacheConfig; +import org.apache.http.impl.client.cache.CachingHttpClientBuilder; import org.junit.Test; +import com.github.jsonldjava.utils.JarCacheStorage; + public class MinimalSchemaOrgRegressionTest { + private static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; + @Test public void testHttpURLConnection() throws Exception { - URL url = new URL("http://schema.org/"); + final URL url = new URL("http://schema.org/"); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); - urlConn.addRequestProperty("Accept", - "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"); + urlConn.addRequestProperty("Accept", ACCEPT_HEADER); InputStream directStream = urlConn.getInputStream(); + verifyInputStream(directStream); + } + + private void verifyInputStream(InputStream directStream) throws IOException { StringWriter output = new StringWriter(); try { IOUtils.copy(directStream, output, Charset.forName("UTF-8")); @@ -35,4 +52,46 @@ public void testHttpURLConnection() throws Exception { assertTrue(outputString.length() > 100000); } + @Test + public void testApacheHttpClient() throws Exception { + final URL url = new URL("http://schema.org/"); + // Common CacheConfig for both the JarCacheStorage and the underlying + // BasicHttpCacheStorage + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + + CloseableHttpClient httpClient = CachingHttpClientBuilder.create() + // allow caching + .setCacheConfig(cacheConfig) + // Wrap the local JarCacheStorage around a BasicHttpCacheStorage + .setHttpCacheStorage(new JarCacheStorage(null, cacheConfig, + new BasicHttpCacheStorage(cacheConfig))) + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + .addInterceptorFirst(new RequestAcceptEncoding()) + .addInterceptorFirst(new ResponseContentEncoding()) + // use system defaults for proxy etc. + .useSystemProperties().build(); + + final HttpUriRequest request = new HttpGet(url.toExternalForm()); + // We prefer application/ld+json, but fallback to application/json + // or whatever is available + request.addHeader("Accept", ACCEPT_HEADER); + + final CloseableHttpResponse response = httpClient.execute(request); + try { + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + InputStream content = response.getEntity().getContent(); + verifyInputStream(content); + } finally { + if (response != null) { + response.close(); + } + } + + } + } From 4ab26b3a0a591d7b7d449fd33873a0f255a09a99 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 00:32:23 -0400 Subject: [PATCH 208/440] Add test that apparently succeeds with Apache HTTP Client Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/Context.java | 8 +- .../jsonldjava/core/DocumentLoader.java | 14 +- .../com/github/jsonldjava/core/JsonLdApi.java | 9 +- .../github/jsonldjava/core/JsonLdConsts.java | 6 +- .../github/jsonldjava/core/JsonLdOptions.java | 6 +- .../jsonldjava/core/JsonLdProcessor.java | 42 ++-- .../github/jsonldjava/core/JsonLdUtils.java | 88 ++++---- .../jsonldjava/core/NormalizeUtils.java | 44 ++-- .../github/jsonldjava/core/RDFDataset.java | 43 ++-- .../jsonldjava/core/RDFDatasetUtils.java | 67 +++--- .../com/github/jsonldjava/core/Regex.java | 28 +-- .../jsonldjava/impl/TurtleRDFParser.java | 62 +++--- .../jsonldjava/impl/TurtleTripleCallback.java | 7 +- .../jsonldjava/utils/JarCacheStorage.java | 13 +- .../github/jsonldjava/utils/JsonLdUrl.java | 12 +- .../github/jsonldjava/utils/JsonUtils.java | 107 +++++---- .../core/ArrayContextToRDFTest.java | 3 +- .../core/ContextCompactionTest.java | 10 +- .../jsonldjava/core/DocumentLoaderTest.java | 50 ++--- .../jsonldjava/core/JsonLdFramingTest.java | 18 +- .../core/JsonLdPerformanceTest.java | 206 ++++++++++-------- .../jsonldjava/core/JsonLdProcessorTest.java | 79 +++---- .../github/jsonldjava/core/LocalBaseTest.java | 3 - .../jsonldjava/core/LongestPrefixTest.java | 16 +- .../com/github/jsonldjava/core/RegexTest.java | 32 +-- .../jsonldjava/impl/TurtleRDFParserTest.java | 28 +-- .../jsonldjava/impl/TurtleRegexTests.java | 8 +- .../jsonldjava/utils/EarlTestSuite.java | 4 +- .../jsonldjava/utils/JsonUtilsTest.java | 4 +- pom.xml | 4 +- 30 files changed, 536 insertions(+), 485 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index c98749f7..3456356d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -145,7 +145,7 @@ public Context parse(Object localContext, List remoteContexts) throws Js /** * Helper method used to work around logic errors related to the recursive * nature of the JSONLD-API Context Processing Algorithm. - * + * * @param localContext * The Local Context object. * @param remoteContexts @@ -200,7 +200,7 @@ else if (context instanceof String) { // with an @context member throw new JsonLdError(Error.INVALID_REMOTE_CONTEXT, context); } - Object tempContext = ((Map) remoteContext) + final Object tempContext = ((Map) remoteContext) .get(JsonLdConsts.CONTEXT); // 3.2.4 @@ -805,10 +805,10 @@ else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { public static String _iriCompactionStep5point4(String iri, Object value, String compactIRI, final String candidate, Map termDefinitions) { - boolean condition1 = (compactIRI == null + final boolean condition1 = (compactIRI == null || compareShortestLeast(candidate, compactIRI) < 0); - boolean condition2 = (!termDefinitions.containsKey(candidate) || (iri + final boolean condition2 = (!termDefinitions.containsKey(candidate) || (iri .equals(((Map) termDefinitions.get(candidate)).get(JsonLdConsts.ID)) && value == null)); diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index b5e34d49..727ef85c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -18,7 +18,8 @@ public class DocumentLoader { public static final String DISALLOW_REMOTE_CONTEXT_LOADING = "com.github.jsonldjava.disallowRemoteContextLoading"; public RemoteDocument loadDocument(String url) throws JsonLdError { - String disallowRemote = System.getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); + final String disallowRemote = System + .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); if ("true".equalsIgnoreCase(disallowRemote)) { throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); @@ -26,7 +27,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { final RemoteDocument doc = new RemoteDocument(url, null); try { - if(url.equalsIgnoreCase("http://schema.org/")) { + if (url.equalsIgnoreCase("http://schema.org/")) { doc.setDocument(JsonUtils.fromURLJavaNet(new URL(url))); } else { doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); @@ -39,6 +40,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { /** * An HTTP Accept header that prefers JSONLD. + * * @deprecated Use {@link JsonUtils#ACCEPT_HEADER} instead. */ @Deprecated @@ -64,7 +66,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { public Object fromURL(java.net.URL url) throws JsonParseException, IOException { return JsonUtils.fromURL(url, getHttpClient()); } - + /** * Opens an {@link InputStream} for the given {@link java.net.URL}, * including support for http and https URLs that are requested using @@ -82,13 +84,13 @@ public Object fromURL(java.net.URL url) throws JsonParseException, IOException { public InputStream openStreamFromURL(java.net.URL url) throws IOException { return JsonUtils.openStreamForURL(url, getHttpClient()); } - + public CloseableHttpClient getHttpClient() { CloseableHttpClient result = httpClient; if (result == null) { - synchronized(DocumentLoader.class) { + synchronized (DocumentLoader.class) { result = httpClient; - if(result == null) { + if (result == null) { result = httpClient = JsonUtils.getDefaultHttpClient(); } } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 0928ea03..a22f98e1 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1625,20 +1625,21 @@ private boolean filterNode(FramingContext state, Map node, for (final String key : frame.keySet()) { if (JsonLdConsts.ID.equals(key) || !isKeyword(key) && !(node.containsKey(key))) { - Object frameObject = frame.get(key); + final Object frameObject = frame.get(key); if (frameObject instanceof ArrayList) { - ArrayList o = (ArrayList) frame.get(key); + final ArrayList o = (ArrayList) frame.get(key); boolean _default = false; - for (Object oo : o) { + for (final Object oo : o) { if (oo instanceof Map) { if (((Map) oo).containsKey(JsonLdConsts.DEFAULT)) { _default = true; } } } - if (_default) + if (_default) { continue; + } } return false; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java index 0e311c67..d4400326 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java @@ -27,14 +27,14 @@ public final class JsonLdConsts { public static final String RDF_OBJECT = RDF_SYNTAX_NS + "object"; public static final String RDF_LANGSTRING = RDF_SYNTAX_NS + "langString"; public static final String RDF_LIST = RDF_SYNTAX_NS + "List"; - + public static final String TEXT_TURTLE = "text/turtle"; public static final String APPLICATION_NQUADS = "application/nquads"; - + public static final String FLATTENED = "flattened"; public static final String COMPACTED = "compacted"; public static final String EXPANDED = "expanded"; - + public static final String ID = "@id"; public static final String DEFAULT = "@default"; public static final String GRAPH = "@graph"; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 51f3145d..3bea9492 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -1,9 +1,9 @@ package com.github.jsonldjava.core; /** - * The JsonLdOptions type as specified in the JSON-LD-API - * specification. + * The JsonLdOptions type as specified in the + * JSON-LD- + * API specification. * * @author tristan * diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 7bad0938..efbfcf0e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -16,8 +16,8 @@ /** * This class implements the JsonLdProcessor interface, except that it does not currently support + * "http://json-ld.org/spec/latest/json-ld-api/#the-jsonldprocessor-interface" > + * JsonLdProcessor interface, except that it does not currently support * asynchronous processing, and hence does not return Promises, instead directly * returning the results. * @@ -50,7 +50,8 @@ public static Map compact(Object input, Object context, JsonLdOp // 2-6) NOTE: these are all the same steps as in expand final Object expanded = expand(input, opts); // 7) - if (context instanceof Map && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { + if (context instanceof Map + && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { context = ((Map) context).get(JsonLdConsts.CONTEXT); } Context activeCtx = new Context(opts); @@ -92,8 +93,8 @@ public static Map compact(Object input, Object context, JsonLdOp } /** - * Expands the given input according to the steps in the Expansion + * Expands the given input according to the steps in the + * Expansion * algorithm. * * @param input @@ -132,7 +133,8 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL // 4) if (opts.getExpandContext() != null) { Object exCtx = opts.getExpandContext(); - if (exCtx instanceof Map && ((Map) exCtx).containsKey(JsonLdConsts.CONTEXT)) { + if (exCtx instanceof Map + && ((Map) exCtx).containsKey(JsonLdConsts.CONTEXT)) { exCtx = ((Map) exCtx).get(JsonLdConsts.CONTEXT); } activeCtx = activeCtx.parse(exCtx); @@ -163,8 +165,8 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL } /** - * Expands the given input according to the steps in the Expansion + * Expands the given input according to the steps in the + * Expansion * algorithm, using the default {@link JsonLdOptions}. * * @param input @@ -182,7 +184,8 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // 2-6) NOTE: these are all the same steps as in expand final Object expanded = expand(input, opts); // 7) - if (context instanceof Map && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { + if (context instanceof Map + && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { context = ((Map) context).get(JsonLdConsts.CONTEXT); } // 8) NOTE: blank node generation variables are members of JsonLdApi @@ -195,7 +198,8 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) // 2) new JsonLdApi(opts).generateNodeMap(expanded, nodeMap); // 3) - final Map defaultGraph = (Map) nodeMap.remove(JsonLdConsts.DEFAULT); + final Map defaultGraph = (Map) nodeMap + .remove(JsonLdConsts.DEFAULT); // 4) for (final String graphName : nodeMap.keySet()) { final Map graph = (Map) nodeMap.get(graphName); @@ -257,9 +261,9 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) /** * Flattens the given input and compacts it using the passed context - * according to the steps in the Flattening - * algorithm: + * according to the steps in the + * + * Flattening algorithm: * * @param input * The input JSON-LD object. @@ -275,8 +279,9 @@ public static Object flatten(Object input, JsonLdOptions opts) throws JsonLdErro } /** - * Frames the given input using the frame according to the steps in the + * Frames the given input using the frame according to the steps in the + * * Framing Algorithm. * * @param input @@ -304,7 +309,8 @@ public static Map frame(Object input, Object frame, JsonLdOption final JsonLdApi api = new JsonLdApi(expandedInput, opts); final List framed = api.frame(expandedInput, expandedFrame); - final Context activeCtx = api.context.parse(((Map) frame).get(JsonLdConsts.CONTEXT)); + final Context activeCtx = api.context + .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); Object compacted = api.compact(activeCtx, null, framed); if (!(compacted instanceof List)) { @@ -431,8 +437,8 @@ public static Object fromRDF(Object input, JsonLdOptions options, RDFParser pars } else if (JsonLdConsts.FLATTENED.equals(options.outputForm)) { return flatten(rval, dataset.getContext(), options); } else { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, "Output form was unknown: " - + options.outputForm); + throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, + "Output form was unknown: " + options.outputForm); } } return rval; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 10955298..6c6469ce 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -21,7 +21,8 @@ public class JsonLdUtils { * * @param v * the value to check. - * @param [ctx] the active context to check against. + * @param [ctx] + * the active context to check against. * * @return true if the value is a keyword, false if not. */ @@ -127,12 +128,13 @@ static void laxMergeValue(Map obj, String key, Object value) { values = new ArrayList(); obj.put(key, values); } - //if ("@list".equals(key) - // || (value instanceof Map && ((Map) value).containsKey("@list")) - //|| !deepContains(values, value) - // ) { - values.add(value); - //} + // if ("@list".equals(key) + // || (value instanceof Map && ((Map) + // value).containsKey("@list")) + // || !deepContains(values, value) + // ) { + values.add(value); + // } } static void mergeCompactedValue(Map obj, String key, Object value) { @@ -173,9 +175,8 @@ static boolean isNode(Object v) { // 1. It is an Object. // 2. It is not a @value, @set, or @list. // 3. It has more than 1 key OR any existing key is not @id. - if (v instanceof Map - && !(((Map) v).containsKey("@value") || ((Map) v).containsKey("@set") || ((Map) v) - .containsKey("@list"))) { + if (v instanceof Map && !(((Map) v).containsKey("@value") || ((Map) v).containsKey("@set") + || ((Map) v).containsKey("@list"))) { return ((Map) v).size() > 1 || !((Map) v).containsKey("@id"); } return false; @@ -193,8 +194,8 @@ static boolean isNodeReference(Object v) { // Note: A value is a subject reference if all of these hold true: // 1. It is an Object. // 2. It has a single key: @id. - return (v instanceof Map && ((Map) v).size() == 1 && ((Map) v) - .containsKey("@id")); + return (v instanceof Map && ((Map) v).size() == 1 + && ((Map) v).containsKey("@id")); } // TODO: fix this test @@ -221,10 +222,12 @@ public static boolean isRelativeIri(String value) { * the property that relates the value to the subject. * @param value * the value to add. - * @param [propertyIsArray] true if the property is always an array, false - * if not (default: false). - * @param [allowDuplicate] true if the property is a @list, false if not - * (default: false). + * @param [propertyIsArray] + * true if the property is always an array, false if not + * (default: false). + * @param [allowDuplicate] + * true if the property is a @list, false if not (default: + * false). */ static void addValue(Map subject, String property, Object value, boolean propertyIsArray, boolean allowDuplicate) { @@ -400,8 +403,8 @@ static boolean validateTypeValue(Object v) throws JsonLdError { // must be a string, subject reference, or empty object if (v instanceof String - || (v instanceof Map && (((Map) v).containsKey("@id") || ((Map) v) - .size() == 0))) { + || (v instanceof Map && (((Map) v).containsKey("@id") + || ((Map) v).size() == 0))) { return true; } @@ -410,8 +413,8 @@ static boolean validateTypeValue(Object v) throws JsonLdError { if (v instanceof List) { isValid = true; for (final Object i : (List) v) { - if (!(i instanceof String || i instanceof Map - && ((Map) i).containsKey("@id"))) { + if (!(i instanceof String + || i instanceof Map && ((Map) i).containsKey("@id"))) { isValid = false; break; } @@ -670,9 +673,9 @@ private static boolean hasProperty(Map subject, String property) * Compares two JSON-LD values for equality. Two JSON-LD values will be * considered equal if: * - * 1. They are both primitives of the same type and value. 2. They are both @values - * with the same @value, @type, and @language, OR 3. They both have @ids - * they are the same. + * 1. They are both primitives of the same type and value. 2. They are + * both @values with the same @value, @type, and @language, OR 3. They both + * have @ids they are the same. * * @param v1 * the first value. @@ -686,23 +689,22 @@ static boolean compareValues(Object v1, Object v2) { return true; } - if (isValue(v1) - && isValue(v2) + if (isValue(v1) && isValue(v2) && Obj.equals(((Map) v1).get("@value"), ((Map) v2).get("@value")) - && Obj.equals(((Map) v1).get("@type"), - ((Map) v2).get("@type")) - && Obj.equals(((Map) v1).get("@language"), - ((Map) v2).get("@language")) - && Obj.equals(((Map) v1).get("@index"), - ((Map) v2).get("@index"))) { + && Obj.equals(((Map) v1).get("@type"), + ((Map) v2).get("@type")) + && Obj.equals(((Map) v1).get("@language"), + ((Map) v2).get("@language")) + && Obj.equals(((Map) v1).get("@index"), + ((Map) v2).get("@index"))) { return true; } if ((v1 instanceof Map && ((Map) v1).containsKey("@id")) && (v2 instanceof Map && ((Map) v2).containsKey("@id")) - && ((Map) v1).get("@id").equals( - ((Map) v2).get("@id"))) { + && ((Map) v1).get("@id") + .equals(((Map) v2).get("@id"))) { return true; } @@ -718,15 +720,17 @@ && isValue(v2) * the property that relates the value to the subject. * @param value * the value to remove. - * @param [options] the options to use: [propertyIsArray] true if the - * property is always an array, false if not (default: false). + * @param [options] + * the options to use: [propertyIsArray] true if the property is + * always an array, false if not (default: false). */ - static void removeValue(Map subject, String property, Map value) { + static void removeValue(Map subject, String property, + Map value) { removeValue(subject, property, value, false); } - static void removeValue(Map subject, String property, - Map value, boolean propertyIsArray) { + static void removeValue(Map subject, String property, Map value, + boolean propertyIsArray) { // filter out value final List values = new ArrayList(); if (subject.get(property) instanceof List) { @@ -767,9 +771,8 @@ static boolean isBlankNode(Object v) { if (((Map) v).containsKey("@id")) { return ((String) ((Map) v).get("@id")).startsWith("_:"); } else { - return ((Map) v).size() == 0 - || !(((Map) v).containsKey("@value") || ((Map) v).containsKey("@set") || ((Map) v) - .containsKey("@list")); + return ((Map) v).size() == 0 || !(((Map) v).containsKey("@value") + || ((Map) v).containsKey("@set") || ((Map) v).containsKey("@list")); } } return false; @@ -788,7 +791,8 @@ static boolean isBlankNode(Object v) { * * @return true if new URLs to resolve were found, false if not. */ - private static boolean findContextUrls(Object input, Map urls, Boolean replace) { + private static boolean findContextUrls(Object input, Map urls, + Boolean replace) { final int count = urls.size(); if (input instanceof List) { for (final Object i : (List) input) { diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index 6aab6e46..2745d53f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -31,7 +31,7 @@ public NormalizeUtils(List quads, Map bnodes, UniqueName this.namer = namer; } - // generates unique and duplicate hashes for bnodes + // generates unique and duplicate hashes for bnodes public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { List unnamed = new ArrayList(unnamed_); List nextUnnamed = new ArrayList(); @@ -93,24 +93,24 @@ public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { for (int cai = 0; cai < quads.size(); ++cai) { final Map quad = (Map) quads .get(cai); - for (final String attr : new String[] { "subject", "object", "name" }) { + for (final String attr : new String[] { "subject", "object", + "name" }) { if (quad.containsKey(attr)) { final Map qa = (Map) quad .get(attr); - if (qa != null - && "blank node".equals(qa.get("type")) - && ((String) qa.get("value")).indexOf("_:c14n") != 0) { + if (qa != null && "blank node".equals(qa.get("type")) + && ((String) qa.get("value")) + .indexOf("_:c14n") != 0) { qa.put("value", namer.getName((String) qa.get(("value")))); } } } - normalized - .add(toNQuad( - (RDFDataset.Quad) quad, - quad.containsKey("name") - && quad.get("name") != null ? (String) ((Map) quad - .get("name")).get("value") : null)); + normalized.add(toNQuad((RDFDataset.Quad) quad, + quad.containsKey("name") && quad.get("name") != null + ? (String) ((Map) quad.get("name")) + .get("value") + : null)); } // sort normalized output @@ -119,7 +119,7 @@ public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { // handle output format if (options.format != null) { if ("application/nquads".equals(options.format)) { - StringBuilder rval = new StringBuilder(); + final StringBuilder rval = new StringBuilder(); for (final String n : normalized) { rval.append(n); } @@ -129,7 +129,7 @@ public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { options.format); } } - StringBuilder rval = new StringBuilder(); + final StringBuilder rval = new StringBuilder(); for (final String n : normalized) { rval.append(n); } @@ -171,7 +171,8 @@ public int compare(HashResult a, HashResult b) { final UniqueNamer pathNamer = new UniqueNamer("_:b"); pathNamer.getName(bnode); - final HashResult result = hashPaths(bnode, bnodes, namer, pathNamer); + final HashResult result = hashPaths(bnode, bnodes, namer, + pathNamer); results.add(result); } } @@ -435,8 +436,10 @@ private static String hashQuads(String id, Map bnodes, UniqueNam final List nquads = new ArrayList(); for (int i = 0; i < quads.size(); ++i) { nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), - quads.get(i).get("name") != null ? (String) ((Map) quads.get(i) - .get("name")).get("value") : null, id)); + quads.get(i).get("name") != null + ? (String) ((Map) quads.get(i).get("name")).get("value") + : null, + id)); } // sort serialized quads Collections.sort(nquads); @@ -490,8 +493,8 @@ private static String encodeHex(final byte[] data) { */ private static String getAdjacentBlankNodeName(Map node, String id) { return "blank node".equals(node.get("type")) - && (!node.containsKey("value") || !Obj.equals(node.get("value"), id)) ? (String) node - .get("value") : null; + && (!node.containsKey("value") || !Obj.equals(node.get("value"), id)) + ? (String) node.get("value") : null; } private static class Permutator { @@ -540,8 +543,9 @@ public List next() { final String element = this.list.get(i); final Boolean left = this.left.get(element); if ((k == null || element.compareTo(k) > 0) - && ((left && i > 0 && element.compareTo(this.list.get(i - 1)) > 0) || (!left - && i < (length - 1) && element.compareTo(this.list.get(i + 1)) > 0))) { + && ((left && i > 0 && element.compareTo(this.list.get(i - 1)) > 0) + || (!left && i < (length - 1) + && element.compareTo(this.list.get(i + 1)) > 0))) { k = element; pos = i; } diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index e1bf55c1..be0ef294 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -48,8 +48,8 @@ public static class Quad extends LinkedHashMap implements Compar public Quad(final String subject, final String predicate, final String object, final String graph) { - this(subject, predicate, object.startsWith("_:") ? new BlankNode(object) : new IRI( - object), graph); + this(subject, predicate, + object.startsWith("_:") ? new BlankNode(object) : new IRI(object), graph); }; public Quad(final String subject, final String predicate, final String value, @@ -59,11 +59,12 @@ public Quad(final String subject, final String predicate, final String value, private Quad(final String subject, final String predicate, final Node object, final String graph) { - this(subject.startsWith("_:") ? new BlankNode(subject) : new IRI(subject), new IRI( - predicate), object, graph); + this(subject.startsWith("_:") ? new BlankNode(subject) : new IRI(subject), + new IRI(predicate), object, graph); }; - public Quad(final Node subject, final Node predicate, final Node object, final String graph) { + public Quad(final Node subject, final Node predicate, final Node object, + final String graph) { super(); put("subject", subject); put("predicate", predicate); @@ -112,8 +113,8 @@ public int compareTo(Quad o) { } } - public static abstract class Node extends LinkedHashMap implements - Comparable { + public static abstract class Node extends LinkedHashMap + implements Comparable { private static final long serialVersionUID = 1460990331795672793L; public abstract boolean isLiteral(); @@ -198,10 +199,11 @@ Map toObject(Boolean useNativeTypes) throws JsonLdError { rval.put("@type", type); } } else if ( - // http://www.w3.org/TR/xmlschema11-2/#integer - (XSD_INTEGER.equals(type) && PATTERN_INTEGER.matcher(value).matches()) + // http://www.w3.org/TR/xmlschema11-2/#integer + (XSD_INTEGER.equals(type) && PATTERN_INTEGER.matcher(value).matches()) // http://www.w3.org/TR/xmlschema11-2/#nt-doubleRep - || (XSD_DOUBLE.equals(type) && PATTERN_DOUBLE.matcher(value).matches())) { + || (XSD_DOUBLE.equals(type) + && PATTERN_DOUBLE.matcher(value).matches())) { try { final Double d = Double.parseDouble(value); if (!Double.isNaN(d) && !Double.isInfinite(d)) { @@ -638,26 +640,27 @@ private Node objectToRDF(Object item) { if (value instanceof Boolean || value instanceof Number) { // convert to XSD datatype if (value instanceof Boolean) { - return new Literal(value.toString(), datatype == null ? XSD_BOOLEAN - : (String) datatype, null); + return new Literal(value.toString(), + datatype == null ? XSD_BOOLEAN : (String) datatype, null); } else if (value instanceof Double || value instanceof Float || XSD_DOUBLE.equals(datatype)) { // canonical double representation final DecimalFormat df = new DecimalFormat("0.0###############E0"); df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); - return new Literal(df.format(value), datatype == null ? XSD_DOUBLE - : (String) datatype, null); + return new Literal(df.format(value), + datatype == null ? XSD_DOUBLE : (String) datatype, null); } else { final DecimalFormat df = new DecimalFormat("0"); - return new Literal(df.format(value), datatype == null ? XSD_INTEGER - : (String) datatype, null); + return new Literal(df.format(value), + datatype == null ? XSD_INTEGER : (String) datatype, null); } } else if (((Map) item).containsKey("@language")) { - return new Literal((String) value, datatype == null ? RDF_LANGSTRING - : (String) datatype, (String) ((Map) item).get("@language")); + return new Literal((String) value, + datatype == null ? RDF_LANGSTRING : (String) datatype, + (String) ((Map) item).get("@language")); } else { - return new Literal((String) value, datatype == null ? XSD_STRING - : (String) datatype, null); + return new Literal((String) value, + datatype == null ? XSD_STRING : (String) datatype, null); } } // convert string/node object to RDF diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 4961752a..30e8f0af 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -106,8 +106,8 @@ static List graphToRDF(Map graph, UniqueNamer namer) { * @param triples * the array of triples to append to. */ - private static void listToRDF(List list, UniqueNamer namer, - Map subject, Map predicate, List triples) { + private static void listToRDF(List list, UniqueNamer namer, Map subject, + Map predicate, List triples) { final Map first = newMap(); first.put("type", "IRI"); first.put("value", RDF_FIRST); @@ -215,10 +215,11 @@ private static Object objectToRDF(Object item, UniqueNamer namer) { } public static String toNQuads(RDFDataset dataset) { - StringBuilder output = new StringBuilder(256); + final StringBuilder output = new StringBuilder(256); toNQuads(dataset, output); return output.toString(); } + public static void toNQuads(RDFDataset dataset, StringBuilder output) { final List quads = new ArrayList(); for (String graphName : dataset.graphNames()) { @@ -237,11 +238,13 @@ public static void toNQuads(RDFDataset dataset, StringBuilder output) { } static String toNQuad(RDFDataset.Quad triple, String graphName, String bnode) { - StringBuilder output = new StringBuilder(256); + final StringBuilder output = new StringBuilder(256); toNQuad(triple, graphName, bnode, output); return output.toString(); } - static void toNQuad(RDFDataset.Quad triple, String graphName, String bnode, StringBuilder output) { + + static void toNQuad(RDFDataset.Quad triple, String graphName, String bnode, + StringBuilder output) { final RDFDataset.Node s = triple.getSubject(); final RDFDataset.Node p = triple.getPredicate(); final RDFDataset.Node o = triple.getObject(); @@ -252,7 +255,7 @@ static void toNQuad(RDFDataset.Quad triple, String graphName, String bnode, Stri escape(s.getValue(), output); output.append(">"); } - // normalization mode + // normalization mode else if (bnode != null) { output.append(bnode.equals(s.getValue()) ? "_:a" : "_:z"); } @@ -321,8 +324,8 @@ static String toNQuad(RDFDataset.Quad triple, String graphName) { return toNQuad(triple, graphName, null); } - final private static Pattern UCHAR_MATCHED = Pattern.compile("\\u005C(?:([tbnrf\\\"'])|(?:u(" - + HEX + "{4}))|(?:U(" + HEX + "{8})))"); + final private static Pattern UCHAR_MATCHED = Pattern + .compile("\\u005C(?:([tbnrf\\\"'])|(?:u(" + HEX + "{4}))|(?:U(" + HEX + "{8})))"); public static String unescape(String str) { String rval = str; @@ -393,20 +396,26 @@ public static String unescape(String str) { /** * Escapes the given string according to the N-Quads escape rules - * @param str The string to escape + * + * @param str + * The string to escape * @return The escaped string * @deprecated Use {@link #escape(String, StringBuilder)} instead. */ + @Deprecated public static String escape(String str) { - StringBuilder rval = new StringBuilder(); + final StringBuilder rval = new StringBuilder(); escape(str, rval); return rval.toString(); } - + /** * Escapes the given string according to the N-Quads escape rules - * @param str The string to escape - * @param rval The {@link StringBuilder} to append to. + * + * @param str + * The string to escape + * @param rval + * The {@link StringBuilder} to append to. */ public static void escape(String str, StringBuilder rval) { for (int i = 0; i < str.length(); i++) { @@ -417,12 +426,12 @@ public static void escape(String str, StringBuilder rval) { // supplement // characters ((hi >= 0x24F // 0x24F is the end of latin extensions - && !Character.isHighSurrogate(hi)) + && !Character.isHighSurrogate(hi)) // TODO: there's probably a lot of other characters that // shouldn't be escaped that // fall outside these ranges, this is one example from the // json-ld tests - )) { + )) { rval.append(String.format("\\u%04x", (int) hi)); } else if (Character.isHighSurrogate(hi)) { final char lo = str.charAt(++i); @@ -445,9 +454,9 @@ public static void escape(String str, StringBuilder rval) { case '\r': rval.append("\\r"); break; - // case '\'': - // rval += "\\'"; - // break; + // case '\'': + // rval += "\\'"; + // break; case '\"': rval.append("\\\""); // rval += "\\u0022"; @@ -462,7 +471,7 @@ public static void escape(String str, StringBuilder rval) { } } } - //return rval; + // return rval; } private static class Regex { @@ -474,8 +483,8 @@ private static class Regex { final public static Pattern PLAIN = Pattern.compile("\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\""); final public static Pattern DATATYPE = Pattern.compile("(?:\\^\\^" + IRI + ")"); final public static Pattern LANGUAGE = Pattern.compile("(?:@([a-z]+(?:-[a-zA-Z0-9]+)*))"); - final public static Pattern LITERAL = Pattern.compile("(?:" + PLAIN + "(?:" + DATATYPE - + "|" + LANGUAGE + ")?)"); + final public static Pattern LITERAL = Pattern + .compile("(?:" + PLAIN + "(?:" + DATATYPE + "|" + LANGUAGE + ")?)"); final public static Pattern WS = Pattern.compile("[ \\t]+"); final public static Pattern WSO = Pattern.compile("[ \\t]*"); final public static Pattern EOLN = Pattern.compile("(?:\r\n)|(?:\n)|(?:\r)"); @@ -484,14 +493,14 @@ private static class Regex { // define quad part regexes final public static Pattern SUBJECT = Pattern.compile("(?:" + IRI + "|" + BNODE + ")" + WS); final public static Pattern PROPERTY = Pattern.compile(IRI.pattern() + WS.pattern()); - final public static Pattern OBJECT = Pattern.compile("(?:" + IRI + "|" + BNODE + "|" - + LITERAL + ")" + WSO); - final public static Pattern GRAPH = Pattern.compile("(?:\\.|(?:(?:" + IRI + "|" + BNODE - + ")" + WSO + "\\.))"); + final public static Pattern OBJECT = Pattern + .compile("(?:" + IRI + "|" + BNODE + "|" + LITERAL + ")" + WSO); + final public static Pattern GRAPH = Pattern + .compile("(?:\\.|(?:(?:" + IRI + "|" + BNODE + ")" + WSO + "\\.))"); // full quad regex - final public static Pattern QUAD = Pattern.compile("^" + WSO + SUBJECT + PROPERTY + OBJECT - + GRAPH + WSO + "$"); + final public static Pattern QUAD = Pattern + .compile("^" + WSO + SUBJECT + PROPERTY + OBJECT + GRAPH + WSO + "$"); } /** @@ -545,8 +554,8 @@ public static RDFDataset parseNQuads(String input) throws JsonLdError { object = new RDFDataset.BlankNode(unescape(match.group(5))); } else { final String language = unescape(match.group(8)); - final String datatype = match.group(7) != null ? unescape(match.group(7)) : match - .group(8) != null ? RDF_LANGSTRING : XSD_STRING; + final String datatype = match.group(7) != null ? unescape(match.group(7)) + : match.group(8) != null ? RDF_LANGSTRING : XSD_STRING; final String unescaped = unescape(match.group(6)); object = new RDFDataset.Literal(unescaped, datatype, language); } diff --git a/core/src/main/java/com/github/jsonldjava/core/Regex.java b/core/src/main/java/com/github/jsonldjava/core/Regex.java index a34a1ee7..7a6236a7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Regex.java +++ b/core/src/main/java/com/github/jsonldjava/core/Regex.java @@ -7,40 +7,40 @@ public class Regex { // ("1.7".equals(System.getProperty("java.specification.version")) ? // "[\\x{10000}-\\x{EFFFF}]" : "[\uD800\uDC00-\uDB7F\uDFFF]" // this seems to work with jdk1.6 - ); + ); // for ttl - final public static Pattern PN_CHARS_BASE = Pattern - .compile("[a-zA-Z]|[\\u00C0-\\u00D6]|[\\u00D8-\\u00F6]|[\\u00F8-\\u02FF]|[\\u0370-\\u037D]|[\\u037F-\\u1FFF]|" + final public static Pattern PN_CHARS_BASE = Pattern.compile( + "[a-zA-Z]|[\\u00C0-\\u00D6]|[\\u00D8-\\u00F6]|[\\u00F8-\\u02FF]|[\\u0370-\\u037D]|[\\u037F-\\u1FFF]|" + "[\\u200C-\\u200D]|[\\u2070-\\u218F]|[\\u2C00-\\u2FEF]|[\\u3001-\\uD7FF]|[\\uF900-\\uFDCF]|[\\uFDF0-\\uFFFD]|" + TRICKY_UTF_CHARS); final public static Pattern PN_CHARS_U = Pattern.compile(PN_CHARS_BASE + "|[_]"); - final public static Pattern PN_CHARS = Pattern.compile(PN_CHARS_U - + "|[-0-9]|[\\u00B7]|[\\u0300-\\u036F]|[\\u203F-\\u2040]"); - final public static Pattern PN_PREFIX = Pattern.compile("(?:(?:" + PN_CHARS_BASE + ")(?:(?:" - + PN_CHARS + "|[\\.])*(?:" + PN_CHARS + "))?)"); + final public static Pattern PN_CHARS = Pattern + .compile(PN_CHARS_U + "|[-0-9]|[\\u00B7]|[\\u0300-\\u036F]|[\\u203F-\\u2040]"); + final public static Pattern PN_PREFIX = Pattern.compile( + "(?:(?:" + PN_CHARS_BASE + ")(?:(?:" + PN_CHARS + "|[\\.])*(?:" + PN_CHARS + "))?)"); final public static Pattern HEX = Pattern.compile("[0-9A-Fa-f]"); final public static Pattern PN_LOCAL_ESC = Pattern .compile("[\\\\][_~\\.\\-!$&'\\(\\)*+,;=/?#@%]"); final public static Pattern PERCENT = Pattern.compile("%" + HEX + HEX); final public static Pattern PLX = Pattern.compile(PERCENT + "|" + PN_LOCAL_ESC); - final public static Pattern PN_LOCAL = Pattern.compile("((?:" + PN_CHARS_U + "|[:]|[0-9]|" - + PLX + ")(?:(?:" + PN_CHARS + "|[.]|[:]|" + PLX + ")*(?:" + PN_CHARS + "|[:]|" + PLX - + "))?)"); + final public static Pattern PN_LOCAL = Pattern + .compile("((?:" + PN_CHARS_U + "|[:]|[0-9]|" + PLX + ")(?:(?:" + PN_CHARS + "|[.]|[:]|" + + PLX + ")*(?:" + PN_CHARS + "|[:]|" + PLX + "))?)"); final public static Pattern PNAME_NS = Pattern.compile("((?:" + PN_PREFIX + ")?):"); final public static Pattern PNAME_LN = Pattern.compile("" + PNAME_NS + PN_LOCAL); final public static Pattern UCHAR = Pattern.compile("\\u005Cu" + HEX + HEX + HEX + HEX + "|\\u005CU" + HEX + HEX + HEX + HEX + HEX + HEX + HEX + HEX); final public static Pattern ECHAR = Pattern.compile("\\u005C[tbnrf\\u005C\"']"); - final public static Pattern IRIREF = Pattern.compile("(?:<((?:[^\\x00-\\x20<>\"{}|\\^`\\\\]|" - + UCHAR + ")*)>)"); + final public static Pattern IRIREF = Pattern + .compile("(?:<((?:[^\\x00-\\x20<>\"{}|\\^`\\\\]|" + UCHAR + ")*)>)"); final public static Pattern BLANK_NODE_LABEL = Pattern.compile("(?:_:((?:" + PN_CHARS_U + "|[0-9])(?:(?:" + PN_CHARS + "|[\\.])*(?:" + PN_CHARS + "))?))"); final public static Pattern WS = Pattern.compile("[ \t\r\n]"); final public static Pattern WS_0_N = Pattern.compile(WS + "*"); final public static Pattern WS_0_1 = Pattern.compile(WS + "?"); final public static Pattern WS_1_N = Pattern.compile(WS + "+"); - final public static Pattern STRING_LITERAL_QUOTE = Pattern - .compile("\"(?:[^\\u0022\\u005C\\u000A\\u000D]|(?:" + ECHAR + ")|(?:" + UCHAR + "))*\""); + final public static Pattern STRING_LITERAL_QUOTE = Pattern.compile( + "\"(?:[^\\u0022\\u005C\\u000A\\u000D]|(?:" + ECHAR + ")|(?:" + UCHAR + "))*\""); final public static Pattern STRING_LITERAL_SINGLE_QUOTE = Pattern .compile("'(?:[^\\u0027\\u005C\\u000A\\u000D]|(?:" + ECHAR + ")|(?:" + UCHAR + "))*'"); final public static Pattern STRING_LITERAL_LONG_SINGLE_QUOTE = Pattern diff --git a/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java b/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java index ab2959e6..0e721045 100644 --- a/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java +++ b/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java @@ -51,38 +51,38 @@ public class TurtleRDFParser implements RDFParser { static class Regex { - final public static Pattern PREFIX_ID = Pattern.compile("@prefix" + WS_1_N + PNAME_NS - + WS_1_N + IRIREF + WS_0_N + "\\." + WS_0_N); - final public static Pattern BASE = Pattern.compile("@base" + WS_1_N + IRIREF + WS_0_N - + "\\." + WS_0_N); - final public static Pattern SPARQL_PREFIX = Pattern.compile("[Pp][Rr][Ee][Ff][Ii][Xx]" + WS - + PNAME_NS + WS + IRIREF + WS_0_N); - final public static Pattern SPARQL_BASE = Pattern.compile("[Bb][Aa][Ss][Ee]" + WS + IRIREF - + WS_0_N); - - final public static Pattern PREFIXED_NAME = Pattern.compile("(?:" + PNAME_LN + "|" - + PNAME_NS + ")"); - final public static Pattern IRI = Pattern.compile("(?:" + IRIREF + "|" + PREFIXED_NAME - + ")"); + final public static Pattern PREFIX_ID = Pattern + .compile("@prefix" + WS_1_N + PNAME_NS + WS_1_N + IRIREF + WS_0_N + "\\." + WS_0_N); + final public static Pattern BASE = Pattern + .compile("@base" + WS_1_N + IRIREF + WS_0_N + "\\." + WS_0_N); + final public static Pattern SPARQL_PREFIX = Pattern + .compile("[Pp][Rr][Ee][Ff][Ii][Xx]" + WS + PNAME_NS + WS + IRIREF + WS_0_N); + final public static Pattern SPARQL_BASE = Pattern + .compile("[Bb][Aa][Ss][Ee]" + WS + IRIREF + WS_0_N); + + final public static Pattern PREFIXED_NAME = Pattern + .compile("(?:" + PNAME_LN + "|" + PNAME_NS + ")"); + final public static Pattern IRI = Pattern + .compile("(?:" + IRIREF + "|" + PREFIXED_NAME + ")"); final public static Pattern ANON = Pattern.compile("(?:\\[" + WS + "*\\])"); final public static Pattern BLANK_NODE = Pattern.compile(BLANK_NODE_LABEL + "|" + ANON); - final public static Pattern STRING = Pattern.compile("(" + STRING_LITERAL_LONG_SINGLE_QUOTE - + "|" + STRING_LITERAL_LONG_QUOTE + "|" + STRING_LITERAL_QUOTE + "|" - + STRING_LITERAL_SINGLE_QUOTE + ")"); + final public static Pattern STRING = Pattern + .compile("(" + STRING_LITERAL_LONG_SINGLE_QUOTE + "|" + STRING_LITERAL_LONG_QUOTE + + "|" + STRING_LITERAL_QUOTE + "|" + STRING_LITERAL_SINGLE_QUOTE + ")"); final public static Pattern BOOLEAN_LITERAL = Pattern.compile("(true|false)"); - final public static Pattern RDF_LITERAL = Pattern.compile(STRING + "(?:" + LANGTAG - + "|\\^\\^" + IRI + ")?"); - final public static Pattern NUMERIC_LITERAL = Pattern.compile("(" + DOUBLE + ")|(" - + DECIMAL + ")|(" + INTEGER + ")"); - final public static Pattern LITERAL = Pattern.compile(RDF_LITERAL + "|" + NUMERIC_LITERAL - + "|" + BOOLEAN_LITERAL); - - final public static Pattern DIRECTIVE = Pattern.compile("^(?:" + PREFIX_ID + "|" + BASE - + "|" + SPARQL_PREFIX + "|" + SPARQL_BASE + ")"); + final public static Pattern RDF_LITERAL = Pattern + .compile(STRING + "(?:" + LANGTAG + "|\\^\\^" + IRI + ")?"); + final public static Pattern NUMERIC_LITERAL = Pattern + .compile("(" + DOUBLE + ")|(" + DECIMAL + ")|(" + INTEGER + ")"); + final public static Pattern LITERAL = Pattern + .compile(RDF_LITERAL + "|" + NUMERIC_LITERAL + "|" + BOOLEAN_LITERAL); + + final public static Pattern DIRECTIVE = Pattern.compile( + "^(?:" + PREFIX_ID + "|" + BASE + "|" + SPARQL_PREFIX + "|" + SPARQL_BASE + ")"); final public static Pattern SUBJECT = Pattern.compile("^" + IRI + "|" + BLANK_NODE); final public static Pattern PREDICATE = Pattern.compile("^" + IRI + "|a" + WS_1_N); - final public static Pattern OBJECT = Pattern.compile("^" + IRI + "|" + BLANK_NODE + "|" - + LITERAL); + final public static Pattern OBJECT = Pattern + .compile("^" + IRI + "|" + BLANK_NODE + "|" + LITERAL); // others // final public static Pattern WS_AT_LINE_START = Pattern.compile("^" + @@ -92,8 +92,8 @@ static class Regex { // final public static Pattern EMPTY_LINE = Pattern.compile("^" + WS + // "*$"); - final public static Pattern COMMENT_OR_WS = Pattern.compile("^(?:(?:[#].*(?:" + EOLN + ")" - + WS_0_N + ")|(?:" + WS_1_N + "))"); + final public static Pattern COMMENT_OR_WS = Pattern + .compile("^(?:(?:[#].*(?:" + EOLN + ")" + WS_0_N + ")|(?:" + WS_1_N + "))"); } private class State { @@ -180,7 +180,7 @@ public void advanceLinePosition(int len) throws JsonLdError { if ("".equals(line) && !endIsOK()) { throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, "Error while parsing Turtle; unexpected end of input. {line: " + lineNumber - + ", position:" + linePosition + "}"); + + ", position:" + linePosition + "}"); } } @@ -450,7 +450,7 @@ else if (state.line.startsWith("(")) { if (!RDF_FIRST.equals(state.curPredicate)) { throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, "Error while parsing Turtle; unexpected ). {line: " + state.lineNumber - + "position: " + state.linePosition + "}"); + + "position: " + state.linePosition + "}"); } result.addTriple(state.curSubject, RDF_REST, RDF_NIL); state.pop(); diff --git a/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java b/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java index 92e4aad7..d7ee1695 100644 --- a/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java +++ b/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java @@ -220,8 +220,8 @@ private String generateObject(Object object, String sep, boolean hasNext, int in } else if (dt != null) { // TODO: this probably isn't an exclusive list of all the // datatype literals that can be represented as native types - if (!(XSD_DOUBLE.equals(dt) || XSD_INTEGER.equals(dt) || XSD_FLOAT.equals(dt) || XSD_BOOLEAN - .equals(dt))) { + if (!(XSD_DOUBLE.equals(dt) || XSD_INTEGER.equals(dt) || XSD_FLOAT.equals(dt) + || XSD_BOOLEAN.equals(dt))) { obj = "\"" + obj + "\""; if (!XSD_STRING.equals(dt)) { obj += "^^" + getURI(dt); @@ -240,7 +240,8 @@ private String generateObject(Object object, String sep, boolean hasNext, int in final int idxofcr = obj.indexOf("\n"); // check if output will fix in the max line length (factor in comma if // not the last item, current line length and length to the next CR) - if ((hasNext ? 1 : 0) + lineLength + (idxofcr != -1 ? idxofcr : obj.length()) > MAX_LINE_LENGTH) { + if ((hasNext ? 1 : 0) + lineLength + + (idxofcr != -1 ? idxofcr : obj.length()) > MAX_LINE_LENGTH) { rval += "\n" + tabs(indentation + 1); lineLength = (indentation + 1) * TAB_SPACES; } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 35ecce90..8744f796 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -49,7 +49,7 @@ public class JarCacheStorage implements HttpCacheStorage { * All live caching that is not found locally is delegated to this * implementation. */ - private HttpCacheStorage delegate; + private final HttpCacheStorage delegate; ObjectMapper mapper = new ObjectMapper(); @@ -83,7 +83,7 @@ public JarCacheStorage() { } /** - * + * * @param classLoader * The ClassLoader to use to locate JAR files and resources, or * null to use the Thread context class loader in each case. @@ -223,8 +223,9 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach responseHeaders.add(new BasicHeader(headerName, header.asText())); } - return new HttpCacheEntry(new Date(), new Date(), new BasicStatusLine(HttpVersion.HTTP_1_1, - 200, "OK"), responseHeaders.toArray(new Header[0]), resource); + return new HttpCacheEntry(new Date(), new Date(), + new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"), + responseHeaders.toArray(new Header[0]), resource); } @Override @@ -233,8 +234,8 @@ public void removeEntry(String key) throws IOException { } @Override - public void updateEntry(String key, HttpCacheUpdateCallback callback) throws IOException, - HttpCacheUpdateException { + public void updateEntry(String key, HttpCacheUpdateCallback callback) + throws IOException, HttpCacheUpdateException { delegate.updateEntry(key, callback); } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java index b7a316c4..db0fed7e 100755 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java @@ -31,8 +31,8 @@ public class JsonLdUrl { public String normalizedPath = null; public String authority = null; - private static Pattern parser = Pattern - .compile("^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"); + private static Pattern parser = Pattern.compile( + "^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"); public static JsonLdUrl parse(String url) { final JsonLdUrl rval = new JsonLdUrl(); @@ -189,13 +189,13 @@ else if (iri.indexOf("//") != 0) { final JsonLdUrl rel = JsonLdUrl.parse(iri.substring(root.length())); // remove path segments that match - final List baseSegments = new ArrayList(Arrays.asList(base.normalizedPath - .split("/"))); + final List baseSegments = new ArrayList( + Arrays.asList(base.normalizedPath.split("/"))); if (base.normalizedPath.endsWith("/")) { baseSegments.add(""); } - final List iriSegments = new ArrayList(Arrays.asList(rel.normalizedPath - .split("/"))); + final List iriSegments = new ArrayList( + Arrays.asList(rel.normalizedPath.split("/"))); if (rel.normalizedPath.endsWith("/")) { iriSegments.add(""); } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 25ed4a94..304bbf91 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -9,7 +9,6 @@ import java.io.StringWriter; import java.io.Writer; import java.net.HttpURLConnection; -import java.net.URL; import java.nio.charset.Charset; import java.util.List; import java.util.Map; @@ -98,7 +97,10 @@ public static Object fromInputStream(InputStream input) throws IOException { * If there was an IO error during parsing. */ public static Object fromInputStream(InputStream input, String enc) throws IOException { - return fromReader(new BufferedReader(new InputStreamReader(input, enc))); + try (InputStreamReader in = new InputStreamReader(input, enc); + BufferedReader reader = new BufferedReader(in);) { + return fromReader(reader); + } } /** @@ -116,7 +118,7 @@ public static Object fromInputStream(InputStream input, String enc) throws IOExc */ public static Object fromReader(Reader reader) throws IOException { final JsonParser jp = JSON_FACTORY.createParser(reader); - Object rval ; + Object rval; final JsonToken initialToken = jp.nextToken(); if (initialToken == JsonToken.START_ARRAY) { @@ -133,19 +135,24 @@ public static Object fromReader(Reader reader) throws IOException { } else if (initialToken == JsonToken.VALUE_NULL) { rval = null; } else { - throw new JsonParseException(jp, "document doesn't start with a valid json element : " - + initialToken, jp.getCurrentLocation()); + throw new JsonParseException(jp, + "document doesn't start with a valid json element : " + initialToken, + jp.getCurrentLocation()); } - - JsonToken t ; - try { t = jp.nextToken(); } - catch (JsonParseException ex) { - throw new JsonParseException(jp, "Document contains more content after json-ld element - (possible mismatched {}?)", - jp.getCurrentLocation()); + + JsonToken t; + try { + t = jp.nextToken(); + } catch (final JsonParseException ex) { + throw new JsonParseException(jp, + "Document contains more content after json-ld element - (possible mismatched {}?)", + jp.getCurrentLocation()); + } + if (t != null) { + throw new JsonParseException(jp, + "Document contains possible json content after the json-ld element - (possible mismatched {}?)", + jp.getCurrentLocation()); } - if ( t != null ) - throw new JsonParseException(jp, "Document contains possible json content after the json-ld element - (possible mismatched {}?)", - jp.getCurrentLocation()); return rval; } @@ -177,7 +184,8 @@ public static Object fromString(String jsonString) throws JsonParseException, IO * If there was a JSON related error during parsing. * @throws IOException * If there was an IO error during parsing. - * @deprecated Use {@link #fromURL(java.net.URL, CloseableHttpClient)} instead. + * @deprecated Use {@link #fromURL(java.net.URL, CloseableHttpClient)} + * instead. */ @Deprecated public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { @@ -196,8 +204,8 @@ public static Object fromURL(java.net.URL url) throws JsonParseException, IOExce * @throws IOException * If there is an IO error during serialization. */ - public static String toPrettyString(Object jsonObject) throws JsonGenerationException, - IOException { + public static String toPrettyString(Object jsonObject) + throws JsonGenerationException, IOException { final StringWriter sw = new StringWriter(); writePrettyPrint(sw, jsonObject); return sw.toString(); @@ -232,8 +240,8 @@ public static String toString(Object jsonObject) throws JsonGenerationException, * @throws IOException * If there is an IO error during serialization. */ - public static void write(Writer writer, Object jsonObject) throws JsonGenerationException, - IOException { + public static void write(Writer writer, Object jsonObject) + throws JsonGenerationException, IOException { final JsonGenerator jw = JSON_FACTORY.createGenerator(writer); jw.writeObject(jsonObject); } @@ -259,15 +267,22 @@ public static void writePrettyPrint(Writer writer, Object jsonObject) } /** - * Attempts to open an {@link InputStream} that will contain the content of the URL, as resolved by the given HTTP Client. + * Attempts to open an {@link InputStream} that will contain the content of + * the URL, as resolved by the given HTTP Client. + * + * If the URL is not an HTTP or HTTPS URL it is resolved using the default + * {@link java.net.URL#openStream()} method. * - * If the URL is not an HTTP or HTTPS URL it is resolved using the default {@link java.net.URL#openStream()} method. - * @param url The URL to resolve. - * @param httpClient The CloseableHttpClient to use to resolve the URL. + * @param url + * The URL to resolve. + * @param httpClient + * The CloseableHttpClient to use to resolve the URL. * @return An InputStream containing the contents of the resolved URL. - * @throws IOException If there are any IO exceptions while resolving the URL. + * @throws IOException + * If there are any IO exceptions while resolving the URL. */ - public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) throws IOException { + public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) + throws IOException { final String protocol = url.getProtocol(); if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { // Can't use the HTTP client for those! @@ -279,7 +294,7 @@ public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient // We prefer application/ld+json, but fallback to application/json // or whatever is available request.addHeader("Accept", ACCEPT_HEADER); - + final CloseableHttpResponse response = httpClient.execute(request); try { final int status = response.getStatusLine().getStatusCode(); @@ -301,7 +316,7 @@ public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient * * @param url * The JsonLdUrl to resolve - * @param httpClient + * @param httpClient * The {@link CloseableHttpClient} to use to resolve the URL. * @return A JSON Object. * @throws JsonParseException @@ -309,7 +324,8 @@ public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient * @throws IOException * If there was an IO error during parsing. */ - public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) throws JsonParseException, IOException { + public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) + throws JsonParseException, IOException { final InputStream in = openStreamForURL(url, httpClient); try { return fromInputStream(in); @@ -319,8 +335,12 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) t } /** - * Fallback method directly using the {@link java.net.HttpURLConnection} class for cases where servers do not interoperate correctly with Apache HTTPClient. - * @param url The URL to access. + * Fallback method directly using the {@link java.net.HttpURLConnection} + * class for cases where servers do not interoperate correctly with Apache + * HTTPClient. + * + * @param url + * The URL to access. * @return The result, after conversion from JSON to a Java Object. * @throws JsonParseException * If there was a JSON related error during parsing. @@ -328,23 +348,22 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) t * If there was an IO error during parsing. */ public static Object fromURLJavaNet(java.net.URL url) throws JsonParseException, IOException { - HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); + final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.addRequestProperty("Accept", ACCEPT_HEADER); - InputStream directStream = urlConn.getInputStream(); - - StringWriter output = new StringWriter(); + final InputStream directStream = urlConn.getInputStream(); + + final StringWriter output = new StringWriter(); try { IOUtils.copy(directStream, output, Charset.forName("UTF-8")); - } - finally { + } finally { directStream.close(); output.flush(); } - Object context = JsonUtils.fromReader(new StringReader(output.toString())); + final Object context = JsonUtils.fromReader(new StringReader(output.toString())); return context; } - + public static CloseableHttpClient getDefaultHttpClient() { CloseableHttpClient result = DEFAULT_HTTP_CLIENT; if (result == null) { @@ -363,22 +382,20 @@ private static CloseableHttpClient createDefaultHttpClient() { // BasicHttpCacheStorage final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) .setMaxObjectSize(1024 * 128).build(); - - CloseableHttpClient result = CachingHttpClientBuilder - .create() + + final CloseableHttpClient result = CachingHttpClientBuilder.create() // allow caching .setCacheConfig(cacheConfig) // Wrap the local JarCacheStorage around a BasicHttpCacheStorage - .setHttpCacheStorage( - new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( - cacheConfig))) + .setHttpCacheStorage(new JarCacheStorage(null, cacheConfig, + new BasicHttpCacheStorage(cacheConfig))) // Support compressed data // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 .addInterceptorFirst(new RequestAcceptEncoding()) .addInterceptorFirst(new ResponseContentEncoding()) // use system defaults for proxy etc. .useSystemProperties().build(); - + return result; } } diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index 2283d5cb..a16db832 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -21,7 +21,8 @@ public void toRdfWithNamespace() throws Exception { final URL arrayContextUrl = getClass().getResource("/custom/array-context.jsonld"); assertNotNull(arrayContextUrl); - final Object arrayContext = JsonUtils.fromURL(arrayContextUrl, JsonUtils.getDefaultHttpClient()); + final Object arrayContext = JsonUtils.fromURL(arrayContextUrl, + JsonUtils.getDefaultHttpClient()); assertNotNull(arrayContext); final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index 9861ed32..0a08ce8d 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -1,24 +1,20 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; -import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -import com.fasterxml.jackson.core.JsonGenerationException; import com.github.jsonldjava.utils.JsonUtils; public class ContextCompactionTest { - //@Ignore("Disable until schema.org is fixed") + // @Ignore("Disable until schema.org is fixed") @Test public void testCompaction() throws Exception { diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 8f0cfc76..d9881f07 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -41,7 +41,6 @@ import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.util.EntityUtils; import org.junit.After; -import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -50,7 +49,7 @@ @SuppressWarnings("unchecked") public class DocumentLoaderTest { - private DocumentLoader documentLoader = new DocumentLoader(); + private final DocumentLoader documentLoader = new DocumentLoader(); @After public void setContextClassLoader() { @@ -120,13 +119,14 @@ public void fromURLredirect() throws Exception { // @Ignore("Integration test") @Test public void loadDocumentWf4ever() throws Exception { - final RemoteDocument document = documentLoader.loadDocument("http://purl.org/wf4ever/ro-bundle/context.json"); - Object context = document.getDocument(); + final RemoteDocument document = documentLoader + .loadDocument("http://purl.org/wf4ever/ro-bundle/context.json"); + final Object context = document.getDocument(); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); } - @Ignore("Broken at server side") + // @Ignore("Broken at server side") @Test public void fromURLSchemaOrg() throws Exception { final URL url = new URL("http://schema.org/"); @@ -135,33 +135,32 @@ public void fromURLSchemaOrg() throws Exception { assertFalse(((Map) context).isEmpty()); } - //@Ignore("Integration test") + // @Ignore("Integration test") @Test public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { final URL url = new URL("http://schema.org/"); - - HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); + + final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.addRequestProperty("Accept", "application/ld+json"); - InputStream directStream = urlConn.getInputStream(); - - StringWriter output = new StringWriter(); + final InputStream directStream = urlConn.getInputStream(); + + final StringWriter output = new StringWriter(); try { IOUtils.copy(directStream, output, Charset.forName("UTF-8")); - } - finally { + } finally { directStream.close(); } - Object context = JsonUtils.fromReader(new StringReader(output.toString())); + final Object context = JsonUtils.fromReader(new StringReader(output.toString())); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); } - //@Ignore("Integration test") + // @Ignore("Integration test") @Test public void loadDocumentSchemaOrg() throws Exception { final RemoteDocument document = documentLoader.loadDocument("http://schema.org/"); - Object context = document.getDocument(); + final Object context = document.getDocument(); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); } @@ -282,8 +281,8 @@ public void fromURLAcceptHeaders() throws Exception { public void jarCacheHit() throws Exception { // If no cache, should fail-fast as nonexisting.example.com is not in // DNS - final Object context = documentLoader.fromURL(new URL( - "http://nonexisting.example.com/context")); + final Object context = documentLoader + .fromURL(new URL("http://nonexisting.example.com/context")); assertTrue(context instanceof Map); assertTrue(((Map) context).containsKey("@context")); } @@ -299,8 +298,8 @@ public void jarCacheMiss404() throws Exception { public void jarCacheMissThreadCtx() throws Exception { final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); Thread.currentThread().setContextClassLoader(findNothingCL); - final Object context = documentLoader.fromURL(new URL( - "http://nonexisting.example.com/context")); + final Object context = documentLoader + .fromURL(new URL("http://nonexisting.example.com/context")); } @Test @@ -340,26 +339,27 @@ public void differentHttpClient() throws Exception { @Test public void testDisallowRemoteContexts() throws Exception { - String testUrl = "http://json-ld.org/contexts/person.jsonld"; - Object test = documentLoader.loadDocument(testUrl); + final String testUrl = "http://json-ld.org/contexts/person.jsonld"; + final Object test = documentLoader.loadDocument(testUrl); assertNotNull( "Was not able to fetch from URL before testing disallow remote contexts loading", test); - String disallowProperty = System + final String disallowProperty = System .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); try { System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true"); documentLoader.loadDocument(testUrl); fail("Expected exception to occur"); - } catch (JsonLdError e) { + } catch (final JsonLdError e) { assertEquals(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, e.getType()); } finally { if (disallowProperty == null) { System.clearProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); } else { - System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, disallowProperty); + System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, + disallowProperty); } } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 882b5d5e..91c01975 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -1,23 +1,25 @@ package com.github.jsonldjava.core; -import com.github.jsonldjava.utils.JsonUtils; +import static org.junit.Assert.assertEquals; + import java.io.IOException; import java.util.Map; import org.junit.Test; -import static org.junit.Assert.*; + +import com.github.jsonldjava.utils.JsonUtils; public class JsonLdFramingTest { @Test public void testFrame0001() throws IOException, JsonLdError { - Object frame = JsonUtils.fromInputStream( - getClass().getResourceAsStream("/custom/frame-0001-frame.jsonld")); - Object in = JsonUtils.fromInputStream( - getClass().getResourceAsStream("/custom/frame-0001-in.jsonld")); + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0001-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0001-in.jsonld")); + + final Map frame2 = JsonLdProcessor.frame(in, frame, new JsonLdOptions()); - Map frame2 = JsonLdProcessor.frame(in, frame, new JsonLdOptions()); - assertEquals(2, frame2.size()); } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 7fdd527a..bdaf624d 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -11,7 +11,6 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; -import java.util.DoubleSummaryStatistics; import java.util.List; import java.util.LongSummaryStatistics; import java.util.Random; @@ -88,14 +87,14 @@ public final void testLaxMergeValuesPerfSlow() throws Exception { private void testCompaction(String label, InputStream nextInputStream) throws IOException, FileNotFoundException, JsonLdError { - File testFile = File.createTempFile("jsonld-perf-source-", ".jsonld", testDir); + final File testFile = File.createTempFile("jsonld-perf-source-", ".jsonld", testDir); FileUtils.copyInputStreamToFile(nextInputStream, testFile); - LongSummaryStatistics parseStats = new LongSummaryStatistics(); - LongSummaryStatistics compactStats = new LongSummaryStatistics(); + final LongSummaryStatistics parseStats = new LongSummaryStatistics(); + final LongSummaryStatistics compactStats = new LongSummaryStatistics(); for (int i = 0; i < 1000; i++) { - InputStream testInput = new BufferedInputStream(new FileInputStream(testFile)); + final InputStream testInput = new BufferedInputStream(new FileInputStream(testFile)); try { final long parseStart = System.currentTimeMillis(); final Object inputObject = JsonUtils.fromInputStream(testInput); @@ -117,16 +116,16 @@ private void testCompaction(String label, InputStream nextInputStream) @Ignore("Disable performance tests by default") @Test public final void testPerformanceRandom() throws Exception { - Random prng = new Random(); - int rounds = 10000; + final Random prng = new Random(); + final int rounds = 10000; - String exNs = "http://example.org/"; + final String exNs = "http://example.org/"; - String bnode = "_:anon"; - String uri1 = exNs + "a1"; - String uri2 = exNs + "b2"; - String uri3 = exNs + "c3"; - List potentialSubjects = new ArrayList(); + final String bnode = "_:anon"; + final String uri1 = exNs + "a1"; + final String uri2 = exNs + "b2"; + final String uri3 = exNs + "c3"; + final List potentialSubjects = new ArrayList(); potentialSubjects.add(bnode); potentialSubjects.add(uri1); potentialSubjects.add(uri2); @@ -143,11 +142,11 @@ public final void testPerformanceRandom() throws Exception { } Collections.shuffle(potentialSubjects, prng); - List potentialObjects = new ArrayList(); + final List potentialObjects = new ArrayList(); potentialObjects.addAll(potentialSubjects); Collections.shuffle(potentialObjects, prng); - List potentialPredicates = new ArrayList(); + final List potentialPredicates = new ArrayList(); potentialPredicates.add(JsonLdConsts.RDF_TYPE); potentialPredicates.add(JsonLdConsts.RDF_LIST); potentialPredicates.add(JsonLdConsts.RDF_NIL); @@ -156,10 +155,10 @@ public final void testPerformanceRandom() throws Exception { potentialPredicates.add(JsonLdConsts.XSD_STRING); Collections.shuffle(potentialPredicates, prng); - RDFDataset testData = new RDFDataset(); + final RDFDataset testData = new RDFDataset(); for (int i = 0; i < 2000; i++) { - String nextObject = potentialObjects.get(prng.nextInt(potentialObjects.size())); + final String nextObject = potentialObjects.get(prng.nextInt(potentialObjects.size())); boolean isLiteral = true; if (nextObject.startsWith("_:") || nextObject.startsWith("http://")) { isLiteral = false; @@ -193,13 +192,13 @@ public final void testPerformanceRandom() throws Exception { System.out.println( "RDF triples to JSON-LD (internal objects, not parsed from a document)..."); - JsonLdOptions options = new JsonLdOptions(); - JsonLdApi jsonLdApi = new JsonLdApi(options); - int[] hashCodes = new int[rounds]; - LongSummaryStatistics statsFirst5000 = new LongSummaryStatistics(); - LongSummaryStatistics stats = new LongSummaryStatistics(); + final JsonLdOptions options = new JsonLdOptions(); + final JsonLdApi jsonLdApi = new JsonLdApi(options); + final int[] hashCodes = new int[rounds]; + final LongSummaryStatistics statsFirst5000 = new LongSummaryStatistics(); + final LongSummaryStatistics stats = new LongSummaryStatistics(); for (int i = 0; i < rounds; i++) { - long start = System.nanoTime(); + final long start = System.nanoTime(); Object fromRDF = jsonLdApi.fromRDF(testData); if (i < 5000) { statsFirst5000.accept(System.nanoTime() - start); @@ -225,13 +224,13 @@ public final void testPerformanceRandom() throws Exception { System.out.println( "RDF triples to JSON-LD (internal objects, not parsed from a document), using laxMergeValue..."); - JsonLdOptions optionsLax = new JsonLdOptions(); - JsonLdApi jsonLdApiLax = new JsonLdApi(optionsLax); - int[] hashCodesLax = new int[rounds]; - LongSummaryStatistics statsLaxFirst5000 = new LongSummaryStatistics(); - LongSummaryStatistics statsLax = new LongSummaryStatistics(); + final JsonLdOptions optionsLax = new JsonLdOptions(); + final JsonLdApi jsonLdApiLax = new JsonLdApi(optionsLax); + final int[] hashCodesLax = new int[rounds]; + final LongSummaryStatistics statsLaxFirst5000 = new LongSummaryStatistics(); + final LongSummaryStatistics statsLax = new LongSummaryStatistics(); for (int i = 0; i < rounds; i++) { - long start = System.nanoTime(); + final long start = System.nanoTime(); Object fromRDF = jsonLdApiLax.fromRDF(testData, true); if (i < 5000) { statsLaxFirst5000.accept(System.nanoTime() - start); @@ -256,13 +255,13 @@ public final void testPerformanceRandom() throws Exception { System.out.println("Count: " + statsLax.getCount()); System.out.println("Non-pretty print benchmarking..."); - JsonLdOptions options2 = new JsonLdOptions(); - JsonLdApi jsonLdApi2 = new JsonLdApi(options2); - LongSummaryStatistics statsFirst5000Part2 = new LongSummaryStatistics(); - LongSummaryStatistics statsPart2 = new LongSummaryStatistics(); - Object fromRDF2 = jsonLdApi2.fromRDF(testData); + final JsonLdOptions options2 = new JsonLdOptions(); + final JsonLdApi jsonLdApi2 = new JsonLdApi(options2); + final LongSummaryStatistics statsFirst5000Part2 = new LongSummaryStatistics(); + final LongSummaryStatistics statsPart2 = new LongSummaryStatistics(); + final Object fromRDF2 = jsonLdApi2.fromRDF(testData); for (int i = 0; i < rounds; i++) { - long start = System.nanoTime(); + final long start = System.nanoTime(); JsonUtils.toString(fromRDF2); if (i < 5000) { statsFirst5000Part2.accept(System.nanoTime() - start); @@ -285,13 +284,13 @@ public final void testPerformanceRandom() throws Exception { System.out.println("Count: " + statsPart2.getCount()); System.out.println("Pretty print benchmarking..."); - JsonLdOptions options3 = new JsonLdOptions(); - JsonLdApi jsonLdApi3 = new JsonLdApi(options3); - LongSummaryStatistics statsFirst5000Part3 = new LongSummaryStatistics(); - LongSummaryStatistics statsPart3 = new LongSummaryStatistics(); - Object fromRDF3 = jsonLdApi3.fromRDF(testData); + final JsonLdOptions options3 = new JsonLdOptions(); + final JsonLdApi jsonLdApi3 = new JsonLdApi(options3); + final LongSummaryStatistics statsFirst5000Part3 = new LongSummaryStatistics(); + final LongSummaryStatistics statsPart3 = new LongSummaryStatistics(); + final Object fromRDF3 = jsonLdApi3.fromRDF(testData); for (int i = 0; i < rounds; i++) { - long start = System.nanoTime(); + final long start = System.nanoTime(); JsonUtils.toPrettyString(fromRDF3); if (i < 5000) { statsFirst5000Part3.accept(System.nanoTime() - start); @@ -314,13 +313,13 @@ public final void testPerformanceRandom() throws Exception { System.out.println("Count: " + statsPart3.getCount()); System.out.println("Expansion benchmarking..."); - JsonLdOptions options4 = new JsonLdOptions(); - JsonLdApi jsonLdApi4 = new JsonLdApi(options4); - LongSummaryStatistics statsFirst5000Part4 = new LongSummaryStatistics(); - LongSummaryStatistics statsPart4 = new LongSummaryStatistics(); - Object fromRDF4 = jsonLdApi4.fromRDF(testData); + final JsonLdOptions options4 = new JsonLdOptions(); + final JsonLdApi jsonLdApi4 = new JsonLdApi(options4); + final LongSummaryStatistics statsFirst5000Part4 = new LongSummaryStatistics(); + final LongSummaryStatistics statsPart4 = new LongSummaryStatistics(); + final Object fromRDF4 = jsonLdApi4.fromRDF(testData); for (int i = 0; i < rounds; i++) { - long start = System.nanoTime(); + final long start = System.nanoTime(); JsonLdProcessor.expand(fromRDF4, options4); if (i < 5000) { statsFirst5000Part4.accept(System.nanoTime() - start); @@ -346,7 +345,7 @@ public final void testPerformanceRandom() throws Exception { /** * many triples with same subject and prop: current implementation is slow - * + * * @author fpservant */ @Ignore("Disable performance tests by default") @@ -355,24 +354,27 @@ public final void slowVsFast5Predicates() throws Exception { final String ns = "http://www.example.com/foo/"; - Function subjectGenerator = new Function() { + final Function subjectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "s"; } }; - Function predicateGenerator = new Function() { + final Function predicateGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "p" + Integer.toString(index % 5); } }; - Function objectGenerator = new Function() { + final Function objectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "o" + Integer.toString(index); } }; - int tripleCount = 2000; - int warmingRounds = 200; - int rounds = 1000; + final int tripleCount = 2000; + final int warmingRounds = 200; + final int rounds = 1000; runLaxVersusSlowToRDFTest("5 predicates", ns, subjectGenerator, predicateGenerator, objectGenerator, tripleCount, warmingRounds, rounds); @@ -381,7 +383,7 @@ public String apply(Integer index) { /** * many triples with same subject and prop: current implementation is slow - * + * * @author fpservant */ @Ignore("Disable performance tests by default") @@ -390,24 +392,27 @@ public final void slowVsFast2Predicates() throws Exception { final String ns = "http://www.example.com/foo/"; - Function subjectGenerator = new Function() { + final Function subjectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "s"; } }; - Function predicateGenerator = new Function() { + final Function predicateGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "p" + Integer.toString(index % 2); } }; - Function objectGenerator = new Function() { + final Function objectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "o" + Integer.toString(index); } }; - int tripleCount = 2000; - int warmingRounds = 200; - int rounds = 1000; + final int tripleCount = 2000; + final int warmingRounds = 200; + final int rounds = 1000; runLaxVersusSlowToRDFTest("2 predicates", ns, subjectGenerator, predicateGenerator, objectGenerator, tripleCount, warmingRounds, rounds); @@ -416,7 +421,7 @@ public String apply(Integer index) { /** * many triples with same subject and prop: current implementation is slow - * + * * @author fpservant */ @Ignore("Disable performance tests by default") @@ -425,24 +430,27 @@ public final void slowVsFast1Predicate() throws Exception { final String ns = "http://www.example.com/foo/"; - Function subjectGenerator = new Function() { + final Function subjectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "s"; } }; - Function predicateGenerator = new Function() { + final Function predicateGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "p"; } }; - Function objectGenerator = new Function() { + final Function objectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "o" + Integer.toString(index); } }; - int tripleCount = 2000; - int warmingRounds = 200; - int rounds = 1000; + final int tripleCount = 2000; + final int warmingRounds = 200; + final int rounds = 1000; runLaxVersusSlowToRDFTest("1 predicate", ns, subjectGenerator, predicateGenerator, objectGenerator, tripleCount, warmingRounds, rounds); @@ -451,42 +459,45 @@ public String apply(Integer index) { /** * many triples with same subject and prop: current implementation is slow - * + * * @author fpservant */ - @Ignore("Disable performance tests by default") + @Ignore("Disable performance tests by default") @Test public final void slowVsFastMultipleSubjects1Predicate() throws Exception { final String ns = "http://www.example.com/foo/"; - Function subjectGenerator = new Function() { + final Function subjectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "s" + Integer.toString(index % 100); } }; - Function predicateGenerator = new Function() { + final Function predicateGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "p"; } }; - Function objectGenerator = new Function() { + final Function objectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "o" + Integer.toString(index); } }; - int tripleCount = 2000; - int warmingRounds = 200; - int rounds = 1000; + final int tripleCount = 2000; + final int warmingRounds = 200; + final int rounds = 1000; - runLaxVersusSlowToRDFTest("100 subjects and 1 predicate", ns, subjectGenerator, predicateGenerator, - objectGenerator, tripleCount, warmingRounds, rounds); + runLaxVersusSlowToRDFTest("100 subjects and 1 predicate", ns, subjectGenerator, + predicateGenerator, objectGenerator, tripleCount, warmingRounds, rounds); } /** * many triples with same subject and prop: current implementation is slow - * + * * @author fpservant */ @Ignore("Disable performance tests by default") @@ -495,33 +506,36 @@ public final void slowVsFastMultipleSubjects5Predicates() throws Exception { final String ns = "http://www.example.com/foo/"; - Function subjectGenerator = new Function() { + final Function subjectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "s" + Integer.toString(index % 1000); } }; - Function predicateGenerator = new Function() { + final Function predicateGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "p" + Integer.toString(index % 5); } }; - Function objectGenerator = new Function() { + final Function objectGenerator = new Function() { + @Override public String apply(Integer index) { return ns + "o" + Integer.toString(index); } }; - int tripleCount = 2000; - int warmingRounds = 200; - int rounds = 1000; + final int tripleCount = 2000; + final int warmingRounds = 200; + final int rounds = 1000; - runLaxVersusSlowToRDFTest("1000 subjects and 5 predicates", ns, subjectGenerator, predicateGenerator, - objectGenerator, tripleCount, warmingRounds, rounds); + runLaxVersusSlowToRDFTest("1000 subjects and 5 predicates", ns, subjectGenerator, + predicateGenerator, objectGenerator, tripleCount, warmingRounds, rounds); } /** * Run a test on lax versus slow methods for toRDF. - * + * * @param ns * The namespace to assign * @param subjectGenerator @@ -546,7 +560,7 @@ private void runLaxVersusSlowToRDFTest(final String label, final String ns, System.out.println("Running test for lax versus slow for " + label); - RDFDataset inputRdf = new RDFDataset(); + final RDFDataset inputRdf = new RDFDataset(); inputRdf.setNamespace("ex", ns); for (int i = 0; i < tripleCount; i++) { @@ -569,9 +583,9 @@ private void runLaxVersusSlowToRDFTest(final String label, final String ns, // true)); } - System.out.println("Average time to parse a dataset containing " - + tripleCount + " different triples:"); - long startLax = System.currentTimeMillis(); + System.out.println("Average time to parse a dataset containing " + tripleCount + + " different triples:"); + final long startLax = System.currentTimeMillis(); for (int i = 0; i < rounds; i++) { new JsonLdApi(options).fromRDF(inputRdf, true); // JsonLdProcessor.expand(new JsonLdApi(options).fromRDF(inputRdf, @@ -580,7 +594,7 @@ private void runLaxVersusSlowToRDFTest(final String label, final String ns, System.out.println("\t- Assuming no duplicates: " + (((System.currentTimeMillis() - startLax)) / rounds)); - long start = System.currentTimeMillis(); + final long start = System.currentTimeMillis(); for (int i = 0; i < rounds; i++) { new JsonLdApi(options).fromRDF(inputRdf); // JsonLdProcessor.expand(new JsonLdApi(options).fromRDF(inputRdf)); @@ -594,14 +608,14 @@ private void runLaxVersusSlowToRDFTest(final String label, final String ns, */ @Test public final void duplicatedTriplesInAnRDFDataset() throws Exception { - RDFDataset inputRdf = new RDFDataset(); - String ns = "http://www.example.com/foo/"; + final RDFDataset inputRdf = new RDFDataset(); + final String ns = "http://www.example.com/foo/"; inputRdf.setNamespace("ex", ns); inputRdf.addTriple(ns + "s", ns + "p", ns + "o"); inputRdf.addTriple(ns + "s", ns + "p", ns + "o"); System.out.println("Twice the same triple in RDFDataset:/n"); - for (Quad quad : inputRdf.getQuads("@default")) { + for (final Quad quad : inputRdf.getQuads("@default")) { System.out.println(quad); } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index d1562ec4..108c81ec 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -155,8 +155,8 @@ public static void prepareReportFrame() { private static final String reportOutputFile = "reports/report"; @AfterClass - public static void writeReport() throws JsonGenerationException, JsonMappingException, - IOException, JsonLdError { + public static void writeReport() + throws JsonGenerationException, JsonMappingException, IOException, JsonLdError { // Only write reports if "-Dreport.format=..." is set String reportFormat = System.getProperty("report.format"); @@ -169,8 +169,9 @@ public static void writeReport() throws JsonGenerationException, JsonMappingExce if ("application/ld+json".equals(reportFormat) || "jsonld".equals(reportFormat) || "*".equals(reportFormat)) { System.out.println("Generating JSON-LD Report"); - JsonUtils.writePrettyPrint(new OutputStreamWriter(new FileOutputStream(reportOutputFile - + ".jsonld")), REPORT); + JsonUtils.writePrettyPrint( + new OutputStreamWriter(new FileOutputStream(reportOutputFile + ".jsonld")), + REPORT); } if ("text/plain".equals(reportFormat) || "nquads".equals(reportFormat) @@ -183,8 +184,8 @@ public static void writeReport() throws JsonGenerationException, JsonMappingExce } }; final String rdf = (String) JsonLdProcessor.toRDF(REPORT, options); - final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream( - reportOutputFile + ".nq")); + final OutputStreamWriter writer = new OutputStreamWriter( + new FileOutputStream(reportOutputFile + ".nq")); writer.write(rdf); writer.close(); } @@ -200,8 +201,8 @@ public static void writeReport() throws JsonGenerationException, JsonMappingExce }; final String rdf = (String) JsonLdProcessor.toRDF(REPORT, new TurtleTripleCallback(), options); - final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream( - reportOutputFile + ".ttl")); + final OutputStreamWriter writer = new OutputStreamWriter( + new FileOutputStream(reportOutputFile + ".ttl")); writer.write(rdf); writer.close(); } @@ -283,8 +284,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { if (url.startsWith(this.base)) { final String classpath = url.substring(this.base.length()); final ClassLoader cl = Thread.currentThread().getContextClassLoader(); - final InputStream inputStream = cl.getResourceAsStream(TEST_DIR + "/" - + classpath); + final InputStream inputStream = cl + .getResourceAsStream(TEST_DIR + "/" + classpath); try { return new RemoteDocument(url, JsonUtils.fromInputStream(inputStream)); } catch (final IOException e) { @@ -328,7 +329,8 @@ public void addHttpLink(String nextLink) { private final String group; private final Map test; - public JsonLdProcessorTest(final String group, final String id, final Map test) { + public JsonLdProcessorTest(final String group, final String id, + final Map test) { this.group = group; this.test = test; } @@ -356,8 +358,8 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { input = JsonUtils.fromInputStream(inputStream); } else if (inputType.equals("nt") || inputType.equals("nq")) { final List inputLines = new ArrayList(); - final BufferedReader buf = new BufferedReader(new InputStreamReader(inputStream, - "UTF-8")); + final BufferedReader buf = new BufferedReader( + new InputStreamReader(inputStream, "UTF-8")); String line; while ((line = buf.readLine()) != null) { line = line.trim(); @@ -389,8 +391,8 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { expect = JsonUtils.fromInputStream(expectStream); } else if (expectType.equals("nt") || expectType.equals("nq")) { final List expectLines = new ArrayList(); - final BufferedReader buf = new BufferedReader(new InputStreamReader( - expectStream, "UTF-8")); + final BufferedReader buf = new BufferedReader( + new InputStreamReader(expectStream, "UTF-8")); String line; while ((line = buf.readLine()) != null) { line = line.trim(); @@ -409,8 +411,8 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { } else if (sparqlFile != null) { final InputStream sparqlStream = cl.getResourceAsStream(TEST_DIR + "/" + sparqlFile); assertNotNull("unable to find expect file: " + sparqlFile, sparqlStream); - final BufferedReader buf = new BufferedReader(new InputStreamReader(sparqlStream, - "UTF-8")); + final BufferedReader buf = new BufferedReader( + new InputStreamReader(sparqlStream, "UTF-8")); String buffer = null; while ((buffer = buf.readLine()) != null) { sparql += buffer + "\n"; @@ -424,8 +426,8 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { Object result = null; // OPTIONS SETUP - final JsonLdOptions options = new JsonLdOptions("http://json-ld.org/test-suite/tests/" - + test.get("input")); + final JsonLdOptions options = new JsonLdOptions( + "http://json-ld.org/test-suite/tests/" + test.get("input")); final TestDocumentLoader testLoader = new TestDocumentLoader( "http://json-ld.org/test-suite/tests/"); options.setDocumentLoader(testLoader); @@ -435,8 +437,8 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { options.setBase((String) test_opts.get("base")); } if (test_opts.containsKey("expandContext")) { - final InputStream contextStream = cl.getResourceAsStream(TEST_DIR + "/" - + test_opts.get("expandContext")); + final InputStream contextStream = cl + .getResourceAsStream(TEST_DIR + "/" + test_opts.get("expandContext")); options.setExpandContext(JsonUtils.fromInputStream(contextStream)); } if (test_opts.containsKey("compactArrays")) { @@ -476,22 +478,22 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { if (testType.contains("jld:ExpandTest")) { result = JsonLdProcessor.expand(input, options); } else if (testType.contains("jld:CompactTest")) { - final InputStream contextStream = cl.getResourceAsStream(TEST_DIR + "/" - + test.get("context")); + final InputStream contextStream = cl + .getResourceAsStream(TEST_DIR + "/" + test.get("context")); final Object contextJson = JsonUtils.fromInputStream(contextStream); result = JsonLdProcessor.compact(input, contextJson, options); } else if (testType.contains("jld:FlattenTest")) { if (test.containsKey("context")) { - final InputStream contextStream = cl.getResourceAsStream(TEST_DIR + "/" - + test.get("context")); + final InputStream contextStream = cl + .getResourceAsStream(TEST_DIR + "/" + test.get("context")); final Object contextJson = JsonUtils.fromInputStream(contextStream); result = JsonLdProcessor.flatten(input, contextJson, options); } else { result = JsonLdProcessor.flatten(input, options); } } else if (testType.contains("jld:FrameTest")) { - final InputStream frameStream = cl.getResourceAsStream(TEST_DIR + "/" - + test.get("frame")); + final InputStream frameStream = cl + .getResourceAsStream(TEST_DIR + "/" + test.get("frame")); final Map frameJson = (Map) JsonUtils .fromInputStream(frameStream); result = JsonLdProcessor.frame(input, frameJson, options); @@ -581,28 +583,17 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { { put("@id", "http://json-ld.org/test-suite/tests/error-expand-manifest.jsonld" - .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); + .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); } }); } }); - assertTrue( - "\nFailed test: " - + group - + test.get("@id") - + " " - + test.get("name") - + " (" - + test.get("input") - + "," - + test.get("expect") - + ")\n" - + "expected: " - + JsonUtils.toPrettyString(expect) - + "\nresult: " - + (result instanceof JsonLdError ? ((JsonLdError) result).toString() - : JsonUtils.toPrettyString(result)), testpassed); + assertTrue("\nFailed test: " + group + test.get("@id") + " " + test.get("name") + " (" + + test.get("input") + "," + test.get("expect") + ")\n" + "expected: " + + JsonUtils.toPrettyString(expect) + "\nresult: " + (result instanceof JsonLdError + ? ((JsonLdError) result).toString() : JsonUtils.toPrettyString(result)), + testpassed); } } diff --git a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java index 4e975b56..0e2419c5 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java @@ -1,14 +1,11 @@ package com.github.jsonldjava.core; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.Reader; -import java.net.URL; import java.nio.charset.Charset; import org.junit.Test; diff --git a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java index 1471feaf..1ccddd62 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java @@ -31,7 +31,7 @@ public void toRdfWithNamespace() throws Exception { @Test public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Exception { - RDFDataset inputRdf = new RDFDataset(); + final RDFDataset inputRdf = new RDFDataset(); inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); inputRdf.setNamespace("aat_rev", "http://vocab.getty.edu/aat/rev/"); @@ -41,7 +41,7 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Excepti final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; - Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + final Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); @@ -49,7 +49,7 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Excepti assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aat_rev")); - String toJSONLD = JsonUtils.toPrettyString(fromRDF); + final String toJSONLD = JsonUtils.toPrettyString(fromRDF); System.out.println(toJSONLD); assertTrue("The lexicographically shortest URI was not chosen", @@ -59,7 +59,7 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Excepti @Test public void fromRdfWithNamespaceLexicographicallyShortestChosen2() throws Exception { - RDFDataset inputRdf = new RDFDataset(); + final RDFDataset inputRdf = new RDFDataset(); inputRdf.setNamespace("aat", "http://vocab.getty.edu/aat/"); inputRdf.setNamespace("aatrev", "http://vocab.getty.edu/aat/rev/"); @@ -69,7 +69,7 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen2() throws Except final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; - Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + final Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); @@ -77,7 +77,7 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen2() throws Except assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aatrev")); - String toJSONLD = JsonUtils.toPrettyString(fromRDF); + final String toJSONLD = JsonUtils.toPrettyString(fromRDF); System.out.println(toJSONLD); assertFalse("The lexicographically shortest URI was not chosen", @@ -95,9 +95,9 @@ public void prefixUsedToShortenPredicate() throws Exception { final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; - Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + final Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); - String toJSONLD = JsonUtils.toPrettyString(fromRDF); + final String toJSONLD = JsonUtils.toPrettyString(fromRDF); System.out.println(toJSONLD); assertFalse("The lexicographically shortest URI was not chosen", diff --git a/core/src/test/java/com/github/jsonldjava/core/RegexTest.java b/core/src/test/java/com/github/jsonldjava/core/RegexTest.java index 89854f85..fa833f39 100644 --- a/core/src/test/java/com/github/jsonldjava/core/RegexTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/RegexTest.java @@ -101,8 +101,8 @@ public void test_PNAME_NS() { public void test_PNAME_LN() { assertTrue(":p".matches("^" + Regex.PNAME_LN + "$")); assertTrue("abc:def".matches("^" + Regex.PNAME_LN + "$")); - assertTrue("\u00F8\u02FF\u0370\u037D:\u00F8\u02FF\u0370\u037D".matches("^" + Regex.PNAME_LN - + "$")); + assertTrue("\u00F8\u02FF\u0370\u037D:\u00F8\u02FF\u0370\u037D" + .matches("^" + Regex.PNAME_LN + "$")); } @Test @@ -147,16 +147,16 @@ public void test_STRING_LITERAL_QUOTE() { .matcher("\"IRI with four digit numeric escape (\\\\u)\" ;"); assertTrue(matcher.find()); - assertTrue("\"dffhjkasdhfskldhfoiw'eu\\\"fhowleifh \u00F8\u02FF\u0370\u037D\"".matches("^" - + Regex.STRING_LITERAL_QUOTE + "$")); + assertTrue("\"dffhjkasdhfskldhfoiw'eu\\\"fhowleifh \u00F8\u02FF\u0370\u037D\"" + .matches("^" + Regex.STRING_LITERAL_QUOTE + "$")); assertFalse("\"dffhjkasdhfs\nkldhfoiw\\\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"" .matches("^" + Regex.STRING_LITERAL_QUOTE + "$")); } @Test public void test_STRING_LITERAL_SINGLE_QUOTE() { - assertTrue("'dffhjkasdhfskldhf\\'oiweu\"fhowleifh \u00F8\u02FF\u0370\u037D'".matches("^" - + Regex.STRING_LITERAL_SINGLE_QUOTE + "$")); + assertTrue("'dffhjkasdhfskldhf\\'oiweu\"fhowleifh \u00F8\u02FF\u0370\u037D'" + .matches("^" + Regex.STRING_LITERAL_SINGLE_QUOTE + "$")); assertFalse("\"dffhjkasdhfs\nkldhfoiw\\\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"" .matches("^" + Regex.STRING_LITERAL_SINGLE_QUOTE + "$")); } @@ -199,15 +199,17 @@ public void test_unescape() { r = RDFDatasetUtils.unescape("\\t\\u007A\\U000F0000\\U00010000\\n"); assertTrue("\t\u007A\uDB80\uDC00\uD800\uDC00\n".equals(r)); - r = RDFDatasetUtils - .unescape("http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef"); - assertTrue("http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef" - .equals(r)); - - r = RDFDatasetUtils - .unescape("http://a.example/AZaz\\u00c0\\u00d6\\u00d8\\u00f6\\u00f8\\u02ff\\u0370\\u037d\\u0384\\u1ffe\\u200c\\u200d\\u2070\\u2189\\u2c00\\u2fd5\\u3001\\ud7fb\\ufa0e\\ufdc7\\ufdf0\\uffef\\U00010000\\U000e01ef"); - assertTrue("http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef\uD800\uDC00\uDB40\uDDEF" - .equals(r)); + r = RDFDatasetUtils.unescape( + "http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef"); + assertTrue( + "http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef" + .equals(r)); + + r = RDFDatasetUtils.unescape( + "http://a.example/AZaz\\u00c0\\u00d6\\u00d8\\u00f6\\u00f8\\u02ff\\u0370\\u037d\\u0384\\u1ffe\\u200c\\u200d\\u2070\\u2189\\u2c00\\u2fd5\\u3001\\ud7fb\\ufa0e\\ufdc7\\ufdf0\\uffef\\U00010000\\U000e01ef"); + assertTrue( + "http://a.example/AZaz\u00c0\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u0384\u1ffe\u200c\u200d\u2070\u2189\u2c00\u2fd5\u3001\ud7fb\ufa0e\ufdc7\ufdf0\uffef\uD800\uDC00\uDB40\uDDEF" + .equals(r)); } @Test diff --git a/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java b/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java index 7c16d507..d47d744b 100644 --- a/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java +++ b/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java @@ -108,10 +108,10 @@ public void simpleTest() throws JsonLdError { }; final Object json = null; /* - * JsonLdProcessor.fromRDF(input, new - * JsonLdOptions() { { format = "text/turtle"; - * } }, new TurtleRDFParser()); - */ + * JsonLdProcessor.fromRDF(input, new + * JsonLdOptions() { { format = "text/turtle"; + * } }, new TurtleRDFParser()); + */ assertTrue(Obj.equals(expected, json)); } @@ -286,8 +286,8 @@ private Boolean compareDatasets(final String baseIRI, final RDFDataset result, } } else { // add possible mappings for the objects - bnodeMaps.addPossibleMapping(eq.getObject().getValue(), rq.getObject() - .getValue()); + bnodeMaps.addPossibleMapping(eq.getObject().getValue(), + rq.getObject().getValue()); } } // otherwise, if the objects aren't equal we can't have a @@ -301,8 +301,8 @@ else if (!eq.getObject().equals(rq.getObject())) { // if subject is not locked add a possible mapping between // subjects if (!subjectLocked) { - bnodeMaps.addPossibleMapping(eq.getSubject().getValue(), rq.getSubject() - .getValue()); + bnodeMaps.addPossibleMapping(eq.getSubject().getValue(), + rq.getSubject().getValue()); } } // otherwise check if the subjects are equal @@ -320,8 +320,8 @@ else if (eq.getSubject().equals(rq.getSubject())) { } } else { // add possible mappings for the objects - bnodeMaps.addPossibleMapping(eq.getObject().getValue(), rq.getObject() - .getValue()); + bnodeMaps.addPossibleMapping(eq.getObject().getValue(), + rq.getObject().getValue()); } // if we get here we have a match matches++; @@ -345,13 +345,13 @@ else if (eq.getObject().equals(rq.getObject())) { // we have one match if (eq.getSubject().isBlankNode()) { // lock this mapping - bnodeMaps.lockMapping(eq.getSubject().getValue(), last_match.getSubject() - .getValue()); + bnodeMaps.lockMapping(eq.getSubject().getValue(), + last_match.getSubject().getValue()); } if (eq.getObject().isBlankNode()) { // lock this mapping - bnodeMaps.lockMapping(eq.getObject().getValue(), last_match.getObject() - .getValue()); + bnodeMaps.lockMapping(eq.getObject().getValue(), + last_match.getObject().getValue()); } res.remove(last_match); } else { diff --git a/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java b/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java index a5403f2b..f019d097 100644 --- a/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java +++ b/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java @@ -177,12 +177,12 @@ public void test_BLANK_NODE() { @Test public void test_STRING() { - assertTrue("\"dffhjkasdhfskldhfoiw'eu\\\"fhowleifh\u00F8\u02FF\u0370\u037D\"".matches("^" - + Regex.STRING + "$")); + assertTrue("\"dffhjkasdhfskldhfoiw'eu\\\"fhowleifh\u00F8\u02FF\u0370\u037D\"" + .matches("^" + Regex.STRING + "$")); assertFalse("\"dffhjkasdhfs\nkldhfoiw\\\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"" .matches("^" + Regex.STRING + "$")); - assertTrue("'dffhjkasdhfskldh\\'foiweu\"fhowleifh \u00F8\u02FF\u0370\u037D'".matches("^" - + Regex.STRING + "$")); + assertTrue("'dffhjkasdhfskldh\\'foiweu\"fhowleifh \u00F8\u02FF\u0370\u037D'" + .matches("^" + Regex.STRING + "$")); assertFalse("\"dffhjkasdhfs\nkldhfoiw\\\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"" .matches("^" + Regex.STRING + "$")); assertTrue("'''dffhjkasdhfsk\nldhfoiw\"'eufhowleifh \u00F8\u02FF\u0370\u037D'''" diff --git a/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java b/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java index 23569186..cfd20c90 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java +++ b/core/src/test/java/com/github/jsonldjava/utils/EarlTestSuite.java @@ -62,8 +62,8 @@ public EarlTestSuite(String manifestURL, String cacheDir, String etag) throws IO if (manifestURL.endsWith(".ttl") || manifestURL.endsWith("nq") || manifestURL.endsWith("nt")) { try { - Map rval = (Map) JsonLdProcessor.fromRDF( - manifestFile, new JsonLdOptions(manifestURL) { + Map rval = (Map) JsonLdProcessor + .fromRDF(manifestFile, new JsonLdOptions(manifestURL) { { this.format = "text/turtle"; this.useNamespaces = true; diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index b87182d7..46cfc09b 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -5,10 +5,10 @@ import java.io.IOException; import java.util.Map; -import com.fasterxml.jackson.core.JsonParseException; - import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; + public class JsonUtilsTest { @SuppressWarnings("unchecked") diff --git a/pom.xml b/pom.xml index b85a7c2a..a1f9fe53 100755 --- a/pom.xml +++ b/pom.xml @@ -45,8 +45,8 @@ 4.12 1.7.21 - 1.6 - 1.6 + 1.7 + 1.7 1.8 1.8 From 6f769c7c0f5870c15d73042ff5f044b00fde28a1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 00:33:36 -0400 Subject: [PATCH 209/440] Add printing to console for debugging Signed-off-by: Peter Ansell --- .../jsonldjava/core/MinimalSchemaOrgRegressionTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index cd8c03e2..51810875 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -1,6 +1,6 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; @@ -45,7 +45,8 @@ private void verifyInputStream(InputStream directStream) throws IOException { directStream.close(); output.flush(); } - String outputString = output.toString(); + final String outputString = output.toString(); + System.out.println(outputString); // Test for some basic conditions without including the JSON/JSON-LD // parsing code here assertTrue(outputString.endsWith("}\n")); From 5c7a38331053985eaaacbe83d159784bfd30f15c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 00:34:52 -0400 Subject: [PATCH 210/440] More automated cleanup to follow style Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/DocumentLoader.java | 2 +- .../com/github/jsonldjava/core/RDFDatasetUtils.java | 4 ++-- .../java/com/github/jsonldjava/utils/JsonUtils.java | 4 ++-- .../core/MinimalSchemaOrgRegressionTest.java | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 727ef85c..a4b728cc 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -40,7 +40,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { /** * An HTTP Accept header that prefers JSONLD. - * + * * @deprecated Use {@link JsonUtils#ACCEPT_HEADER} instead. */ @Deprecated diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 30e8f0af..27eeb647 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -396,7 +396,7 @@ public static String unescape(String str) { /** * Escapes the given string according to the N-Quads escape rules - * + * * @param str * The string to escape * @return The escaped string @@ -411,7 +411,7 @@ public static String escape(String str) { /** * Escapes the given string according to the N-Quads escape rules - * + * * @param str * The string to escape * @param rval diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 304bbf91..89f92543 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -272,7 +272,7 @@ public static void writePrettyPrint(Writer writer, Object jsonObject) * * If the URL is not an HTTP or HTTPS URL it is resolved using the default * {@link java.net.URL#openStream()} method. - * + * * @param url * The URL to resolve. * @param httpClient @@ -338,7 +338,7 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) * Fallback method directly using the {@link java.net.HttpURLConnection} * class for cases where servers do not interoperate correctly with Apache * HTTPClient. - * + * * @param url * The URL to access. * @return The result, after conversion from JSON to a Java Object. diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index 51810875..0f26aecd 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -30,15 +30,15 @@ public class MinimalSchemaOrgRegressionTest { @Test public void testHttpURLConnection() throws Exception { final URL url = new URL("http://schema.org/"); - HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); + final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.addRequestProperty("Accept", ACCEPT_HEADER); - InputStream directStream = urlConn.getInputStream(); + final InputStream directStream = urlConn.getInputStream(); verifyInputStream(directStream); } private void verifyInputStream(InputStream directStream) throws IOException { - StringWriter output = new StringWriter(); + final StringWriter output = new StringWriter(); try { IOUtils.copy(directStream, output, Charset.forName("UTF-8")); } finally { @@ -61,7 +61,7 @@ public void testApacheHttpClient() throws Exception { final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) .setMaxObjectSize(1024 * 128).build(); - CloseableHttpClient httpClient = CachingHttpClientBuilder.create() + final CloseableHttpClient httpClient = CachingHttpClientBuilder.create() // allow caching .setCacheConfig(cacheConfig) // Wrap the local JarCacheStorage around a BasicHttpCacheStorage @@ -85,7 +85,7 @@ public void testApacheHttpClient() throws Exception { if (status != 200 && status != 203) { throw new IOException("Can't retrieve " + url + ", status code: " + status); } - InputStream content = response.getEntity().getContent(); + final InputStream content = response.getEntity().getContent(); verifyInputStream(content); } finally { if (response != null) { From 792578291edbaccc5191c58c692707d8f5fe1dd8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 00:40:01 -0400 Subject: [PATCH 211/440] more work, including fixing animal sniffer for the java-7 update Signed-off-by: Peter Ansell --- .../github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java | 1 + pom.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index 0f26aecd..7ffe9012 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import com.github.jsonldjava.utils.JarCacheStorage; +import com.github.jsonldjava.utils.JsonUtils; public class MinimalSchemaOrgRegressionTest { diff --git a/pom.xml b/pom.xml index a1f9fe53..d8a3f7a3 100755 --- a/pom.xml +++ b/pom.xml @@ -318,7 +318,7 @@ org.codehaus.mojo.signature - java16 + java17 1.0 From 236f95a6a892c8a7a7a601928c49af8f09a8afbc Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 00:55:07 -0400 Subject: [PATCH 212/440] Remove the methods instead of deprecating Will bump version to 0.9.0 to cope with the API breakage Signed-off-by: Peter Ansell --- .../jsonldjava/core/DocumentLoader.java | 37 ---------------- .../github/jsonldjava/utils/JsonUtils.java | 36 +++------------- .../jsonldjava/core/DocumentLoaderTest.java | 42 +++++++------------ 3 files changed, 19 insertions(+), 96 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index a4b728cc..5977c8e3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -48,43 +48,6 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { private volatile CloseableHttpClient httpClient; - /** - * Returns a Map, List, or String containing the contents of the JSON - * resource resolved from the JsonLdUrl. - * - * @param url - * The JsonLdUrl to resolve - * @return The Map, List, or String that represent the JSON resource - * resolved from the JsonLdUrl - * @throws JsonParseException - * If the JSON was not valid. - * @throws IOException - * If there was an error resolving the resource. - * @deprecated Since 0.8.4, use {@link #loadDocument(String)} instead. - */ - @Deprecated - public Object fromURL(java.net.URL url) throws JsonParseException, IOException { - return JsonUtils.fromURL(url, getHttpClient()); - } - - /** - * Opens an {@link InputStream} for the given {@link java.net.URL}, - * including support for http and https URLs that are requested using - * Content Negotiation with application/ld+json as the preferred content - * type. - * - * @param url - * The {@link java.net.URL} identifying the source. - * @return An InputStream containing the contents of the source. - * @throws IOException - * If there was an error resolving the {@link java.net.URL}. - * @deprecated Since 0.8.4, use {@link #loadDocument(String)} instead. - */ - @Deprecated - public InputStream openStreamFromURL(java.net.URL url) throws IOException { - return JsonUtils.openStreamForURL(url, getHttpClient()); - } - public CloseableHttpClient getHttpClient() { CloseableHttpClient result = httpClient; if (result == null) { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 89f92543..248f0749 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -172,26 +172,6 @@ public static Object fromString(String jsonString) throws JsonParseException, IO return fromReader(new StringReader(jsonString)); } - /** - * Parses a JSON-LD document, from the contents of the JSON resource - * resolved from the JsonLdUrl, to an object that can be used as input for - * the {@link JsonLdApi} and {@link JsonLdProcessor} methods. - * - * @param url - * The JsonLdUrl to resolve - * @return A JSON Object. - * @throws JsonParseException - * If there was a JSON related error during parsing. - * @throws IOException - * If there was an IO error during parsing. - * @deprecated Use {@link #fromURL(java.net.URL, CloseableHttpClient)} - * instead. - */ - @Deprecated - public static Object fromURL(java.net.URL url) throws JsonParseException, IOException { - return fromURL(url, getDefaultHttpClient()); - } - /** * Writes the given JSON-LD Object out to a String, using indentation and * new lines to improve readability. @@ -281,7 +261,7 @@ public static void writePrettyPrint(Writer writer, Object jsonObject) * @throws IOException * If there are any IO exceptions while resolving the URL. */ - public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) + private static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) throws IOException { final String protocol = url.getProtocol(); if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { @@ -296,17 +276,11 @@ public static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient request.addHeader("Accept", ACCEPT_HEADER); final CloseableHttpResponse response = httpClient.execute(request); - try { - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - return response.getEntity().getContent(); - } finally { - if (response != null) { - response.close(); - } + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); } + return response.getEntity().getContent(); } /** diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index d9881f07..b58aa8e7 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -60,7 +60,7 @@ public void setContextClassLoader() { public void fromURLTest0001() throws Exception { final URL contexttest = getClass().getResource("/custom/contexttest-0001.jsonld"); assertNotNull(contexttest); - final Object context = documentLoader.fromURL(contexttest); + final Object context = JsonUtils.fromURL(contexttest, documentLoader.getHttpClient()); assertTrue(context instanceof Map); final Map contextMap = (Map) context; assertEquals(1, contextMap.size()); @@ -75,7 +75,7 @@ public void fromURLTest0001() throws Exception { public void fromURLTest0002() throws Exception { final URL contexttest = getClass().getResource("/custom/contexttest-0002.jsonld"); assertNotNull(contexttest); - final Object context = documentLoader.fromURL(contexttest); + final Object context = JsonUtils.fromURL(contexttest, documentLoader.getHttpClient()); assertTrue(context instanceof List); final List> contextList = (List>) context; @@ -99,7 +99,7 @@ public void fromURLTest0002() throws Exception { @Test public void fromURLredirectHTTPSToHTTP() throws Exception { final URL url = new URL("https://w3id.org/bundle/context"); - final Object context = documentLoader.fromURL(url); + final Object context = JsonUtils.fromURL(url, documentLoader.getHttpClient()); // Should not fail because of // http://stackoverflow.com/questions/1884230/java-doesnt-follow-redirect-in-urlconnection // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571 @@ -111,7 +111,7 @@ public void fromURLredirectHTTPSToHTTP() throws Exception { @Test public void fromURLredirect() throws Exception { final URL url = new URL("http://purl.org/wf4ever/ro-bundle/context.json"); - final Object context = documentLoader.fromURL(url); + final Object context = JsonUtils.fromURL(url, documentLoader.getHttpClient()); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); } @@ -126,16 +126,6 @@ public void loadDocumentWf4ever() throws Exception { assertFalse(((Map) context).isEmpty()); } - // @Ignore("Broken at server side") - @Test - public void fromURLSchemaOrg() throws Exception { - final URL url = new URL("http://schema.org/"); - final Object context = documentLoader.fromURL(url); - assertTrue(context instanceof Map); - assertFalse(((Map) context).isEmpty()); - } - - // @Ignore("Integration test") @Test public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { final URL url = new URL("http://schema.org/"); @@ -156,7 +146,6 @@ public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { assertFalse(((Map) context).isEmpty()); } - // @Ignore("Integration test") @Test public void loadDocumentSchemaOrg() throws Exception { final RemoteDocument document = documentLoader.loadDocument("http://schema.org/"); @@ -168,13 +157,13 @@ public void loadDocumentSchemaOrg() throws Exception { @Test public void fromURLCache() throws Exception { final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); - documentLoader.fromURL(url); + JsonUtils.fromURL(url, documentLoader.getHttpClient()); // Now try to get it again and ensure it is // cached final HttpClient clientCached = documentLoader.getHttpClient(); final HttpUriRequest getCached = new HttpGet(url.toURI()); - getCached.setHeader("Accept", DocumentLoader.ACCEPT_HEADER); + getCached.setHeader("Accept", JsonUtils.ACCEPT_HEADER); final HttpCacheContext localContextCached = HttpCacheContext.create(); final HttpResponse respoCached = clientCached.execute(getCached, localContextCached); EntityUtils.consume(respoCached.getEntity()); @@ -208,7 +197,7 @@ public InputStream getInputStream() throws IOException { }; final URL url = new URL(null, "jsonldtest:context", handler); assertEquals(0, requests.get()); - final Object context = documentLoader.fromURL(url); + final Object context = JsonUtils.fromURL(url, documentLoader.getHttpClient()); assertEquals(1, requests.get()); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); @@ -237,7 +226,7 @@ public void fromURLAcceptHeaders() throws Exception { .forClass(HttpUriRequest.class); documentLoader.setHttpClient(fakeHttpClient(httpRequest)); try { - final Object context = documentLoader.fromURL(url); + final Object context = JsonUtils.fromURL(url, documentLoader.getHttpClient()); assertTrue(context instanceof Map); } finally { documentLoader.setHttpClient(null); @@ -248,7 +237,7 @@ public void fromURLAcceptHeaders() throws Exception { final Header[] accept = req.getHeaders("Accept"); assertEquals(1, accept.length); - assertEquals(DocumentLoader.ACCEPT_HEADER, accept[0].getValue()); + assertEquals(JsonUtils.ACCEPT_HEADER, accept[0].getValue()); // Test that this header parses correctly final HeaderElement[] elems = accept[0].getElements(); assertEquals("application/ld+json", elems[0].getName()); @@ -281,8 +270,7 @@ public void fromURLAcceptHeaders() throws Exception { public void jarCacheHit() throws Exception { // If no cache, should fail-fast as nonexisting.example.com is not in // DNS - final Object context = documentLoader - .fromURL(new URL("http://nonexisting.example.com/context")); + final Object context = JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), documentLoader.getHttpClient()); assertTrue(context instanceof Map); assertTrue(((Map) context).containsKey("@context")); } @@ -290,16 +278,14 @@ public void jarCacheHit() throws Exception { @Test(expected = IOException.class) public void jarCacheMiss404() throws Exception { // Should fail-fast as nonexisting.example.com is not in DNS - final Object context = documentLoader - .fromURL(new URL("http://nonexisting.example.com/miss")); + JsonUtils.fromURL(new URL("http://nonexisting.example.com/miss"), documentLoader.getHttpClient()); } @Test(expected = IOException.class) public void jarCacheMissThreadCtx() throws Exception { final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); Thread.currentThread().setContextClassLoader(findNothingCL); - final Object context = documentLoader - .fromURL(new URL("http://nonexisting.example.com/context")); + JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), documentLoader.getHttpClient()); } @Test @@ -307,7 +293,7 @@ public void jarCacheHitThreadCtx() throws Exception { final URL url = new URL("http://nonexisting.example.com/nested/hello"); final URL nestedJar = getClass().getResource("/nested.jar"); try { - final Object hello = documentLoader.fromURL(url); + JsonUtils.fromURL(url, documentLoader.getHttpClient()); fail("Should not be able to find nested/hello yet"); } catch (final IOException ex) { // expected @@ -315,7 +301,7 @@ public void jarCacheHitThreadCtx() throws Exception { final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); Thread.currentThread().setContextClassLoader(cl); - final Object hello = documentLoader.fromURL(url); + final Object hello = JsonUtils.fromURL(url, documentLoader.getHttpClient()); assertTrue(hello instanceof Map); assertEquals("World!", ((Map) hello).get("Hello")); } From 684fb2dc3478c5a3715e3f78192d41d477c93f44 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 01:10:09 -0400 Subject: [PATCH 213/440] bump to 0.9.0 to reflect removed methods that were breaking schema.org removed methods enable better encapsulation of the input stream lifecycles to make sure they are not closed too early or left open Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 01f5512c..05c5b593 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.8.4-SNAPSHOT + 0.9.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index d8a3f7a3..f5de2598 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.8.4-SNAPSHOT + 0.9.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From b229bfab6037080b656c7d8051bcba823ef61775 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 5 Aug 2016 01:20:55 -0400 Subject: [PATCH 214/440] remove the troublesome method that was only being called from a single location manage its input stream lifecycle in the usual way for a divergent input stream creation case Signed-off-by: Peter Ansell --- .../github/jsonldjava/utils/JsonUtils.java | 64 ++++++++----------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 248f0749..65b123ed 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -246,43 +246,6 @@ public static void writePrettyPrint(Writer writer, Object jsonObject) jw.writeObject(jsonObject); } - /** - * Attempts to open an {@link InputStream} that will contain the content of - * the URL, as resolved by the given HTTP Client. - * - * If the URL is not an HTTP or HTTPS URL it is resolved using the default - * {@link java.net.URL#openStream()} method. - * - * @param url - * The URL to resolve. - * @param httpClient - * The CloseableHttpClient to use to resolve the URL. - * @return An InputStream containing the contents of the resolved URL. - * @throws IOException - * If there are any IO exceptions while resolving the URL. - */ - private static InputStream openStreamForURL(java.net.URL url, CloseableHttpClient httpClient) - throws IOException { - final String protocol = url.getProtocol(); - if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { - // Can't use the HTTP client for those! - // Fallback to Java's built-in JsonLdUrl handler. No need for - // Accept headers as it's likely to be file: or jar: - return url.openStream(); - } - final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to application/json - // or whatever is available - request.addHeader("Accept", ACCEPT_HEADER); - - final CloseableHttpResponse response = httpClient.execute(request); - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - return response.getEntity().getContent(); - } - /** * Parses a JSON-LD document, from the contents of the JSON resource * resolved from the JsonLdUrl, to an object that can be used as input for @@ -300,11 +263,34 @@ private static InputStream openStreamForURL(java.net.URL url, CloseableHttpClien */ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) throws JsonParseException, IOException { - final InputStream in = openStreamForURL(url, httpClient); + final String protocol = url.getProtocol(); + // We can only use the Apache HTTPClient for HTTP/HTTPS, so use the + // native java client for the others + InputStream in = null; try { + if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { + // Can't use the HTTP client for those! + // Fallback to Java's built-in JsonLdUrl handler. No need for + // Accept headers as it's likely to be file: or jar: + in = url.openStream(); + } else { + final HttpUriRequest request = new HttpGet(url.toExternalForm()); + // We prefer application/ld+json, but fallback to application/json + // or whatever is available + request.addHeader("Accept", ACCEPT_HEADER); + + final CloseableHttpResponse response = httpClient.execute(request); + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + in = response.getEntity().getContent(); + } return fromInputStream(in); } finally { - in.close(); + if(in != null) { + in.close(); + } } } From 449d1aac2830c01a4edd51ce7fd5d2b43456c886 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 29 Aug 2016 15:50:38 +1000 Subject: [PATCH 215/440] Add regression test for issue #182 Requirement is to not compact arrays during framing if this option is set on the JsonLdOptions instance Signed-off-by: Peter Ansell --- .../jsonldjava/core/JsonLdFramingTest.java | 18 ++++++++++++++++++ .../resources/custom/frame-0002-frame.jsonld | 6 ++++++ .../test/resources/custom/frame-0002-in.jsonld | 13 +++++++++++++ .../resources/custom/frame-0002-out.jsonld | 13 +++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 core/src/test/resources/custom/frame-0002-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0002-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0002-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 91c01975..1c50a0d0 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -23,4 +23,22 @@ public void testFrame0001() throws IOException, JsonLdError { assertEquals(2, frame2.size()); } + @Test + public void testFrame0002() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setCompactArrays(false); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-out.jsonld")); + System.out.println(JsonUtils.toPrettyString(out)); + System.out.println(JsonUtils.toPrettyString(frame2)); + assertEquals(out, frame2); + } + } diff --git a/core/src/test/resources/custom/frame-0002-frame.jsonld b/core/src/test/resources/custom/frame-0002-frame.jsonld new file mode 100644 index 00000000..43e9937f --- /dev/null +++ b/core/src/test/resources/custom/frame-0002-frame.jsonld @@ -0,0 +1,6 @@ +{ + "@context": { + "@vocab": "http://xmlns.com/foaf/0.1/" + }, + "@type": "Person" +} diff --git a/core/src/test/resources/custom/frame-0002-in.jsonld b/core/src/test/resources/custom/frame-0002-in.jsonld new file mode 100644 index 00000000..ae706c5c --- /dev/null +++ b/core/src/test/resources/custom/frame-0002-in.jsonld @@ -0,0 +1,13 @@ +{ + "@context": { + "@vocab": "http://xmlns.com/foaf/0.1/", + "member": {"@type": "@id"} + }, + "@graph": [{ + "@type": "Person", + "member": "_:b1" + }, { + "@id": "_:b1", + "@type": "Group" + }] +} diff --git a/core/src/test/resources/custom/frame-0002-out.jsonld b/core/src/test/resources/custom/frame-0002-out.jsonld new file mode 100644 index 00000000..c795cb8e --- /dev/null +++ b/core/src/test/resources/custom/frame-0002-out.jsonld @@ -0,0 +1,13 @@ +{ + "@context" : { + "@vocab" : "http://xmlns.com/foaf/0.1/" + }, + "@graph" : [ { + "@id" : "_:b0", + "@type" : "Person", + "member" : [{ + "@id" : "_:b1", + "@type" : "Group" + }] + } ] +} From b629dec5f7d36d4b9bd120efd1e71f0ec064b8d8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 29 Aug 2016 15:51:56 +1000 Subject: [PATCH 216/440] Pass array compaction flag to compaction inside of framing Fixes #182 Signed-off-by: Peter Ansell --- .../main/java/com/github/jsonldjava/core/JsonLdProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index efbfcf0e..e6a9e616 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -312,7 +312,7 @@ public static Map frame(Object input, Object frame, JsonLdOption final Context activeCtx = api.context .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); - Object compacted = api.compact(activeCtx, null, framed); + Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); if (!(compacted instanceof List)) { final List tmp = new ArrayList(); tmp.add(compacted); From 897049000a1457f65468e71454cb08cdb68e7a37 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 29 Aug 2016 15:55:09 +1000 Subject: [PATCH 217/440] Make constant for the default value of compact arrays and reuse it Signed-off-by: Peter Ansell --- .../src/main/java/com/github/jsonldjava/core/JsonLdApi.java | 2 +- .../main/java/com/github/jsonldjava/core/JsonLdOptions.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index a22f98e1..0ca83c95 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -474,7 +474,7 @@ else if (result.containsKey(itemActiveProperty)) { */ public Object compact(Context activeCtx, String activeProperty, Object element) throws JsonLdError { - return compact(activeCtx, activeProperty, element, true); + return compact(activeCtx, activeProperty, element, JsonLdOptions.DEFAULT_COMPACT_ARRAYS); } /*** diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 3bea9492..ab2c339c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -10,7 +10,9 @@ */ public class JsonLdOptions { - /** + public static final boolean DEFAULT_COMPACT_ARRAYS = true; + + /** * Constructs an instance of JsonLdOptions using an empty base. */ public JsonLdOptions() { @@ -37,7 +39,7 @@ public JsonLdOptions(String base) { /** * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-compactArrays */ - private Boolean compactArrays = true; + private Boolean compactArrays = DEFAULT_COMPACT_ARRAYS; /** * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-expandContext */ From 2ac517fe612f8a41209df9f21b0b25bdfae7aa8a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 29 Aug 2016 16:27:41 +1000 Subject: [PATCH 218/440] Add regression test for issue #174 Signed-off-by: Peter Ansell --- .../jsonldjava/core/JsonLdFramingTest.java | 19 +++++++++++++++++++ .../resources/custom/frame-0003-frame.jsonld | 1 + .../resources/custom/frame-0003-in.jsonld | 11 +++++++++++ .../resources/custom/frame-0003-out.jsonld | 14 ++++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 core/src/test/resources/custom/frame-0003-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0003-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0003-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 1c50a0d0..19c15ea1 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -41,4 +41,23 @@ public void testFrame0002() throws IOException, JsonLdError { assertEquals(out, frame2); } + @Test + public void testFrame0003() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0003-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0003-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0003-out.jsonld")); + System.out.println(JsonUtils.toPrettyString(in)); + System.out.println(JsonUtils.toPrettyString(out)); + System.out.println(JsonUtils.toPrettyString(frame2)); + assertEquals(out, frame2); + } + + } diff --git a/core/src/test/resources/custom/frame-0003-frame.jsonld b/core/src/test/resources/custom/frame-0003-frame.jsonld new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/core/src/test/resources/custom/frame-0003-frame.jsonld @@ -0,0 +1 @@ +{} diff --git a/core/src/test/resources/custom/frame-0003-in.jsonld b/core/src/test/resources/custom/frame-0003-in.jsonld new file mode 100644 index 00000000..570de35e --- /dev/null +++ b/core/src/test/resources/custom/frame-0003-in.jsonld @@ -0,0 +1,11 @@ +[ { + "@id" : "http://example.com/canvas-1", + "@type" : "http://example.com" +}, { + "@id" : "http://example.com/element", + "http://example.com" : { + "@list" : [ { + "@id" : "http://example.com/canvas-1" + } ] + } +} ] diff --git a/core/src/test/resources/custom/frame-0003-out.jsonld b/core/src/test/resources/custom/frame-0003-out.jsonld new file mode 100644 index 00000000..63a390ee --- /dev/null +++ b/core/src/test/resources/custom/frame-0003-out.jsonld @@ -0,0 +1,14 @@ +{ + "@graph" : [ { + "@id" : "http://example.com/canvas-1", + "@type" : "http://example.com" + }, { + "@id" : "http://example.com/element", + "http://example.com" : { + "@list" : [ { + "@id" : "http://example.com/canvas-1", + "@type" : "http://example.com" + } ] + } + } ] +} From 1456dc262d73dd7610528dfd091dffe3ed7bab13 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 29 Aug 2016 16:39:14 +1000 Subject: [PATCH 219/440] Clarify test outputs on console Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/core/JsonLdFramingTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 19c15ea1..ad4415ee 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -53,8 +53,11 @@ public void testFrame0003() throws IOException, JsonLdError { final Object out = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0003-out.jsonld")); + System.out.println("Input:"); System.out.println(JsonUtils.toPrettyString(in)); + System.out.println("Expected Output:"); System.out.println(JsonUtils.toPrettyString(out)); + System.out.println("Actual Output:"); System.out.println(JsonUtils.toPrettyString(frame2)); assertEquals(out, frame2); } From e17475a3aeb28c33b3b075d61714c8f004dfffb3 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 23 Dec 2016 06:09:20 +1100 Subject: [PATCH 220/440] Add japicmp to track API changes over time Signed-off-by: Peter Ansell --- core/pom.xml | 4 +++ pom.xml | 69 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 05c5b593..055ac2e5 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -89,6 +89,10 @@ org.jacoco jacoco-maven-plugin + + com.github.siom79.japicmp + japicmp-maven-plugin + diff --git a/pom.xml b/pom.xml index f5de2598..4bd31823 100755 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,8 @@ 4.12 1.7.21 + 0.8.3 + 1.7 1.7 1.8 @@ -323,6 +325,37 @@ + + com.github.siom79.japicmp + japicmp-maven-plugin + 0.9.3 + + + + ${project.groupId} + ${project.artifactId} + ${last-compare-version} + jar + + + + + ${project.build.directory}/${project.artifactId}-${project.version}.jar + + + + true + + + + + verify + + cmp + + + + org.codehaus.mojo appassembler-maven-plugin @@ -462,24 +495,24 @@ - - ide - - false - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.testSource} - ${maven.compiler.testTarget} - - - - - + + ide + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.testSource} + ${maven.compiler.testTarget} + + + + + From ff2baa582f4824a1105ece1309274f950584d1c6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 23 Dec 2016 06:23:52 +1100 Subject: [PATCH 221/440] Hide test console debugging Signed-off-by: Peter Ansell --- .../jsonldjava/core/ArrayContextToRDFTest.java | 2 +- .../jsonldjava/core/ContextCompactionTest.java | 8 ++++---- .../github/jsonldjava/core/JsonLdFramingTest.java | 4 ++-- .../jsonldjava/core/JsonLdPerformanceTest.java | 14 +++++++------- .../com/github/jsonldjava/core/LocalBaseTest.java | 4 ++-- .../github/jsonldjava/core/LongestPrefixTest.java | 12 ++++++------ .../core/MinimalSchemaOrgRegressionTest.java | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index a16db832..28aa9d35 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -36,7 +36,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { }; options.setDocumentLoader(documentLoader); final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(arrayContext, options); - System.out.println(rdf.getNamespaces()); + // System.out.println(rdf.getNamespaces()); assertEquals("http://example.org/", rdf.getNamespace("ex")); assertEquals("http://example.com/2/", rdf.getNamespace("ex2")); // Only 'proper' prefixes returned diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index 0a08ce8d..fa664d10 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -36,15 +36,15 @@ public void testCompaction() throws Exception { options.setBase("http://schema.org/"); options.setCompactArrays(true); - System.out.println("Before compact"); - System.out.println(JsonUtils.toPrettyString(json)); + // System.out.println("Before compact"); + // System.out.println(JsonUtils.toPrettyString(json)); final List newContexts = new LinkedList(); newContexts.add("http://schema.org/"); final Map compacted = JsonLdProcessor.compact(json, newContexts, options); - System.out.println("\n\nAfter compact:"); - System.out.println(JsonUtils.toPrettyString(compacted)); + // System.out.println("\n\nAfter compact:"); + // System.out.println(JsonUtils.toPrettyString(compacted)); assertTrue("Compaction removed the context", compacted.containsKey("@context")); assertFalse("Compaction of context should be a string, not a list", diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 1c50a0d0..71691489 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -36,8 +36,8 @@ public void testFrame0002() throws IOException, JsonLdError { final Object out = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-out.jsonld")); - System.out.println(JsonUtils.toPrettyString(out)); - System.out.println(JsonUtils.toPrettyString(frame2)); + // System.out.println(JsonUtils.toPrettyString(out)); + // System.out.println(JsonUtils.toPrettyString(frame2)); assertEquals(out, frame2); } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index bdaf624d..29945766 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -614,9 +614,9 @@ public final void duplicatedTriplesInAnRDFDataset() throws Exception { inputRdf.addTriple(ns + "s", ns + "p", ns + "o"); inputRdf.addTriple(ns + "s", ns + "p", ns + "o"); - System.out.println("Twice the same triple in RDFDataset:/n"); + // System.out.println("Twice the same triple in RDFDataset:/n"); for (final Quad quad : inputRdf.getQuads("@default")) { - System.out.println(quad); + //System.out.println(quad); } final JsonLdOptions options = new JsonLdOptions(); @@ -625,19 +625,19 @@ public final void duplicatedTriplesInAnRDFDataset() throws Exception { Object fromRDF; String jsonld; - System.out.println("\nJSON-LD output is OK:\n"); + // System.out.println("\nJSON-LD output is OK:\n"); fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); jsonld = JsonUtils.toPrettyString(fromRDF); - System.out.println(jsonld); + // System.out.println(jsonld); - System.out.println( - "\nWouldn't be the case assuming there is no duplicated triple in RDFDataset:\n"); + // System.out.println( + // "\nWouldn't be the case assuming there is no duplicated triple in RDFDataset:\n"); fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf, true), inputRdf.getContext(), options); jsonld = JsonUtils.toPrettyString(fromRDF); - System.out.println(jsonld); + // System.out.println(jsonld); } } diff --git a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java index 0e2419c5..b1a50853 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java @@ -24,7 +24,7 @@ public void testMixedLocalRemoteBaseRemoteContextFirst() throws Exception { final JsonLdOptions options = new JsonLdOptions(); final Object expanded = JsonLdProcessor.expand(context, options); - System.out.println(JsonUtils.toPrettyString(expanded)); + // System.out.println(JsonUtils.toPrettyString(expanded)); final Reader outReader = new BufferedReader(new InputStreamReader( this.getClass().getResourceAsStream("/custom/base-0001-out.jsonld"), @@ -45,7 +45,7 @@ public void testMixedLocalRemoteBaseLocalContextFirst() throws Exception { final JsonLdOptions options = new JsonLdOptions(); final Object expanded = JsonLdProcessor.expand(context, options); - System.out.println(JsonUtils.toPrettyString(expanded)); + // System.out.println(JsonUtils.toPrettyString(expanded)); final Reader outReader = new BufferedReader(new InputStreamReader( this.getClass().getResourceAsStream("/custom/base-0002-out.jsonld"), diff --git a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java index 1ccddd62..69757bb5 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LongestPrefixTest.java @@ -23,7 +23,7 @@ public void toRdfWithNamespace() throws Exception { final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(context, options); - System.out.println(rdf.getNamespaces()); + // System.out.println(rdf.getNamespaces()); assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aat_rev")); } @@ -45,12 +45,12 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen() throws Excepti inputRdf.getContext(), options); final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); - System.out.println(rdf.getNamespaces()); + // System.out.println(rdf.getNamespaces()); assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aat_rev")); final String toJSONLD = JsonUtils.toPrettyString(fromRDF); - System.out.println(toJSONLD); + // System.out.println(toJSONLD); assertTrue("The lexicographically shortest URI was not chosen", toJSONLD.contains("aat:rev/")); @@ -73,12 +73,12 @@ public void fromRdfWithNamespaceLexicographicallyShortestChosen2() throws Except inputRdf.getContext(), options); final RDFDataset rdf = (RDFDataset) JsonLdProcessor.toRDF(fromRDF, options); - System.out.println(rdf.getNamespaces()); + // System.out.println(rdf.getNamespaces()); assertEquals("http://vocab.getty.edu/aat/", rdf.getNamespace("aat")); assertEquals("http://vocab.getty.edu/aat/rev/", rdf.getNamespace("aatrev")); final String toJSONLD = JsonUtils.toPrettyString(fromRDF); - System.out.println(toJSONLD); + // System.out.println(toJSONLD); assertFalse("The lexicographically shortest URI was not chosen", toJSONLD.contains("aat:rev/")); @@ -98,7 +98,7 @@ public void prefixUsedToShortenPredicate() throws Exception { final Object fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); final String toJSONLD = JsonUtils.toPrettyString(fromRDF); - System.out.println(toJSONLD); + // System.out.println(toJSONLD); assertFalse("The lexicographically shortest URI was not chosen", toJSONLD.contains("http://www.a.com/foo/p")); diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index 7ffe9012..ab5eae6e 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -47,7 +47,7 @@ private void verifyInputStream(InputStream directStream) throws IOException { output.flush(); } final String outputString = output.toString(); - System.out.println(outputString); + // System.out.println(outputString); // Test for some basic conditions without including the JSON/JSON-LD // parsing code here assertTrue(outputString.endsWith("}\n")); From aa685e7b5ea90d3d9a07f3e7e76287b45c45be7c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 23 Dec 2016 06:37:16 +1100 Subject: [PATCH 222/440] Release 0.9.0 Signed-off-by: Peter Ansell --- README.md | 8 ++++++-- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 02941c36..a948144d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.8.3 + 0.9.0 Code example @@ -281,7 +281,7 @@ Here is the basic outline for what your module's pom.xml should look like jsonld-java-integration com.github.jsonld-java-parent - 0.8.1-SNAPSHOT + 0.9.1-SNAPSHOT 4.0.0 jsonld-java-{your module} @@ -400,6 +400,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2016-12-23 +* Release 0.9.0 +* Fixes schema.org support that is broken with Apache HTTP Client but works with java.net.URL + ### 2016-05-20 * Fix reported NPE in JsonLdApi.removeDependents diff --git a/core/pom.xml b/core/pom.xml index 055ac2e5..22454bbf 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.9.0-SNAPSHOT + 0.9.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 4bd31823..36413b98 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.9.0-SNAPSHOT + 0.9.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From 11cdacf0431d78737862a1823d9d81595a1baf80 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 23 Dec 2016 06:48:09 +1100 Subject: [PATCH 223/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 22454bbf..b71c6e6b 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.9.0 + 0.9.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 36413b98..03e3cce7 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.9.0 + 0.9.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 098196c86f3fc5f2837e64488efeb823caea7853 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 23 Dec 2016 07:02:21 +1100 Subject: [PATCH 224/440] Set japicmp version to 0.9.0 Signed-off-by: Peter Ansell --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03e3cce7..cc7a6140 100755 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ 4.12 1.7.21 - 0.8.3 + 0.9.0 1.7 1.7 From eb42ed0631398e2b132184a1f552c943798e8258 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 6 Jan 2017 14:05:10 +1100 Subject: [PATCH 225/440] Update copyright --- LICENCE | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LICENCE b/LICENCE index e03ca9bb..2b584c5e 100644 --- a/LICENCE +++ b/LICENCE @@ -1,4 +1,5 @@ Copyright (c) 2012, Deutsche Forschungszentrum für Künstliche Intelligenz GmbH +Copyright (c) 2012-2017, JSONLD-Java contributors All rights reserved. Redistribution and use in source and binary forms, with or without @@ -21,4 +22,4 @@ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From a18f24f8ed72a2a1abc9894be93a18116f4c09f2 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jan 2017 12:45:42 +1100 Subject: [PATCH 226/440] Update plugin and dependency versions Signed-off-by: Peter Ansell --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index cc7a6140..2361cb97 100755 --- a/pom.xml +++ b/pom.xml @@ -40,10 +40,10 @@ UTF-8 4.5.2 - 4.4.4 - 2.7.4 + 4.4.5 + 2.8.5 4.12 - 1.7.21 + 1.7.22 0.9.0 @@ -213,7 +213,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + 3.6.0 default-compile @@ -242,7 +242,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.3 + 2.10.4 org.apache.maven.plugins @@ -252,7 +252,7 @@ org.apache.maven.plugins maven-resources-plugin - 2.7 + 3.0.2 org.apache.maven.plugins @@ -272,7 +272,7 @@ org.apache.maven.plugins maven-jar-plugin - 2.6 + 3.0.2 @@ -284,7 +284,7 @@ org.apache.maven.plugins maven-source-plugin - 2.4 + 3.0.1 attach-source @@ -359,7 +359,7 @@ org.codehaus.mojo appassembler-maven-plugin - 1.10 + 2.0.0 org.apache.felix @@ -370,12 +370,12 @@ org.eluder.coveralls coveralls-maven-plugin - 4.1.0 + 4.3.0 org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + 0.7.8 prepare-agent From 0aad280b92e73d81943f042bed01fe5ba4249514 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jan 2017 12:45:57 +1100 Subject: [PATCH 227/440] issue #188 : Remove schema.org workaround Seems to just work now, but have explicitly defined the redirect strategy to use for the HttpClient instances Signed-off-by: Peter Ansell --- .../jsonldjava/core/DocumentLoader.java | 9 +---- .../jsonldjava/utils/JarCacheStorage.java | 2 +- .../github/jsonldjava/utils/JsonUtils.java | 9 +++-- .../jsonldjava/core/DocumentLoaderTest.java | 33 ++++++++++++----- .../core/MinimalSchemaOrgRegressionTest.java | 36 +++++++++++-------- 5 files changed, 53 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 5977c8e3..7fcacff1 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -1,12 +1,9 @@ package com.github.jsonldjava.core; -import java.io.IOException; -import java.io.InputStream; import java.net.URL; import org.apache.http.impl.client.CloseableHttpClient; -import com.fasterxml.jackson.core.JsonParseException; import com.github.jsonldjava.utils.JsonUtils; public class DocumentLoader { @@ -27,11 +24,7 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { final RemoteDocument doc = new RemoteDocument(url, null); try { - if (url.equalsIgnoreCase("http://schema.org/")) { - doc.setDocument(JsonUtils.fromURLJavaNet(new URL(url))); - } else { - doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); - } + doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); } catch (final Exception e) { throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 8744f796..49fee70a 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -22,9 +22,9 @@ import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.client.cache.Resource; +import org.apache.http.client.utils.DateUtils; import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; -import org.apache.http.impl.cookie.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.HTTP; diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 65b123ed..087ef769 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -20,6 +20,7 @@ import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultRedirectStrategy; import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; @@ -275,10 +276,11 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) in = url.openStream(); } else { final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to application/json + // We prefer application/ld+json, but fallback to + // application/json // or whatever is available request.addHeader("Accept", ACCEPT_HEADER); - + final CloseableHttpResponse response = httpClient.execute(request); final int status = response.getStatusLine().getStatusCode(); if (status != 200 && status != 203) { @@ -288,7 +290,7 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) } return fromInputStream(in); } finally { - if(in != null) { + if (in != null) { in.close(); } } @@ -353,6 +355,7 @@ private static CloseableHttpClient createDefaultHttpClient() { // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 .addInterceptorFirst(new RequestAcceptEncoding()) .addInterceptorFirst(new ResponseContentEncoding()) + .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) // use system defaults for proxy etc. .useSystemProperties().build(); diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index b58aa8e7..d43461e3 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -154,6 +154,15 @@ public void loadDocumentSchemaOrg() throws Exception { assertFalse(((Map) context).isEmpty()); } + @Test + public void loadDocumentSchemaOrgDirect() throws Exception { + final RemoteDocument document = documentLoader + .loadDocument("http://schema.org/docs/jsonldcontext.json"); + final Object context = document.getDocument(); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + @Test public void fromURLCache() throws Exception { final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); @@ -230,6 +239,7 @@ public void fromURLAcceptHeaders() throws Exception { assertTrue(context instanceof Map); } finally { documentLoader.setHttpClient(null); + assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); } assertEquals(1, httpRequest.getAllValues().size()); final HttpUriRequest req = httpRequest.getValue(); @@ -270,7 +280,8 @@ public void fromURLAcceptHeaders() throws Exception { public void jarCacheHit() throws Exception { // If no cache, should fail-fast as nonexisting.example.com is not in // DNS - final Object context = JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), documentLoader.getHttpClient()); + final Object context = JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), + documentLoader.getHttpClient()); assertTrue(context instanceof Map); assertTrue(((Map) context).containsKey("@context")); } @@ -278,14 +289,16 @@ public void jarCacheHit() throws Exception { @Test(expected = IOException.class) public void jarCacheMiss404() throws Exception { // Should fail-fast as nonexisting.example.com is not in DNS - JsonUtils.fromURL(new URL("http://nonexisting.example.com/miss"), documentLoader.getHttpClient()); + JsonUtils.fromURL(new URL("http://nonexisting.example.com/miss"), + documentLoader.getHttpClient()); } @Test(expected = IOException.class) public void jarCacheMissThreadCtx() throws Exception { final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); Thread.currentThread().setContextClassLoader(findNothingCL); - JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), documentLoader.getHttpClient()); + JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), + documentLoader.getHttpClient()); } @Test @@ -315,12 +328,14 @@ public void sharedHttpClient() throws Exception { @Test public void differentHttpClient() throws Exception { // Custom http client - documentLoader.setHttpClient(new SystemDefaultHttpClient()); - assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); - - // Use default again - documentLoader.setHttpClient(null); - assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + try { + documentLoader.setHttpClient(new SystemDefaultHttpClient()); + assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + } finally { + // Use default again + documentLoader.setHttpClient(null); + assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); + } } @Test diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index ab5eae6e..bbfafae7 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -16,13 +16,13 @@ import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultRedirectStrategy; import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; import org.junit.Test; import com.github.jsonldjava.utils.JarCacheStorage; -import com.github.jsonldjava.utils.JsonUtils; public class MinimalSchemaOrgRegressionTest { @@ -72,28 +72,34 @@ public void testApacheHttpClient() throws Exception { // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 .addInterceptorFirst(new RequestAcceptEncoding()) .addInterceptorFirst(new ResponseContentEncoding()) + .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) // use system defaults for proxy etc. .useSystemProperties().build(); - final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to application/json - // or whatever is available - request.addHeader("Accept", ACCEPT_HEADER); - - final CloseableHttpResponse response = httpClient.execute(request); try { - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); + final HttpUriRequest request = new HttpGet(url.toExternalForm()); + // We prefer application/ld+json, but fallback to application/json + // or whatever is available + request.addHeader("Accept", ACCEPT_HEADER); + + final CloseableHttpResponse response = httpClient.execute(request); + try { + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + final InputStream content = response.getEntity().getContent(); + verifyInputStream(content); + } finally { + if (response != null) { + response.close(); + } } - final InputStream content = response.getEntity().getContent(); - verifyInputStream(content); } finally { - if (response != null) { - response.close(); + if (httpClient != null) { + httpClient.close(); } } - } } From dcec5131c60c46ac5540de15f012c238d30bfe0a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jan 2017 12:57:32 +1100 Subject: [PATCH 228/440] Remove unmaintained Turtle parser Signed-off-by: Peter Ansell --- .../jsonldjava/core/JsonLdProcessor.java | 5 - .../jsonldjava/core/RDFDatasetUtils.java | 15 - .../jsonldjava/impl/NQuadRDFParser.java | 5 +- .../jsonldjava/impl/TurtleRDFParser.java | 565 ---------------- .../jsonldjava/impl/TurtleTripleCallback.java | 376 ----------- .../jsonldjava/core/JsonLdProcessorTest.java | 34 - .../jsonldjava/impl/TurtleRDFParserTest.java | 448 ------------ .../jsonldjava/impl/TurtleRegexTests.java | 639 ------------------ 8 files changed, 2 insertions(+), 2085 deletions(-) delete mode 100644 core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java delete mode 100644 core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java delete mode 100644 core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java delete mode 100644 core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index e6a9e616..12cb80a6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -11,8 +11,6 @@ import com.github.jsonldjava.core.JsonLdError.Error; import com.github.jsonldjava.impl.NQuadRDFParser; import com.github.jsonldjava.impl.NQuadTripleCallback; -import com.github.jsonldjava.impl.TurtleRDFParser; -import com.github.jsonldjava.impl.TurtleTripleCallback; /** * This class implements the frame(Object input, Object frame, JsonLdOption { // automatically register nquad serializer put(JsonLdConsts.APPLICATION_NQUADS, new NQuadRDFParser()); - put(JsonLdConsts.TEXT_TURTLE, new TurtleRDFParser()); } }; @@ -513,8 +510,6 @@ public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOp if (options.format != null) { if (JsonLdConsts.APPLICATION_NQUADS.equals(options.format)) { return new NQuadTripleCallback().call(dataset); - } else if (JsonLdConsts.TEXT_TURTLE.equals(options.format)) { - return new TurtleTripleCallback().call(dataset); } else { throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, options.format); } diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 27eeb647..6917e980 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -394,21 +394,6 @@ public static String unescape(String str) { return rval; } - /** - * Escapes the given string according to the N-Quads escape rules - * - * @param str - * The string to escape - * @return The escaped string - * @deprecated Use {@link #escape(String, StringBuilder)} instead. - */ - @Deprecated - public static String escape(String str) { - final StringBuilder rval = new StringBuilder(); - escape(str, rval); - return rval.toString(); - } - /** * Escapes the given string according to the N-Quads escape rules * diff --git a/core/src/main/java/com/github/jsonldjava/impl/NQuadRDFParser.java b/core/src/main/java/com/github/jsonldjava/impl/NQuadRDFParser.java index 3f361dc2..5209cac3 100644 --- a/core/src/main/java/com/github/jsonldjava/impl/NQuadRDFParser.java +++ b/core/src/main/java/com/github/jsonldjava/impl/NQuadRDFParser.java @@ -1,16 +1,15 @@ package com.github.jsonldjava.impl; -import static com.github.jsonldjava.core.RDFDatasetUtils.parseNQuads; - import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.RDFDataset; +import com.github.jsonldjava.core.RDFDatasetUtils; import com.github.jsonldjava.core.RDFParser; public class NQuadRDFParser implements RDFParser { @Override public RDFDataset parse(Object input) throws JsonLdError { if (input instanceof String) { - return parseNQuads((String) input); + return RDFDatasetUtils.parseNQuads((String) input); } else { throw new JsonLdError(JsonLdError.Error.INVALID_INPUT, "NQuad Parser expected string input."); diff --git a/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java b/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java deleted file mode 100644 index 0e721045..00000000 --- a/core/src/main/java/com/github/jsonldjava/impl/TurtleRDFParser.java +++ /dev/null @@ -1,565 +0,0 @@ -package com.github.jsonldjava.impl; - -import static com.github.jsonldjava.core.JsonLdConsts.RDF_FIRST; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_LANGSTRING; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_NIL; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_DECIMAL; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER; -import static com.github.jsonldjava.core.RDFDatasetUtils.unescape; -import static com.github.jsonldjava.core.Regex.BLANK_NODE_LABEL; -import static com.github.jsonldjava.core.Regex.DECIMAL; -import static com.github.jsonldjava.core.Regex.DOUBLE; -import static com.github.jsonldjava.core.Regex.INTEGER; -import static com.github.jsonldjava.core.Regex.IRIREF; -import static com.github.jsonldjava.core.Regex.LANGTAG; -import static com.github.jsonldjava.core.Regex.PNAME_LN; -import static com.github.jsonldjava.core.Regex.PNAME_NS; -import static com.github.jsonldjava.core.Regex.STRING_LITERAL_LONG_QUOTE; -import static com.github.jsonldjava.core.Regex.STRING_LITERAL_LONG_SINGLE_QUOTE; -import static com.github.jsonldjava.core.Regex.STRING_LITERAL_QUOTE; -import static com.github.jsonldjava.core.Regex.STRING_LITERAL_SINGLE_QUOTE; -import static com.github.jsonldjava.core.Regex.UCHAR; -import static com.github.jsonldjava.core.Regex.WS; -import static com.github.jsonldjava.core.Regex.WS_0_N; -import static com.github.jsonldjava.core.Regex.WS_1_N; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Stack; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.core.RDFParser; -import com.github.jsonldjava.core.UniqueNamer; - -/** - * A (probably terribly slow) Parser for turtle. Turtle is the internal - * RDFDataset used by JSOND-Java - * - * TODO: this probably needs to be changed to use a proper parser/lexer - * - * @author Tristan - * - */ -public class TurtleRDFParser implements RDFParser { - - static class Regex { - final public static Pattern PREFIX_ID = Pattern - .compile("@prefix" + WS_1_N + PNAME_NS + WS_1_N + IRIREF + WS_0_N + "\\." + WS_0_N); - final public static Pattern BASE = Pattern - .compile("@base" + WS_1_N + IRIREF + WS_0_N + "\\." + WS_0_N); - final public static Pattern SPARQL_PREFIX = Pattern - .compile("[Pp][Rr][Ee][Ff][Ii][Xx]" + WS + PNAME_NS + WS + IRIREF + WS_0_N); - final public static Pattern SPARQL_BASE = Pattern - .compile("[Bb][Aa][Ss][Ee]" + WS + IRIREF + WS_0_N); - - final public static Pattern PREFIXED_NAME = Pattern - .compile("(?:" + PNAME_LN + "|" + PNAME_NS + ")"); - final public static Pattern IRI = Pattern - .compile("(?:" + IRIREF + "|" + PREFIXED_NAME + ")"); - final public static Pattern ANON = Pattern.compile("(?:\\[" + WS + "*\\])"); - final public static Pattern BLANK_NODE = Pattern.compile(BLANK_NODE_LABEL + "|" + ANON); - final public static Pattern STRING = Pattern - .compile("(" + STRING_LITERAL_LONG_SINGLE_QUOTE + "|" + STRING_LITERAL_LONG_QUOTE - + "|" + STRING_LITERAL_QUOTE + "|" + STRING_LITERAL_SINGLE_QUOTE + ")"); - final public static Pattern BOOLEAN_LITERAL = Pattern.compile("(true|false)"); - final public static Pattern RDF_LITERAL = Pattern - .compile(STRING + "(?:" + LANGTAG + "|\\^\\^" + IRI + ")?"); - final public static Pattern NUMERIC_LITERAL = Pattern - .compile("(" + DOUBLE + ")|(" + DECIMAL + ")|(" + INTEGER + ")"); - final public static Pattern LITERAL = Pattern - .compile(RDF_LITERAL + "|" + NUMERIC_LITERAL + "|" + BOOLEAN_LITERAL); - - final public static Pattern DIRECTIVE = Pattern.compile( - "^(?:" + PREFIX_ID + "|" + BASE + "|" + SPARQL_PREFIX + "|" + SPARQL_BASE + ")"); - final public static Pattern SUBJECT = Pattern.compile("^" + IRI + "|" + BLANK_NODE); - final public static Pattern PREDICATE = Pattern.compile("^" + IRI + "|a" + WS_1_N); - final public static Pattern OBJECT = Pattern - .compile("^" + IRI + "|" + BLANK_NODE + "|" + LITERAL); - - // others - // final public static Pattern WS_AT_LINE_START = Pattern.compile("^" + - // WS_1_N); - final public static Pattern EOLN = Pattern.compile("(?:\r\n)|(?:\n)|(?:\r)"); - final public static Pattern NEXT_EOLN = Pattern.compile("^.*(?:" + EOLN + ")" + WS_0_N); - // final public static Pattern EMPTY_LINE = Pattern.compile("^" + WS + - // "*$"); - - final public static Pattern COMMENT_OR_WS = Pattern - .compile("^(?:(?:[#].*(?:" + EOLN + ")" + WS_0_N + ")|(?:" + WS_1_N + "))"); - } - - private class State { - String baseIri = ""; - Map namespaces = new LinkedHashMap(); - String curSubject = null; - String curPredicate = null; - - String line = null; - - int lineNumber = 0; - int linePosition = 0; - - // int bnodes = 0; - UniqueNamer namer = new UniqueNamer("_:b");// {{ getName(); }}; // call - // getName() after - // construction to make - // first active bnode _:b1 - - private final Stack> stack = new Stack>(); - public boolean expectingBnodeClose = false; - - public State(String input) throws JsonLdError { - line = input; - lineNumber = 1; - advanceLinePosition(0); - } - - public void push() { - stack.push(new LinkedHashMap() { - { - put(curSubject, curPredicate); - } - }); - expectingBnodeClose = true; - curSubject = null; - curPredicate = null; - } - - public void pop() { - if (stack.size() > 0) { - for (final Entry x : stack.pop().entrySet()) { - curSubject = x.getKey(); - curPredicate = x.getValue(); - } - } - if (stack.size() == 0) { - expectingBnodeClose = false; - } - } - - private void advanceLineNumber() throws JsonLdError { - final Matcher match = Regex.NEXT_EOLN.matcher(line); - if (match.find()) { - final String[] split = match.group(0).split("" + Regex.EOLN); - lineNumber += (split.length - 1); - linePosition += split[split.length - 1].length(); - line = line.substring(match.group(0).length()); - } - } - - public void advanceLinePosition(int len) throws JsonLdError { - if (len > 0) { - linePosition += len; - line = line.substring(len); - } - - while (!"".equals(line)) { - // clear any whitespace - final Matcher match = Regex.COMMENT_OR_WS.matcher(line); - if (match.find() && match.group(0).length() > 0) { - final Matcher eoln = Regex.EOLN.matcher(match.group(0)); - int end = 0; - while (eoln.find()) { - lineNumber += 1; - end = eoln.end(); - } - linePosition = match.group(0).length() - end; - line = line.substring(match.group(0).length()); - } else { - break; - } - } - if ("".equals(line) && !endIsOK()) { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; unexpected end of input. {line: " + lineNumber - + ", position:" + linePosition + "}"); - } - } - - private boolean endIsOK() { - return curSubject == null && stack.size() == 0; - } - - public String expandIRI(String ns, String name) throws JsonLdError { - if (namespaces.containsKey(ns)) { - return namespaces.get(ns) + name; - } else { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, "No prefix found for: " + ns - + " {line: " + lineNumber + ", position:" + linePosition + "}"); - } - } - } - - @Override - public RDFDataset parse(Object input) throws JsonLdError { - if (!(input instanceof String)) { - throw new JsonLdError(JsonLdError.Error.INVALID_INPUT, - "Invalid input; Triple RDF Parser requires a string input"); - } - final RDFDataset result = new RDFDataset(); - final State state = new State((String) input); - - while (!"".equals(state.line)) { - // check if line is a directive - Matcher match = Regex.DIRECTIVE.matcher(state.line); - if (match.find()) { - if (match.group(1) != null || match.group(4) != null) { - final String ns = match.group(1) != null ? match.group(1) : match.group(4); - String iri = match.group(1) != null ? match.group(2) : match.group(5); - if (!iri.contains(":")) { - iri = state.baseIri + iri; - } - iri = unescape(iri); - validateIRI(state, iri); - state.namespaces.put(ns, iri); - result.setNamespace(ns, iri); - } else { - String base = match.group(3) != null ? match.group(3) : match.group(6); - base = unescape(base); - validateIRI(state, base); - if (!base.contains(":")) { - state.baseIri = state.baseIri + base; - } else { - state.baseIri = base; - } - } - state.advanceLinePosition(match.group(0).length()); - continue; - } - - if (state.curSubject == null) { - // we need to match a subject - match = Regex.SUBJECT.matcher(state.line); - if (match.find()) { - String iri; - if (match.group(1) != null) { - // matched IRI - iri = unescape(match.group(1)); - if (!iri.contains(":")) { - iri = state.baseIri + iri; - } - } else if (match.group(2) != null) { - // matched NS:NAME - final String ns = match.group(2); - final String name = unescapeReserved(match.group(3)); - iri = state.expandIRI(ns, name); - } else if (match.group(4) != null) { - // match ns: only - iri = state.expandIRI(match.group(4), ""); - } else if (match.group(5) != null) { - // matched BNODE - iri = state.namer.getName(match.group(0).trim()); - } else { - // matched anon node - iri = state.namer.getName(); - } - // make sure IRI still matches an IRI after escaping - validateIRI(state, iri); - state.curSubject = iri; - state.advanceLinePosition(match.group(0).length()); - } - // handle blank nodes - else if (state.line.startsWith("[")) { - final String bnode = state.namer.getName(); - state.advanceLinePosition(1); - state.push(); - state.curSubject = bnode; - } - // handle collections - else if (state.line.startsWith("(")) { - final String bnode = state.namer.getName(); - // so we know we want a predicate if the collection close - // isn't followed by a subject end - state.curSubject = bnode; - state.advanceLinePosition(1); - state.push(); - state.curSubject = bnode; - state.curPredicate = RDF_FIRST; - } - // make sure we have a subject already - else { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; missing expected subject. {line: " - + state.lineNumber + "position: " + state.linePosition + "}"); - } - } - - if (state.curPredicate == null) { - // match predicate - match = Regex.PREDICATE.matcher(state.line); - if (match.find()) { - String iri = ""; - if (match.group(1) != null) { - // matched IRI - iri = unescape(match.group(1)); - if (!iri.contains(":")) { - iri = state.baseIri + iri; - } - } else if (match.group(2) != null) { - // matched NS:NAME - final String ns = match.group(2); - final String name = unescapeReserved(match.group(3)); - iri = state.expandIRI(ns, name); - } else if (match.group(4) != null) { - // matched ns: - iri = state.expandIRI(match.group(4), ""); - } else { - // matched "a" - iri = RDF_TYPE; - } - validateIRI(state, iri); - state.curPredicate = iri; - state.advanceLinePosition(match.group(0).length()); - } else { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; missing expected predicate. {line: " - + state.lineNumber + "position: " + state.linePosition + "}"); - } - } - - // expecting bnode or object - - // match BNODE values - if (state.line.startsWith("[")) { - final String bnode = state.namer.getName(); - result.addTriple(state.curSubject, state.curPredicate, bnode); - state.advanceLinePosition(1); - // check for anonymous objects - if (state.line.startsWith("]")) { - state.advanceLinePosition(1); - // next we expect a statement or object separator - } - // otherwise we're inside the blank node - else { - state.push(); - state.curSubject = bnode; - // next we expect a predicate - continue; - } - } - // match collections - else if (state.line.startsWith("(")) { - state.advanceLinePosition(1); - // check for empty collection - if (state.line.startsWith(")")) { - state.advanceLinePosition(1); - result.addTriple(state.curSubject, state.curPredicate, RDF_NIL); - // next we expect a statement or object separator - } - // otherwise we're inside the collection - else { - final String bnode = state.namer.getName(); - result.addTriple(state.curSubject, state.curPredicate, bnode); - state.push(); - state.curSubject = bnode; - state.curPredicate = RDF_FIRST; - continue; - } - } else { - // match object - match = Regex.OBJECT.matcher(state.line); - if (match.find()) { - String iri = null; - if (match.group(1) != null) { - // matched IRI - iri = unescape(match.group(1)); - if (!iri.contains(":")) { - iri = state.baseIri + iri; - } - } else if (match.group(2) != null) { - // matched NS:NAME - final String ns = match.group(2); - final String name = unescapeReserved(match.group(3)); - iri = state.expandIRI(ns, name); - } else if (match.group(4) != null) { - // matched ns: - iri = state.expandIRI(match.group(4), ""); - } else if (match.group(5) != null) { - // matched BNODE - iri = state.namer.getName(match.group(0).trim()); - } - if (iri != null) { - validateIRI(state, iri); - // we have a object - result.addTriple(state.curSubject, state.curPredicate, iri); - } else { - // we have a literal - String value = match.group(6); - String lang = null; - String datatype = null; - if (value != null) { - // we have a string literal - value = unquoteString(value); - value = unescape(value); - lang = match.group(7); - if (lang == null) { - if (match.group(8) != null) { - datatype = unescape(match.group(8)); - if (!datatype.contains(":")) { - datatype = state.baseIri + datatype; - } - validateIRI(state, datatype); - } else if (match.group(9) != null) { - datatype = state.expandIRI(match.group(9), - unescapeReserved(match.group(10))); - } else if (match.group(11) != null) { - datatype = state.expandIRI(match.group(11), ""); - } - } else { - datatype = RDF_LANGSTRING; - } - } else if (match.group(12) != null) { - // integer literal - value = match.group(12); - datatype = XSD_DOUBLE; - } else if (match.group(13) != null) { - // decimal literal - value = match.group(13); - datatype = XSD_DECIMAL; - } else if (match.group(14) != null) { - // double literal - value = match.group(14); - datatype = XSD_INTEGER; - } else if (match.group(15) != null) { - // boolean literal - value = match.group(15); - datatype = XSD_BOOLEAN; - } - result.addTriple(state.curSubject, state.curPredicate, value, datatype, - lang); - } - state.advanceLinePosition(match.group(0).length()); - } else { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; missing expected object or blank node. {line: " - + state.lineNumber + "position: " + state.linePosition + "}"); - } - } - - // close collection - boolean collectionClosed = false; - while (state.line.startsWith(")")) { - if (!RDF_FIRST.equals(state.curPredicate)) { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; unexpected ). {line: " + state.lineNumber - + "position: " + state.linePosition + "}"); - } - result.addTriple(state.curSubject, RDF_REST, RDF_NIL); - state.pop(); - state.advanceLinePosition(1); - collectionClosed = true; - } - - boolean expectDotOrPred = false; - - // match end of bnode - if (state.line.startsWith("]")) { - final String bnode = state.curSubject; - state.pop(); - state.advanceLinePosition(1); - if (state.curSubject == null) { - // this is a bnode as a subject and we - // expect either a . or a predicate - state.curSubject = bnode; - expectDotOrPred = true; - } - } - - // match list separator - if (!expectDotOrPred && state.line.startsWith(",")) { - state.advanceLinePosition(1); - // now we expect another object/bnode - continue; - } - - // match predicate end - if (!expectDotOrPred) { - while (state.line.startsWith(";")) { - state.curPredicate = null; - state.advanceLinePosition(1); - // now we expect another predicate, or a dot - expectDotOrPred = true; - } - } - - if (state.line.startsWith(".")) { - if (state.expectingBnodeClose) { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; missing expected )\"]\". {line: " - + state.lineNumber + "position: " + state.linePosition + "}"); - } - state.curSubject = null; - state.curPredicate = null; - state.advanceLinePosition(1); - // this can now be the end of the document. - continue; - } else if (expectDotOrPred) { - // we're expecting another predicate since we didn't find a dot - continue; - } - - // if we're in a collection - if (RDF_FIRST.equals(state.curPredicate)) { - final String bnode = state.namer.getName(); - result.addTriple(state.curSubject, RDF_REST, bnode); - state.curSubject = bnode; - continue; - } - - if (collectionClosed) { - // we expect another object - // TODO: it's not clear yet if this is valid - continue; - } - - // if we get here, we're missing a close statement - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; missing expected \"]\" \",\" \";\" or \".\". {line: " - + state.lineNumber + "position: " + state.linePosition + "}"); - } - - return result; - } - - final public static Pattern IRIREF_MINUS_CONTAINER = Pattern - .compile("(?:(?:[^\\x00-\\x20<>\"{}|\\^`\\\\]|" + UCHAR + ")*)|" + Regex.PREFIXED_NAME); - - private void validateIRI(State state, String iri) throws JsonLdError { - if (!IRIREF_MINUS_CONTAINER.matcher(iri).matches()) { - throw new JsonLdError(JsonLdError.Error.PARSE_ERROR, - "Error while parsing Turtle; invalid IRI after escaping. {line: " - + state.lineNumber + "position: " + state.linePosition + "}"); - } - } - - final private static Pattern PN_LOCAL_ESC_MATCHED = Pattern - .compile("[\\\\]([_~\\.\\-!$&'\\(\\)*+,;=/?#@%])"); - - static String unescapeReserved(String str) { - if (str != null) { - final Matcher m = PN_LOCAL_ESC_MATCHED.matcher(str); - if (m.find()) { - return m.replaceAll("$1"); - } - } - return str; - } - - private String unquoteString(String value) { - if (value.startsWith("\"\"\"") || value.startsWith("'''")) { - return value.substring(3, value.length() - 3); - } else if (value.startsWith("\"") || value.startsWith("'")) { - return value.substring(1, value.length() - 1); - } - return value; - } - -} diff --git a/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java b/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java deleted file mode 100644 index d7ee1695..00000000 --- a/core/src/main/java/com/github/jsonldjava/impl/TurtleTripleCallback.java +++ /dev/null @@ -1,376 +0,0 @@ -package com.github.jsonldjava.impl; - -import static com.github.jsonldjava.core.JsonLdConsts.RDF_FIRST; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_NIL; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_FLOAT; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_STRING; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.github.jsonldjava.core.JsonLdTripleCallback; -import com.github.jsonldjava.core.RDFDataset; - -public class TurtleTripleCallback implements JsonLdTripleCallback { - - private static final int MAX_LINE_LENGTH = 160; - private static final int TAB_SPACES = 4; - private static final String COLS_KEY = "..cols.."; // this shouldn't be a - // valid iri/bnode i - // hope! - final Map availableNamespaces = new LinkedHashMap() { - { - // TODO: fill with default namespaces - } - }; - Set usedNamespaces; - - public TurtleTripleCallback() { - } - - @Override - public Object call(RDFDataset dataset) { - for (final Entry e : dataset.getNamespaces().entrySet()) { - availableNamespaces.put(e.getValue(), e.getKey()); - } - usedNamespaces = new LinkedHashSet(); - - final int tabs = 0; - - final Map> refs = new LinkedHashMap>(); - final Map>> ttl = new LinkedHashMap>>(); - - for (String graphName : dataset.keySet()) { - final List triples = dataset.getQuads(graphName); - if ("@default".equals(graphName)) { - graphName = null; - } - - // http://www.w3.org/TR/turtle/#unlabeled-bnodes - // TODO: implement nesting for unlabled nodes - - // map of what the output should look like - // subj (or [ if bnode) > pred > obj - // > obj (set ref if IRI) - // > pred > obj (set ref if bnode) - // subj > etc etc etc - - // subjid -> [ ref, ref, ref ] - - String prevSubject = ""; - String prevPredicate = ""; - - Map> thisSubject = null; - List thisPredicate = null; - - for (final RDFDataset.Quad triple : triples) { - final String subject = triple.getSubject().getValue(); - final String predicate = triple.getPredicate().getValue(); - - if (prevSubject.equals(subject)) { - if (prevPredicate.equals(predicate)) { - // nothing to do - } else { - // new predicate - if (thisSubject.containsKey(predicate)) { - thisPredicate = thisSubject.get(predicate); - } else { - thisPredicate = new ArrayList(); - thisSubject.put(predicate, thisPredicate); - } - prevPredicate = predicate; - } - } else { - // new subject - if (ttl.containsKey(subject)) { - thisSubject = ttl.get(subject); - } else { - thisSubject = new LinkedHashMap>(); - ttl.put(subject, thisSubject); - } - if (thisSubject.containsKey(predicate)) { - thisPredicate = thisSubject.get(predicate); - } else { - thisPredicate = new ArrayList(); - thisSubject.put(predicate, thisPredicate); - } - - prevSubject = subject; - prevPredicate = predicate; - } - - if (triple.getObject().isLiteral()) { - thisPredicate.add(triple.getObject()); - } else { - final String o = triple.getObject().getValue(); - if (o.startsWith("_:")) { - // add ref to o - if (!refs.containsKey(o)) { - refs.put(o, new ArrayList()); - } - refs.get(o).add(thisPredicate); - } - thisPredicate.add(o); - } - } - } - - final Map> collections = new LinkedHashMap>(); - - final List subjects = new ArrayList(ttl.keySet()); - // find collections - for (final String subj : subjects) { - Map> preds = ttl.get(subj); - if (preds != null && preds.containsKey(RDF_FIRST)) { - final List col = new ArrayList(); - collections.put(subj, col); - while (true) { - final List first = preds.remove(RDF_FIRST); - final Object o = first.get(0); - col.add(o); - // refs - if (refs.containsKey(o)) { - refs.get(o).remove(first); - refs.get(o).add(col); - } - final String next = (String) preds.remove(RDF_REST).get(0); - if (RDF_NIL.equals(next)) { - // end of this list - break; - } - // if collections already contains a value for "next", add - // it to this col and break out - if (collections.containsKey(next)) { - col.addAll(collections.remove(next)); - break; - } - preds = ttl.remove(next); - refs.remove(next); - } - } - } - - // process refs (nesting referenced bnodes if only one reference to them - // in the whole graph) - for (final String id : refs.keySet()) { - // skip items if there is more than one reference to them in the - // graph - if (refs.get(id).size() > 1) { - continue; - } - - // otherwise embed them into the referenced location - Object object = ttl.remove(id); - if (collections.containsKey(id)) { - object = new LinkedHashMap>(); - final List tmp = new ArrayList(); - tmp.add(collections.remove(id)); - ((HashMap) object).put(COLS_KEY, tmp); - } - final List predicate = (List) refs.get(id).get(0); - // replace the one bnode ref with the object - predicate.set(predicate.lastIndexOf(id), object); - } - - // replace the rest of the collections - for (final String id : collections.keySet()) { - final Map> subj = ttl.get(id); - if (!subj.containsKey(COLS_KEY)) { - subj.put(COLS_KEY, new ArrayList()); - } - subj.get(COLS_KEY).add(collections.get(id)); - } - - // build turtle output - final String output = generateTurtle(ttl, 0, 0, false); - - String prefixes = ""; - for (final String prefix : usedNamespaces) { - final String name = availableNamespaces.get(prefix); - prefixes += "@prefix " + name + ": <" + prefix + "> .\n"; - } - - return ("".equals(prefixes) ? "" : prefixes + "\n") + output; - } - - private String generateObject(Object object, String sep, boolean hasNext, int indentation, - int lineLength) { - String rval = ""; - String obj; - if (object instanceof String) { - obj = getURI((String) object); - } else if (object instanceof RDFDataset.Literal) { - obj = ((RDFDataset.Literal) object).getValue(); - final String lang = ((RDFDataset.Literal) object).getLanguage(); - final String dt = ((RDFDataset.Literal) object).getDatatype(); - if (lang != null) { - obj = "\"" + obj + "\""; - obj += "@" + lang; - } else if (dt != null) { - // TODO: this probably isn't an exclusive list of all the - // datatype literals that can be represented as native types - if (!(XSD_DOUBLE.equals(dt) || XSD_INTEGER.equals(dt) || XSD_FLOAT.equals(dt) - || XSD_BOOLEAN.equals(dt))) { - obj = "\"" + obj + "\""; - if (!XSD_STRING.equals(dt)) { - obj += "^^" + getURI(dt); - } - } - } else { - obj = "\"" + obj + "\""; - } - } else { - // must be an object - final Map>> tmp = new LinkedHashMap>>(); - tmp.put("_:x", (Map>) object); - obj = generateTurtle(tmp, indentation + 1, lineLength, true); - } - - final int idxofcr = obj.indexOf("\n"); - // check if output will fix in the max line length (factor in comma if - // not the last item, current line length and length to the next CR) - if ((hasNext ? 1 : 0) + lineLength - + (idxofcr != -1 ? idxofcr : obj.length()) > MAX_LINE_LENGTH) { - rval += "\n" + tabs(indentation + 1); - lineLength = (indentation + 1) * TAB_SPACES; - } - rval += obj; - if (idxofcr != -1) { - lineLength += (obj.length() - obj.lastIndexOf("\n")); - } else { - lineLength += obj.length(); - } - if (hasNext) { - rval += sep; - lineLength += sep.length(); - if (lineLength < MAX_LINE_LENGTH) { - rval += " "; - lineLength++; - } else { - rval += "\n"; - } - } - return rval; - } - - private String generateTurtle(Map>> ttl, int indentation, - int lineLength, boolean isObject) { - String rval = ""; - final Iterator subjIter = ttl.keySet().iterator(); - while (subjIter.hasNext()) { - final String subject = subjIter.next(); - final Map> subjval = ttl.get(subject); - // boolean isBlankNode = subject.startsWith("_:"); - boolean hasOpenBnodeBracket = false; - if (subject.startsWith("_:")) { - // only open blank node bracket the node doesn't contain any - // collections - if (!subjval.containsKey(COLS_KEY)) { - rval += "[ "; - lineLength += 2; - hasOpenBnodeBracket = true; - } - - // TODO: according to http://www.rdfabout.com/demo/validator/ - // 1) collections as objects cannot contain any predicates other - // than rdf:first and rdf:rest - // 2) collections cannot be surrounded with [ ] - - // check for collection - if (subjval.containsKey(COLS_KEY)) { - final List collections = subjval.remove(COLS_KEY); - for (final Object collection : collections) { - rval += "( "; - lineLength += 2; - final Iterator objIter = ((List) collection).iterator(); - while (objIter.hasNext()) { - final Object object = objIter.next(); - rval += generateObject(object, "", objIter.hasNext(), indentation, - lineLength); - lineLength = rval.length() - rval.lastIndexOf("\n"); - } - rval += " ) "; - lineLength += 3; - } - } - // check for blank node - } else { - rval += getURI(subject) + " "; - lineLength += subject.length() + 1; - } - final Iterator predIter = ttl.get(subject).keySet().iterator(); - while (predIter.hasNext()) { - final String predicate = predIter.next(); - rval += getURI(predicate) + " "; - lineLength += predicate.length() + 1; - final Iterator objIter = ttl.get(subject).get(predicate).iterator(); - while (objIter.hasNext()) { - final Object object = objIter.next(); - rval += generateObject(object, ",", objIter.hasNext(), indentation, lineLength); - lineLength = rval.length() - rval.lastIndexOf("\n"); - } - if (predIter.hasNext()) { - rval += " ;\n" + tabs(indentation + 1); - lineLength = (indentation + 1) * TAB_SPACES; - } - } - if (hasOpenBnodeBracket) { - rval += " ]"; - } - if (!isObject) { - rval += " .\n"; - if (subjIter.hasNext()) { // add blank space if we have another - // object below this - rval += "\n"; - } - } - } - return rval; - } - - // TODO: Assert (TAB_SPACES == 4) otherwise this needs to be edited, and - // should fail to compile - private String tabs(int tabs) { - String rval = ""; - for (int i = 0; i < tabs; i++) { - rval += " "; // using spaces for tabs - } - return rval; - } - - /** - * checks the URI for a prefix, and if one is found, set used prefixes to - * true - * - * @param predicate - * @return - */ - private String getURI(String uri) { - // check for bnode - if (uri.startsWith("_:")) { - // return the bnode id - return uri; - } - for (final String prefix : availableNamespaces.keySet()) { - if (uri.startsWith(prefix)) { - usedNamespaces.add(prefix); - // return the prefixed URI - return availableNamespaces.get(prefix) + ":" + uri.substring(prefix.length()); - } - } - // return the full URI - return "<" + uri + ">"; - } - -} diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 108c81ec..9a152f6d 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -37,7 +37,6 @@ import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.JsonMappingException; -import com.github.jsonldjava.impl.TurtleTripleCallback; import com.github.jsonldjava.utils.JsonUtils; import com.github.jsonldjava.utils.Obj; import com.github.jsonldjava.utils.TestUtils; @@ -173,39 +172,6 @@ public static void writeReport() new OutputStreamWriter(new FileOutputStream(reportOutputFile + ".jsonld")), REPORT); } - - if ("text/plain".equals(reportFormat) || "nquads".equals(reportFormat) - || "nq".equals(reportFormat) || "nt".equals(reportFormat) - || "ntriples".equals(reportFormat) || "*".equals(reportFormat)) { - System.out.println("Generating Nquads Report"); - final JsonLdOptions options = new JsonLdOptions("") { - { - this.format = "application/nquads"; - } - }; - final String rdf = (String) JsonLdProcessor.toRDF(REPORT, options); - final OutputStreamWriter writer = new OutputStreamWriter( - new FileOutputStream(reportOutputFile + ".nq")); - writer.write(rdf); - writer.close(); - } - if ("text/turtle".equals(reportFormat) || "turtle".equals(reportFormat) - || "ttl".equals(reportFormat) || "*".equals(reportFormat)) { // write - // turtle - System.out.println("Generating Turtle Report"); - final JsonLdOptions options = new JsonLdOptions("") { - { - format = "text/turtle"; - useNamespaces = true; - } - }; - final String rdf = (String) JsonLdProcessor.toRDF(REPORT, new TurtleTripleCallback(), - options); - final OutputStreamWriter writer = new OutputStreamWriter( - new FileOutputStream(reportOutputFile + ".ttl")); - writer.write(rdf); - writer.close(); - } } @Parameters(name = "{0}{1}") diff --git a/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java b/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java deleted file mode 100644 index d47d744b..00000000 --- a/core/src/test/java/com/github/jsonldjava/impl/TurtleRDFParserTest.java +++ /dev/null @@ -1,448 +0,0 @@ -package com.github.jsonldjava.impl; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import com.github.jsonldjava.core.JsonLdError; -import com.github.jsonldjava.core.RDFDataset; -import com.github.jsonldjava.core.RDFDataset.Quad; -import com.github.jsonldjava.core.RDFDatasetUtils; -import com.github.jsonldjava.utils.EarlTestSuite; -import com.github.jsonldjava.utils.Obj; - -@Ignore -@RunWith(Parameterized.class) -public class TurtleRDFParserTest { - - // @Test - public void simpleTest() throws JsonLdError { - - final String input = "@prefix ericFoaf: .\n" - + "@prefix : .\n" - + "ericFoaf:ericP :givenName \"Eric\" ;\n" - + "\t:knows ,\n" - + "\t\t[ :mbox ] ,\n" + "\t\t ."; - - final List> expected = new ArrayList>() { - { - add(new LinkedHashMap() { - { - put("@id", "_:b1"); - put("http://xmlns.com/foaf/0.1/mbox", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@id", "mailto:timbl@w3.org"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://getopenid.com/amyvdh"); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://norman.walsh.name/knows/who/dan-brickley"); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://www.w3.org/People/Eric/ericP-foaf.rdf#ericP"); - put("http://xmlns.com/foaf/0.1/givenName", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@value", "Eric"); - } - }); - } - }); - put("http://xmlns.com/foaf/0.1/knows", new ArrayList() { - { - add(new LinkedHashMap() { - { - put("@id", - "http://norman.walsh.name/knows/who/dan-brickley"); - } - }); - add(new LinkedHashMap() { - { - put("@id", "_:b1"); - } - }); - add(new LinkedHashMap() { - { - put("@id", "http://getopenid.com/amyvdh"); - } - }); - } - }); - } - }); - add(new LinkedHashMap() { - { - put("@id", "mailto:timbl@w3.org"); - } - }); - } - }; - - final Object json = null; /* - * JsonLdProcessor.fromRDF(input, new - * JsonLdOptions() { { format = "text/turtle"; - * } }, new TurtleRDFParser()); - */ - assertTrue(Obj.equals(expected, json)); - } - - @BeforeClass - public static void before() { - if (CACHE_DIR == null) { - System.out.println("Using temp dir: " + System.getProperty("java.io.tmpdir")); - } - } - - private static String TURTLE_TEST_MANIFEST = "https://dvcs.w3.org/hg/rdf/raw-file/default/rdf-turtle/tests-ttl/manifest.ttl"; - private static final String LAST_ETAG = null; // "1369157887.0"; - private static final String CACHE_DIR = null; - - @Parameters(name = "{0}{1}") - public static Collection data() throws URISyntaxException, IOException { - - final EarlTestSuite testSuite = new EarlTestSuite(TURTLE_TEST_MANIFEST, CACHE_DIR, - LAST_ETAG); - - final Collection rdata = new ArrayList(); - - for (final Map test : testSuite.getTests()) { - rdata.add(new Object[] { testSuite, test.get("@id"), test }); - } - - return rdata; - } - - private final Map test; - private final EarlTestSuite testSuite; - - public TurtleRDFParserTest(final EarlTestSuite testSuite, final String id, - final Map test) { - this.test = test; - this.testSuite = testSuite; - } - - @Test - public void runTest() throws IOException, JsonLdError { - final String inputfn = (String) Obj.get(test, "mf:action", "@id"); - final String outputfn = (String) Obj.get(test, "mf:result", "@id"); - final String type = (String) Obj.get(test, "@type"); - final String input = testSuite.getFile(inputfn); - - Boolean passed = false; - String failmsg = ""; - if ("rdft:TestTurtleEval".equals(type)) { - final RDFDataset result = new TurtleRDFParser().parse(input); - final RDFDataset expected = RDFDatasetUtils.parseNQuads(testSuite.getFile(outputfn)); - passed = compareDatasets("http://example/base/" + inputfn, result, expected); - if (!passed) { - failmsg = "\n" + "Expected: " + RDFDatasetUtils.toNQuads(expected) + "\n" - + "Result : " + RDFDatasetUtils.toNQuads(result); - } - } else if ("rdft:TestTurtlePositiveSyntax".equals(type)) { - /* - * JsonLdProcessor.fromRDF(input, new - * JsonLdOptions("http://example/base/") { { format = "text/turtle"; - * } }); passed = true; // otherwise an exception would have been - * thrown - */ - // TODO: temporary until new code is done - throw new JsonLdError(JsonLdError.Error.NOT_IMPLEMENTED, ""); - } else if ("rdft:TestTurtleNegativeSyntax".equals(type) - || "rdft:TestTurtleNegativeEval".equals(type)) { - // TODO: need to figure out how to properly deal with negative tests - try { - /* - * JsonLdProcessor.fromRDF(input, new - * JsonLdOptions("http://example/base/") { { format = - * "text/turtle"; } }); - */ - failmsg = "Expected parse error, but no problems detected"; - throw new JsonLdError(JsonLdError.Error.NOT_IMPLEMENTED, ""); - } catch (final JsonLdError e) { - if (e.getType() == JsonLdError.Error.PARSE_ERROR) { - passed = true; - } else { - failmsg = "Expected parse error, got: " + e.getMessage(); - } - } - } else { - failmsg = "DON'T KNOW HOW TO HANDLE: " + type; - } - assertTrue(failmsg, passed); - } - - /** - * Compare datasets, normalizing the blank nodes and adding baseIRI to - * relative IRIs - * - * @param result - * @param expected - * @return - */ - private Boolean compareDatasets(final String baseIRI, final RDFDataset result, - final RDFDataset expected) { - final String baseIRIpath = baseIRI.substring(0, baseIRI.lastIndexOf("/") + 1); - final List res = new ArrayList() { - { - for (final RDFDataset.Quad q : result.getQuads("@default")) { - final RDFDataset.Node s = q.getSubject(); - final RDFDataset.Node p = q.getPredicate(); - final RDFDataset.Node o = q.getObject(); - if (s.isIRI() && !s.getValue().contains(":")) { - final String v = s.getValue(); - if (v.startsWith("#") || v.startsWith("?")) { - s.put("value", baseIRI + s.getValue()); - } else { - s.put("value", baseIRIpath + s.getValue()); - } - } - if (p.isIRI() && !p.getValue().contains(":")) { - final String v = p.getValue(); - if (v.startsWith("#") || v.startsWith("?")) { - p.put("value", baseIRI + p.getValue()); - } else { - p.put("value", baseIRIpath + p.getValue()); - } - } - if (o.isIRI() && !o.getValue().contains(":")) { - final String v = o.getValue(); - if (v.startsWith("#") || v.startsWith("?")) { - o.put("value", baseIRI + o.getValue()); - } else { - o.put("value", baseIRIpath + o.getValue()); - } - } - add(q); - } - } - }; - final List exp = new ArrayList() { - { - addAll(expected.getQuads("@default")); - } - }; - final List unmatched = new ArrayList(); - final BnodeMappings bnodeMaps = new BnodeMappings(); - boolean finalpass = false; - while (!exp.isEmpty() && !res.isEmpty()) { - final Quad eq = exp.remove(0); - int matches = 0; - RDFDataset.Quad last_match = null; - for (final RDFDataset.Quad rq : res) { - // if predicates are not equal there cannot be a match - if (!eq.getPredicate().equals(rq.getPredicate())) { - continue; - } - if (eq.getSubject().isBlankNode() && rq.getSubject().isBlankNode()) { - // check for locking - boolean subjectLocked = false; - if (bnodeMaps.isLocked(eq.getSubject().getValue())) { - // if this mapping doesn't match the locked mapping, we - // don't have a match - if (!rq.getSubject().getValue() - .equals(bnodeMaps.getMapping(eq.getSubject().getValue()))) { - continue; - } - subjectLocked = true; - } - // if the objects are also both blank nodes - if (eq.getObject().isBlankNode() && rq.getObject().isBlankNode()) { - // check for locking - if (bnodeMaps.isLocked(eq.getObject().getValue())) { - // if this mapping doesn't match the locked mapping, - // we don't have a match - if (!rq.getObject().getValue() - .equals(bnodeMaps.getMapping(eq.getObject().getValue()))) { - continue; - } - } else { - // add possible mappings for the objects - bnodeMaps.addPossibleMapping(eq.getObject().getValue(), - rq.getObject().getValue()); - } - } - // otherwise, if the objects aren't equal we can't have a - // match - else if (!eq.getObject().equals(rq.getObject())) { - continue; - } - // objects are equal or both blank nodes so we have a match - matches++; - last_match = rq; - // if subject is not locked add a possible mapping between - // subjects - if (!subjectLocked) { - bnodeMaps.addPossibleMapping(eq.getSubject().getValue(), - rq.getSubject().getValue()); - } - } - // otherwise check if the subjects are equal - else if (eq.getSubject().equals(rq.getSubject())) { - // if both objects are blank nodes, add possible mappings - // for them - if (eq.getObject().isBlankNode() && rq.getObject().isBlankNode()) { - // check for locking - if (bnodeMaps.isLocked(eq.getObject().getValue())) { - // if this mapping doesn't match the locked mapping, - // we don't have a match - if (!rq.getObject().getValue() - .equals(bnodeMaps.getMapping(eq.getObject().getValue()))) { - continue; - } - } else { - // add possible mappings for the objects - bnodeMaps.addPossibleMapping(eq.getObject().getValue(), - rq.getObject().getValue()); - } - // if we get here we have a match - matches++; - last_match = rq; - } - // otherwise, if the objects are equal we we have an exact - // match - else if (eq.getObject().equals(rq.getObject())) { - matches = 1; - last_match = rq; - break; - } - } - } - - if (matches == 0) { - // if we didn't find any matches, we're done and things didn't - // match! - return false; - } else if (matches == 1) { - // we have one match - if (eq.getSubject().isBlankNode()) { - // lock this mapping - bnodeMaps.lockMapping(eq.getSubject().getValue(), - last_match.getSubject().getValue()); - } - if (eq.getObject().isBlankNode()) { - // lock this mapping - bnodeMaps.lockMapping(eq.getObject().getValue(), - last_match.getObject().getValue()); - } - res.remove(last_match); - } else { - // we got multiple matches, we need to figure this stuff out - // later! - unmatched.add(eq); - } - - // TODO: no tests so far test this out, make one! - if (exp.isEmpty() && !finalpass) { - // if we are at the end and we have unmatched triples - if (!unmatched.isEmpty()) { - // lock the remaining bnodes, and test again - bnodeMaps.lockRemaining(); - exp.addAll(unmatched); - unmatched.clear(); - } - // we also only want to do this once, if we get here again - // without matching everything - // we're not going to match everything - finalpass = true; - } - } - - // they both matched if we have nothing left over - return res.isEmpty() && exp.isEmpty() && unmatched.isEmpty(); - } - - private class BnodeMappings { - Map> possiblebnodemappings = new LinkedHashMap>(); - Map lockedbnodemappings = new LinkedHashMap(); - - public void lockMapping(final String bn1, final String bn2) { - lockedbnodemappings.put(bn1, bn2); - possiblebnodemappings.remove(bn1); - for (final String i : possiblebnodemappings.keySet()) { - // remove bn2 as a possible mapping for any other bnodes - possiblebnodemappings.get(i).remove(bn2); - } - } - - public void lockRemaining() { - final List unlocked = new ArrayList(possiblebnodemappings.keySet()); - for (final String bn1 : unlocked) { - final String bn2 = getMapping(bn1); - assertNotNull("Unable to find mapping for blank node " + bn1 - + ". Possible error in mapping code", bn2); - lockMapping(bn1, bn2); - } - } - - public boolean isLocked(final String b) { - return lockedbnodemappings.containsKey(b); - } - - /** - * return either the locked mapping, or the highest matching - * - * @param b - * @return - */ - public String getMapping(final String b) { - if (isLocked(b)) { - return lockedbnodemappings.get(b); - } else { - int max = -1; - String rval = null; - for (final Entry map : possiblebnodemappings.get(b).entrySet()) { - if (map.getValue() > max) { - max = map.getValue(); - rval = map.getKey(); - } - } - return rval; - } - } - - public void addPossibleMapping(final String bn1, final String bn2) { - Map bn1m; - if (possiblebnodemappings.containsKey(bn1)) { - bn1m = possiblebnodemappings.get(bn1); - } else { - bn1m = new LinkedHashMap(); - possiblebnodemappings.put(bn1, bn1m); - } - Integer mappingcount = 0; - if (bn1m.containsKey(bn2)) { - mappingcount = bn1m.get(bn2); - } - bn1m.put(bn2, mappingcount + 1); - } - } - -} diff --git a/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java b/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java deleted file mode 100644 index f019d097..00000000 --- a/core/src/test/java/com/github/jsonldjava/impl/TurtleRegexTests.java +++ /dev/null @@ -1,639 +0,0 @@ -package com.github.jsonldjava.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.regex.Matcher; - -import org.junit.Test; - -import com.github.jsonldjava.impl.TurtleRDFParser.Regex; - -public class TurtleRegexTests { - - private void printMatcher(Matcher matcher) { - if (matcher.matches()) { - for (int i = 1; i <= matcher.groupCount(); i++) { - System.out.println(matcher.group(i)); - } - } - } - - @Test - public void test_PREFIX_ID() { - Matcher matcher = Regex.PREFIX_ID.matcher("@prefix : ."); - assertTrue(matcher.matches()); - assertEquals(2, matcher.groupCount()); - assertNotNull(matcher.group(1)); - assertNotNull(matcher.group(2)); - assertEquals("", matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(2)); - - matcher = Regex.PREFIX_ID.matcher("@prefix abcdef: ."); - assertTrue(matcher.matches()); - assertEquals(2, matcher.groupCount()); - assertNotNull(matcher.group(1)); - assertNotNull(matcher.group(2)); - assertEquals("abcdef", matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(2)); - } - - @Test - public void test_BASE() { - final Matcher matcher = Regex.BASE.matcher("@base ."); - assertTrue(matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertNotNull(matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(1)); - } - - @Test - public void test_SPARQL_PREFIX() { - Matcher matcher = Regex.SPARQL_PREFIX.matcher("PREFix : "); - assertTrue(matcher.matches()); - assertEquals(2, matcher.groupCount()); - assertNotNull(matcher.group(1)); - assertNotNull(matcher.group(2)); - assertEquals("", matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(2)); - - matcher = Regex.SPARQL_PREFIX.matcher("prefIX abcdef: "); - assertTrue(matcher.matches()); - assertEquals(2, matcher.groupCount()); - assertNotNull(matcher.group(1)); - assertNotNull(matcher.group(2)); - assertEquals("abcdef", matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(2)); - } - - @Test - public void test_SPARQL_BASE() { - final Matcher matcher = Regex.SPARQL_BASE.matcher("BaSe "); - assertTrue(matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertNotNull(matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(1)); - } - - @Test - public void test_DIRECTIVE() { - Matcher matcher = Regex.DIRECTIVE.matcher("@prefix : ."); - assertTrue(matcher.matches()); - assertEquals(6, matcher.groupCount()); - assertEquals("", matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(2)); - - matcher = Regex.DIRECTIVE.matcher("@prefix abc: ."); - assertTrue(matcher.matches()); - assertEquals(6, matcher.groupCount()); - assertEquals("abc", matcher.group(1)); - assertEquals("http://www.google.com/test#", matcher.group(2)); - - matcher = Regex.DIRECTIVE.matcher("@base ."); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertEquals("http://www.google.com/test#", matcher.group(3)); - - matcher = Regex.DIRECTIVE.matcher("PREFix : "); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("", matcher.group(4)); - assertEquals("http://www.google.com/test#", matcher.group(5)); - - matcher = Regex.DIRECTIVE.matcher("PREFix abc: "); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("abc", matcher.group(4)); - assertEquals("http://www.google.com/test#", matcher.group(5)); - - matcher = Regex.DIRECTIVE.matcher("BASE "); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("http://www.google.com/test#", matcher.group(6)); - } - - @Test - public void test_PREFIXED_NAME() { - assertTrue("abc:def".matches("" + Regex.PREFIXED_NAME)); - assertTrue(":def".matches("" + Regex.PREFIXED_NAME)); - } - - @Test - public void test_IRI() { - Matcher matcher = Regex.IRI.matcher(""); - assertTrue(matcher.matches()); - assertEquals(4, matcher.groupCount()); - assertEquals("http://www.google.com/test#hello", matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - - matcher = Regex.IRI.matcher("abc:def"); - assertTrue(matcher.matches()); - assertEquals(4, matcher.groupCount()); - assertNull(matcher.group(1)); - assertEquals("abc", matcher.group(2)); - assertEquals("def", matcher.group(3)); - assertNull(matcher.group(4)); - - matcher = Regex.IRI.matcher("hij:"); - assertTrue(matcher.matches()); - assertEquals(4, matcher.groupCount()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("hij", matcher.group(4)); - } - - @Test - public void test_ANON() { - assertTrue("[ ]".matches("^" + Regex.ANON + "$")); - } - - @Test - public void test_BLANK_NODE() { - Matcher matcher = Regex.BLANK_NODE.matcher("_:b0"); - assertTrue(matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertEquals("b0", matcher.group(1)); - - matcher = Regex.BLANK_NODE.matcher("[ ]"); - assertTrue(matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertEquals(null, matcher.group(1)); - } - - @Test - public void test_STRING() { - assertTrue("\"dffhjkasdhfskldhfoiw'eu\\\"fhowleifh\u00F8\u02FF\u0370\u037D\"" - .matches("^" + Regex.STRING + "$")); - assertFalse("\"dffhjkasdhfs\nkldhfoiw\\\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"" - .matches("^" + Regex.STRING + "$")); - assertTrue("'dffhjkasdhfskldh\\'foiweu\"fhowleifh \u00F8\u02FF\u0370\u037D'" - .matches("^" + Regex.STRING + "$")); - assertFalse("\"dffhjkasdhfs\nkldhfoiw\\\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"" - .matches("^" + Regex.STRING + "$")); - assertTrue("'''dffhjkasdhfsk\nldhfoiw\"'eufhowleifh \u00F8\u02FF\u0370\u037D'''" - .matches("^" + Regex.STRING + "$")); - assertTrue("\"\"\"dffhjkasdhfsk\nldhfoiw\"'eufhowleifh \u00F8\u02FF\u0370\u037D\"\"\"" - .matches("^" + Regex.STRING + "$")); - - Matcher matcher = Regex.STRING.matcher("'''x''y'''"); - assertTrue(matcher.find()); - assertEquals("'''x''y'''", matcher.group(1)); - - matcher = Regex.STRING.matcher("'''" + (char) 0xA + "''' ."); - assertTrue(matcher.find()); - assertEquals("'''" + (char) 0xA + "'''", matcher.group(1)); - - matcher = Regex.STRING.matcher("'''\f'''"); - assertTrue(matcher.find()); - assertEquals("'''\f'''", matcher.group(1)); - - assertFalse("'''x'''y'''".matches("^" + Regex.STRING + "$")); - assertFalse("\"\"\"x\"\"\"y\"\"\"".matches("^" + Regex.STRING + "$")); - } - - @Test - public void test_BOOLEAN_LITERAL() { - assertTrue("true".matches("^" + Regex.BOOLEAN_LITERAL + "$")); - assertTrue("false".matches("^" + Regex.BOOLEAN_LITERAL + "$")); - } - - @Test - public void test_RDF_LITERAL() { - Matcher matcher = Regex.RDF_LITERAL.matcher("\"hello\"@en"); - assertTrue(matcher.matches()); - assertEquals(6, matcher.groupCount()); - assertEquals("\"hello\"", matcher.group(1)); - assertEquals("en", matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - - matcher = Regex.RDF_LITERAL.matcher("\"123\"^^xsd:integer"); - assertTrue(matcher.matches()); - assertEquals(6, matcher.groupCount()); - assertEquals("\"123\"", matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("xsd", matcher.group(4)); - assertEquals("integer", matcher.group(5)); - assertNull(matcher.group(6)); - - matcher = Regex.RDF_LITERAL.matcher("\"123\"^^"); - assertTrue(matcher.matches()); - assertEquals(6, matcher.groupCount()); - assertEquals("\"123\"", matcher.group(1)); - assertNull(matcher.group(2)); - assertEquals("http://fake/type", matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - - matcher = Regex.RDF_LITERAL.matcher("\"123\"^^def:"); - assertTrue(matcher.matches()); - assertEquals(6, matcher.groupCount()); - assertEquals("\"123\"", matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("def", matcher.group(6)); - } - - @Test - public void test_NUMERIC_LITERAL() { - Matcher matcher = Regex.NUMERIC_LITERAL.matcher("3E1"); - assertTrue(matcher.matches()); - assertEquals(3, matcher.groupCount()); - assertEquals("3E1", matcher.group(1)); - - matcher = Regex.NUMERIC_LITERAL.matcher("-5.1E-10000"); - assertTrue(matcher.matches()); - assertEquals("-5.1E-10000", matcher.group(1)); - - matcher = Regex.NUMERIC_LITERAL.matcher("2.01"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertEquals("2.01", matcher.group(2)); - - matcher = Regex.NUMERIC_LITERAL.matcher("123"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertEquals("123", matcher.group(3)); - - matcher = Regex.NUMERIC_LITERAL.matcher("-1"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertEquals("-1", matcher.group(3)); - } - - @Test - public void test_SUBJECT() { - Matcher matcher = Regex.SUBJECT.matcher(""); - assertTrue(matcher.matches()); - assertEquals(5, matcher.groupCount()); - assertEquals("http://www.google.com/test#hello", matcher.group(1)); - - matcher = Regex.SUBJECT.matcher("abc:def"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertEquals("abc", matcher.group(2)); - assertEquals("def", matcher.group(3)); - - matcher = Regex.SUBJECT.matcher("hij:"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("hij", matcher.group(4)); - - matcher = Regex.SUBJECT.matcher("_:b0"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertEquals("b0", matcher.group(5)); - - // a subject match without any matching groups should == an anonymous - // subject - matcher = Regex.SUBJECT.matcher("[ ]"); - assertTrue(matcher.matches()); - } - - @Test - public void test_PREDICATE() { - Matcher matcher = Regex.PREDICATE.matcher(""); - assertTrue(matcher.matches()); - assertEquals(4, matcher.groupCount()); - assertEquals("http://www.google.com/test#hello", matcher.group(1)); - - matcher = Regex.PREDICATE.matcher("abc:def"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertEquals("abc", matcher.group(2)); - assertEquals("def", matcher.group(3)); - - matcher = Regex.PREDICATE.matcher("hij:"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("hij", matcher.group(4)); - - // match rdf:type shorthand - matcher = Regex.PREDICATE.matcher("a "); - assertTrue(matcher.matches()); - assertEquals("a ", matcher.group(0)); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - } - - @Test - public void test_LITERAL() { - Matcher matcher = Regex.LITERAL.matcher("\"hello\"@en"); - assertTrue(matcher.matches()); - assertEquals(10, matcher.groupCount()); - assertEquals("\"hello\"", matcher.group(1)); - assertEquals("en", matcher.group(2)); - - matcher = Regex.LITERAL.matcher("\"123\"^^xsd:integer"); - assertTrue(matcher.matches()); - assertEquals("\"123\"", matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("xsd", matcher.group(4)); - assertEquals("integer", matcher.group(5)); - - matcher = Regex.LITERAL.matcher("\"123\"^^"); - assertTrue(matcher.matches()); - assertEquals("\"123\"", matcher.group(1)); - assertNull(matcher.group(2)); - assertEquals("http://fake/type", matcher.group(3)); - - matcher = Regex.LITERAL.matcher("\"123\"^^def:"); - assertTrue(matcher.matches()); - assertEquals("\"123\"", matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("def", matcher.group(6)); - - matcher = Regex.LITERAL.matcher("123"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertEquals("123", matcher.group(9)); - - matcher = Regex.LITERAL.matcher("-1"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertEquals("-1", matcher.group(9)); - - matcher = Regex.LITERAL.matcher("2.01"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertEquals("2.01", matcher.group(8)); - assertNull(matcher.group(9)); - - matcher = Regex.LITERAL.matcher("3E1"); - assertTrue(matcher.matches()); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertEquals("3E1", matcher.group(7)); - - matcher = Regex.LITERAL.matcher("-5.1E-10000"); - assertTrue(matcher.matches()); - assertTrue(matcher.matches()); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertEquals("-5.1E-10000", matcher.group(7)); - - matcher = Regex.LITERAL.matcher("true"); - assertTrue(matcher.matches()); - assertTrue(matcher.matches()); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertEquals("true", matcher.group(10)); - - } - - @Test - public void test_OBJECT() { - // IRIs should be at position 1 - Matcher matcher = Regex.OBJECT.matcher("<>"); - assertTrue(matcher.matches()); - assertEquals(15, matcher.groupCount()); - assertEquals("", matcher.group(1)); - - matcher = Regex.OBJECT.matcher(""); - assertTrue(matcher.matches()); - assertEquals("http://test", matcher.group(1)); - - // prefixed names should be at pos 2 + 3 - matcher = Regex.OBJECT.matcher("abc:def"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertEquals("abc", matcher.group(2)); - assertEquals("def", matcher.group(3)); - - matcher = Regex.OBJECT.matcher(":def"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertEquals("", matcher.group(2)); - assertEquals("def", matcher.group(3)); - - // prefixes only should be at pos 4 - matcher = Regex.OBJECT.matcher("hij:"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertEquals("hij", matcher.group(4)); - - // blank node ids should be at pos 5 - matcher = Regex.OBJECT.matcher("_:b0"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertEquals("b0", matcher.group(5)); - - // strings should be in position 6 - matcher = Regex.OBJECT.matcher("\"hello world\""); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("\"hello world\"", matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertNull(matcher.group(11)); - - // language taged strings should be at position 6 + 7 for langtag - matcher = Regex.OBJECT.matcher("\"hello\"@en"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("\"hello\"", matcher.group(6)); - assertEquals("en", matcher.group(7)); - - // literals with IRI datatype should be at pos 6 + 8 - matcher = Regex.OBJECT.matcher("\"123\"^^"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("\"123\"", matcher.group(6)); - assertNull(matcher.group(7)); - assertEquals("http://test/type", matcher.group(8)); - - // literals with ns:name datatype should be at pos 6 + 9 + 10 - matcher = Regex.OBJECT.matcher("\"123\"^^xsd:integer"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("\"123\"", matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertEquals("xsd", matcher.group(9)); - assertEquals("integer", matcher.group(10)); - - // literals with ns: datatype should be at pos 6 + 11 - matcher = Regex.OBJECT.matcher("\"123\"^^def:"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertEquals("\"123\"", matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertNull(matcher.group(10)); - assertEquals("def", matcher.group(11)); - - // double literals should be at pos 12 - matcher = Regex.OBJECT.matcher("1.234E-10"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertNull(matcher.group(10)); - assertNull(matcher.group(11)); - assertEquals("1.234E-10", matcher.group(12)); - - // decimal literals should be at pos 13 - matcher = Regex.OBJECT.matcher("12.34"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertNull(matcher.group(10)); - assertNull(matcher.group(11)); - assertNull(matcher.group(12)); - assertEquals("12.34", matcher.group(13)); - - // integer literals should be at pos 14 - matcher = Regex.OBJECT.matcher("1234"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertNull(matcher.group(10)); - assertNull(matcher.group(11)); - assertNull(matcher.group(12)); - assertNull(matcher.group(13)); - assertEquals("1234", matcher.group(14)); - - // boolean literals should be at pos 15 - matcher = Regex.OBJECT.matcher("false"); - assertTrue(matcher.matches()); - assertNull(matcher.group(1)); - assertNull(matcher.group(2)); - assertNull(matcher.group(3)); - assertNull(matcher.group(4)); - assertNull(matcher.group(5)); - assertNull(matcher.group(6)); - assertNull(matcher.group(7)); - assertNull(matcher.group(8)); - assertNull(matcher.group(9)); - assertNull(matcher.group(10)); - assertNull(matcher.group(11)); - assertNull(matcher.group(12)); - assertNull(matcher.group(13)); - assertNull(matcher.group(14)); - assertEquals("false", matcher.group(15)); - - matcher = Regex.OBJECT.matcher("\"IRI with four digit numeric escape (\\\\u)\" ;"); - assertTrue(matcher.find()); - } -} From a39cdb638c6bb0862436ebff8f8ec93ce7df7afb Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jan 2017 13:13:00 +1100 Subject: [PATCH 229/440] Remove unused utility methods Signed-off-by: Peter Ansell --- .../github/jsonldjava/core/JsonLdUtils.java | 521 ------------------ .../jsonldjava/core/RDFDatasetUtils.java | 202 ------- 2 files changed, 723 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 6c6469ce..150b551f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -137,26 +137,6 @@ static void laxMergeValue(Map obj, String key, Object value) { // } } - static void mergeCompactedValue(Map obj, String key, Object value) { - if (obj == null) { - return; - } - final Object prop = obj.get(key); - if (prop == null) { - obj.put(key, value); - return; - } - if (!(prop instanceof List)) { - final List tmp = new ArrayList(); - tmp.add(prop); - } - if (value instanceof List) { - ((List) prop).addAll((List) value); - } else { - ((List) prop).add(value); - } - } - public static boolean isAbsoluteIri(String value) { // TODO: this is a bit simplistic! return value.contains(":"); @@ -206,311 +186,6 @@ public static boolean isRelativeIri(String value) { return false; } - // //////////////////////////////////////////////////// OLD CODE BELOW - - /** - * Adds a value to a subject. If the value is an array, all values in the - * array will be added. - * - * Note: If the value is a subject that already exists as a property of the - * given subject, this method makes no attempt to deeply merge properties. - * Instead, the value will not be added. - * - * @param subject - * the subject to add the value to. - * @param property - * the property that relates the value to the subject. - * @param value - * the value to add. - * @param [propertyIsArray] - * true if the property is always an array, false if not - * (default: false). - * @param [allowDuplicate] - * true if the property is a @list, false if not (default: - * false). - */ - static void addValue(Map subject, String property, Object value, - boolean propertyIsArray, boolean allowDuplicate) { - - if (isArray(value)) { - if (((List) value).size() == 0 && propertyIsArray && !subject.containsKey(property)) { - subject.put(property, new ArrayList()); - } - for (final Object val : (List) value) { - addValue(subject, property, val, propertyIsArray, allowDuplicate); - } - } else if (subject.containsKey(property)) { - // check if subject already has the value if duplicates not allowed - final boolean hasValue = !allowDuplicate && hasValue(subject, property, value); - - // make property an array if value not present or always an array - if (!isArray(subject.get(property)) && (!hasValue || propertyIsArray)) { - final List tmp = new ArrayList(); - tmp.add(subject.get(property)); - subject.put(property, tmp); - } - - // add new value - if (!hasValue) { - ((List) subject.get(property)).add(value); - } - } else { - // add new value as a set or single value - Object tmp; - if (propertyIsArray) { - tmp = new ArrayList(); - ((List) tmp).add(value); - } else { - tmp = value; - } - subject.put(property, tmp); - } - } - - static void addValue(Map subject, String property, Object value, - boolean propertyIsArray) { - addValue(subject, property, value, propertyIsArray, true); - } - - static void addValue(Map subject, String property, Object value) { - addValue(subject, property, value, false, true); - } - - /** - * Prepends a base IRI to the given relative IRI. - * - * @param base - * the base IRI. - * @param iri - * the relative IRI. - * - * @return the absolute IRI. - * - * TODO: the JsonLdUrl class isn't as forgiving as the Node.js url - * parser, we may need to re-implement the parser here to support - * the flexibility required - */ - private static String prependBase(Object baseobj, String iri) { - // already an absolute IRI - if (iri.indexOf(":") != -1) { - return iri; - } - - // parse base if it is a string - JsonLdUrl base; - if (isString(baseobj)) { - base = JsonLdUrl.parse((String) baseobj); - } else { - // assume base is already a JsonLdUrl - base = (JsonLdUrl) baseobj; - } - - final JsonLdUrl rel = JsonLdUrl.parse(iri); - - // start hierarchical part - String hierPart = base.protocol; - if (!"".equals(rel.authority)) { - hierPart += "//" + rel.authority; - } else if (!"".equals(base.href)) { - hierPart += "//" + base.authority; - } - - // per RFC3986 normalize - String path; - - // IRI represents an absolute path - if (rel.pathname.indexOf("/") == 0) { - path = rel.pathname; - } else { - path = base.pathname; - - // append relative path to the end of the last directory from base - if (!"".equals(rel.pathname)) { - path = path.substring(0, path.lastIndexOf("/") + 1); - if (path.length() > 0 && !path.endsWith("/")) { - path += "/"; - } - path += rel.pathname; - } - } - - // remove slashes anddots in path - path = JsonLdUrl.removeDotSegments(path, !"".equals(hierPart)); - - // add query and hash - if (!"".equals(rel.query)) { - path += "?" + rel.query; - } - - if (!"".equals(rel.hash)) { - path += rel.hash; - } - - final String rval = hierPart + path; - - if ("".equals(rval)) { - return "./"; - } - return rval; - } - - /** - * Expands a language map. - * - * @param languageMap - * the language map to expand. - * - * @return the expanded language map. - * @throws JsonLdError - */ - static List expandLanguageMap(Map languageMap) throws JsonLdError { - final List rval = new ArrayList(); - final List keys = new ArrayList(languageMap.keySet()); - Collections.sort(keys); // lexicographically sort languages - for (final String key : keys) { - List val; - if (!isArray(languageMap.get(key))) { - val = new ArrayList(); - val.add(languageMap.get(key)); - } else { - val = (List) languageMap.get(key); - } - for (final Object item : val) { - if (!isString(item)) { - throw new JsonLdError(JsonLdError.Error.SYNTAX_ERROR); - } - final Map tmp = newMap(); - tmp.put("@value", item); - tmp.put("@language", key.toLowerCase()); - rval.add(tmp); - } - } - - return rval; - } - - /** - * Throws an exception if the given value is not a valid @type value. - * - * @param v - * the value to check. - * @throws JsonLdError - */ - static boolean validateTypeValue(Object v) throws JsonLdError { - if (v == null) { - throw new NullPointerException("\"@type\" value cannot be null"); - } - - // must be a string, subject reference, or empty object - if (v instanceof String - || (v instanceof Map && (((Map) v).containsKey("@id") - || ((Map) v).size() == 0))) { - return true; - } - - // must be an array - boolean isValid = false; - if (v instanceof List) { - isValid = true; - for (final Object i : (List) v) { - if (!(i instanceof String - || i instanceof Map && ((Map) i).containsKey("@id"))) { - isValid = false; - break; - } - } - } - - if (!isValid) { - throw new JsonLdError(JsonLdError.Error.SYNTAX_ERROR); - } - return true; - } - - /** - * Removes a base IRI from the given absolute IRI. - * - * @param base - * the base IRI. - * @param iri - * the absolute IRI. - * - * @return the relative IRI if relative to base, otherwise the absolute IRI. - */ - private static String removeBase(Object baseobj, String iri) { - JsonLdUrl base; - if (isString(baseobj)) { - base = JsonLdUrl.parse((String) baseobj); - } else { - base = (JsonLdUrl) baseobj; - } - - // establish base root - String root = ""; - if (!"".equals(base.href)) { - root += (base.protocol) + "//" + base.authority; - } - // support network-path reference with empty base - else if (iri.indexOf("//") != 0) { - root += "//"; - } - - // IRI not relative to base - if (iri.indexOf(root) != 0) { - return iri; - } - - // remove root from IRI and parse remainder - final JsonLdUrl rel = JsonLdUrl.parse(iri.substring(root.length())); - - // remove path segments that match - final List baseSegments = _split(base.normalizedPath, "/"); - final List iriSegments = _split(rel.normalizedPath, "/"); - - while (baseSegments.size() > 0 && iriSegments.size() > 0) { - if (!baseSegments.get(0).equals(iriSegments.get(0))) { - break; - } - if (baseSegments.size() > 0) { - baseSegments.remove(0); - } - if (iriSegments.size() > 0) { - iriSegments.remove(0); - } - } - - // use '../' for each non-matching base segment - String rval = ""; - if (baseSegments.size() > 0) { - // don't count the last segment if it isn't a path (doesn't end in - // '/') - // don't count empty first segment, it means base began with '/' - if (!base.normalizedPath.endsWith("/") || "".equals(baseSegments.get(0))) { - baseSegments.remove(baseSegments.size() - 1); - } - for (int i = 0; i < baseSegments.size(); ++i) { - rval += "../"; - } - } - - // prepend remaining segments - rval += _join(iriSegments, "/"); - - // add query and hash - if (!"".equals(rel.query)) { - rval += "?" + rel.query; - } - if (!"".equals(rel.hash)) { - rval += rel.hash; - } - - if ("".equals(rval)) { - rval = "./"; - } - - return rval; - } - /** * Removes the @preserve keywords as the last step of the framing algorithm. * @@ -571,42 +246,6 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro return input; } - /** - * replicate javascript .join because i'm too lazy to keep doing it manually - * - * @param iriSegments - * @param string - * @return - */ - private static String _join(List list, String joiner) { - String rval = ""; - if (list.size() > 0) { - rval += list.get(0); - } - for (int i = 1; i < list.size(); i++) { - rval += joiner + list.get(i); - } - return rval; - } - - /** - * replicates the functionality of javascript .split, which has different - * results to java's String.split if there is a trailing / - * - * @param string - * @param delim - * @return - */ - private static List _split(String string, String delim) { - final List rval = new ArrayList(Arrays.asList(string.split(delim))); - if (string.endsWith("/")) { - // javascript .split includes a blank entry if the string ends with - // the delimiter, java .split does not so we need to add it manually - rval.add(""); - } - return rval; - } - /** * Compares two strings first based on length and then lexicographically. * @@ -626,49 +265,6 @@ static int compareShortestLeast(String a, String b) { return Integer.signum(a.compareTo(b)); } - /** - * Determines if the given value is a property of the given subject. - * - * @param subject - * the subject to check. - * @param property - * the property to check. - * @param value - * the value to check. - * - * @return true if the value exists, false if not. - */ - static boolean hasValue(Map subject, String property, Object value) { - boolean rval = false; - if (hasProperty(subject, property)) { - Object val = subject.get(property); - final boolean isList = isList(val); - if (isList || val instanceof List) { - if (isList) { - val = ((Map) val).get("@list"); - } - for (final Object i : (List) val) { - if (compareValues(value, i)) { - rval = true; - break; - } - } - } else if (!(value instanceof List)) { - rval = compareValues(value, val); - } - } - return rval; - } - - private static boolean hasProperty(Map subject, String property) { - boolean rval = false; - if (subject.containsKey(property)) { - final Object value = subject.get(property); - rval = (!(value instanceof List) || ((List) value).size() > 0); - } - return rval; - } - /** * Compares two JSON-LD values for equality. Two JSON-LD values will be * considered equal if: @@ -711,49 +307,6 @@ static boolean compareValues(Object v1, Object v2) { return false; } - /** - * Removes a value from a subject. - * - * @param subject - * the subject. - * @param property - * the property that relates the value to the subject. - * @param value - * the value to remove. - * @param [options] - * the options to use: [propertyIsArray] true if the property is - * always an array, false if not (default: false). - */ - static void removeValue(Map subject, String property, - Map value) { - removeValue(subject, property, value, false); - } - - static void removeValue(Map subject, String property, Map value, - boolean propertyIsArray) { - // filter out value - final List values = new ArrayList(); - if (subject.get(property) instanceof List) { - for (final Object e : ((List) subject.get(property))) { - if (!(value.equals(e))) { - values.add(value); - } - } - } else { - if (!value.equals(subject.get(property))) { - values.add(subject.get(property)); - } - } - - if (values.size() == 0) { - subject.remove(property); - } else if (values.size() == 1 && !propertyIsArray) { - subject.put(property, values.get(0)); - } else { - subject.put(property, values); - } - } - /** * Returns true if the given value is a blank node. * @@ -778,80 +331,6 @@ static boolean isBlankNode(Object v) { return false; } - /** - * Finds all @context URLs in the given JSON-LD input. - * - * @param input - * the JSON-LD input. - * @param urls - * a map of URLs (url => false/@contexts). - * @param replace - * true to replace the URLs in the given input with the - * @contexts from the urls map, false not to. - * - * @return true if new URLs to resolve were found, false if not. - */ - private static boolean findContextUrls(Object input, Map urls, - Boolean replace) { - final int count = urls.size(); - if (input instanceof List) { - for (final Object i : (List) input) { - findContextUrls(i, urls, replace); - } - return count < urls.size(); - } else if (input instanceof Map) { - for (final String key : ((Map) input).keySet()) { - if (!"@context".equals(key)) { - findContextUrls(((Map) input).get(key), urls, replace); - continue; - } - - // get @context - final Object ctx = ((Map) input).get(key); - - // array @context - if (ctx instanceof List) { - int length = ((List) ctx).size(); - for (int i = 0; i < length; i++) { - Object _ctx = ((List) ctx).get(i); - if (_ctx instanceof String) { - // replace w/@context if requested - if (replace) { - _ctx = urls.get(_ctx); - if (_ctx instanceof List) { - // add flattened context - ((List) ctx).remove(i); - ((List) ctx).addAll((Collection) _ctx); - i += ((List) _ctx).size(); - length += ((List) _ctx).size(); - } else { - ((List) ctx).set(i, _ctx); - } - } - // @context JsonLdUrl found - else if (!urls.containsKey(_ctx)) { - urls.put((String) _ctx, Boolean.FALSE); - } - } - } - } - // string @context - else if (ctx instanceof String) { - // replace w/@context if requested - if (replace) { - ((Map) input).put(key, urls.get(ctx)); - } - // @context JsonLdUrl found - else if (!urls.containsKey(ctx)) { - urls.put((String) ctx, Boolean.FALSE); - } - } - } - return (count < urls.size()); - } - return false; - } - static Object clone(Object value) {// throws // CloneNotSupportedException { Object rval = null; diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 6917e980..926a28b2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -1,219 +1,17 @@ package com.github.jsonldjava.core; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_FIRST; import static com.github.jsonldjava.core.JsonLdConsts.RDF_LANGSTRING; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_NIL; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; -import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE; -import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER; import static com.github.jsonldjava.core.JsonLdConsts.XSD_STRING; -import static com.github.jsonldjava.core.JsonLdUtils.isKeyword; -import static com.github.jsonldjava.core.JsonLdUtils.isList; -import static com.github.jsonldjava.core.JsonLdUtils.isObject; -import static com.github.jsonldjava.core.JsonLdUtils.isValue; import static com.github.jsonldjava.core.Regex.HEX; -import static com.github.jsonldjava.utils.Obj.newMap; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Locale; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RDFDatasetUtils { - /** - * Creates an array of RDF triples for the given graph. - * - * @param graph - * the graph to create RDF triples for. - * @param namer - * a UniqueNamer for assigning blank node names. - * - * @return the array of RDF triples for the given graph. - * @deprecated Use {@link RDFDataset#graphToRDF(String, Map)} instead - */ - @Deprecated - static List graphToRDF(Map graph, UniqueNamer namer) { - final List rval = new ArrayList(); - for (final String id : graph.keySet()) { - final Map node = (Map) graph.get(id); - final List properties = new ArrayList(node.keySet()); - Collections.sort(properties); - for (String property : properties) { - final Object items = node.get(property); - if ("@type".equals(property)) { - property = RDF_TYPE; - } else if (isKeyword(property)) { - continue; - } - - for (final Object item : (List) items) { - // RDF subjects - final Map subject = newMap(); - if (id.indexOf("_:") == 0) { - subject.put("type", "blank node"); - subject.put("value", namer.getName(id)); - } else { - subject.put("type", "IRI"); - subject.put("value", id); - } - - // RDF predicates - final Map predicate = newMap(); - predicate.put("type", "IRI"); - predicate.put("value", property); - - // convert @list to triples - if (isList(item)) { - listToRDF((List) ((Map) item).get("@list"), namer, - subject, predicate, rval); - } - // convert value or node object to triple - else { - final Object object = objectToRDF(item, namer); - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", object); - rval.add(tmp); - } - } - } - } - - return rval; - } - - /** - * Converts a @list value into linked list of blank node RDF triples (an RDF - * collection). - * - * @param list - * the @list value. - * @param namer - * a UniqueNamer for assigning blank node names. - * @param subject - * the subject for the head of the list. - * @param predicate - * the predicate for the head of the list. - * @param triples - * the array of triples to append to. - */ - private static void listToRDF(List list, UniqueNamer namer, Map subject, - Map predicate, List triples) { - final Map first = newMap(); - first.put("type", "IRI"); - first.put("value", RDF_FIRST); - final Map rest = newMap(); - rest.put("type", "IRI"); - rest.put("value", RDF_REST); - final Map nil = newMap(); - nil.put("type", "IRI"); - nil.put("value", RDF_NIL); - - for (final Object item : list) { - final Map blankNode = newMap(); - blankNode.put("type", "blank node"); - blankNode.put("value", namer.getName()); - - { - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", blankNode); - triples.add(tmp); - } - - subject = blankNode; - predicate = first; - final Object object = objectToRDF(item, namer); - - { - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", object); - triples.add(tmp); - } - - predicate = rest; - } - final Map tmp = newMap(); - tmp.put("subject", subject); - tmp.put("predicate", predicate); - tmp.put("object", nil); - triples.add(tmp); - } - - /** - * Converts a JSON-LD value object to an RDF literal or a JSON-LD string or - * node object to an RDF resource. - * - * @param item - * the JSON-LD value or node object. - * @param namer - * the UniqueNamer to use to assign blank node names. - * - * @return the RDF literal or RDF resource. - */ - private static Object objectToRDF(Object item, UniqueNamer namer) { - final Map object = newMap(); - - // convert value object to RDF - if (isValue(item)) { - object.put("type", "literal"); - final Object value = ((Map) item).get("@value"); - final Object datatype = ((Map) item).get("@type"); - - // convert to XSD datatypes as appropriate - if (value instanceof Boolean || value instanceof Number) { - // convert to XSD datatype - if (value instanceof Boolean) { - object.put("value", value.toString()); - object.put("datatype", datatype == null ? XSD_BOOLEAN : datatype); - } else if (value instanceof Double || value instanceof Float) { - // canonical double representation - final DecimalFormat df = new DecimalFormat("0.0###############E0"); - df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); - object.put("value", df.format(value)); - object.put("datatype", datatype == null ? XSD_DOUBLE : datatype); - } else { - final DecimalFormat df = new DecimalFormat("0"); - object.put("value", df.format(value)); - object.put("datatype", datatype == null ? XSD_INTEGER : datatype); - } - } else if (((Map) item).containsKey("@language")) { - object.put("value", value); - object.put("datatype", datatype == null ? RDF_LANGSTRING : datatype); - object.put("language", ((Map) item).get("@language")); - } else { - object.put("value", value); - object.put("datatype", datatype == null ? XSD_STRING : datatype); - } - } - // convert string/node object to RDF - else { - final String id = isObject(item) ? (String) ((Map) item).get("@id") - : (String) item; - if (id.indexOf("_:") == 0) { - object.put("type", "blank node"); - object.put("value", namer.getName(id)); - } else { - object.put("type", "IRI"); - object.put("value", id); - } - } - - return object; - } - public static String toNQuads(RDFDataset dataset) { final StringBuilder output = new StringBuilder(256); toNQuads(dataset, output); From f9d81e388b02e9899fe714cffaa8274cd6599e6c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jan 2017 13:53:43 +1100 Subject: [PATCH 230/440] Use non-deprecated methods in JarCacheTest Signed-off-by: Peter Ansell --- .../jsonldjava/utils/JarCacheStorage.java | 30 +------- .../github/jsonldjava/utils/JarCacheTest.java | 70 +++++++++++++------ 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 49fee70a..6e520eae 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -42,7 +42,7 @@ public class JarCacheStorage implements HttpCacheStorage { private final Logger log = LoggerFactory.getLogger(getClass()); private final CacheConfig cacheConfig; - // private final CacheConfig cacheConfig = new CacheConfig(); + private ClassLoader classLoader; /** @@ -51,7 +51,7 @@ public class JarCacheStorage implements HttpCacheStorage { */ private final HttpCacheStorage delegate; - ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper = new ObjectMapper(); /** * Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) to a @@ -59,7 +59,7 @@ public class JarCacheStorage implements HttpCacheStorage { * * @see #getJarCache(URL) */ - protected ConcurrentMap> jarCaches = new ConcurrentHashMap>(); + protected final ConcurrentMap> jarCaches = new ConcurrentHashMap>(); public ClassLoader getClassLoader() { if (classLoader != null) { @@ -72,30 +72,6 @@ public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } - /** - * @deprecated Use - * {@link JarCacheStorage#JarCacheStorage(ClassLoader, CacheConfig)} - * instead. - */ - @Deprecated - public JarCacheStorage() { - this(null, CacheConfig.DEFAULT); - } - - /** - * - * @param classLoader - * The ClassLoader to use to locate JAR files and resources, or - * null to use the Thread context class loader in each case. - * @deprecated Use - * {@link JarCacheStorage#JarCacheStorage(ClassLoader, CacheConfig)} - * instead. - */ - @Deprecated - public JarCacheStorage(ClassLoader classLoader) { - this(classLoader, CacheConfig.DEFAULT); - } - public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig) { this(classLoader, cacheConfig, new BasicHttpCacheStorage(cacheConfig)); } diff --git a/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java b/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java index 4dca5951..259ca515 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JarCacheTest.java @@ -12,8 +12,12 @@ import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.SystemDefaultHttpClient; -import org.apache.http.impl.client.cache.CachingHttpClient; +import org.apache.http.client.protocol.RequestAcceptEncoding; +import org.apache.http.client.protocol.ResponseContentEncoding; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultRedirectStrategy; +import org.apache.http.impl.client.cache.CacheConfig; +import org.apache.http.impl.client.cache.CachingHttpClientBuilder; import org.junit.After; import org.junit.Test; @@ -21,9 +25,10 @@ public class JarCacheTest { @Test public void cacheHit() throws Exception { - final JarCacheStorage storage = new JarCacheStorage(); - final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, - storage.getCacheConfig()); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + final JarCacheStorage storage = new JarCacheStorage(null, cacheConfig); + final HttpClient httpClient = createTestHttpClient(cacheConfig, storage); final HttpGet get = new HttpGet("http://nonexisting.example.com/context"); final HttpResponse resp = httpClient.execute(get); @@ -34,20 +39,22 @@ public void cacheHit() throws Exception { @Test(expected = IOException.class) public void cacheMiss() throws Exception { - final JarCacheStorage storage = new JarCacheStorage(); - final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, - storage.getCacheConfig()); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + final JarCacheStorage storage = new JarCacheStorage(null, cacheConfig); + final HttpClient httpClient = createTestHttpClient(cacheConfig, storage); final HttpGet get = new HttpGet("http://nonexisting.example.com/notfound"); // Should throw an IOException as the DNS name // nonexisting.example.com does not exist - final HttpResponse resp = httpClient.execute(get); + httpClient.execute(get); } @Test public void doubleLoad() throws Exception { - final JarCacheStorage storage = new JarCacheStorage(); - final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, - storage.getCacheConfig()); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + final JarCacheStorage storage = new JarCacheStorage(null, cacheConfig); + final HttpClient httpClient = createTestHttpClient(cacheConfig, storage); final HttpGet get = new HttpGet("http://nonexisting.example.com/context"); HttpResponse resp = httpClient.execute(get); resp = httpClient.execute(get); @@ -59,10 +66,10 @@ public void doubleLoad() throws Exception { public void customClassPath() throws Exception { final URL nestedJar = getClass().getResource("/nested.jar"); final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); - final JarCacheStorage storage = new JarCacheStorage(cl); - - final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, - storage.getCacheConfig()); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + final JarCacheStorage storage = new JarCacheStorage(cl, cacheConfig); + final HttpClient httpClient = createTestHttpClient(cacheConfig, storage); final HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); final HttpResponse resp = httpClient.execute(get); @@ -77,11 +84,12 @@ public void contextClassLoader() throws Exception { assertNotNull(nestedJar); final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); - final JarCacheStorage storage = new JarCacheStorage(); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + final JarCacheStorage storage = new JarCacheStorage(cl, cacheConfig); Thread.currentThread().setContextClassLoader(cl); - final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, - storage.getCacheConfig()); + final HttpClient httpClient = createTestHttpClient(cacheConfig, storage); final HttpGet get = new HttpGet("http://nonexisting.example.com/nested/hello"); final HttpResponse resp = httpClient.execute(get); @@ -99,13 +107,31 @@ public void setContextClassLoader() { public void systemClassLoader() throws Exception { final URL nestedJar = getClass().getResource("/nested.jar"); assertNotNull(nestedJar); - final JarCacheStorage storage = new JarCacheStorage(null); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + final JarCacheStorage storage = new JarCacheStorage(null, cacheConfig); - final HttpClient httpClient = new CachingHttpClient(new SystemDefaultHttpClient(), storage, - storage.getCacheConfig()); + final HttpClient httpClient = createTestHttpClient(cacheConfig, storage); final HttpGet get = new HttpGet("http://nonexisting.example.com/context"); final HttpResponse resp = httpClient.execute(get); assertEquals("application/ld+json", resp.getEntity().getContentType().getValue()); } + private static CloseableHttpClient createTestHttpClient(CacheConfig cacheConfig, + JarCacheStorage jarCacheConfig) { + final CloseableHttpClient result = CachingHttpClientBuilder.create() + // allow caching + .setCacheConfig(cacheConfig) + // Set the JarCacheStorage instance as the HttpCache + .setHttpCacheStorage(jarCacheConfig) + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + .addInterceptorFirst(new RequestAcceptEncoding()) + .addInterceptorFirst(new ResponseContentEncoding()) + .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) + // use system defaults for proxy etc. + .useSystemProperties().build(); + + return result; + } } From 99638b8b0e13a0e550d053146484385a588afa24 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 9 Jan 2017 11:11:44 +1100 Subject: [PATCH 231/440] Fix issue #189 : Propagate causes for JsonLdError Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/Context.java | 7 +---- .../github/jsonldjava/core/JsonLdError.java | 26 +++++++++---------- .../jsonldjava/core/JsonLdProcessor.java | 2 +- .../jsonldjava/core/JsonLdProcessorTest.java | 6 ++--- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 3456356d..c8919a73 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -349,7 +349,7 @@ private void createTermDefinition(Map context, String term, if (error.getType() != Error.INVALID_IRI_MAPPING) { throw error; } - throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type); + throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type, error); } // TODO: fix check for absoluteIri (blank nodes shouldn't count, at // least not here!) @@ -1128,11 +1128,6 @@ else if (this.get(JsonLdConsts.LANGUAGE) != null) { return rval; } - public Object getContextValue(String activeProperty, String string) throws JsonLdError { - throw new JsonLdError(Error.NOT_IMPLEMENTED, - "getContextValue is only used by old code so far and thus isn't implemented"); - } - public Map serialize() { final Map ctx = newMap(); if (this.get(JsonLdConsts.BASE) != null diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java index 9bdccf41..5002b1f5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java @@ -1,11 +1,9 @@ package com.github.jsonldjava.core; -import java.util.Map; - public class JsonLdError extends Exception { - Map details; - private Error type; + private static final long serialVersionUID = -8685402790466459014L; + private final Error type; public JsonLdError(Error type, Object detail) { // TODO: pretty toString (e.g. print whole json objects) @@ -18,6 +16,17 @@ public JsonLdError(Error type) { this.type = type; } + public JsonLdError(Error type, Object detail, Throwable cause) { + // TODO: pretty toString (e.g. print whole json objects) + super(detail == null ? "" : detail.toString(), cause); + this.type = type; + } + + public JsonLdError(Error type, Throwable cause) { + super(cause); + this.type = type; + } + public enum Error { LOADING_DOCUMENT_FAILED("loading document failed"), @@ -114,19 +123,10 @@ public String toString() { } } - public JsonLdError setType(Error error) { - this.type = error; - return this; - }; - public Error getType() { return type; } - public Map getDetails() { - return details; - } - @Override public String getMessage() { final String msg = super.getMessage(); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 12cb80a6..adc68dc8 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -115,7 +115,7 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL input = tmp.document; // TODO: figure out how to deal with remote context } catch (final Exception e) { - throw new JsonLdError(Error.LOADING_DOCUMENT_FAILED, e.getMessage()); + throw new JsonLdError(Error.LOADING_DOCUMENT_FAILED, e); } // if set the base in options should override the base iri in the // active context diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 9a152f6d..9979f0e7 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -243,7 +243,7 @@ public TestDocumentLoader(String base) { @Override public RemoteDocument loadDocument(String url) throws JsonLdError { if (url == null) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, "URL was null"); } if (url.contains(":")) { // check if the url is relative to the test base @@ -255,12 +255,12 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { try { return new RemoteDocument(url, JsonUtils.fromInputStream(inputStream)); } catch (final IOException e) { - throw new JsonLdError(JsonLdError.Error.LOADING_DOCUMENT_FAILED); + throw new JsonLdError(JsonLdError.Error.LOADING_DOCUMENT_FAILED, e); } } } // we can't load this remote document from the test suite - throw new JsonLdError(JsonLdError.Error.NOT_IMPLEMENTED); + throw new JsonLdError(JsonLdError.Error.NOT_IMPLEMENTED, "URL scheme was not recognised: " + url); } public void setRedirectTo(String string) { From 6818423a72261968bc1945ec4bed9113da7dbbb0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 9 Jan 2017 11:15:29 +1100 Subject: [PATCH 232/440] Fix another case for issue #189 Signed-off-by: Peter Ansell --- .../main/java/com/github/jsonldjava/core/DocumentLoader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 7fcacff1..e5134253 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -19,14 +19,14 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); if ("true".equalsIgnoreCase(disallowRemote)) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, "Remote context loading has been disallowed (url was " + url + ")"); } final RemoteDocument doc = new RemoteDocument(url, null); try { doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); } catch (final Exception e) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url, e); } return doc; } From f713c7e53e57c173da532ab66facc1e793bdc1d0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 9 Jan 2017 11:16:03 +1100 Subject: [PATCH 233/440] Bump version number to reflect API changes Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index b71c6e6b..c9a97386 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.9.1-SNAPSHOT + 0.10.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 2361cb97..8fc366b5 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.9.1-SNAPSHOT + 0.10.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From e387bb5caaa4bf94716759d62cbaffd527270fdc Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 9 Jan 2017 11:23:19 +1100 Subject: [PATCH 234/440] Add changelog Signed-off-by: Peter Ansell --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a948144d..6e004b14 100644 --- a/README.md +++ b/README.md @@ -400,6 +400,12 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-01-09 +* Propagate causes for JsonLdError instances where they were caused by other Exceptions +* Remove schema.org hack as it appears to work again now... +* Remove deprecated and unused APIs +* Bump version to 0.10.0-SNAPSHOT per the removed/changed APIs + ### 2016-12-23 * Release 0.9.0 * Fixes schema.org support that is broken with Apache HTTP Client but works with java.net.URL From 7339a64805a085225f3208d201a8dfbaefd55e79 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 8 Feb 2017 17:17:41 +0000 Subject: [PATCH 235/440] Test .equals() and .compareTo() on RDFDataset.Node subclasses --- .../jsonldjava/core/NodeCompareTest.java | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java diff --git a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java new file mode 100644 index 00000000..2f401689 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java @@ -0,0 +1,140 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import java.util.List; + +import org.junit.Test; + +import com.github.jsonldjava.core.RDFDataset.Literal; +import com.github.jsonldjava.core.RDFDataset.Node; +import com.github.jsonldjava.core.RDFDataset.Quad; + +public class NodeCompareTest { + + @Test + public void literalSameValue() throws Exception { + Literal l1 = new RDFDataset.Literal("Same", null, null); + Literal l2 = new RDFDataset.Literal("Same", null, null); + assertEquals(l1, l2); + assertEquals(0, l1.compareTo(l2)); + } + + @Test + public void literalDifferentValue() throws Exception { + Literal l1 = new RDFDataset.Literal("Same", null, null); + Literal l2 = new RDFDataset.Literal("Different", null, null); + assertNotEquals(l1, l2); + assertNotEquals(0, l1.compareTo(l2)); + } + + @Test + public void literalSameValuSameLang() throws Exception { + Literal l1 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); + Literal l2 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); + assertEquals(l1, l2); + assertEquals(0, l1.compareTo(l2)); + } + + @Test + public void literalDifferentValueSameLang() throws Exception { + Literal l1 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); + Literal l2 = new RDFDataset.Literal("Different", JsonLdConsts.RDF_LANGSTRING, "en"); + assertNotEquals(l1, l2); + assertNotEquals(0, l1.compareTo(l2)); + } + + @Test + public void literalSameValueDifferentLang() throws Exception { + Literal l1 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); + Literal l2 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "no"); + assertNotEquals(l1, l2); + assertNotEquals(0, l1.compareTo(l2)); + } + + @Test + public void literalSameValueSameType() throws Exception { + Literal l1 = new RDFDataset.Literal("1", JsonLdConsts.XSD_INTEGER, null); + Literal l2 = new RDFDataset.Literal("1", JsonLdConsts.XSD_INTEGER, null); + assertEquals(l1, l2); + assertEquals(0, l1.compareTo(l2)); + } + + @Test + public void literalSameValueDifferentType() throws Exception { + Literal l1 = new RDFDataset.Literal("1", JsonLdConsts.XSD_INTEGER, null); + Literal l2 = new RDFDataset.Literal("1", JsonLdConsts.XSD_STRING, null); + assertNotEquals(l1, l2); + assertNotEquals(0, l1.compareTo(l2)); + } + + + + @Test + public void literalsInDataset() throws Exception { + RDFDataset dataset = new RDFDataset(); + dataset.addQuad("http://example.com/p", "http://example.com/p", "Same", null, null, "http://example.com/g1"); + dataset.addQuad("http://example.com/p", "http://example.com/p", "Different", null, null, "http://example.com/g1"); + List quads = dataset.getQuads("http://example.com/g1"); + Quad q1 = quads.get(0); + Quad q2 = quads.get(1); + assertNotEquals(q1, q2); + assertNotEquals(0, q1.compareTo(q2)); + assertNotEquals(0, q1.getObject().compareTo(q2.getObject())); + } + + @Test + public void iriDifferentLiteral() throws Exception { + Node iri = new RDFDataset.IRI("http://example.com/"); + Node literal = new RDFDataset.Literal("http://example.com/", null, null); + assertNotEquals(iri, literal); + assertNotEquals(0, iri.compareTo(literal)); + } + + @Test + public void iriDifferentIri() throws Exception { + Node iri = new RDFDataset.IRI("http://example.com/"); + Node other = new RDFDataset.IRI("http://example.com/other"); + assertNotEquals(iri, other); + assertNotEquals(0, iri.compareTo(other)); + } + + @Test + public void iriSameIri() throws Exception { + Node iri = new RDFDataset.IRI("http://example.com/same"); + Node same = new RDFDataset.IRI("http://example.com/same"); + assertEquals(iri, same); + assertEquals(0, iri.compareTo(same)); + } + + @Test + public void iriDifferentBlankNode() throws Exception { + // We'll use a relative IRI to avoid :-issues + Node iri = new RDFDataset.IRI("b1"); + Node bnode = new RDFDataset.BlankNode("b1"); + assertNotEquals(iri, bnode); + assertNotEquals(0, iri.compareTo(bnode)); + } + + @Test + public void literalDifferentIri() throws Exception { + Node literal = new RDFDataset.Literal("http://example.com/", null, null); + Node iri = new RDFDataset.IRI("http://example.com/"); + assertNotEquals(literal, iri); + assertNotEquals(0, literal.compareTo(iri)); + } + + @Test + public void literalDifferentBlankNode() throws Exception { + // We'll use a relative IRI to avoid :-issues + Node literal = new RDFDataset.Literal("b1", null, null); + Node bnode = new RDFDataset.BlankNode("b1"); + assertNotEquals(literal, bnode); + assertNotEquals(0, literal.compareTo(bnode)); + } + + + + +} From eee29a1bca33d69892123067e35c69671dcda486 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 8 Feb 2017 17:31:10 +0000 Subject: [PATCH 236/440] Complete Node.compareTo() for Literal --- .../github/jsonldjava/core/RDFDataset.java | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index be0ef294..602e0f85 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -137,6 +137,10 @@ public String getLanguage() { @Override public int compareTo(Node o) { + if (o == null) { + // valid nodes are > null nodes + return 1; + } if (this.isIRI()) { if (!o.isIRI()) { // IRIs > everything @@ -150,7 +154,13 @@ public int compareTo(Node o) { // blank node > literal return 1; } + } else if (this.isLiteral()) { + if (o.isIRI() || o.isBlankNode()) { + return -1; // literals < blanknode < IRI + } } + // NOTE: Literal will also need to compare + // language and datatype return this.getValue().compareTo(o.getValue()); } @@ -265,31 +275,38 @@ public boolean isBlankNode() { return false; } - @Override - public int compareTo(Node o) { - if (o == null) { - // valid nodes are > null nodes + @SuppressWarnings("rawtypes") + private static int nullSafeCompare(Comparable a, Comparable b) { + if (a == null && b == null) { + return 0; + } + if (a == null) { return 1; } - if (o.isIRI()) { - // literals < iri + if (b == null) { return -1; } - if (o.isBlankNode()) { - // blank node < iri - return -1; + return a.compareTo(b); + } + + @Override + public int compareTo(Node o) { + // NOTE: this will also compare getValue()! + int nodeCompare = super.compareTo(o); + if (nodeCompare != 0) { + // null, different type or different value + return nodeCompare; } - if (this.getLanguage() == null && ((Literal) o).getLanguage() != null) { - return -1; - } else if (this.getLanguage() != null && ((Literal) o).getLanguage() == null) { - return 1; + + int langCompare = nullSafeCompare(this.getLanguage(), o.getLanguage()); + if (langCompare != 0) { + return langCompare; } - - if (this.getDatatype() != null) { - return this.getDatatype().compareTo(((Literal) o).getDatatype()); - } else if (((Literal) o).getDatatype() != null) { - return -1; + int dataTypeCompare = nullSafeCompare(this.getDatatype(), o.getDatatype()); + if (dataTypeCompare != 0) { + return dataTypeCompare; } + // NOTE: getValue() has already compared by super.compareTo() return 0; } } From 79bc0901cc4a87d8f51dcac0222e7aaf4640d3bd Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 8 Feb 2017 21:31:43 +0000 Subject: [PATCH 237/440] Improve test coverage of comparisons --- .../jsonldjava/core/NodeCompareTest.java | 49 ++++++++++---- .../jsonldjava/core/QuadCompareTest.java | 66 +++++++++++++++++++ 2 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java diff --git a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java index 2f401689..a050dae3 100644 --- a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java @@ -30,7 +30,7 @@ public void literalDifferentValue() throws Exception { } @Test - public void literalSameValuSameLang() throws Exception { + public void literalSameValueSameLang() throws Exception { Literal l1 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); Literal l2 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); assertEquals(l1, l2); @@ -52,6 +52,16 @@ public void literalSameValueDifferentLang() throws Exception { assertNotEquals(l1, l2); assertNotEquals(0, l1.compareTo(l2)); } + + @Test + public void literalSameValueLangNull() throws Exception { + Literal l1 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, "en"); + Literal l2 = new RDFDataset.Literal("Same", JsonLdConsts.RDF_LANGSTRING, null); + assertNotEquals(l1, l2); + assertNotEquals(0, l1.compareTo(l2)); + assertNotEquals(0, l2.compareTo(l1)); + } + @Test public void literalSameValueSameType() throws Exception { @@ -61,6 +71,15 @@ public void literalSameValueSameType() throws Exception { assertEquals(0, l1.compareTo(l2)); } + @Test + public void literalSameValueSameTypeNull() throws Exception { + Literal l1 = new RDFDataset.Literal("1", JsonLdConsts.XSD_STRING, null); + Literal l2 = new RDFDataset.Literal("1", null, null); + assertEquals(l1, l2); + assertEquals(0, l1.compareTo(l2)); + } + + @Test public void literalSameValueDifferentType() throws Exception { Literal l1 = new RDFDataset.Literal("1", JsonLdConsts.XSD_INTEGER, null); @@ -90,8 +109,21 @@ public void iriDifferentLiteral() throws Exception { Node literal = new RDFDataset.Literal("http://example.com/", null, null); assertNotEquals(iri, literal); assertNotEquals(0, iri.compareTo(literal)); + assertNotEquals(0, literal.compareTo(iri)); + } + + @Test + public void iriDifferentNull() throws Exception { + Node iri = new RDFDataset.IRI("http://example.com/"); + assertNotEquals(0, iri.compareTo(null)); } + @Test + public void literalDifferentNull() throws Exception { + Node literal = new RDFDataset.Literal("hello", null, null); + assertNotEquals(0, literal.compareTo(null)); + } + @Test public void iriDifferentIri() throws Exception { Node iri = new RDFDataset.IRI("http://example.com/"); @@ -114,27 +146,22 @@ public void iriDifferentBlankNode() throws Exception { Node iri = new RDFDataset.IRI("b1"); Node bnode = new RDFDataset.BlankNode("b1"); assertNotEquals(iri, bnode); + assertNotEquals(bnode, iri); assertNotEquals(0, iri.compareTo(bnode)); + assertNotEquals(0, bnode.compareTo(iri)); } - @Test - public void literalDifferentIri() throws Exception { - Node literal = new RDFDataset.Literal("http://example.com/", null, null); - Node iri = new RDFDataset.IRI("http://example.com/"); - assertNotEquals(literal, iri); - assertNotEquals(0, literal.compareTo(iri)); - } - @Test public void literalDifferentBlankNode() throws Exception { // We'll use a relative IRI to avoid :-issues Node literal = new RDFDataset.Literal("b1", null, null); Node bnode = new RDFDataset.BlankNode("b1"); assertNotEquals(literal, bnode); + assertNotEquals(bnode, literal); assertNotEquals(0, literal.compareTo(bnode)); - } - + assertNotEquals(0, bnode.compareTo(literal)); + } } diff --git a/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java new file mode 100644 index 00000000..c7d4f50a --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java @@ -0,0 +1,66 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.Test; + +import com.github.jsonldjava.core.RDFDataset.Quad; + +public class QuadCompareTest { + + Quad q = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/o1", "http://example.com/g1"); + + @Test + public void compareToNull() throws Exception { + assertNotEquals(0, q.compareTo(null)); + } + + @Test + public void compareToSame() throws Exception { + Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/o1", "http://example.com/g1"); + assertEquals(0, q.compareTo(q2)); + // Should still compare equal, even if extra attributes are added + q2.put("example", "value"); + assertEquals(0, q.compareTo(q2)); + } + + @Test + public void compareToDifferentGraph() throws Exception { + Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/o1", "http://example.com/other"); + assertNotEquals(0, q.compareTo(q2)); + } + + @Test + public void compareToDifferentSubject() throws Exception { + Quad q2 = new Quad("http://example.com/other", "http://example.com/p1", + "http://example.com/o1", "http://example.com/g1"); + assertNotEquals(0, q.compareTo(q2)); + } + + @Test + public void compareToDifferentPredicate() throws Exception { + Quad q2 = new Quad("http://example.com/s1", "http://example.com/other", + "http://example.com/o1", "http://example.com/g1"); + assertNotEquals(0, q.compareTo(q2)); + } + + @Test + public void compareToDifferentObject() throws Exception { + Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/other", "http://example.com/g1"); + assertNotEquals(0, q.compareTo(q2)); + } + + @Test + public void compareToDifferentObjectType() throws Exception { + Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/other", null, null, // literal + "http://example.com/g1"); + assertNotEquals(0, q.compareTo(q2)); + } + +} From 2bc10b566e94da1c5f1d8263a59a77fdb96e93d7 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 8 Feb 2017 22:04:36 +0000 Subject: [PATCH 238/440] Test sort order --- .../github/jsonldjava/core/RDFDataset.java | 4 +- .../jsonldjava/core/NodeCompareTest.java | 124 +++++++++++++----- 2 files changed, 94 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 602e0f85..e23e81ca 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -291,7 +291,7 @@ private static int nullSafeCompare(Comparable a, Comparable b) { @Override public int compareTo(Node o) { - // NOTE: this will also compare getValue()! + // NOTE: this will also compare getValue() early! int nodeCompare = super.compareTo(o); if (nodeCompare != 0) { // null, different type or different value @@ -306,7 +306,7 @@ public int compareTo(Node o) { if (dataTypeCompare != 0) { return dataTypeCompare; } - // NOTE: getValue() has already compared by super.compareTo() + // NOTE: getValue() already compared by super.compareTo() return 0; } } diff --git a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java index a050dae3..382fdf0e 100644 --- a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java @@ -1,62 +1,122 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Random; import org.junit.Test; +import com.github.jsonldjava.core.RDFDataset.IRI; +import com.github.jsonldjava.core.RDFDataset.BlankNode; import com.github.jsonldjava.core.RDFDataset.Literal; import com.github.jsonldjava.core.RDFDataset.Node; import com.github.jsonldjava.core.RDFDataset.Quad; +import junit.framework.Assert; + public class NodeCompareTest { + @Test + public void ordered() throws Exception { + List expected = Arrays.asList( + // While this order might not particularly make sense, it + // is at least documented + + new Literal("1", JsonLdConsts.XSD_INTEGER, null), + new Literal("10", JsonLdConsts.XSD_INTEGER, null), + new Literal("2", JsonLdConsts.XSD_INTEGER, null), // still ordered by string value + + new Literal("a", JsonLdConsts.RDF_LANGSTRING, "en"), + new Literal("a", JsonLdConsts.RDF_LANGSTRING, "fr"), + new Literal("a", null, null), // equivalent to xsd:string + new Literal("b", JsonLdConsts.XSD_STRING, null), + new Literal("false", JsonLdConsts.XSD_BOOLEAN, null), + new Literal("true", JsonLdConsts.XSD_BOOLEAN, null), + + new Literal("x", JsonLdConsts.XSD_STRING, null), + + new Literal("z", JsonLdConsts.RDF_LANGSTRING, "en"), + new Literal("z", JsonLdConsts.RDF_LANGSTRING, "fr"), + new Literal("z", null, null), + + new BlankNode("a"), + new BlankNode("f"), + new BlankNode("z"), + + new IRI("http://example.com/ex1"), + new IRI("http://example.com/ex2"), + new IRI("http://example.org/ex"), + new IRI("https://example.net/") + ); + + List shuffled = new ArrayList<>(expected); + Random rand = new Random(1337); // fixed seed + Collections.shuffle(shuffled, rand); + //System.out.println("Shuffled:"); + //shuffled.stream().forEach(System.out::println); + assertNotEquals(expected, shuffled); + + Collections.sort(shuffled); + List sorted = shuffled; + //System.out.println("Now sorted:"); + //sorted.stream().forEach(System.out::println); + // Not so useful output from this + // assertEquals(expected, sorted); + // so we'll instead do: + for (int i=0; i Date: Wed, 8 Feb 2017 23:04:10 +0000 Subject: [PATCH 239/440] RDF 1.1-style Literal comparison of language tags --- .../com/github/jsonldjava/core/RDFDataset.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index e23e81ca..221090cc 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -297,17 +297,15 @@ public int compareTo(Node o) { // null, different type or different value return nodeCompare; } - - int langCompare = nullSafeCompare(this.getLanguage(), o.getLanguage()); - if (langCompare != 0) { - return langCompare; - } - int dataTypeCompare = nullSafeCompare(this.getDatatype(), o.getDatatype()); - if (dataTypeCompare != 0) { - return dataTypeCompare; + if (this.getLanguage() != null || o.getLanguage() != null) { + // We'll ignore type-checking if either has language tag + // as language tagged literals should always have the type + // rdf:langString in RDF 1.1 + return nullSafeCompare(this.getLanguage(), o.getLanguage()); + } else { + return nullSafeCompare(this.getDatatype(), o.getDatatype()); } // NOTE: getValue() already compared by super.compareTo() - return 0; } } From 7a3714ea4ccc9253dc2cc5595ba3bda5ea562791 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Wed, 8 Feb 2017 23:05:23 +0000 Subject: [PATCH 240/440] Comment about ordering not being important. --- .../github/jsonldjava/core/NodeCompareTest.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java index 382fdf0e..8f2940c4 100644 --- a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java @@ -1,6 +1,7 @@ package com.github.jsonldjava.core; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import java.util.ArrayList; import java.util.Arrays; @@ -10,22 +11,23 @@ import org.junit.Test; -import com.github.jsonldjava.core.RDFDataset.IRI; import com.github.jsonldjava.core.RDFDataset.BlankNode; +import com.github.jsonldjava.core.RDFDataset.IRI; import com.github.jsonldjava.core.RDFDataset.Literal; import com.github.jsonldjava.core.RDFDataset.Node; import com.github.jsonldjava.core.RDFDataset.Quad; -import junit.framework.Assert; - public class NodeCompareTest { + /** + * While this order might not particularly make sense (RDF is unordered), + * this is at least documented. Feel free to move things around below if the + * underlying .compareTo() changes. + */ @Test public void ordered() throws Exception { List expected = Arrays.asList( - // While this order might not particularly make sense, it - // is at least documented - + new Literal("1", JsonLdConsts.XSD_INTEGER, null), new Literal("10", JsonLdConsts.XSD_INTEGER, null), new Literal("2", JsonLdConsts.XSD_INTEGER, null), // still ordered by string value From a5e6051d0e8d1d192195bcb1f5fac71f17939486 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 16 Feb 2017 14:33:33 +1100 Subject: [PATCH 241/440] Update plugin version Signed-off-by: Peter Ansell --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8fc366b5..2eb9d587 100755 --- a/pom.xml +++ b/pom.xml @@ -364,7 +364,7 @@ org.apache.felix maven-bundle-plugin - 3.0.1 + 3.2.0 From 73972032fb020f40d3cf202f8ee0905fb8987040 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 16 Feb 2017 14:44:24 +1100 Subject: [PATCH 242/440] Update dependencies Signed-off-by: Peter Ansell --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2eb9d587..4bfd073a 100755 --- a/pom.xml +++ b/pom.xml @@ -39,11 +39,11 @@ UTF-8 UTF-8 - 4.5.2 - 4.4.5 - 2.8.5 + 4.5.3 + 4.4.6 + 2.8.6 4.12 - 1.7.22 + 1.7.23 0.9.0 From edad675df5fe1dfbfee5a9509b849a47e8b42fdd Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 16 Feb 2017 14:48:27 +1100 Subject: [PATCH 243/440] Add changelog Signed-off-by: Peter Ansell --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e004b14..3ae5113b 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.9.0 + 0.10.0 Code example @@ -281,7 +281,7 @@ Here is the basic outline for what your module's pom.xml should look like jsonld-java-integration com.github.jsonld-java-parent - 0.9.1-SNAPSHOT + 0.10.1-SNAPSHOT 4.0.0 jsonld-java-{your module} @@ -400,6 +400,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-02-16 +* Make literals compare consistently (Patch by @stain) +* Release 0.10.0 + ### 2017-01-09 * Propagate causes for JsonLdError instances where they were caused by other Exceptions * Remove schema.org hack as it appears to work again now... From 9598eb1d44d065599caac848cf6c95d05c819a47 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 16 Feb 2017 15:40:55 +1100 Subject: [PATCH 244/440] Release 0.10.0 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index c9a97386..16300dc8 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.10.0-SNAPSHOT + 0.10.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 4bfd073a..dfbf8b15 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.10.0-SNAPSHOT + 0.10.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From b3e9e9c574d5b07d4fa674020d8ece00736671b0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 16 Feb 2017 15:51:54 +1100 Subject: [PATCH 245/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 16300dc8..f379fc46 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.10.0 + 0.10.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index dfbf8b15..16d5a386 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.10.0 + 0.10.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 1f36fa9be802677ae2ffa4d877783adc1744451d Mon Sep 17 00:00:00 2001 From: Ryan Kenney Date: Mon, 6 Mar 2017 11:12:50 -0800 Subject: [PATCH 246/440] Added the ability to inject a json-ld context file into the DocumentLoader, without the need for the context file to be available as a URL or within the classpath. --- .../jsonldjava/core/DocumentLoader.java | 26 +++++++++++++++++-- .../github/jsonldjava/core/JsonLdError.java | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index e5134253..656bf588 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -1,6 +1,8 @@ package com.github.jsonldjava.core; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import org.apache.http.impl.client.CloseableHttpClient; @@ -8,21 +10,41 @@ public class DocumentLoader { + private Map m_injectedDocs = new HashMap<>(); + /** * Identifies a system property that can be set to "true" in order to * disallow remote context loading. */ public static final String DISALLOW_REMOTE_CONTEXT_LOADING = "com.github.jsonldjava.disallowRemoteContextLoading"; + public DocumentLoader addInjectedDoc(String url, String doc) throws JsonLdError { + try { + m_injectedDocs.put(url, JsonUtils.fromString(doc)); + return this; + } catch (final Exception e) { + throw new JsonLdError(JsonLdError.Error.LOADING_INJECTED_CONTEXT_FAILED, url, e); + } + } + public RemoteDocument loadDocument(String url) throws JsonLdError { + final RemoteDocument doc = new RemoteDocument(url, null); + + if (m_injectedDocs.containsKey(url)) { + try { + doc.setDocument(m_injectedDocs.get(url)); + } catch (final Exception e) { + throw new JsonLdError(JsonLdError.Error.LOADING_INJECTED_CONTEXT_FAILED, url, e); + } + return doc; + } + final String disallowRemote = System .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); - if ("true".equalsIgnoreCase(disallowRemote)) { throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, "Remote context loading has been disallowed (url was " + url + ")"); } - final RemoteDocument doc = new RemoteDocument(url, null); try { doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); } catch (final Exception e) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java index 5002b1f5..b30a85ae 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java @@ -44,6 +44,8 @@ public enum Error { LOADING_REMOTE_CONTEXT_FAILED("loading remote context failed"), + LOADING_INJECTED_CONTEXT_FAILED("loading injected context failed"), + INVALID_REMOTE_CONTEXT("invalid remote context"), RECURSIVE_CONTEXT_INCLUSION("recursive context inclusion"), From eb34e32525b79f1bbd944e3ec695b24aca0b53e2 Mon Sep 17 00:00:00 2001 From: Ryan Kenney Date: Mon, 6 Mar 2017 11:37:20 -0800 Subject: [PATCH 247/440] Updated README --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ae5113b..01e4140a 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ The default HTTP Client is wrapped with a small memory-based cache (1000 objects, max 128 kB each) of regularly accessed contexts. -### Loading contexts from classpath/JAR +### Loading contexts from classpath Your application might be parsing JSONLD documents which always use the same external `@context` IRIs. Although the default HTTP cache (see above) will @@ -137,6 +137,30 @@ You can also use the constant provided in DocumentLoader for the same purpose: Note that if you override DocumentLoader you should also support this setting for consistency. + +### Loading contexts from a string + +Your application might be parsing JSONLD documents which reference external `@context` IRIs +that are not available as file URIs on the classpath. In this case, the `jarcache.json` +approch will not work. Instead you can inject the literal context file strings through +the `JsonLdOptions` object, as follows: + +```java +// Inject a context document into the options as a literal string +DocumentLoader dl = new DocumentLoader(); +JsonLdOptions options = new JsonLdOptions(); +// ... the contents of "contexts/example.jsonld" +String jsonContext = "{ \"@contxt\": { ... } }"; +dl.addInjectedDoc("http://www.example.com/context", jsonContext); +options.setDocumentLoader(dl); + +InputStream inputStream = new FileInputStream("input.json"); +Object jsonObject = JsonUtils.fromInputStream(inputStream); +Map context = new HashMap(); +Object compact = JsonLdProcessor.compact(jsonObject, context, options); +System.out.println(JsonUtils.toPrettyString(compact)); +``` + ### Customizing the Apache HttpClient To customize the HTTP behaviour (e.g. to disable the cache or provide From d3a1737fb5ad5a10be4d8a0f3fa8950993e558ab Mon Sep 17 00:00:00 2001 From: Ryan Kenney Date: Mon, 6 Mar 2017 14:20:32 -0800 Subject: [PATCH 248/440] Added unit test --- .../jsonldjava/core/DocumentLoaderTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index d43461e3..9c377dad 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -364,4 +364,33 @@ public void testDisallowRemoteContexts() throws Exception { } } } + + @Test + public void injectContext() throws Exception { + + final Object jsonObject = JsonUtils.fromString("{ \"@context\":\"http://nonexisting.example.com/thing\", \"pony\":5 }"); + final JsonLdOptions options = new JsonLdOptions(); + + // Verify fails to find context by default + try { + JsonLdProcessor.expand(jsonObject, options); + fail("Expected exception to occur"); + } catch (JsonLdError e) { + // Success + } + + // Inject context + final DocumentLoader dl = new DocumentLoader(); + dl.addInjectedDoc("http://nonexisting.example.com/thing", + "{ \"@context\": { \"pony\":\"http://nonexisting.example.com/thing/pony\" } }"); + options.setDocumentLoader(dl); + + // Execute + final List expand = JsonLdProcessor.expand(jsonObject, options); + + // Verify result + Object v = ((Map) ((Map) ((List) ((Map) + expand.get(0)).get("http://nonexisting.example.com/thing/pony")).get(0))).get("@value"); + assertEquals(5, v); + } } From fd198708a472590077badf912307c37763e3c126 Mon Sep 17 00:00:00 2001 From: Dietrich Schulten Date: Sun, 12 Mar 2017 09:08:27 +0100 Subject: [PATCH 249/440] exposes JsonParser as input to create an object suitable for jsonld processing --- .../com/github/jsonldjava/utils/JsonUtils.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 087ef769..a2c35165 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -119,6 +119,23 @@ public static Object fromInputStream(InputStream input, String enc) throws IOExc */ public static Object fromReader(Reader reader) throws IOException { final JsonParser jp = JSON_FACTORY.createParser(reader); + return fromJsonParser(jp); + } + + /** + * Parses a JSON-LD document from the given {@link JsonParser} to an object that + * can be used as input for the {@link JsonLdApi} and + * {@link JsonLdProcessor} methods. + * + * @param jp + * The JSON-LD document in a {@link JsonParser}. + * @return A JSON Object. + * @throws JsonParseException + * If there was a JSON related error during parsing. + * @throws IOException + * If there was an IO error during parsing. + */ + public static Object fromJsonParser(JsonParser jp) throws IOException { Object rval; final JsonToken initialToken = jp.nextToken(); From 9191907cb867771e4f7f79524d3aa1816eeffb19 Mon Sep 17 00:00:00 2001 From: Nicolas F Rouquette Date: Sun, 12 Mar 2017 18:25:17 -0700 Subject: [PATCH 250/440] Fixed application/n-quads mediatype --- .../main/java/com/github/jsonldjava/core/JsonLdConsts.java | 2 +- .../main/java/com/github/jsonldjava/core/NormalizeUtils.java | 2 +- .../java/com/github/jsonldjava/core/JsonLdProcessorTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java index d4400326..2dd4a4e5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java @@ -29,7 +29,7 @@ public final class JsonLdConsts { public static final String RDF_LIST = RDF_SYNTAX_NS + "List"; public static final String TEXT_TURTLE = "text/turtle"; - public static final String APPLICATION_NQUADS = "application/nquads"; + public static final String APPLICATION_NQUADS = "application/n-quads"; // https://www.w3.org/TR/n-quads/#sec-mediatype public static final String FLATTENED = "flattened"; public static final String COMPACTED = "compacted"; diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index 2745d53f..1c6df6d4 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -118,7 +118,7 @@ public Object hashBlankNodes(Collection unnamed_) throws JsonLdError { // handle output format if (options.format != null) { - if ("application/nquads".equals(options.format)) { + if (JsonLdConsts.APPLICATION_NQUADS.equals(options.format)) { final StringBuilder rval = new StringBuilder(); for (final String n : normalized) { rval.append(n); diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 9979f0e7..98d37da6 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -466,11 +466,11 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { } else if (testType.contains("jld:FromRDFTest")) { result = JsonLdProcessor.fromRDF(input, options); } else if (testType.contains("jld:ToRDFTest")) { - options.format = "application/nquads"; + options.format = JsonLdConsts.APPLICATION_NQUADS; result = JsonLdProcessor.toRDF(input, options); result = ((String) result).trim(); } else if (testType.contains("jld:NormalizeTest")) { - options.format = "application/nquads"; + options.format = JsonLdConsts.APPLICATION_NQUADS; result = JsonLdProcessor.normalize(input, options); result = ((String) result).trim(); } else { From dfea2dae5be6ab6b03e39b90cd7b3b802814ca44 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 5 Jun 2017 15:10:59 +1000 Subject: [PATCH 251/440] Some updates to get closer to Java-9 support Signed-off-by: Peter Ansell --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 16d5a386..c1e7fdd2 100755 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 4.5.3 4.4.6 - 2.8.6 + 2.8.8 4.12 1.7.23 @@ -197,7 +197,7 @@ org.mockito mockito-core - 1.10.19 + 2.8.9 commons-io @@ -213,7 +213,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.6.0 + 3.6.1 default-compile @@ -303,7 +303,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.19.1 + 2.20 org.codehaus.mojo @@ -328,7 +328,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.9.3 + 0.10.0 @@ -364,7 +364,7 @@ org.apache.felix maven-bundle-plugin - 3.2.0 + 3.3.0 @@ -375,7 +375,7 @@ org.jacoco jacoco-maven-plugin - 0.7.8 + 0.7.9 prepare-agent From eb0ed9c095af2e0ac835cb679b0843b1a69ccdd6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 14 Jun 2017 16:34:03 +1000 Subject: [PATCH 252/440] Work on compatibility with Java-9 Still waiting on japicmp-maven-plugin updates Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 84 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index f379fc46..17b9240a 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.10.1-SNAPSHOT + 0.11.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index c1e7fdd2..6deb5a51 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.10.1-SNAPSHOT + 0.11.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom @@ -41,20 +41,13 @@ 4.5.3 4.4.6 - 2.8.8 + 2.8.9 4.12 1.7.23 - 0.9.0 - - 1.7 - 1.7 - 1.8 - 1.8 + 0.10.0 - - 3.0.5 - + @@ -208,36 +201,70 @@ + + + org.apache.maven.plugins + maven-enforcer-plugin + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + org.apache.maven.plugins - maven-compiler-plugin - 3.6.1 + maven-enforcer-plugin + 1.4.1 - default-compile + enforce-maven-3 + + enforce + - true - true - - ${maven.compiler.target} - ${maven.compiler.source} - + + + [3.0.5,) + + + [1.8,) + + - default-testCompile + enforce-bytecode-version + + enforce + - true - true - - ${maven.compiler.testTarget} - ${maven.compiler.testSource} - + + + 1.8 + + + true + + + org.codehaus.mojo + extra-enforcer-rules + 1.0-beta-6 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + org.apache.maven.plugins @@ -311,6 +338,7 @@ 1.15 + check-jdk-compliance test check @@ -320,7 +348,7 @@ org.codehaus.mojo.signature - java17 + java18 1.0 From a7ff33190c4c9c4ea8a5257ae82ed71aecf56286 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 11 Jul 2017 09:19:09 +1000 Subject: [PATCH 253/440] Standardise readme on one code formatting convention Signed-off-by: Peter Ansell --- README.md | 236 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 132 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index 01e4140a..83c64f9e 100644 --- a/README.md +++ b/README.md @@ -107,8 +107,10 @@ automatically injected together with the current `Date`, meaning that the resource loaded from the JAR will effectively never expire (the real HTTP server will never be consulted by the Apache HTTP client): - Date: Wed, 19 Mar 2014 13:25:08 GMT - Cache-Control: max-age=2147483647 +``` +Date: Wed, 19 Mar 2014 13:25:08 GMT +Cache-Control: max-age=2147483647 +``` The mechanism for loading `jarcache.json` relies on [Thread.currentThread().getContextClassLoader()](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getContextClassLoader%28%29) @@ -116,27 +118,32 @@ to locate resources from the classpath - if you are running on a command line, within a framework (e.g. OSGi) or Servlet container (e.g. Tomcat) this should normally be set correctly. If not, try: - ClassLoader oldContextCL = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - JsonLdProcessor.expand(input); // or any other JsonLd operation - } finally { - // Restore, in case the current thread was doing something else - // with the context classloader before calling our method - Thread.currentThread().setContextClassLoader(oldContextCL); - } +```java +ClassLoader oldContextCL = Thread.currentThread().getContextClassLoader(); +try { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + JsonLdProcessor.expand(input); // or any other JsonLd operation +} finally { + // Restore, in case the current thread was doing something else + // with the context classloader before calling our method + Thread.currentThread().setContextClassLoader(oldContextCL); +} +``` To disable all remote document fetching, when using the default DocumentLoader, set the following Java System Property to "true" using: - System.setProperty("com.github.jsonldjava.disallowRemoteContextLoading", "true"); +```java +System.setProperty("com.github.jsonldjava.disallowRemoteContextLoading", "true"); +``` You can also use the constant provided in DocumentLoader for the same purpose: - System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true"); - -Note that if you override DocumentLoader you should also support this setting for consistency. +```java +System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true"); +``` +Note that if you override DocumentLoader you should also support this setting for consistency and security. ### Loading contexts from a string @@ -173,40 +180,40 @@ and passed as an argument to `JsonLdProcessor` arguments. Example of inserting a credential provider (e.g. to load a `@context` protected by HTTP Basic Auth): - - Object input = JsonUtils.fromInputStream(..); - DocumentLoader documentLoader = new DocumentLoader(); - - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials( - new AuthScope("localhost", 443), - new UsernamePasswordCredentials("username", "password")); + +```java +Object input = JsonUtils.fromInputStream(..); +DocumentLoader documentLoader = new DocumentLoader(); - CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) - .setMaxObjectSize(1024 * 128).build(); - - CloseableHttpClient httpClient = CachingHttpClientBuilder - .create() - // allow caching - .setCacheConfig(cacheConfig) - // Wrap the local JarCacheStorage around a BasicHttpCacheStorage - .setHttpCacheStorage( - new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( - cacheConfig))).... +CredentialsProvider credsProvider = new BasicCredentialsProvider(); +credsProvider.setCredentials( + new AuthScope("localhost", 443), + new UsernamePasswordCredentials("username", "password")); + +CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + +CloseableHttpClient httpClient = CachingHttpClientBuilder + .create() + // allow caching + .setCacheConfig(cacheConfig) + // Wrap the local JarCacheStorage around a BasicHttpCacheStorage + .setHttpCacheStorage( + new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage( + cacheConfig))).... - // Add in the credentials provider - .setDefaultCredentialsProvider(credsProvider); - + // Add in the credentials provider + .setDefaultCredentialsProvider(credsProvider); + // When you are finished setting the properties, call build + .build(); - // When you are finished setting the properties, call build - .build(); - - documentLoader.setHttpClient(httpClient); +documentLoader.setHttpClient(httpClient); - JsonLdOptions options = new JsonLdOptions(); - options.setDocumentLoader(documentLoader); - // .. and any other options - Object rdf = JsonLdProcessor.toRDF(input, options); +JsonLdOptions options = new JsonLdOptions(); +options.setDocumentLoader(documentLoader); +// .. and any other options +Object rdf = JsonLdProcessor.toRDF(input, options); +``` PLAYGROUND ---------- @@ -215,14 +222,18 @@ The [jsonld-java-tools](https://github.com/jsonld-java/jsonld-java-tools) reposi ### Initial clone and setup - git clone git@github.com:jsonld-java/jsonld-java-tools.git - chmod +x ./jsonldplayground +```bash +git clone git@github.com:jsonld-java/jsonld-java-tools.git +chmod +x ./jsonldplayground +``` ### Usage run the following to get usage details: - ./jsonldplayground --help +```bash +./jsonldplayground --help +``` For Developers -------------- @@ -235,11 +246,15 @@ The tests require Java-8 to compile, while the rest of the codebase is still com ### Running tests - mvn test +```bash +mvn test +``` or - mvn test -pl core +```bash +mvn test -pl core +``` to run only core package tests @@ -268,7 +283,9 @@ https://github.com/jsonld-java/jsonld-java/tree/master/core/reports Implementation Reports conforming to the [JSON-LD Implementation Report](http://json-ld.org/test-suite/reports/#instructions-for-submitting-implementation-reports) document can be regenerated using the following command: - mvn test -pl core -Dtest=JsonLdProcessorTest -Dreport.format= +```bash +mvn test -pl core -Dtest=JsonLdProcessorTest -Dreport.format= +``` Current possible values for `` include JSON-LD (`application/ld+json` or `jsonld`), NQuads (`text/plain`, `nquads`, `ntriples`, `nq` or `nt`) and Turtle (`text/turtle`, `turtle` or `ttl`). `*` can be used to generate reports in all available formats. @@ -280,7 +297,7 @@ This is the base package for JSONLD-Java. Integration with other Java packages a Existing integrations --------------------- -* [OpenRDF Sesame](https://bitbucket.org/openrdf/sesame) +* [Eclipse RDF4J](https://github.com/eclipse/rdf4j) * [Apache Jena](https://github.com/apache/jena/) * [RDF2GO](https://github.com/jsonld-java/jsonld-java-rdf2go) * [Apache Clerezza](https://github.com/jsonld-java/jsonld-java-clerezza) @@ -299,54 +316,56 @@ Create maven module Here is the basic outline for what your module's pom.xml should look like - - - - jsonld-java-integration - com.github.jsonld-java-parent - 0.10.1-SNAPSHOT - - 4.0.0 - jsonld-java-{your module} - JSONLD Java :: {your module name} - JSON-LD Java integration module for {RDF Library your module integrates} - jar - - - - {YOU} - {YOUR EMAIL ADDRESS} - - - - - - ${project.groupId} - jsonld-java - ${project.version} - jar - compile - - - ${project.groupId} - jsonld-java - ${project.version} - test-jar - test - - - junit - junit - test - - - org.slf4j - slf4j-jdk14 - test - - - +```xml + + + + jsonld-java-integration + com.github.jsonld-java-parent + 0.11.0-SNAPSHOT + + 4.0.0 + jsonld-java-{your module} + JSONLD Java :: {your module name} + JSON-LD Java integration module for {RDF Library your module integrates} + jar + + + + {YOU} + {YOUR EMAIL ADDRESS} + + + + + + ${project.groupId} + jsonld-java + ${project.version} + jar + compile + + + ${project.groupId} + jsonld-java + ${project.version} + test-jar + test + + + junit + junit + test + + + org.slf4j + slf4j-jdk14 + test + + + +``` Make sure you edit the following: * `project/artifactId` : set this to `jsonld-java-{module id}`, where `{module id}` usually represents the RDF library you're integrating (e.g. `jsonld-java-jena`) @@ -381,12 +400,16 @@ There are two ways to use your `RDFParser` implementation. Register your parser with the `JSONLD` class and set `options.format` when you call `fromRDF` - JSONLD.registerRDFParser("format/identifier", new YourRDFParser()); - Object jsonld = JSONLD.fromRDF(yourInput, new Options("") {{ format = "format/identifier" }}); +```java +JSONLD.registerRDFParser("format/identifier", new YourRDFParser()); +Object jsonld = JSONLD.fromRDF(yourInput, new Options("") {{ format = "format/identifier" }}); +``` or pass an instance of your `RDFParser` into the `fromRDF` function - Object jsonld = JSONLD.fromRDF(yourInput, new YourRDFParser()); +```java +Object jsonld = JSONLD.fromRDF(yourInput, new YourRDFParser()); +``` ### JSONLDTripleCallback @@ -395,7 +418,9 @@ RDF model from JSON-LD - being called for each triple (technically quad). Pass an instance of your `TripleCallback` to `JSONLD.toRDF` - Object yourOutput = JSONLD.toRDF(jsonld, new YourTripleCallback()); +```java +Object yourOutput = JSONLD.toRDF(jsonld, new YourTripleCallback()); +``` Integrate with your framework ----------------------------- @@ -424,6 +449,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-07-11 +* Add injection of contexts directly into DocumentLoader (Patch by @ryankenney) + ### 2017-02-16 * Make literals compare consistently (Patch by @stain) * Release 0.10.0 From 609553d9356c90a3999cc0ca5f69b9bf3bb36141 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 11 Jul 2017 10:13:34 +1000 Subject: [PATCH 254/440] Add test for JsonUtils.fromJsonParser Just verifies that the method exists so it won't be removed accidentally, as it is already tested by the testsuite. Signed-off-by: Peter Ansell --- .../github/jsonldjava/utils/JsonUtilsTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 46cfc09b..f0ceee08 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -2,12 +2,18 @@ import static org.junit.Assert.assertTrue; +import java.io.File; import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; import java.util.Map; import org.junit.Test; +import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.ObjectMapper; public class JsonUtilsTest { @@ -35,6 +41,15 @@ public void fromStringTest() { } } + @Test + public void testFromJsonParser() throws Exception { + ObjectMapper jsonMapper = new ObjectMapper(); + JsonFactory jsonFactory = new JsonFactory(jsonMapper); + Reader testInputString = new StringReader("{}"); + JsonParser jp = jsonFactory.createParser(testInputString); + JsonUtils.fromJsonParser(jp ); + } + @Test public void trailingContent_1() throws JsonParseException, IOException { trailingContent("{}"); From c79608d51b7b584f7bbd03ca237db769e7b57d83 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 11 Jul 2017 10:23:45 +1000 Subject: [PATCH 255/440] Add changelog entries Signed-off-by: Peter Ansell --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 83c64f9e..d3e0ea5b 100644 --- a/README.md +++ b/README.md @@ -451,6 +451,8 @@ CHANGELOG ### 2017-07-11 * Add injection of contexts directly into DocumentLoader (Patch by @ryankenney) +* Fix N-Quads content type (Patch by @NicolasRouquette) +* Add JsonUtils.fromJsonParser (Patch by @dschulten) ### 2017-02-16 * Make literals compare consistently (Patch by @stain) From e79b27d355127d08403b5f9c9239fa0dad00e667 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Tue, 18 Jul 2017 14:13:29 +0200 Subject: [PATCH 256/440] Support `pruneBlankNodeIdentifiers` framing option in 1.1 mode See: https://json-ld.org/spec/latest/json-ld-framing/#jsonldoptions https://github.com/json-ld/json-ld.org/issues/293 --- .../com/github/jsonldjava/core/JsonLdApi.java | 4 +++ .../github/jsonldjava/core/JsonLdOptions.java | 18 ++++++++++- .../jsonldjava/core/JsonLdProcessor.java | 31 ++++++++++++++++++- .../github/jsonldjava/core/JsonLdUtils.java | 21 ++++++++----- .../jsonldjava/core/JsonLdFramingTest.java | 19 ++++++++++++ .../resources/custom/frame-0003-out.jsonld | 11 +++++++ 6 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 core/src/test/resources/custom/frame-0003-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 0ca83c95..d4c8e55f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -11,12 +11,16 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index ab2c339c..5f1964a4 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -10,6 +10,10 @@ */ public class JsonLdOptions { + private static final String JSON_LD_1_0 = "json-ld-1.0"; + + private static final String JSON_LD_1_1 = "json-ld-1.1"; + public static final boolean DEFAULT_COMPACT_ARRAYS = true; /** @@ -47,7 +51,7 @@ public JsonLdOptions(String base) { /** * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-processingMode */ - private String processingMode = "json-ld-1.0"; + private String processingMode = JSON_LD_1_0; /** * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-documentLoader */ @@ -58,6 +62,7 @@ public JsonLdOptions(String base) { private Boolean embed = null; private Boolean explicit = null; private Boolean omitDefault = null; + private Boolean pruneBlankNodeIdentifiers = true; // RDF conversion options : // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm @@ -90,6 +95,17 @@ public void setOmitDefault(Boolean omitDefault) { this.omitDefault = omitDefault; } + public Boolean getPruneBlankNodeIdentifiers() { + return pruneBlankNodeIdentifiers && getProcessingMode().equals(JSON_LD_1_1); + } + + public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { + if(pruneBlankNodeIdentifiers) { + setProcessingMode(JSON_LD_1_1); + } + this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; + } + public Boolean getCompactArrays() { return compactArrays; } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index adc68dc8..19330077 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -4,9 +4,15 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.stream.Stream; import com.github.jsonldjava.core.JsonLdError.Error; import com.github.jsonldjava.impl.NQuadRDFParser; @@ -319,10 +325,33 @@ public static Map frame(Object input, Object frame, JsonLdOption final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); final Map rval = activeCtx.serialize(); rval.put(alias, compacted); - JsonLdUtils.removePreserve(activeCtx, rval, opts); + + Set toPrune = opts.getPruneBlankNodeIdentifiers() ? + blankNodeIdsToPrune(rval, new HashSet<>()) : Collections.emptySet(); + JsonLdUtils.removePreserveAndPrune(activeCtx, rval, opts, toPrune); return rval; } + private static Set blankNodeIdsToPrune(Object input, Set set) { + if (input instanceof List) { + ((List) input).forEach(e -> blankNodeIdsToPrune(e, set)); + } else if (input instanceof Map) { + ((Map) input).entrySet().forEach(e -> blankNodeIdsToPrune(e.getValue(), set)); + } else if (input instanceof String) { + String p = (String) input; + if (p.startsWith("_:")) { + if(set.contains(p)){ + // more than 1, don't prune + set.remove(p); + } else { + // exactly 1, prune + set.add(p); + } + } + } + return set; + } + /** * A registry for RDF Parsers (in this case, JSONLDSerializers) used by * fromRDF if no specific serializer is specified and options.format is set. diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 150b551f..73190644 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -6,8 +6,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import com.github.jsonldjava.utils.JsonLdUrl; import com.github.jsonldjava.utils.Obj; @@ -187,24 +189,25 @@ public static boolean isRelativeIri(String value) { } /** - * Removes the @preserve keywords as the last step of the framing algorithm. + * Removes the @preserve keywords and blank node IDs to prune as the last step of the framing algorithm. * * @param ctx * the active context used to compact the input. * @param input * the framed, compacted output. + * @param toPrune The blank node IDs to prune. * @param options * the compaction options used. * * @return the resulting output. * @throws JsonLdError */ - static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) throws JsonLdError { + static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions opts, Set toPrune) throws JsonLdError { // recurse through arrays if (isArray(input)) { final List output = new ArrayList(); for (final Object i : (List) input) { - final Object result = removePreserve(ctx, i, opts); + final Object result = removePreserveAndPrune(ctx, i, opts, toPrune); // drop nulls from arrays if (result != null) { output.add(result); @@ -228,19 +231,23 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro // recurse through @lists if (isList(input)) { ((Map) input).put("@list", - removePreserve(ctx, ((Map) input).get("@list"), opts)); + removePreserveAndPrune(ctx, ((Map) input).get("@list"), opts, toPrune)); return input; } // recurse through properties - for (final String prop : ((Map) input).keySet()) { - Object result = removePreserve(ctx, ((Map) input).get(prop), opts); + for (final String prop : new LinkedHashSet<>(((Map) input).keySet())) { + Object result = removePreserveAndPrune(ctx, ((Map) input).get(prop), opts, toPrune); final String container = ctx.getContainer(prop); if (opts.getCompactArrays() && isArray(result) && ((List) result).size() == 1 && container == null) { result = ((List) result).get(0); } - ((Map) input).put(prop, result); + if(ctx.expandIri(prop, false, false, null, null).equals(JsonLdConsts.ID) && toPrune.contains(result)) { + ((Map) input).remove(prop); + } else { + ((Map) input).put(prop, result); + } } } return input; diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 71691489..7fab2a66 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -1,6 +1,7 @@ package com.github.jsonldjava.core; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.io.IOException; import java.util.Map; @@ -41,4 +42,22 @@ public void testFrame0002() throws IOException, JsonLdError { assertEquals(out, frame2); } + @Test + public void testFrame0003() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setCompactArrays(false); + opts.setProcessingMode("json-ld-1.1"); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + assertFalse("Result should contain no blank nodes", frame2.toString().contains("_:")); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0003-out.jsonld")); + assertEquals(out, frame2); + } + } diff --git a/core/src/test/resources/custom/frame-0003-out.jsonld b/core/src/test/resources/custom/frame-0003-out.jsonld new file mode 100644 index 00000000..b87d5710 --- /dev/null +++ b/core/src/test/resources/custom/frame-0003-out.jsonld @@ -0,0 +1,11 @@ +{ + "@context" : { + "@vocab" : "http://xmlns.com/foaf/0.1/" + }, + "@graph" : [ { + "@type" : "Person", + "member" : [{ + "@type" : "Group" + }] + } ] +} From 034e33b5979e3c70b135fbaa3684b9d2886f4323 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 31 Jul 2017 11:56:39 +1000 Subject: [PATCH 257/440] Experiment with Java-9 testing Signed-off-by: Peter Ansell --- .travis.yml | 6 ++---- pom.xml | 14 +++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index f39b7428..f6961b66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,8 @@ language: java -sudo: false -cache: - directories: - - $HOME/.m2 +dist: trusty jdk: - oraclejdk8 + - oraclejdk9 notifications: email: - ansell.peter@gmail.com diff --git a/pom.xml b/pom.xml index 6deb5a51..741c880f 100755 --- a/pom.xml +++ b/pom.xml @@ -41,9 +41,9 @@ 4.5.3 4.4.6 - 2.8.9 + 2.9.0 4.12 - 1.7.23 + 1.7.25 0.10.0 @@ -190,7 +190,7 @@ org.mockito mockito-core - 2.8.9 + 2.8.47 commons-io @@ -216,7 +216,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 1.4.1 + 3.0.0-M1 enforce-maven-3 @@ -269,7 +269,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.0.0-M1 org.apache.maven.plugins @@ -353,7 +353,7 @@ - + org.codehaus.mojo appassembler-maven-plugin From 33a922331a6d206a3c67186092b0520f60534757 Mon Sep 17 00:00:00 2001 From: Christopher Johnson Date: Fri, 28 Jul 2017 18:01:07 +0200 Subject: [PATCH 258/440] adds implicit "flag only" subframe to fix incomplete list recursion --- .../com/github/jsonldjava/core/JsonLdApi.java | 34 +-- .../jsonldjava/core/JsonLdFramingTest.java | 18 ++ .../resources/custom/frame-0004-frame.jsonld | 144 ++++++++++++ .../resources/custom/frame-0004-in.jsonld | 217 ++++++++++++++++++ .../resources/custom/frame-0004-out.jsonld | 216 +++++++++++++++++ 5 files changed, 614 insertions(+), 15 deletions(-) create mode 100644 core/src/test/resources/custom/frame-0004-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0004-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0004-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 0ca83c95..9cfce263 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1320,8 +1320,6 @@ public List frame(Object input, List frame) throws JsonLdError { * * @param state * the current framing state. - * @param subjects - * the subjects to filter. * @param frame * the frame. * @param parent @@ -1339,7 +1337,10 @@ private void frame(FramingContext state, Map nodes, Map flags = newMap(); + flags.put(JsonLdConsts.EXPLICIT, explicitOn); + flags.put(JsonLdConsts.EMBED, embedOn); // add matches to output final List ids = new ArrayList(matches.keySet()); @@ -1411,11 +1412,7 @@ private void frame(FramingContext state, Map nodes, Map nodes, Map) ((List) frame.get(prop)) - .get(0), - list, JsonLdConsts.LIST); + Map subframe; + if (frame.containsKey(prop)) { + subframe = (Map) ((List) frame.get(prop)).get(0); + } else { + subframe = flags; + } + frame(state, tmp, subframe, list, JsonLdConsts.LIST); } else { // include other values automatcially (TODO: // may need JsonLdUtils.clone(n)) @@ -1463,9 +1463,13 @@ else if (JsonLdUtils.isNodeReference(item)) { // TODO: nodes may need to be node_map, which is // global tmp.put(itemid, this.nodeMap.get(itemid)); - frame(state, tmp, - (Map) ((List) frame.get(prop)).get(0), - output, prop); + Map subframe; + if (frame.containsKey(prop)) { + subframe = (Map) ((List) frame.get(prop)).get(0); + } else { + subframe = flags; + } + frame(state, tmp, subframe, output, prop); } else { // include other values automatically (TODO: may // need JsonLdUtils.clone(o)) diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 71691489..6aaa3054 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -41,4 +41,22 @@ public void testFrame0002() throws IOException, JsonLdError { assertEquals(out, frame2); } + @Test + public void testFrame0004() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0004-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0004-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setCompactArrays(true); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0004-out.jsonld")); + //System.out.println(JsonUtils.toPrettyString(out)); + //System.out.println(JsonUtils.toPrettyString(frame2)); + assertEquals(out, frame2); + } + } diff --git a/core/src/test/resources/custom/frame-0004-frame.jsonld b/core/src/test/resources/custom/frame-0004-frame.jsonld new file mode 100644 index 00000000..f4575230 --- /dev/null +++ b/core/src/test/resources/custom/frame-0004-frame.jsonld @@ -0,0 +1,144 @@ +{ "@context" : { + "sc" : "http://iiif.io/api/presentation/2#", + "iiif" : "http://iiif.io/api/image/2#", + "exif" : "http://www.w3.org/2003/12/exif/ns#", + "oa" : "http://www.w3.org/ns/oa#", + "cnt" : "http://www.w3.org/2011/content#", + "dc" : "http://purl.org/dc/elements/1.1/", + "dcterms" : "http://purl.org/dc/terms/", + "dctypes" : "http://purl.org/dc/dcmitype/", + "doap" : "http://usefulinc.com/ns/doap#", + "foaf" : "http://xmlns.com/foaf/0.1/", + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", + "xsd" : "http://www.w3.org/2001/XMLSchema#", + "svcs" : "http://rdfs.org/sioc/services#", + "as" : "http://www.w3.org/ns/activitystreams#", + "service" : { + "@type" : "@id", + "@id" : "svcs:has_service" + }, + "profile" : { + "@type" : "@id", + "@id" : "doap:implements" + }, + "manifests" : { + "@type" : "@id", + "@id" : "sc:hasManifests", + "@container" : "@list" + }, + "sequences" : { + "@type" : "@id", + "@id" : "sc:hasSequences", + "@container" : "@list" + }, + "canvases" : { + "@type" : "@id", + "@id" : "sc:hasCanvases", + "@container" : "@list" + }, + "resources" : { + "@type" : "@id", + "@id" : "sc:hasAnnotations", + "@container" : "@set" + }, + "images" : { + "@type" : "@id", + "@id" : "sc:hasImageAnnotations", + "@container" : "@list" + }, + "otherContent" : { + "@type" : "@id", + "@id" : "sc:hasLists", + "@container" : "@list" + }, + "height" : { + "@type" : "xsd:integer", + "@id" : "exif:height" + }, + "width" : { + "@type" : "xsd:integer", + "@id" : "exif:width" + }, + "viewingDirection" : { + "@id" : "sc:viewingDirection", + "@type" : "@vocab" + }, + "viewingHint" : { + "@id" : "sc:viewingHint", + "@type" : "@vocab" + }, + "paged" : { + "@id" : "sc:pagedHint" + }, + "motivation" : { + "@type" : "@id", + "@id" : "oa:motivatedBy" + }, + "resource" : { + "@type" : "@id", + "@id" : "oa:hasBody" + }, + "on" : { + "@type" : "@id", + "@id" : "oa:hasTarget" + }, + "chars" : { + "@id" : "cnt:chars" + }, + "format" : { + "@id" : "dc:format" + }, + "value" : { + "@id" : "rdf:value" + }, + "label" : { + "@id" : "rdfs:label" + } +}, + "@type": "sc:Manifest", + "sequences": [ + { + "@type": "sc:Sequence", + "startCanvas": { + "@type": "sc:Canvas", + "@omitDefault": true, + "@embed": false + }, + "canvases": [ + { + "@type": "sc:Canvas", + "images": [ + { + "@type": "oa:Annotation", + "@embed": true + } + ], + "otherContent": [ + { + "@type": "sc:AnnotationList", + "@embed": true + } + ] + } + ] + } + ], + "structures": [ + { + "@type": "sc:Range", + "@embed": true, + "@omitDefault": true, + "canvases": [ + { + "@embed": false + } + ], + "ranges": [ + { + "@embed": false + } + ] + } + ] +} diff --git a/core/src/test/resources/custom/frame-0004-in.jsonld b/core/src/test/resources/custom/frame-0004-in.jsonld new file mode 100644 index 00000000..08389f11 --- /dev/null +++ b/core/src/test/resources/custom/frame-0004-in.jsonld @@ -0,0 +1,217 @@ +{ + "@graph" : [ { + "@id" : "_:b050f2c1f-4845-40aa-99a9-9185f01d7a0f", + "@type" : "oa:Annotation", + "resource" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000003.jp2", + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000003", + "motivation" : "sc:painting" + }, { + "@id" : "_:b313a6dc0-11a8-44f1-84fc-a838cf5c92bf", + "@type" : "oa:Annotation", + "resource" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000002.jp2", + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000002", + "motivation" : "sc:painting" + }, { + "@id" : "_:b47ae33d8-1da6-47a3-9cc0-929453b1024d", + "@type" : "oa:Annotation", + "resource" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000001.jp2", + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000001", + "motivation" : "sc:painting" + }, { + "@id" : "_:bba9a4e97-8214-44f1-986c-728a6107ec9d", + "@type" : "oa:Annotation", + "resource" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000000.jp2", + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000000", + "motivation" : "sc:painting" + }, { + "@id" : "http://localhost:3000/api/graphs/listsearch.nt", + "profile" : "http://iiif.io/api/search/0/search" + }, { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000000.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000001.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000002.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000003.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000000", + "@type" : "sc:Canvas", + "images" : [ "_:bba9a4e97-8214-44f1-986c-728a6107ec9d" ], + "otherContent" : [ "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000000" ], + "label" : "00000000", + "height" : "574", + "width" : "984" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000001", + "@type" : "sc:Canvas", + "images" : [ "_:b47ae33d8-1da6-47a3-9cc0-929453b1024d" ], + "otherContent" : [ "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000001" ], + "label" : "00000001", + "height" : "614", + "width" : "992" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000002", + "@type" : "sc:Canvas", + "images" : [ "_:b313a6dc0-11a8-44f1-84fc-a838cf5c92bf" ], + "otherContent" : [ "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000002" ], + "label" : "00000002", + "height" : "608", + "width" : "992" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000003", + "@type" : "sc:Canvas", + "images" : [ "_:b050f2c1f-4845-40aa-99a9-9185f01d7a0f" ], + "otherContent" : [ "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000003" ], + "label" : "00000003", + "height" : "599", + "width" : "984" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000000", + "@type" : "sc:AnnotationList" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000001", + "@type" : "sc:AnnotationList" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000002", + "@type" : "sc:AnnotationList" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000003", + "@type" : "sc:AnnotationList" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/manifest", + "@type" : "sc:Manifest", + "sequences" : [ "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/sequence/normal" ], + "service" : "http://localhost:3000/api/graphs/listsearch.nt", + "label" : "" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000000.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : "http://localhost:5004/collection_ak4_0_11_res_00000000.jp2", + "height" : "574", + "width" : "984" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000001.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : "http://localhost:5004/collection_ak4_0_11_res_00000001.jp2", + "height" : "614", + "width" : "992" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000002.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : "http://localhost:5004/collection_ak4_0_11_res_00000002.jp2", + "height" : "608", + "width" : "992" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000003.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : "http://localhost:5004/collection_ak4_0_11_res_00000003.jp2", + "height" : "599", + "width" : "984" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/sequence/normal", + "@type" : "sc:Sequence", + "canvases" : [ "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000000", "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000001", "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000002", "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000003" ], + "viewingHint" : "paged" + } ], + "@context" : { + "sc" : "http://iiif.io/api/presentation/2#", + "iiif" : "http://iiif.io/api/image/2#", + "exif" : "http://www.w3.org/2003/12/exif/ns#", + "oa" : "http://www.w3.org/ns/oa#", + "cnt" : "http://www.w3.org/2011/content#", + "dc" : "http://purl.org/dc/elements/1.1/", + "dcterms" : "http://purl.org/dc/terms/", + "dctypes" : "http://purl.org/dc/dcmitype/", + "doap" : "http://usefulinc.com/ns/doap#", + "foaf" : "http://xmlns.com/foaf/0.1/", + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", + "xsd" : "http://www.w3.org/2001/XMLSchema#", + "svcs" : "http://rdfs.org/sioc/services#", + "as" : "http://www.w3.org/ns/activitystreams#", + "service" : { + "@id" : "svcs:has_service", + "@type" : "@id" + }, + "profile" : { + "@id" : "doap:implements", + "@type" : "@id" + }, + "manifests" : { + "@id" : "sc:hasManifests", + "@type" : "@id", + "@container" : "@list" + }, + "sequences" : { + "@id" : "sc:hasSequences", + "@type" : "@id", + "@container" : "@list" + }, + "canvases" : { + "@id" : "sc:hasCanvases", + "@type" : "@id", + "@container" : "@list" + }, + "resources" : { + "@id" : "sc:hasAnnotations", + "@type" : "@id", + "@container" : "@set" + }, + "images" : { + "@id" : "sc:hasImageAnnotations", + "@type" : "@id", + "@container" : "@list" + }, + "otherContent" : { + "@id" : "sc:hasLists", + "@type" : "@id", + "@container" : "@list" + }, + "height" : { + "@id" : "exif:height", + "@type" : "xsd:integer" + }, + "width" : { + "@id" : "exif:width", + "@type" : "xsd:integer" + }, + "viewingDirection" : { + "@id" : "sc:viewingDirection", + "@type" : "@vocab" + }, + "viewingHint" : { + "@id" : "sc:viewingHint", + "@type" : "@vocab" + }, + "paged" : "sc:pagedHint", + "motivation" : { + "@id" : "oa:motivatedBy", + "@type" : "@id" + }, + "resource" : { + "@id" : "oa:hasBody", + "@type" : "@id" + }, + "on" : { + "@id" : "oa:hasTarget", + "@type" : "@id" + }, + "chars" : "cnt:chars", + "format" :"dc:format", + "value" : "rdf:value", + "label" : "rdfs:label" + } +} diff --git a/core/src/test/resources/custom/frame-0004-out.jsonld b/core/src/test/resources/custom/frame-0004-out.jsonld new file mode 100644 index 00000000..4539e3e4 --- /dev/null +++ b/core/src/test/resources/custom/frame-0004-out.jsonld @@ -0,0 +1,216 @@ +{ "@context" : { + "sc" : "http://iiif.io/api/presentation/2#", + "iiif" : "http://iiif.io/api/image/2#", + "exif" : "http://www.w3.org/2003/12/exif/ns#", + "oa" : "http://www.w3.org/ns/oa#", + "cnt" : "http://www.w3.org/2011/content#", + "dc" : "http://purl.org/dc/elements/1.1/", + "dcterms" : "http://purl.org/dc/terms/", + "dctypes" : "http://purl.org/dc/dcmitype/", + "doap" : "http://usefulinc.com/ns/doap#", + "foaf" : "http://xmlns.com/foaf/0.1/", + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", + "xsd" : "http://www.w3.org/2001/XMLSchema#", + "svcs" : "http://rdfs.org/sioc/services#", + "as" : "http://www.w3.org/ns/activitystreams#", + "service" : { + "@id" : "svcs:has_service", + "@type" : "@id" + }, + "profile" : { + "@id" : "doap:implements", + "@type" : "@id" + }, + "manifests" : { + "@id" : "sc:hasManifests", + "@type" : "@id", + "@container" : "@list" + }, + "sequences" : { + "@id" : "sc:hasSequences", + "@type" : "@id", + "@container" : "@list" + }, + "canvases" : { + "@id" : "sc:hasCanvases", + "@type" : "@id", + "@container" : "@list" + }, + "resources" : { + "@id" : "sc:hasAnnotations", + "@type" : "@id", + "@container" : "@set" + }, + "images" : { + "@id" : "sc:hasImageAnnotations", + "@type" : "@id", + "@container" : "@list" + }, + "otherContent" : { + "@id" : "sc:hasLists", + "@type" : "@id", + "@container" : "@list" + }, + "height" : { + "@id" : "exif:height", + "@type" : "xsd:integer" + }, + "width" : { + "@id" : "exif:width", + "@type" : "xsd:integer" + }, + "viewingDirection" : { + "@id" : "sc:viewingDirection", + "@type" : "@vocab" + }, + "viewingHint" : { + "@id" : "sc:viewingHint", + "@type" : "@vocab" + }, + "paged" : "sc:pagedHint", + "motivation" : { + "@id" : "oa:motivatedBy", + "@type" : "@id" + }, + "resource" : { + "@id" : "oa:hasBody", + "@type" : "@id" + }, + "on" : { + "@id" : "oa:hasTarget", + "@type" : "@id" + }, + "chars" : "cnt:chars", + "format" :"dc:format", + "value" : "rdf:value", + "label" : "rdfs:label" +}, + "@graph" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/manifest", + "@type" : "sc:Manifest", + "sequences" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/sequence/normal", + "@type" : "sc:Sequence", + "canvases" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000000", + "@type" : "sc:Canvas", + "images" : [ { + "@id" : "_:b3", + "@type" : "oa:Annotation", + "resource" : { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000000.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000000.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, + "height" : "574", + "width" : "984" + }, + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000000", + "motivation" : "sc:painting" + } ], + "otherContent" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000000", + "@type" : "sc:AnnotationList" + } ], + "label" : "00000000", + "height" : "574", + "width" : "984" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000001", + "@type" : "sc:Canvas", + "images" : [ { + "@id" : "_:b2", + "@type" : "oa:Annotation", + "resource" : { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000001.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000001.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, + "height" : "614", + "width" : "992" + }, + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000001", + "motivation" : "sc:painting" + } ], + "otherContent" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000001", + "@type" : "sc:AnnotationList" + } ], + "label" : "00000001", + "height" : "614", + "width" : "992" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000002", + "@type" : "sc:Canvas", + "images" : [ { + "@id" : "_:b1", + "@type" : "oa:Annotation", + "resource" : { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000002.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000002.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, + "height" : "608", + "width" : "992" + }, + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000002", + "motivation" : "sc:painting" + } ], + "otherContent" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000002", + "@type" : "sc:AnnotationList" + } ], + "label" : "00000002", + "height" : "608", + "width" : "992" + }, { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000003", + "@type" : "sc:Canvas", + "images" : [ { + "@id" : "_:b0", + "@type" : "oa:Annotation", + "resource" : { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/res/00000003.jp2", + "@type" : "dctypes:Image", + "format" : "image/jpeg 2000", + "service" : { + "@id" : "http://localhost:5004/collection_ak4_0_11_res_00000003.jp2", + "@type" : "http://iiif.io/api/image/2/context.json", + "profile" : "http://iiif.io/api/image/2/level1.json" + }, + "height" : "599", + "width" : "984" + }, + "on" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/canvas/00000003", + "motivation" : "sc:painting" + } ], + "otherContent" : [ { + "@id" : "http://localhost:8080/fcrepo/rest/collection/ak4/0_11/list/00000003", + "@type" : "sc:AnnotationList" + } ], + "label" : "00000003", + "height" : "599", + "width" : "984" + } ], + "viewingHint" : "paged" + } ], + "service" : { + "@id" : "http://localhost:3000/api/graphs/listsearch.nt", + "profile" : "http://iiif.io/api/search/0/search" + }, + "label" : "" + } ] +} From a6539e712e4bc4b39b1f943dd24042bce6315e67 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Mon, 21 Aug 2017 11:23:53 +0200 Subject: [PATCH 259/440] handle new @embed options --- .../com/github/jsonldjava/core/JsonLdApi.java | 41 ++++++++++++++++--- .../github/jsonldjava/core/JsonLdConsts.java | 4 +- .../github/jsonldjava/core/JsonLdError.java | 2 + .../github/jsonldjava/core/JsonLdOptions.java | 38 +++++++++++++++-- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 5eb30a94..202161df 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.github.jsonldjava.core.JsonLdConsts.Embed; import com.github.jsonldjava.core.JsonLdError.Error; import com.github.jsonldjava.utils.Obj; @@ -1254,12 +1255,12 @@ String generateBlankNodeIdentifier() { */ private class FramingContext { - public boolean embed; + public Embed embed; public boolean explicit; public boolean omitDefault; public FramingContext() { - embed = true; + embed = Embed.LAST; explicit = false; omitDefault = false; embeds = null; @@ -1268,7 +1269,7 @@ public FramingContext() { public FramingContext(JsonLdOptions opts) { this(); if (opts.getEmbed() != null) { - this.embed = opts.getEmbed(); + this.embed = opts.getEmbedVal(); } if (opts.getExplicit() != null) { this.explicit = opts.getExplicit(); @@ -1340,7 +1341,8 @@ private void frame(FramingContext state, Map nodes, Map matches = filterNodes(state, nodes, frame); // get flags for current frame - Boolean embedOn = getFrameFlag(frame, JsonLdConsts.EMBED, state.embed); + Embed generalEmbed = getFrameEmbed(frame, state.embed); + Boolean embedOn = generalEmbed != Embed.NEVER; final Boolean explicitOn = getFrameFlag(frame, JsonLdConsts.EXPLICIT, state.explicit); final Map flags = newMap(); flags.put(JsonLdConsts.EXPLICIT, explicitOn); @@ -1522,7 +1524,7 @@ else if (JsonLdUtils.isNodeReference(item)) { } } - private Boolean getFrameFlag(Map frame, String name, boolean thedefault) { + private Object getFrameValue(Map frame, String name) { Object value = frame.get(name); if (value instanceof List) { if (((List) value).size() > 0) { @@ -1532,12 +1534,41 @@ private Boolean getFrameFlag(Map frame, String name, boolean the if (value instanceof Map && ((Map) value).containsKey(JsonLdConsts.VALUE)) { value = ((Map) value).get(JsonLdConsts.VALUE); } + return value; + } + + private Boolean getFrameFlag(Map frame, String name, boolean thedefault) { + Object value = getFrameValue(frame, name); if (value instanceof Boolean) { return (Boolean) value; } return thedefault; } + private Embed getFrameEmbed(Map frame, Embed thedefault) throws JsonLdError { + Object value = getFrameValue(frame, JsonLdConsts.EMBED); + if (value == null) + return thedefault; + if (value instanceof Boolean) { + return (Boolean) value ? Embed.LAST : Embed.NEVER; + } + if (value instanceof String) { + switch ((String) value) { + case "@always": + return Embed.ALWAYS; + case "@never": + return Embed.NEVER; + case "@last": + return Embed.LAST; + case "@link": + return Embed.LINK; + default: + throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); + } + } + throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); + } + /** * Removes an existing embed. * diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java index 2dd4a4e5..e55deabd 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java @@ -57,4 +57,6 @@ public final class JsonLdConsts { public static final String BLANK_NODE_PREFIX = "_:"; public static final String VOCAB = "@vocab"; public static final String BASE = "@base"; -} + + public enum Embed { ALWAYS, NEVER, LAST, LINK; } +} \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java index b30a85ae..b047f210 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdError.java @@ -100,6 +100,8 @@ public enum Error { INVALID_REVERSE_PROPERTY_VALUE("invalid reverse property value"), + INVALID_EMBED_VALUE("invalid @embed value"), + // non spec related errors SYNTAX_ERROR("syntax error"), diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 5f1964a4..fb808f7c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -1,5 +1,7 @@ package com.github.jsonldjava.core; +import com.github.jsonldjava.core.JsonLdConsts.Embed; + /** * The JsonLdOptions type as specified in the * JSON-LD- @@ -59,7 +61,7 @@ public JsonLdOptions(String base) { // Frame options : http://json-ld.org/spec/latest/json-ld-framing/ - private Boolean embed = null; + private Embed embed = Embed.LAST; private Boolean explicit = null; private Boolean omitDefault = null; private Boolean pruneBlankNodeIdentifiers = true; @@ -71,12 +73,40 @@ public JsonLdOptions(String base) { Boolean useNativeTypes = false; private boolean produceGeneralizedRdf = false; - public Boolean getEmbed() { - return embed; + public String getEmbed() { + switch (this.embed) { + case ALWAYS: + return "@always"; + case NEVER: + return "@never"; + case LINK: + return "@link"; + default: + return "@last"; + } + } + + Embed getEmbedVal() { + return this.embed; } public void setEmbed(Boolean embed) { - this.embed = embed; + this.embed = embed ? Embed.LAST : Embed.NEVER; + } + + public void setEmbed(String embed) throws JsonLdError { + switch (embed) { + case "@always": + this.embed = Embed.ALWAYS; + case "@never": + this.embed = Embed.NEVER; + case "@last": + this.embed = Embed.LAST; + case "@link": + this.embed = Embed.LINK; + default: + throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); + } } public Boolean getExplicit() { From 2514ee2e5b922cf94d62dd6075a88b8c39119cb0 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Mon, 21 Aug 2017 11:48:08 +0200 Subject: [PATCH 260/440] add frame-0030 test --- .../json-ld.org/frame-0030-frame.jsonld | 12 ++++++++++ .../json-ld.org/frame-0030-in.jsonld | 15 ++++++++++++ .../json-ld.org/frame-0030-out.jsonld | 16 +++++++++++++ .../json-ld.org/frame-manifest.jsonld | 24 ++++++++++++------- 4 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/frame-0030-frame.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-0030-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-0030-out.jsonld diff --git a/core/src/test/resources/json-ld.org/frame-0030-frame.jsonld b/core/src/test/resources/json-ld.org/frame-0030-frame.jsonld new file mode 100644 index 00000000..415e2b8f --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0030-frame.jsonld @@ -0,0 +1,12 @@ +{ + "@context": { + "ex": "http://www.example.com/#" + }, + "@type": "ex:Thing", + "ex:embed": { + "@embed": "@always" + }, + "ex:noembed": { + "@embed": "@never" + } +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0030-in.jsonld b/core/src/test/resources/json-ld.org/frame-0030-in.jsonld new file mode 100644 index 00000000..d5df9e32 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0030-in.jsonld @@ -0,0 +1,15 @@ +{ + "@context": { + "ex": "http://www.example.com/#" + }, + "@id": "ex:subject", + "@type": "ex:Thing", + "ex:embed": { + "@id": "ex:embedded", + "ex:title": "Embedded" + }, + "ex:noembed": { + "@id": "ex:notembedded", + "ex:title": "Not Embedded" + } +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0030-out.jsonld b/core/src/test/resources/json-ld.org/frame-0030-out.jsonld new file mode 100644 index 00000000..358ab54c --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0030-out.jsonld @@ -0,0 +1,16 @@ +{ + "@context": { + "ex": "http://www.example.com/#" + }, + "@graph": [{ + "@id": "ex:subject", + "@type": "ex:Thing", + "ex:embed": { + "@id": "ex:embedded", + "ex:title": "Embedded" + }, + "ex:noembed": { + "@id": "ex:notembedded" + } + }] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index d476dbac..fe3b6e38 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -152,13 +152,19 @@ "input": "frame-0021-in.jsonld", "frame": "frame-0021-frame.jsonld", "expect": "frame-0021-out.jsonld" - } - , { - "@id": "#t0022", - "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], - "name": "Default inside sets", - "input": "frame-0022-in.jsonld", - "frame": "frame-0022-frame.jsonld", - "expect": "frame-0022-out.jsonld" - }] + } , { + "@id": "#t0022", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Default inside sets", + "input": "frame-0022-in.jsonld", + "frame": "frame-0022-frame.jsonld", + "expect": "frame-0022-out.jsonld" + } , { + "@id": "#t0030", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "@embed", + "input": "frame-0030-in.jsonld", + "frame": "frame-0030-frame.jsonld", + "expect": "frame-0030-out.jsonld" + }] } From 437e709c46d7df7a13e84ef31ee5bbaef739528b Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Mon, 21 Aug 2017 13:01:15 +0200 Subject: [PATCH 261/440] Add spec tests and fix issue with `pruneBlankNodeIdentifiers` - Add tests p010, p020, p021, and p046 (thanks for the pointer @eroux) - Update test data for test 0021 from https://json-ld.org/test-suite/ - Fix issue with `pruneBlankNodeIdentifiers` exposed by test p021 --- .../jsonldjava/core/JsonLdProcessor.java | 24 +++--- .../jsonldjava/core/JsonLdProcessorTest.java | 3 + .../json-ld.org/frame-0021-frame.jsonld | 2 +- .../json-ld.org/frame-0021-in.jsonld | 6 +- .../json-ld.org/frame-0021-out.jsonld | 10 +-- .../json-ld.org/frame-0046-frame.jsonld | 4 + .../json-ld.org/frame-0046-in.jsonld | 11 +++ .../json-ld.org/frame-manifest.jsonld | 49 +++++++++--- .../json-ld.org/frame-p010-out.jsonld | 17 ++++ .../json-ld.org/frame-p020-out.jsonld | 79 +++++++++++++++++++ .../json-ld.org/frame-p021-out.jsonld | 46 +++++++++++ .../json-ld.org/frame-p046-out.jsonld | 8 ++ 12 files changed, 228 insertions(+), 31 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/frame-0046-frame.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-0046-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-p010-out.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-p020-out.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-p021-out.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-p046-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 19330077..abcaec8e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -326,30 +326,28 @@ public static Map frame(Object input, Object frame, JsonLdOption final Map rval = activeCtx.serialize(); rval.put(alias, compacted); - Set toPrune = opts.getPruneBlankNodeIdentifiers() ? - blankNodeIdsToPrune(rval, new HashSet<>()) : Collections.emptySet(); + Set toPrune = opts.getPruneBlankNodeIdentifiers() ? blankNodeIdsToPrune(rval) : Collections.emptySet(); JsonLdUtils.removePreserveAndPrune(activeCtx, rval, opts, toPrune); return rval; } - private static Set blankNodeIdsToPrune(Object input, Set set) { + private static Set blankNodeIdsToPrune(final Map rval) { + return countBlankNodeIds(rval, new HashMap<>()).entrySet().stream().filter(e -> e.getValue() == 1) + .map(e -> e.getKey()).collect(Collectors.toSet()); + } + + private static Map countBlankNodeIds(Object input, Map frequencies) { if (input instanceof List) { - ((List) input).forEach(e -> blankNodeIdsToPrune(e, set)); + ((List) input).forEach(e -> countBlankNodeIds(e, frequencies)); } else if (input instanceof Map) { - ((Map) input).entrySet().forEach(e -> blankNodeIdsToPrune(e.getValue(), set)); + ((Map) input).entrySet().forEach(e -> countBlankNodeIds(e.getValue(), frequencies)); } else if (input instanceof String) { String p = (String) input; if (p.startsWith("_:")) { - if(set.contains(p)){ - // more than 1, don't prune - set.remove(p); - } else { - // exactly 1, prune - set.add(p); - } + frequencies.put(p, frequencies.containsKey(p) ? frequencies.get(p) + 1 : 1); } } - return set; + return frequencies; } /** diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 98d37da6..b61ea157 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -419,6 +419,9 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { if (test_opts.containsKey("produceGeneralizedRdf")) { options.setProduceGeneralizedRdf((Boolean) test_opts.get("produceGeneralizedRdf")); } + if (test_opts.containsKey("pruneBlankNodeIdentifiers")) { + options.setPruneBlankNodeIdentifiers((Boolean) test_opts.get("pruneBlankNodeIdentifiers")); + } if (test_opts.containsKey("redirectTo")) { testLoader.setRedirectTo((String) test_opts.get("redirectTo")); } diff --git a/core/src/test/resources/json-ld.org/frame-0021-frame.jsonld b/core/src/test/resources/json-ld.org/frame-0021-frame.jsonld index da74d30b..32bfc6a6 100644 --- a/core/src/test/resources/json-ld.org/frame-0021-frame.jsonld +++ b/core/src/test/resources/json-ld.org/frame-0021-frame.jsonld @@ -2,6 +2,6 @@ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#", - "dc:list": {"@container": "@list"} + "ex:list": {"@container": "@list"} } } \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0021-in.jsonld b/core/src/test/resources/json-ld.org/frame-0021-in.jsonld index d645c097..ccb878c3 100644 --- a/core/src/test/resources/json-ld.org/frame-0021-in.jsonld +++ b/core/src/test/resources/json-ld.org/frame-0021-in.jsonld @@ -6,12 +6,12 @@ "ex:contains": { "@type": "@id" }, - "dc:list": {"@container": "@list"} + "ex:list": {"@container": "@list"} }, "@graph": [ { "@id": "_:Book", - "dc:label": "Book type" + "dc:title": "Book type" }, { "@id": "http://example.org/library", "@type": "ex:Library", @@ -27,6 +27,6 @@ "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction", - "dc:list": [1, 2, 3, 4, 4, 4, 5] + "ex:list": [1, 2, 3, 4, 4, 4, 5] }] } \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0021-out.jsonld b/core/src/test/resources/json-ld.org/frame-0021-out.jsonld index c1bd1c0b..a5e67d43 100644 --- a/core/src/test/resources/json-ld.org/frame-0021-out.jsonld +++ b/core/src/test/resources/json-ld.org/frame-0021-out.jsonld @@ -2,12 +2,12 @@ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#", - "dc:list": {"@container": "@list"} + "ex:list": {"@container": "@list"} }, "@graph": [ { "@id": "_:b0", - "dc:label": "Book type" + "dc:title": "Book type" }, { "@id": "http://example.org/library", "@type": "ex:Library", @@ -21,7 +21,7 @@ "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction", - "dc:list": [1, 2, 3, 4, 4, 4, 5] + "ex:list": [1, 2, 3, 4, 4, 4, 5] } } }, { @@ -32,7 +32,7 @@ "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction", - "dc:list": [1, 2, 3, 4, 4, 4, 5] + "ex:list": [1, 2, 3, 4, 4, 4, 5] }, "dc:creator": "Plato", "dc:title": "The Republic" @@ -40,7 +40,7 @@ "@id": "http://example.org/library/the-republic#introduction", "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", - "dc:list": [1, 2, 3, 4, 4, 4, 5], + "ex:list": [1, 2, 3, 4, 4, 4, 5], "dc:title": "The Introduction" }] } diff --git a/core/src/test/resources/json-ld.org/frame-0046-frame.jsonld b/core/src/test/resources/json-ld.org/frame-0046-frame.jsonld new file mode 100644 index 00000000..edd59d96 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0046-frame.jsonld @@ -0,0 +1,4 @@ +{ + "@context": {"@vocab": "urn:"}, + "@type": "Class" +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-0046-in.jsonld b/core/src/test/resources/json-ld.org/frame-0046-in.jsonld new file mode 100644 index 00000000..a092c9da --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-0046-in.jsonld @@ -0,0 +1,11 @@ +{ + "@context": {"@vocab": "urn:"}, + "@id": "urn:id-1", + "@type": "Class", + "preserve": { + "@graph": { + "@id": "urn:id-2", + "term": "data" + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index d476dbac..acf0d8ad 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -152,13 +152,44 @@ "input": "frame-0021-in.jsonld", "frame": "frame-0021-frame.jsonld", "expect": "frame-0021-out.jsonld" - } - , { - "@id": "#t0022", - "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], - "name": "Default inside sets", - "input": "frame-0022-in.jsonld", - "frame": "frame-0022-frame.jsonld", - "expect": "frame-0022-out.jsonld" - }] + }, { + "@id": "#t0022", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Default inside sets", + "input": "frame-0022-in.jsonld", + "frame": "frame-0022-frame.jsonld", + "expect": "frame-0022-out.jsonld" + }, { + "@id": "p0010", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Property CURIE conflict (prune bnodes)", + "option" : {"pruneBlankNodeIdentifiers" : true}, + "input": "frame-0010-in.jsonld", + "frame": "frame-0010-frame.jsonld", + "expect": "frame-p010-out.jsonld" + }, { + "@id": "p0020", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Blank nodes in an array (prune bnodes)", + "option" : {"pruneBlankNodeIdentifiers" : true}, + "input": "frame-0020-in.jsonld", + "frame": "frame-0020-frame.jsonld", + "expect": "frame-p020-out.jsonld" + }, { + "@id": "p0021", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Blank nodes in @type (prune bnodes)", + "option" : {"pruneBlankNodeIdentifiers" : true}, + "input": "frame-0021-in.jsonld", + "frame": "frame-0021-frame.jsonld", + "expect": "frame-p021-out.jsonld" + }, { + "@id": "p0046", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Merge graphs if no outer @graph is used (prune bnodes)", + "option" : {"pruneBlankNodeIdentifiers" : true}, + "input": "frame-0046-in.jsonld", + "frame": "frame-0046-frame.jsonld", + "expect": "frame-p046-out.jsonld" + }] } diff --git a/core/src/test/resources/json-ld.org/frame-p010-out.jsonld b/core/src/test/resources/json-ld.org/frame-p010-out.jsonld new file mode 100644 index 00000000..cddb9a62 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p010-out.jsonld @@ -0,0 +1,17 @@ +{ + "@context": { + "dc": "http://purl.org/dc/terms/", + "dc:creator": { + "@type": "@id" + }, + "foaf": "http://xmlns.com/foaf/0.1/", + "ps": "http://purl.org/payswarm#" + }, + "@graph": [{ + "@id": "http://example.com/asset", + "@type": "ps:Asset", + "dc:creator": { + "foaf:name": "John Doe" + } + }] +} diff --git a/core/src/test/resources/json-ld.org/frame-p020-out.jsonld b/core/src/test/resources/json-ld.org/frame-p020-out.jsonld new file mode 100644 index 00000000..e9d42b94 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p020-out.jsonld @@ -0,0 +1,79 @@ +{ + "@graph": [ + { + "http://rdf.data-vocabulary.org/#ingredients": ["12 fresh mint leaves", "1/2 lime, juiced with pulp", "1 tablespoons white sugar", "1 cup ice cubes", "2 fluid ounces white rum", "1/2 cup club soda"], + "http://rdf.data-vocabulary.org/#instructions": [{ + "@id": "_:b1", + "http://rdf.data-vocabulary.org/#description": "Crush lime juice, mint and sugar together in glass.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 1 + } + }, { + "@id": "_:b2", + "http://rdf.data-vocabulary.org/#description": "Fill glass to top with ice cubes.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 2 + } + }, { + "@id": "_:b3", + "http://rdf.data-vocabulary.org/#description": "Pour white rum over ice.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 3 + } + }, { + "@id": "_:b4", + "http://rdf.data-vocabulary.org/#description": "Fill the rest of glass with club soda, stir.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 4 + } + }, { + "@id": "_:b5", + "http://rdf.data-vocabulary.org/#description": "Garnish with a lime wedge.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 5 + } + }], + "http://rdf.data-vocabulary.org/#name": "Mojito", + "http://rdf.data-vocabulary.org/#yield": "1 cocktail" + }, { + "@id": "_:b1", + "http://rdf.data-vocabulary.org/#description": "Crush lime juice, mint and sugar together in glass.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 1 + } + }, { + "@id": "_:b2", + "http://rdf.data-vocabulary.org/#description": "Fill glass to top with ice cubes.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 2 + } + }, { + "@id": "_:b3", + "http://rdf.data-vocabulary.org/#description": "Pour white rum over ice.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 3 + } + }, { + "@id": "_:b4", + "http://rdf.data-vocabulary.org/#description": "Fill the rest of glass with club soda, stir.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 4 + } + }, { + "@id": "_:b5", + "http://rdf.data-vocabulary.org/#description": "Garnish with a lime wedge.", + "http://rdf.data-vocabulary.org/#step": { + "@type": "http://www.w3.org/2001/XMLSchema#integer", + "@value": 5 + } + }] +} diff --git a/core/src/test/resources/json-ld.org/frame-p021-out.jsonld b/core/src/test/resources/json-ld.org/frame-p021-out.jsonld new file mode 100644 index 00000000..a5e67d43 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p021-out.jsonld @@ -0,0 +1,46 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#", + "ex:list": {"@container": "@list"} + }, + "@graph": [ + { + "@id": "_:b0", + "dc:title": "Book type" + }, { + "@id": "http://example.org/library", + "@type": "ex:Library", + "ex:contains": { + "@id": "http://example.org/library/the-republic", + "@type": "_:b0", + "dc:creator": "Plato", + "dc:title": "The Republic", + "ex:contains": { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Chapter", + "dc:description": "An introductory chapter on The Republic.", + "dc:title": "The Introduction", + "ex:list": [1, 2, 3, 4, 4, 4, 5] + } + } + }, { + "@id": "http://example.org/library/the-republic", + "@type": "_:b0", + "ex:contains": { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Chapter", + "dc:description": "An introductory chapter on The Republic.", + "dc:title": "The Introduction", + "ex:list": [1, 2, 3, 4, 4, 4, 5] + }, + "dc:creator": "Plato", + "dc:title": "The Republic" + }, { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Chapter", + "dc:description": "An introductory chapter on The Republic.", + "ex:list": [1, 2, 3, 4, 4, 4, 5], + "dc:title": "The Introduction" + }] +} diff --git a/core/src/test/resources/json-ld.org/frame-p046-out.jsonld b/core/src/test/resources/json-ld.org/frame-p046-out.jsonld new file mode 100644 index 00000000..dd3b7aed --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p046-out.jsonld @@ -0,0 +1,8 @@ +{ + "@context": {"@vocab": "urn:"}, + "@graph": [{ + "@id": "urn:id-1", + "@type": "Class", + "preserve": {} + }] +} \ No newline at end of file From 4fe56fd4edcf943782879023483284ab8ad08c65 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Mon, 21 Aug 2017 16:49:05 +0200 Subject: [PATCH 262/440] lots of framing improvements (fix #202) --- .../com/github/jsonldjava/core/JsonLdApi.java | 529 +++++++++--------- .../github/jsonldjava/core/JsonLdOptions.java | 6 +- .../jsonldjava/core/JsonLdProcessor.java | 14 +- 3 files changed, 295 insertions(+), 254 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 202161df..aebf4bdb 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -507,6 +508,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element) */ public Object expand(Context activeCtx, String activeProperty, Object element) throws JsonLdError { + boolean frameExpansion = this.opts.getProcessingMode().equals(JsonLdOptions.JSON_LD_1_1_FRAME); // 1) if (element == null) { return null; @@ -580,12 +582,37 @@ else if (element instanceof Map) { } // 7.4.3) if (JsonLdConsts.ID.equals(expandedProperty)) { - if (!(value instanceof String)) { + if (value instanceof String) { + expandedValue = activeCtx.expandIri((String) value, true, false, null, + null); + } + else if (frameExpansion) { + if (value instanceof Map) { + if (((Map) value).size() != 0) { + throw new JsonLdError(Error.INVALID_ID_VALUE, + "@id value must be a an empty object for framing"); + } + expandedValue = value; + } else if (value instanceof List) { + expandedValue = new ArrayList(); + for (final Object v : (List) value) { + if (!(v instanceof String)) { + throw new JsonLdError(Error.INVALID_ID_VALUE, + "@id value must be a string, an array of strings or an empty dictionary"); + } + ((List) expandedValue).add( + activeCtx.expandIri((String) v, true, true, null, null)); + } + } + else { + throw new JsonLdError(Error.INVALID_ID_VALUE, + "value of @id must be a string, an array of strings or an empty dictionary"); + } + } + else { throw new JsonLdError(Error.INVALID_ID_VALUE, "value of @id must be a string"); } - expandedValue = activeCtx.expandIri((String) value, true, false, null, - null); } // 7.4.4) else if (JsonLdConsts.TYPE.equals(expandedProperty)) { @@ -604,7 +631,7 @@ else if (JsonLdConsts.TYPE.equals(expandedProperty)) { null); } // TODO: SPEC: no mention of empty map check - else if (value instanceof Map) { + else if (frameExpansion && value instanceof Map) { if (((Map) value).size() != 0) { throw new JsonLdError(Error.INVALID_TYPE_VALUE, "@type value must be a an empty object for framing"); @@ -746,11 +773,11 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { continue; } // TODO: SPEC no mention of @explicit etc in spec - else if (JsonLdConsts.EXPLICIT.equals(expandedProperty) + else if (frameExpansion && (JsonLdConsts.EXPLICIT.equals(expandedProperty) || JsonLdConsts.DEFAULT.equals(expandedProperty) || JsonLdConsts.EMBED.equals(expandedProperty) || JsonLdConsts.EMBED_CHILDREN.equals(expandedProperty) - || JsonLdConsts.OMIT_DEFAULT.equals(expandedProperty)) { + || JsonLdConsts.OMIT_DEFAULT.equals(expandedProperty))) { expandedValue = expand(activeCtx, expandedProperty, value); } // 7.4.12) @@ -1258,12 +1285,15 @@ private class FramingContext { public Embed embed; public boolean explicit; public boolean omitDefault; + public Map uniqueEmbeds; + public LinkedList subjectStack; public FramingContext() { embed = Embed.LAST; explicit = false; omitDefault = false; - embeds = null; + uniqueEmbeds = new HashMap<>(); + subjectStack = new LinkedList<>(); } public FramingContext(JsonLdOptions opts) { @@ -1278,13 +1308,16 @@ public FramingContext(JsonLdOptions opts) { this.omitDefault = opts.getOmitDefault(); } } - - public Map embeds = null; } private class EmbedNode { public Object parent = null; public String property = null; + + public EmbedNode(Object parent, String property) { + this.parent = parent; + this.property = property; + } } private Map nodeMap; @@ -1305,7 +1338,7 @@ public List frame(Object input, List frame) throws JsonLdError { // create framing state final FramingContext state = new FramingContext(this.opts); - // use tree map so keys are sotred by default + // use tree map so keys are sorted by default final Map nodes = new TreeMap(); generateNodeMap(input, nodes); this.nodeMap = (Map) nodes.get(JsonLdConsts.DEFAULT); @@ -1313,6 +1346,8 @@ public List frame(Object input, List frame) throws JsonLdError { final List framed = new ArrayList(); // NOTE: frame validation is done by the function not allowing anything // other than list to me passed + // 1. + // If frame is an array, set frame to the first member of the array, which MUST be a valid frame. frame(state, this.nodeMap, (frame != null && frame.size() > 0 ? (Map) frame.get(0) : newMap()), framed, null); @@ -1320,6 +1355,10 @@ public List frame(Object input, List frame) throws JsonLdError { return framed; } + private boolean createsCircularReference(String id, FramingContext state) { + return state.subjectStack.contains(id); + } + /** * Frames subjects according to the given frame. * @@ -1336,191 +1375,197 @@ public List frame(Object input, List frame) throws JsonLdError { */ private void frame(FramingContext state, Map nodes, Map frame, Object parent, String property) throws JsonLdError { - - // filter out subjects that match the frame - final Map matches = filterNodes(state, nodes, frame); - - // get flags for current frame - Embed generalEmbed = getFrameEmbed(frame, state.embed); - Boolean embedOn = generalEmbed != Embed.NEVER; + + // https://json-ld.org/spec/latest/json-ld-framing/#framing-algorithm + + // 2. + // Initialize flags embed, explicit, and requireAll from object embed flag, + // explicit inclusion flag, and require all flag in state overriding from + // any property values for @embed, @explicit, and @requireAll in frame. + // TODO: handle @requireAll + Embed embed = getFrameEmbed(frame, state.embed); final Boolean explicitOn = getFrameFlag(frame, JsonLdConsts.EXPLICIT, state.explicit); final Map flags = newMap(); flags.put(JsonLdConsts.EXPLICIT, explicitOn); - flags.put(JsonLdConsts.EMBED, embedOn); + flags.put(JsonLdConsts.EMBED, embed); - // add matches to output + // 3. + // Create a list of matched subjects by filtering subjects against frame + // using the Frame Matching algorithm with state, subjects, frame, and requireAll. + final Map matches = filterNodes(state, nodes, frame); final List ids = new ArrayList(matches.keySet()); Collections.sort(ids); + + // 4. + // Set link the the value of link in state associated with graph name in state, + // creating a new empty dictionary, if necessary. + Map link = state.uniqueEmbeds; + + // 5. + // For each id and associated node object node from the set of matched subjects, ordered by id: for (final String id : ids) { - if (property == null) { - state.embeds = new LinkedHashMap(); - } + final Map subject = (Map) matches.get(id); - // start output + // 5.1 + // Initialize output to a new dictionary with @id and id and add output to link associated with id. final Map output = newMap(); output.put(JsonLdConsts.ID, id); - // prepare embed meta info - final EmbedNode embeddedNode = new EmbedNode(); - embeddedNode.parent = parent; - embeddedNode.property = property; - - // if embed is on and there is an existing embed - if (embedOn && state.embeds.containsKey(id)) { - final EmbedNode existing = state.embeds.get(id); - embedOn = false; - - if (existing.parent instanceof List) { - for (final Object p : (List) existing.parent) { - if (JsonLdUtils.compareValues(output, p)) { - embedOn = true; - break; - } - } - } - // existing embed's parent is an object - else { - if (((Map) existing.parent).containsKey(existing.property)) { - for (final Object v : (List) ((Map) existing.parent) - .get(existing.property)) { - if (v instanceof Map && Obj.equals(id, - ((Map) v).get(JsonLdConsts.ID))) { - embedOn = true; - break; - } - } - } - } + // 5.2 + // If embed is @link and id is in link, node already exists in results. + // Add the associated node object from link to parent and do not perform + // additional processing for this node. + if (embed == Embed.LINK && state.uniqueEmbeds.containsKey(id)) { + addFrameOutput(state, parent, property, state.uniqueEmbeds.get(id)); + continue; + } + + // Occurs only at top level, compartmentalize each top-level match + if(property == null) { + state.uniqueEmbeds = new HashMap<>(); + } + + // 5.3 + // Otherwise, if embed is @never or if a circular reference would be created by an embed, + // add output to parent and do not perform additional processing for this node. + if (embed == Embed.NEVER || createsCircularReference(id, state)) { + addFrameOutput(state, parent, property, output); + continue; + } - // existing embed has already been added, so allow an overwrite - if (embedOn) { + // 5.4 + // Otherwise, if embed is @last, remove any existing embedded node from parent associated + // with graph name in state. Requires sorting of subjects. + if (embed == Embed.LAST) { + if (state.uniqueEmbeds.containsKey(id)) { removeEmbed(state, id); } - } - - // not embedding, add output without any other properties - if (!embedOn) { - addFrameOutput(state, parent, property, output); - } else { - // add embed meta info - state.embeds.put(id, embeddedNode); - - // iterate over subject properties - final Map element = (Map) matches.get(id); - List props = new ArrayList(element.keySet()); - Collections.sort(props); - for (final String prop : props) { - - // copy keywords to output - if (isKeyword(prop)) { - output.put(prop, JsonLdUtils.clone(element.get(prop))); - continue; - } + state.uniqueEmbeds.put(id, new EmbedNode(parent, property)); + } + + state.subjectStack.push(id); + + // 5.5 If embed is @last or @always + + // Skip 5.5.1 + + // 5.5.2 For each property and objects in node, ordered by property: + final Map element = (Map) matches.get(id); + List props = new ArrayList(element.keySet()); + Collections.sort(props); + for (final String prop : props) { + + // 5.5.2.1 If property is a keyword, add property and objects to output. + if (isKeyword(prop)) { + output.put(prop, JsonLdUtils.clone(element.get(prop))); + continue; + } - // if property isn't in the frame - if (explicitOn && !frame.containsKey(prop)) { - continue; - } + // 5.5.2.2 Otherwise, if property is not in frame, and explicit is true, processors + // MUST NOT add any values for property to output, and the following steps are skipped. + if (explicitOn && !frame.containsKey(prop)) { + continue; + } - // add objects - final List value = (List) element.get(prop); - - for (final Object item : value) { - - // recurse into list - if ((item instanceof Map) - && ((Map) item).containsKey(JsonLdConsts.LIST)) { - // add empty list - final Map list = newMap(); - list.put(JsonLdConsts.LIST, new ArrayList()); - addFrameOutput(state, output, prop, list); - - // add list objects - for (final Object listitem : (List) ((Map) item) - .get(JsonLdConsts.LIST)) { - // recurse into subject reference - if (JsonLdUtils.isNodeReference(listitem)) { - final Map tmp = newMap(); - final String itemid = (String) ((Map) listitem) - .get(JsonLdConsts.ID); - // TODO: nodes may need to be node_map, - // which is global - tmp.put(itemid, this.nodeMap.get(itemid)); - Map subframe; - if (frame.containsKey(prop)) { - subframe = (Map) ((List) frame.get(prop)).get(0); - } else { - subframe = flags; - } - frame(state, tmp, subframe, list, JsonLdConsts.LIST); + // add objects + final List value = (List) element.get(prop); + + // 5.5.2.3 For each item in objects: + for (final Object item : value) { + if ((item instanceof Map) + && ((Map) item).containsKey(JsonLdConsts.LIST)) { + // add empty list + final Map list = newMap(); + list.put(JsonLdConsts.LIST, new ArrayList()); + addFrameOutput(state, output, prop, list); + + // add list objects + for (final Object listitem : (List) ((Map) item) + .get(JsonLdConsts.LIST)) { + // 5.5.2.3.1.1 recurse into subject reference + if (JsonLdUtils.isNodeReference(listitem)) { + final Map tmp = newMap(); + final String itemid = (String) ((Map) listitem) + .get(JsonLdConsts.ID); + // TODO: nodes may need to be node_map, + // which is global + tmp.put(itemid, this.nodeMap.get(itemid)); + Map subframe; + if (frame.containsKey(prop)) { + subframe = (Map) ((List) frame.get(prop)).get(0); } else { - // include other values automatcially (TODO: - // may need JsonLdUtils.clone(n)) - addFrameOutput(state, list, JsonLdConsts.LIST, listitem); + subframe = flags; } - } - } - - // recurse into subject reference - else if (JsonLdUtils.isNodeReference(item)) { - final Map tmp = newMap(); - final String itemid = (String) ((Map) item) - .get(JsonLdConsts.ID); - // TODO: nodes may need to be node_map, which is - // global - tmp.put(itemid, this.nodeMap.get(itemid)); - Map subframe; - if (frame.containsKey(prop)) { - subframe = (Map) ((List) frame.get(prop)).get(0); + frame(state, tmp, subframe, list, JsonLdConsts.LIST); } else { - subframe = flags; + + // include other values automatcially (TODO: + // may need JsonLdUtils.clone(n)) + addFrameOutput(state, list, JsonLdConsts.LIST, listitem); } - frame(state, tmp, subframe, output, prop); + } + } + // recurse into subject reference + else if (JsonLdUtils.isNodeReference(item)) { + final Map tmp = newMap(); + final String itemid = (String) ((Map) item) + .get(JsonLdConsts.ID); + // TODO: nodes may need to be node_map, which is + // global + tmp.put(itemid, this.nodeMap.get(itemid)); + Map subframe; + if (frame.containsKey(prop)) { + subframe = (Map) ((List) frame.get(prop)).get(0); } else { - // include other values automatically (TODO: may - // need JsonLdUtils.clone(o)) - addFrameOutput(state, output, prop, item); + subframe = flags; } + frame(state, tmp, subframe, output, prop); + } else { + // include other values automatically (TODO: may + // need JsonLdUtils.clone(o)) + addFrameOutput(state, output, prop, item); } } + } - // handle defaults - props = new ArrayList(frame.keySet()); - Collections.sort(props); - for (final String prop : props) { - // skip keywords - if (isKeyword(prop)) { - continue; - } + // handle defaults + props = new ArrayList(frame.keySet()); + Collections.sort(props); + for (final String prop : props) { + // skip keywords + if (isKeyword(prop)) { + continue; + } - final List pf = (List) frame.get(prop); - Map propertyFrame = pf.size() > 0 - ? (Map) pf.get(0) : null; - if (propertyFrame == null) { - propertyFrame = newMap(); + final List pf = (List) frame.get(prop); + Map propertyFrame = pf.size() > 0 + ? (Map) pf.get(0) : null; + if (propertyFrame == null) { + propertyFrame = newMap(); + } + final boolean omitDefaultOn = getFrameFlag(propertyFrame, + JsonLdConsts.OMIT_DEFAULT, state.omitDefault); + if (!omitDefaultOn && !output.containsKey(prop)) { + Object def = "@null"; + if (propertyFrame.containsKey(JsonLdConsts.DEFAULT)) { + def = JsonLdUtils.clone(propertyFrame.get(JsonLdConsts.DEFAULT)); } - final boolean omitDefaultOn = getFrameFlag(propertyFrame, - JsonLdConsts.OMIT_DEFAULT, state.omitDefault); - if (!omitDefaultOn && !output.containsKey(prop)) { - Object def = "@null"; - if (propertyFrame.containsKey(JsonLdConsts.DEFAULT)) { - def = JsonLdUtils.clone(propertyFrame.get(JsonLdConsts.DEFAULT)); - } - if (!(def instanceof List)) { - final List tmp = new ArrayList(); - tmp.add(def); - def = tmp; - } - final Map tmp1 = newMap(JsonLdConsts.PRESERVE, def); - final List tmp2 = new ArrayList(); - tmp2.add(tmp1); - output.put(prop, tmp2); + if (!(def instanceof List)) { + final List tmp = new ArrayList(); + tmp.add(def); + def = tmp; } + final Map tmp1 = newMap(JsonLdConsts.PRESERVE, def); + final List tmp2 = new ArrayList(); + tmp2.add(tmp1); + output.put(prop, tmp2); } - - // add output to parent - addFrameOutput(state, parent, property, output); } + + // add output to parent + addFrameOutput(state, parent, property, output); + + state.subjectStack.pop(); } } @@ -1552,6 +1597,9 @@ private Embed getFrameEmbed(Map frame, Embed thedefault) throws if (value instanceof Boolean) { return (Boolean) value ? Embed.LAST : Embed.NEVER; } + if (value instanceof Embed) { + return (Embed) value; + } if (value instanceof String) { switch ((String) value) { case "@always": @@ -1579,8 +1627,8 @@ private Embed getFrameEmbed(Map frame, Embed thedefault) throws */ private static void removeEmbed(FramingContext state, String id) { // get existing embed - final Map embeds = state.embeds; - final EmbedNode embed = embeds.get(id); + final Map links = state.uniqueEmbeds; + final EmbedNode embed = links.get(id); final Object parent = embed.parent; final String property = embed.property; @@ -1604,7 +1652,7 @@ private static void removeEmbed(FramingContext state, String id) { ((Map) parent).put(property, newvals); } // recursively remove dependent dangling embeds - removeDependents(embeds, id); + removeDependents(links, id); } private static void removeDependents(Map embeds, String id) { @@ -1637,6 +1685,36 @@ private Map filterNodes(FramingContext state, Map node, Map frame) throws JsonLdError { final Object types = frame.get(JsonLdConsts.TYPE); + final Object frameIds = frame.get(JsonLdConsts.ID); + // https://json-ld.org/spec/latest/json-ld-framing/#frame-matching + // + // 1. Node matches if it has an @id property including any IRI or + // blank node in the @id property in frame. + if (frameIds != null) { + if (frameIds instanceof String) { + Object nodeId = node.get(JsonLdConsts.ID); + if (nodeId == null) + return false; + if (JsonLdUtils.deepCompare(nodeId, frameIds)) { + return true; + } + } + else if (!(frameIds instanceof List)) { + throw new JsonLdError(Error.SYNTAX_ERROR, "frame @id must be an array"); + } + else { + Object nodeId = node.get(JsonLdConsts.ID); + if (nodeId == null) + return false; + for (final Object j : (List) frameIds) { + if (JsonLdUtils.deepCompare(nodeId, j)) { + return true; + } + } + } + } + // 2. Node matches if frame has no non-keyword properties.TODO + // 3.1 If property is @type: if (types != null) { if (!(types instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "frame @type must be an array"); @@ -1647,45 +1725,48 @@ private boolean filterNode(FramingContext state, Map node, } else if (!(nodeTypes instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "node @type must be an array"); } + // 3.1.1 Property matches if the @type property in frame includes any IRI in values. + for (final Object i : (List) nodeTypes) { + for (final Object j : (List) types) { + if (JsonLdUtils.deepCompare(i, j)) { + return true; + } + } + } + // TODO: 3.1.2 + // 3.1.3 Otherwise, property matches if values is empty and the @type property in frame is match none. if (((List) types).size() == 1 && ((List) types).get(0) instanceof Map && ((Map) ((List) types).get(0)).size() == 0) { return !((List) nodeTypes).isEmpty(); - } else { - for (final Object i : (List) nodeTypes) { - for (final Object j : (List) types) { - if (JsonLdUtils.deepCompare(i, j)) { - return true; - } - } - } - return false; } - } else { - for (final String key : frame.keySet()) { - if (JsonLdConsts.ID.equals(key) || !isKeyword(key) && !(node.containsKey(key))) { - - final Object frameObject = frame.get(key); - if (frameObject instanceof ArrayList) { - final ArrayList o = (ArrayList) frame.get(key); - - boolean _default = false; - for (final Object oo : o) { - if (oo instanceof Map) { - if (((Map) oo).containsKey(JsonLdConsts.DEFAULT)) { - _default = true; - } + // 3.1.4 Otherwise, property does not match. + return false; + } + // 3.2 + for (final String key : frame.keySet()) { + if (!isKeyword(key) && !(node.containsKey(key))) { + + final Object frameObject = frame.get(key); + if (frameObject instanceof ArrayList) { + final ArrayList o = (ArrayList) frame.get(key); + + boolean _default = false; + for (final Object oo : o) { + if (oo instanceof Map) { + if (((Map) oo).containsKey(JsonLdConsts.DEFAULT)) { + _default = true; } } - if (_default) { - continue; - } } - - return false; + if (_default) { + continue; + } } + + return false; } - return true; } + return true; } /** @@ -1714,60 +1795,6 @@ private static void addFrameOutput(FramingContext state, Object parent, String p } } - /** - * Embeds values for the given subject and property into the given output - * during the framing algorithm. - * - * @param state - * the current framing state. - * @param element - * the subject. - * @param property - * the property. - * @param output - * the output. - */ - private void embedValues(FramingContext state, Map element, String property, - Object output) { - // embed subject properties in output - final List objects = (List) element.get(property); - for (Object o : objects) { - // handle subject reference - if (JsonLdUtils.isNodeReference(o)) { - final String sid = (String) ((Map) o).get(JsonLdConsts.ID); - - // embed full subject if isn't already embedded - if (!state.embeds.containsKey(sid)) { - // add embed - final EmbedNode embed = new EmbedNode(); - embed.parent = output; - embed.property = property; - state.embeds.put(sid, embed); - - // recurse into subject - o = newMap(); - Map s = (Map) this.nodeMap.get(sid); - if (s == null) { - s = newMap(JsonLdConsts.ID, sid); - } - for (final String prop : s.keySet()) { - // copy keywords - if (isKeyword(prop)) { - ((Map) o).put(prop, JsonLdUtils.clone(s.get(prop))); - continue; - } - embedValues(state, s, prop, o); - } - } - addFrameOutput(state, output, property, o); - } - // copy non-subject value - else { - addFrameOutput(state, output, property, JsonLdUtils.clone(o)); - } - } - } - /*** * ____ _ __ ____ ____ _____ _ _ _ _ _ / ___|___ _ ____ _____ _ __| |_ / _|_ * __ ___ _ __ ___ | _ \| _ \| ___| / \ | | __ _ ___ _ __(_) |_| |__ _ __ diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index fb808f7c..962ef0b6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -12,9 +12,11 @@ */ public class JsonLdOptions { - private static final String JSON_LD_1_0 = "json-ld-1.0"; + public static final String JSON_LD_1_0 = "json-ld-1.0"; - private static final String JSON_LD_1_1 = "json-ld-1.1"; + public static final String JSON_LD_1_1 = "json-ld-1.1"; + + public static final String JSON_LD_1_1_FRAME = "json-ld-1.1-expand-frame"; public static final boolean DEFAULT_COMPACT_ARRAYS = true; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 19330077..c21afb80 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -308,13 +308,25 @@ public static Map frame(Object input, Object frame, JsonLdOption } // TODO string/IO input + // 2. Set expanded input to the result of using the expand method using input and options. final Object expandedInput = expand(input, opts); + + // 3. Set expanded frame to the result of using the expand method using frame and options + // with expandContext set to null and processingMode set to json-ld-1.1-expand-frame. + String savedProcessingMode = opts.getProcessingMode(); + Object savedExpandedContext = opts.getExpandContext(); + opts.setProcessingMode(JsonLdOptions.JSON_LD_1_1_FRAME); + opts.setExpandContext(null); final List expandedFrame = expand(frame, opts); + opts.setProcessingMode(savedProcessingMode); + opts.setExpandContext(savedExpandedContext); + // 4. Set context to the value of @context from frame, if it exists, or to a new empty + // context, otherwise. final JsonLdApi api = new JsonLdApi(expandedInput, opts); - final List framed = api.frame(expandedInput, expandedFrame); final Context activeCtx = api.context .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); + final List framed = api.frame(expandedInput, expandedFrame); Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); if (!(compacted instanceof List)) { From 558912460ce7cf4dd72c4a4f556d4b25dabae269 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 22 Aug 2017 09:20:53 +1000 Subject: [PATCH 263/440] Add recent changelog entries Signed-off-by: Peter Ansell --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d3e0ea5b..13df4a86 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,11 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-08-22 +* Add implicit "flag only" subframe to fix incomplete list recursion (Patch by @christopher-johnson) +* Support pruneBlankNodeIdentifiers framing option in 1.1 mode (Patch by @fsteeg and @eroux) +* Support new @embed values (Patch by @eroux) + ### 2017-07-11 * Add injection of contexts directly into DocumentLoader (Patch by @ryankenney) * Fix N-Quads content type (Patch by @NicolasRouquette) From 0e723d6ea1b74b7c952df1bf9772fabb7a0bc502 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Mon, 21 Aug 2017 17:43:47 +0200 Subject: [PATCH 264/440] add new version of frame-0022 and fix edge cases see https://github.com/json-ld/json-ld.org/issues/532 --- .../com/github/jsonldjava/core/JsonLdApi.java | 3 +- .../json-ld.org/frame-0022-frame.jsonld | 14 ++------ .../json-ld.org/frame-0022-in.jsonld | 32 ++++++------------- .../json-ld.org/frame-0022-out.jsonld | 31 ++++-------------- 4 files changed, 20 insertions(+), 60 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index aebf4bdb..9e6440af 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -994,7 +994,7 @@ else if (result.containsKey(JsonLdConsts.SET) result = null; } // 12.2) - else if (result != null && result.containsKey(JsonLdConsts.ID) + else if (result != null && !frameExpansion && result.containsKey(JsonLdConsts.ID) && result.size() == 1) { result = null; } @@ -1712,6 +1712,7 @@ else if (!(frameIds instanceof List)) { } } } + return false; } // 2. Node matches if frame has no non-keyword properties.TODO // 3.1 If property is @type: diff --git a/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld b/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld index 1f6d39e7..dc15b5fd 100644 --- a/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld +++ b/core/src/test/resources/json-ld.org/frame-0022-frame.jsonld @@ -1,12 +1,4 @@ { - "@context": { - "dc": "http://purl.org/dc/elements/1.1/", - "ex": "http://example.org/vocab#" - }, - "@type": "ex:Library", - "ex:contains": { - "@explicit":true, - "dc:title":{"@default":"Title missing"}, - "dc:creator":{} - } -} \ No newline at end of file + "@context": {"ex": "http://example.org/"}, + "@id": "ex:Sub1" +} diff --git a/core/src/test/resources/json-ld.org/frame-0022-in.jsonld b/core/src/test/resources/json-ld.org/frame-0022-in.jsonld index 6c0feddb..3e9969a6 100644 --- a/core/src/test/resources/json-ld.org/frame-0022-in.jsonld +++ b/core/src/test/resources/json-ld.org/frame-0022-in.jsonld @@ -1,24 +1,10 @@ { - "@context": { - "dc": "http://purl.org/dc/elements/1.1/", - "ex": "http://example.org/vocab#" - }, - "@graph": [ - { - "@id": "http://example.org/library", - "@type": "ex:Library", - "ex:contains": [{"@id":"http://example.org/library/the-republic#introduction"},{"@id":"http://example.org/library/the-republic"}] - }, - { - "@id": "http://example.org/library/the-republic", - "@type": "ex:Book", - "dc:creator": "Plato", - "dc:title": "The Republic" - }, - { - "@id": "http://example.org/library/the-republic#introduction", - "@type": "ex:Book", - "dc:creator": "Plato" - } - ] -} \ No newline at end of file + "@context": {"ex": "http://example.org/"}, + "@graph": [{ + "@id": "ex:Sub1", + "@type": "ex:Type1" + }, { + "@id": "ex:Sub2", + "@type": "ex:Type2" + }] +} diff --git a/core/src/test/resources/json-ld.org/frame-0022-out.jsonld b/core/src/test/resources/json-ld.org/frame-0022-out.jsonld index 42836207..ef560bfc 100644 --- a/core/src/test/resources/json-ld.org/frame-0022-out.jsonld +++ b/core/src/test/resources/json-ld.org/frame-0022-out.jsonld @@ -1,26 +1,7 @@ { - "@context": { - "dc": "http://purl.org/dc/elements/1.1/", - "ex": "http://example.org/vocab#" - }, - "@graph": [ - { - "@id": "http://example.org/library", - "@type": "ex:Library", - "ex:contains": [ - { - "@id": "http://example.org/library/the-republic#introduction", - "@type": "ex:Book", - "dc:creator": "Plato", - "dc:title": "Title missing" - }, - { - "@id": "http://example.org/library/the-republic", - "@type": "ex:Book", - "dc:creator": "Plato", - "dc:title": "The Republic" - } - ] - } - ] -} \ No newline at end of file + "@context": {"ex": "http://example.org/"}, + "@graph": [{ + "@id": "ex:Sub1", + "@type": "ex:Type1" + }] +} From 88872bd1f7d0ee98e0d1debbeb0278c23a921929 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Tue, 22 Aug 2017 10:01:14 +0200 Subject: [PATCH 265/440] add tests for #174 and #206 --- .../jsonldjava/core/JsonLdFramingTest.java | 32 +++++++++++++++++++ .../resources/custom/frame-0005-frame.jsonld | 4 +++ .../resources/custom/frame-0005-in.jsonld | 19 +++++++++++ .../resources/custom/frame-0005-out.jsonld | 15 +++++++++ .../resources/custom/frame-0006-frame.jsonld | 1 + .../resources/custom/frame-0006-in.jsonld | 11 +++++++ .../resources/custom/frame-0006-out.jsonld | 14 ++++++++ 7 files changed, 96 insertions(+) create mode 100644 core/src/test/resources/custom/frame-0005-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0005-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0005-out.jsonld create mode 100644 core/src/test/resources/custom/frame-0006-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0006-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0006-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index cd248258..2825f26a 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -75,4 +75,36 @@ public void testFrame0004() throws IOException, JsonLdError { .fromInputStream(getClass().getResourceAsStream("/custom/frame-0004-out.jsonld")); assertEquals(out, frame2); } + + @Test + public void testFrame0005() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0005-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0005-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setCompactArrays(true); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0005-out.jsonld")); + assertEquals(out, frame2); + } + + @Test + public void testFrame0006() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0006-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0006-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setCompactArrays(true); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0006-out.jsonld")); + assertEquals(out, frame2); + } } diff --git a/core/src/test/resources/custom/frame-0005-frame.jsonld b/core/src/test/resources/custom/frame-0005-frame.jsonld new file mode 100644 index 00000000..d7ec9aa6 --- /dev/null +++ b/core/src/test/resources/custom/frame-0005-frame.jsonld @@ -0,0 +1,4 @@ +{ + "@context": {}, + "@type": "http://www.myresource/uuidtype" +} diff --git a/core/src/test/resources/custom/frame-0005-in.jsonld b/core/src/test/resources/custom/frame-0005-in.jsonld new file mode 100644 index 00000000..14701a93 --- /dev/null +++ b/core/src/test/resources/custom/frame-0005-in.jsonld @@ -0,0 +1,19 @@ +{ + "@context": { + "rdfs": "http://www.w3.org/2000/01/rdf-schema#" + }, + "@id": "http://www.myresource/uuid", + "@type": "http://www.myresource/uuidtype", + "http://www.myresource.com/ontology/1.0#talksAbout": { + "@list": [ + { + "@id": "http://rdf.freebase.com/ns/m.018w8", + "rdfs:label": [ + { + "@value": "Basketball", + "@language": "en" + } + ] + } + ] } +} diff --git a/core/src/test/resources/custom/frame-0005-out.jsonld b/core/src/test/resources/custom/frame-0005-out.jsonld new file mode 100644 index 00000000..394cffe6 --- /dev/null +++ b/core/src/test/resources/custom/frame-0005-out.jsonld @@ -0,0 +1,15 @@ +{ + "@graph" : [ { + "@id" : "http://www.myresource/uuid", + "@type" : "http://www.myresource/uuidtype", + "http://www.myresource.com/ontology/1.0#talksAbout" : { + "@list" : [ { + "@id" : "http://rdf.freebase.com/ns/m.018w8", + "http://www.w3.org/2000/01/rdf-schema#label" : { + "@language" : "en", + "@value" : "Basketball" + } + } ] + } + } ] +} diff --git a/core/src/test/resources/custom/frame-0006-frame.jsonld b/core/src/test/resources/custom/frame-0006-frame.jsonld new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/core/src/test/resources/custom/frame-0006-frame.jsonld @@ -0,0 +1 @@ +{} diff --git a/core/src/test/resources/custom/frame-0006-in.jsonld b/core/src/test/resources/custom/frame-0006-in.jsonld new file mode 100644 index 00000000..570de35e --- /dev/null +++ b/core/src/test/resources/custom/frame-0006-in.jsonld @@ -0,0 +1,11 @@ +[ { + "@id" : "http://example.com/canvas-1", + "@type" : "http://example.com" +}, { + "@id" : "http://example.com/element", + "http://example.com" : { + "@list" : [ { + "@id" : "http://example.com/canvas-1" + } ] + } +} ] diff --git a/core/src/test/resources/custom/frame-0006-out.jsonld b/core/src/test/resources/custom/frame-0006-out.jsonld new file mode 100644 index 00000000..63a390ee --- /dev/null +++ b/core/src/test/resources/custom/frame-0006-out.jsonld @@ -0,0 +1,14 @@ +{ + "@graph" : [ { + "@id" : "http://example.com/canvas-1", + "@type" : "http://example.com" + }, { + "@id" : "http://example.com/element", + "http://example.com" : { + "@list" : [ { + "@id" : "http://example.com/canvas-1", + "@type" : "http://example.com" + } ] + } + } ] +} From 54e2a288c09f8c32e601c92959a97463d69578a1 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Tue, 22 Aug 2017 10:46:58 +0200 Subject: [PATCH 266/440] start handling @requireAll --- .../com/github/jsonldjava/core/JsonLdApi.java | 21 +++++++++++++++---- .../github/jsonldjava/core/JsonLdConsts.java | 1 + .../github/jsonldjava/core/JsonLdOptions.java | 10 +++++++++ .../github/jsonldjava/core/JsonLdUtils.java | 2 +- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 9e6440af..ff818d68 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -776,6 +776,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { else if (frameExpansion && (JsonLdConsts.EXPLICIT.equals(expandedProperty) || JsonLdConsts.DEFAULT.equals(expandedProperty) || JsonLdConsts.EMBED.equals(expandedProperty) + || JsonLdConsts.REQUIRE_ALL.equals(expandedProperty) || JsonLdConsts.EMBED_CHILDREN.equals(expandedProperty) || JsonLdConsts.OMIT_DEFAULT.equals(expandedProperty))) { expandedValue = expand(activeCtx, expandedProperty, value); @@ -1287,11 +1288,13 @@ private class FramingContext { public boolean omitDefault; public Map uniqueEmbeds; public LinkedList subjectStack; + public boolean requireAll; public FramingContext() { embed = Embed.LAST; explicit = false; omitDefault = false; + requireAll = false; uniqueEmbeds = new HashMap<>(); subjectStack = new LinkedList<>(); } @@ -1307,6 +1310,9 @@ public FramingContext(JsonLdOptions opts) { if (opts.getOmitDefault() != null) { this.omitDefault = opts.getOmitDefault(); } + if (opts.getRequireAll() != null) { + this.requireAll = opts.getRequireAll(); + } } } @@ -1385,14 +1391,16 @@ private void frame(FramingContext state, Map nodes, Map flags = newMap(); flags.put(JsonLdConsts.EXPLICIT, explicitOn); flags.put(JsonLdConsts.EMBED, embed); + flags.put(JsonLdConsts.REQUIRE_ALL, requireAll); // 3. // Create a list of matched subjects by filtering subjects against frame // using the Frame Matching algorithm with state, subjects, frame, and requireAll. - final Map matches = filterNodes(state, nodes, frame); + final Map matches = filterNodes(state, nodes, frame, requireAll); final List ids = new ArrayList(matches.keySet()); Collections.sort(ids); @@ -1671,11 +1679,11 @@ private static void removeDependents(Map embeds, String id) { } private Map filterNodes(FramingContext state, Map nodes, - Map frame) throws JsonLdError { + Map frame, boolean requireAll) throws JsonLdError { final Map rval = newMap(); for (final String id : nodes.keySet()) { final Map element = (Map) nodes.get(id); - if (element != null && filterNode(state, element, frame)) { + if (element != null && filterNode(state, element, frame, requireAll)) { rval.put(id, element); } } @@ -1683,7 +1691,7 @@ private Map filterNodes(FramingContext state, Map node, - Map frame) throws JsonLdError { + Map frame, boolean requireAll) throws JsonLdError { final Object types = frame.get(JsonLdConsts.TYPE); final Object frameIds = frame.get(JsonLdConsts.ID); // https://json-ld.org/spec/latest/json-ld-framing/#frame-matching @@ -1715,6 +1723,11 @@ else if (!(frameIds instanceof List)) { return false; } // 2. Node matches if frame has no non-keyword properties.TODO + // 3. If requireAll is true, node matches if all non-keyword properties + // (property) in frame match any of the following conditions. Or, if + // requireAll is false, if any of the non-keyword properties (property) + // in frame match any of the following conditions. For the values of each + // property from frame in node: // 3.1 If property is @type: if (types != null) { if (!(types instanceof List)) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java index e55deabd..c692327a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java @@ -57,6 +57,7 @@ public final class JsonLdConsts { public static final String BLANK_NODE_PREFIX = "_:"; public static final String VOCAB = "@vocab"; public static final String BASE = "@base"; + public static final String REQUIRE_ALL = "@requireAll"; public enum Embed { ALWAYS, NEVER, LAST, LINK; } } \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 962ef0b6..6f82bb91 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -67,6 +67,7 @@ public JsonLdOptions(String base) { private Boolean explicit = null; private Boolean omitDefault = null; private Boolean pruneBlankNodeIdentifiers = true; + private Boolean requireAll = false; // RDF conversion options : // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm @@ -138,6 +139,14 @@ public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; } + public Boolean getRequireAll() { + return this.requireAll; + } + + public void setRequireAll(Boolean requireAll) { + this.requireAll = requireAll; + } + public Boolean getCompactArrays() { return compactArrays; } @@ -207,4 +216,5 @@ public void setDocumentLoader(DocumentLoader documentLoader) { public String format = null; public Boolean useNamespaces = false; public String outputForm = null; + } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 73190644..eb9c5b4a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -37,7 +37,7 @@ static boolean isKeyword(Object key) { || "@graph".equals(key) || "@id".equals(key) || "@index".equals(key) || "@language".equals(key) || "@list".equals(key) || "@omitDefault".equals(key) || "@reverse".equals(key) || "@preserve".equals(key) || "@set".equals(key) - || "@type".equals(key) || "@value".equals(key) || "@vocab".equals(key); + || "@type".equals(key) || "@value".equals(key) || "@vocab".equals(key) || "@requireAll".equals(key); } public static Boolean deepCompare(Object v1, Object v2, Boolean listOrderMatters) { From 227461cd2f56b32faa48b7718f43ee07761a1051 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Wed, 23 Aug 2017 15:27:44 +0200 Subject: [PATCH 267/440] address comments --- .../jsonldjava/core/JsonLdFramingTest.java | 16 ++++++++++++ .../resources/custom/frame-0007-frame.jsonld | 12 +++++++++ .../resources/custom/frame-0007-in.jsonld | 24 +++++++++++++++++ .../resources/custom/frame-0007-out.jsonld | 26 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 core/src/test/resources/custom/frame-0007-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0007-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0007-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 2825f26a..96ac2ba6 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -107,4 +107,20 @@ public void testFrame0006() throws IOException, JsonLdError { .fromInputStream(getClass().getResourceAsStream("/custom/frame-0006-out.jsonld")); assertEquals(out, frame2); } + + @Test + public void testFrame0007() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0007-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0007-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setCompactArrays(true); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0007-out.jsonld")); + assertEquals(out, frame2); + } } diff --git a/core/src/test/resources/custom/frame-0007-frame.jsonld b/core/src/test/resources/custom/frame-0007-frame.jsonld new file mode 100644 index 00000000..1f6d39e7 --- /dev/null +++ b/core/src/test/resources/custom/frame-0007-frame.jsonld @@ -0,0 +1,12 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@type": "ex:Library", + "ex:contains": { + "@explicit":true, + "dc:title":{"@default":"Title missing"}, + "dc:creator":{} + } +} \ No newline at end of file diff --git a/core/src/test/resources/custom/frame-0007-in.jsonld b/core/src/test/resources/custom/frame-0007-in.jsonld new file mode 100644 index 00000000..c10df848 --- /dev/null +++ b/core/src/test/resources/custom/frame-0007-in.jsonld @@ -0,0 +1,24 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@graph": [ + { + "@id": "http://example.org/library", + "@type": "ex:Library", + "ex:contains": [{"@id":"http://example.org/library/the-republic#introduction"},{"@id":"http://example.org/library/the-republic"}] + }, + { + "@id": "http://example.org/library/the-republic", + "@type": "ex:Book", + "dc:creator": "Plato", + "dc:title": "The Republic" + }, + { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Book", + "dc:creator": "Plato" + } + ] +} diff --git a/core/src/test/resources/custom/frame-0007-out.jsonld b/core/src/test/resources/custom/frame-0007-out.jsonld new file mode 100644 index 00000000..42836207 --- /dev/null +++ b/core/src/test/resources/custom/frame-0007-out.jsonld @@ -0,0 +1,26 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@graph": [ + { + "@id": "http://example.org/library", + "@type": "ex:Library", + "ex:contains": [ + { + "@id": "http://example.org/library/the-republic#introduction", + "@type": "ex:Book", + "dc:creator": "Plato", + "dc:title": "Title missing" + }, + { + "@id": "http://example.org/library/the-republic", + "@type": "ex:Book", + "dc:creator": "Plato", + "dc:title": "The Republic" + } + ] + } + ] +} \ No newline at end of file From 6f573d84dba570c6be20765963e16910e27bacf1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Aug 2017 09:02:17 +1000 Subject: [PATCH 268/440] Fix javadoc issue Signed-off-by: Peter Ansell --- core/src/main/java/com/github/jsonldjava/core/Context.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index c8919a73..2f15dbf5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -799,7 +799,7 @@ else if (((Map) value).containsKey(JsonLdConsts.TYPE)) { return iri; } - /** + /* * This method is only visible for testing. */ public static String _iriCompactionStep5point4(String iri, Object value, String compactIRI, From 230cd0fd014889ea432443c1247567050320c652 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Aug 2017 09:24:47 +1000 Subject: [PATCH 269/440] Bump some plugin versions to latest and prepare for release Signed-off-by: Peter Ansell --- README.md | 5 ++++- core/pom.xml | 4 ---- pom.xml | 56 ++++------------------------------------------------ 3 files changed, 8 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 13df4a86..1ac8fdf0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.10.0 + 0.11.0 Code example @@ -449,6 +449,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-08-24 +* Release 0.11.0 + ### 2017-08-22 * Add implicit "flag only" subframe to fix incomplete list recursion (Patch by @christopher-johnson) * Support pruneBlankNodeIdentifiers framing option in 1.1 mode (Patch by @fsteeg and @eroux) diff --git a/core/pom.xml b/core/pom.xml index 17b9240a..65f64409 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -89,10 +89,6 @@ org.jacoco jacoco-maven-plugin - - com.github.siom79.japicmp - japicmp-maven-plugin - diff --git a/pom.xml b/pom.xml index 741c880f..244625f2 100755 --- a/pom.xml +++ b/pom.xml @@ -260,7 +260,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.6.1 + 3.6.2 1.8 1.8 @@ -335,7 +335,7 @@ org.codehaus.mojo animal-sniffer-maven-plugin - 1.15 + 1.16 check-jdk-compliance @@ -413,36 +413,6 @@ - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.jacoco - - jacoco-maven-plugin - - - [0.7.2.201409121644,) - - - prepare-agent - - - - - - - - - - @@ -483,7 +453,7 @@ org.apache.maven.plugins maven-source-plugin - 2.4 + 3.0.1 attach-sources @@ -496,7 +466,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.3 + 3.0.0-M1 attach-javadocs @@ -523,24 +493,6 @@ - - ide - - false - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.testSource} - ${maven.compiler.testTarget} - - - - - From 8f9f890b209134501b4a87c34bf25e25f8903fe8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Aug 2017 09:25:22 +1000 Subject: [PATCH 270/440] Release 0.11.0 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 65f64409..167ac90b 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.11.0-SNAPSHOT + 0.11.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 244625f2..c766d8a5 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.11.0-SNAPSHOT + 0.11.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From 494dd5313c7d47d2dd4e1c7ed84be0c7d36cb4a3 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Aug 2017 09:36:57 +1000 Subject: [PATCH 271/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 167ac90b..af38443c 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.11.0 + 0.11.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index c766d8a5..284bf35e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.11.0 + 0.11.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 8b392302eff7551508a89555681c8b4f297fc4b8 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 25 Aug 2017 17:41:31 +0200 Subject: [PATCH 272/440] Fix "switch" fallthrough bug in JsonLdOptions --- .../main/java/com/github/jsonldjava/core/JsonLdOptions.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 6f82bb91..9dd5ad3f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -101,12 +101,16 @@ public void setEmbed(String embed) throws JsonLdError { switch (embed) { case "@always": this.embed = Embed.ALWAYS; + break; case "@never": this.embed = Embed.NEVER; + break; case "@last": this.embed = Embed.LAST; + break; case "@link": this.embed = Embed.LINK; + break; default: throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); } From e5af222f5242150dcf4e48e2f5cc6fd246b07814 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 25 Aug 2017 17:25:42 +0200 Subject: [PATCH 273/440] Provide a test for frames using @embed:@always This complements 4fe56fd4edcf943782879023483284ab8ad08c65 and shows that #150 is indeed resolved. --- .../jsonldjava/core/JsonLdFramingTest.java | 17 ++++++++++++++++ .../resources/custom/frame-0008-frame.jsonld | 7 +++++++ .../resources/custom/frame-0008-in.jsonld | 20 +++++++++++++++++++ .../resources/custom/frame-0008-out.jsonld | 20 +++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 core/src/test/resources/custom/frame-0008-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0008-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0008-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 96ac2ba6..29201791 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -123,4 +123,21 @@ public void testFrame0007() throws IOException, JsonLdError { .fromInputStream(getClass().getResourceAsStream("/custom/frame-0007-out.jsonld")); assertEquals(out, frame2); } + + @Test + public void testFrame0008() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0008-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0008-in.jsonld")); + + JsonLdOptions opts = new JsonLdOptions(); + opts.setEmbed("@always"); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0008-out.jsonld")); + assertEquals(out, frame2); + } } + diff --git a/core/src/test/resources/custom/frame-0008-frame.jsonld b/core/src/test/resources/custom/frame-0008-frame.jsonld new file mode 100644 index 00000000..16d05498 --- /dev/null +++ b/core/src/test/resources/custom/frame-0008-frame.jsonld @@ -0,0 +1,7 @@ +{ + "@context": { + "dct": "http://purl.org/dc/terms/", + "ex": "http://example.org/vocab#" + }, + "@type": "ex:Biography" +} diff --git a/core/src/test/resources/custom/frame-0008-in.jsonld b/core/src/test/resources/custom/frame-0008-in.jsonld new file mode 100644 index 00000000..75eef110 --- /dev/null +++ b/core/src/test/resources/custom/frame-0008-in.jsonld @@ -0,0 +1,20 @@ +{ + "@context": { + "dct": "http://purl.org/dc/terms/", + "ex": "http://example.org/vocab#" + }, + "@graph": [ + { + "@id": "http://lobid.org/resources/HT019277879", + "@type": "ex:Biography", + "dct:creator": { + "@id" : "https://www.wikidata.org/entity/Q115211", + "ex:name": "Harry Rowohlt" + }, + "dct:subject": { + "@id" : "https://www.wikidata.org/entity/Q115211", + "ex:name": "Harry Rowohlt" + } + } + ] +} diff --git a/core/src/test/resources/custom/frame-0008-out.jsonld b/core/src/test/resources/custom/frame-0008-out.jsonld new file mode 100644 index 00000000..75eef110 --- /dev/null +++ b/core/src/test/resources/custom/frame-0008-out.jsonld @@ -0,0 +1,20 @@ +{ + "@context": { + "dct": "http://purl.org/dc/terms/", + "ex": "http://example.org/vocab#" + }, + "@graph": [ + { + "@id": "http://lobid.org/resources/HT019277879", + "@type": "ex:Biography", + "dct:creator": { + "@id" : "https://www.wikidata.org/entity/Q115211", + "ex:name": "Harry Rowohlt" + }, + "dct:subject": { + "@id" : "https://www.wikidata.org/entity/Q115211", + "ex:name": "Harry Rowohlt" + } + } + ] +} From d8a5e54f8e818da6d4f82c6c0f4ac98097fc40f0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 26 Aug 2017 10:29:25 +1000 Subject: [PATCH 274/440] Release 0.11.1 Signed-off-by: Peter Ansell --- README.md | 4 ++++ core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1ac8fdf0..d764ff83 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-08-26 +* Release 0.11.1 +* Fix @embed:@always support (Patch by @dr0i) + ### 2017-08-24 * Release 0.11.0 diff --git a/core/pom.xml b/core/pom.xml index af38443c..912a42cf 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.11.1-SNAPSHOT + 0.11.1 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 284bf35e..fcdf8397 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.11.1-SNAPSHOT + 0.11.1 JSONLD Java :: Parent Json-LD Java Parent POM pom From 163288d43dbb2736746ce697d34d3d48a32418e2 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 26 Aug 2017 10:36:36 +1000 Subject: [PATCH 275/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 912a42cf..74c531ee 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.11.1 + 0.11.2-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index fcdf8397..c43c9646 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.11.1 + 0.11.2-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 099d8a8b9471c2d0160c9f263d747242ef19f237 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 11 Oct 2017 08:42:55 +1100 Subject: [PATCH 276/440] Update maven version in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d764ff83..aa79c7b3 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.11.0 + 0.11.1 Code example From 52820996af708dc674edcc9651212c0a2a00488e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 23 Oct 2017 09:39:10 +1100 Subject: [PATCH 277/440] Re-enable japicmp plugin Signed-off-by: Peter Ansell --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index c43c9646..999c6210 100755 --- a/pom.xml +++ b/pom.xml @@ -40,12 +40,12 @@ UTF-8 4.5.3 - 4.4.6 - 2.9.0 + 4.4.8 + 2.9.1 4.12 1.7.25 - 0.10.0 + 0.11.0 @@ -185,17 +185,17 @@ commons-codec commons-codec - 1.10 + 1.11 org.mockito mockito-core - 2.8.47 + 2.11.0 commons-io commons-io - 2.5 + 2.6 @@ -260,7 +260,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.6.2 + 3.7.0 1.8 1.8 @@ -330,7 +330,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20 + 2.20.1 org.codehaus.mojo @@ -353,10 +353,10 @@ - + org.codehaus.mojo appassembler-maven-plugin From dd2f4ce0151f727a86853aedd7e03aa43bcf08ab Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 23 Oct 2017 11:10:50 +1100 Subject: [PATCH 278/440] Automated cleanup to get code to match defaults again Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/Context.java | 9 +- .../jsonldjava/core/DocumentLoader.java | 5 +- .../com/github/jsonldjava/core/JsonLdApi.java | 146 ++++++++-------- .../github/jsonldjava/core/JsonLdConsts.java | 4 +- .../github/jsonldjava/core/JsonLdOptions.java | 6 +- .../jsonldjava/core/JsonLdProcessor.java | 36 ++-- .../github/jsonldjava/core/JsonLdUtils.java | 28 ++-- .../jsonldjava/core/NormalizeUtils.java | 6 +- .../github/jsonldjava/core/RDFDataset.java | 8 +- .../jsonldjava/utils/JarCacheStorage.java | 2 +- .../github/jsonldjava/utils/JsonUtils.java | 24 ++- .../core/ContextCompactionTest.java | 2 - .../jsonldjava/core/DocumentLoaderTest.java | 13 +- .../jsonldjava/core/JsonLdFramingTest.java | 17 +- .../core/JsonLdPerformanceTest.java | 5 +- .../jsonldjava/core/JsonLdProcessorTest.java | 9 +- .../jsonldjava/core/NodeCompareTest.java | 156 +++++++++--------- .../jsonldjava/core/QuadCompareTest.java | 36 ++-- .../jsonldjava/utils/JsonUtilsTest.java | 13 +- 19 files changed, 278 insertions(+), 247 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 2f15dbf5..79f70b47 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -826,11 +826,10 @@ public static String _iriCompactionStep5point4(String iri, Object value, String * ":". * * @param onlyCommonPrefixes - * If true, the result will not include - * "not so useful" prefixes, such as "term1": - * "http://example.com/term1", e.g. all IRIs will end with "/" or - * "#". If false, all potential prefixes are - * returned. + * If true, the result will not include "not so + * useful" prefixes, such as "term1": "http://example.com/term1", + * e.g. all IRIs will end with "/" or "#". If false, + * all potential prefixes are returned. * * @return A map from prefix string to IRI string */ diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 656bf588..787dbe6f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -10,7 +10,7 @@ public class DocumentLoader { - private Map m_injectedDocs = new HashMap<>(); + private final Map m_injectedDocs = new HashMap<>(); /** * Identifies a system property that can be set to "true" in order to @@ -42,7 +42,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { final String disallowRemote = System .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); if ("true".equalsIgnoreCase(disallowRemote)) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, "Remote context loading has been disallowed (url was " + url + ")"); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, + "Remote context loading has been disallowed (url was " + url + ")"); } try { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index ff818d68..6c1665ee 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -17,11 +17,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -508,7 +505,8 @@ public Object compact(Context activeCtx, String activeProperty, Object element) */ public Object expand(Context activeCtx, String activeProperty, Object element) throws JsonLdError { - boolean frameExpansion = this.opts.getProcessingMode().equals(JsonLdOptions.JSON_LD_1_1_FRAME); + final boolean frameExpansion = this.opts.getProcessingMode() + .equals(JsonLdOptions.JSON_LD_1_1_FRAME); // 1) if (element == null) { return null; @@ -585,8 +583,7 @@ else if (element instanceof Map) { if (value instanceof String) { expandedValue = activeCtx.expandIri((String) value, true, false, null, null); - } - else if (frameExpansion) { + } else if (frameExpansion) { if (value instanceof Map) { if (((Map) value).size() != 0) { throw new JsonLdError(Error.INVALID_ID_VALUE, @@ -600,16 +597,14 @@ else if (frameExpansion) { throw new JsonLdError(Error.INVALID_ID_VALUE, "@id value must be a string, an array of strings or an empty dictionary"); } - ((List) expandedValue).add( - activeCtx.expandIri((String) v, true, true, null, null)); + ((List) expandedValue).add(activeCtx + .expandIri((String) v, true, true, null, null)); } - } - else { + } else { throw new JsonLdError(Error.INVALID_ID_VALUE, "value of @id must be a string, an array of strings or an empty dictionary"); } - } - else { + } else { throw new JsonLdError(Error.INVALID_ID_VALUE, "value of @id must be a string"); } @@ -1319,7 +1314,7 @@ public FramingContext(JsonLdOptions opts) { private class EmbedNode { public Object parent = null; public String property = null; - + public EmbedNode(Object parent, String property) { this.parent = parent; this.property = property; @@ -1353,7 +1348,8 @@ public List frame(Object input, List frame) throws JsonLdError { // NOTE: frame validation is done by the function not allowing anything // other than list to me passed // 1. - // If frame is an array, set frame to the first member of the array, which MUST be a valid frame. + // If frame is an array, set frame to the first member of the array, + // which MUST be a valid frame. frame(state, this.nodeMap, (frame != null && frame.size() > 0 ? (Map) frame.get(0) : newMap()), framed, null); @@ -1364,7 +1360,7 @@ public List frame(Object input, List frame) throws JsonLdError { private boolean createsCircularReference(String id, FramingContext state) { return state.subjectStack.contains(id); } - + /** * Frames subjects according to the given frame. * @@ -1381,15 +1377,17 @@ private boolean createsCircularReference(String id, FramingContext state) { */ private void frame(FramingContext state, Map nodes, Map frame, Object parent, String property) throws JsonLdError { - + // https://json-ld.org/spec/latest/json-ld-framing/#framing-algorithm // 2. - // Initialize flags embed, explicit, and requireAll from object embed flag, - // explicit inclusion flag, and require all flag in state overriding from + // Initialize flags embed, explicit, and requireAll from object embed + // flag, + // explicit inclusion flag, and require all flag in state overriding + // from // any property values for @embed, @explicit, and @requireAll in frame. // TODO: handle @requireAll - Embed embed = getFrameEmbed(frame, state.embed); + final Embed embed = getFrameEmbed(frame, state.embed); final Boolean explicitOn = getFrameFlag(frame, JsonLdConsts.EXPLICIT, state.explicit); final Boolean requireAll = getFrameFlag(frame, JsonLdConsts.REQUIRE_ALL, state.requireAll); final Map flags = newMap(); @@ -1399,50 +1397,59 @@ private void frame(FramingContext state, Map nodes, Map matches = filterNodes(state, nodes, frame, requireAll); final List ids = new ArrayList(matches.keySet()); Collections.sort(ids); - + // 4. - // Set link the the value of link in state associated with graph name in state, + // Set link the the value of link in state associated with graph name in + // state, // creating a new empty dictionary, if necessary. - Map link = state.uniqueEmbeds; - + final Map link = state.uniqueEmbeds; + // 5. - // For each id and associated node object node from the set of matched subjects, ordered by id: + // For each id and associated node object node from the set of matched + // subjects, ordered by id: for (final String id : ids) { final Map subject = (Map) matches.get(id); // 5.1 - // Initialize output to a new dictionary with @id and id and add output to link associated with id. + // Initialize output to a new dictionary with @id and id and add + // output to link associated with id. final Map output = newMap(); output.put(JsonLdConsts.ID, id); // 5.2 - // If embed is @link and id is in link, node already exists in results. - // Add the associated node object from link to parent and do not perform + // If embed is @link and id is in link, node already exists in + // results. + // Add the associated node object from link to parent and do not + // perform // additional processing for this node. if (embed == Embed.LINK && state.uniqueEmbeds.containsKey(id)) { addFrameOutput(state, parent, property, state.uniqueEmbeds.get(id)); continue; } - + // Occurs only at top level, compartmentalize each top-level match - if(property == null) { + if (property == null) { state.uniqueEmbeds = new HashMap<>(); } - + // 5.3 - // Otherwise, if embed is @never or if a circular reference would be created by an embed, - // add output to parent and do not perform additional processing for this node. + // Otherwise, if embed is @never or if a circular reference would be + // created by an embed, + // add output to parent and do not perform additional processing for + // this node. if (embed == Embed.NEVER || createsCircularReference(id, state)) { addFrameOutput(state, parent, property, output); continue; } // 5.4 - // Otherwise, if embed is @last, remove any existing embedded node from parent associated + // Otherwise, if embed is @last, remove any existing embedded node + // from parent associated // with graph name in state. Requires sorting of subjects. if (embed == Embed.LAST) { if (state.uniqueEmbeds.containsKey(id)) { @@ -1450,27 +1457,30 @@ private void frame(FramingContext state, Map nodes, Map element = (Map) matches.get(id); List props = new ArrayList(element.keySet()); Collections.sort(props); for (final String prop : props) { - // 5.5.2.1 If property is a keyword, add property and objects to output. + // 5.5.2.1 If property is a keyword, add property and objects to + // output. if (isKeyword(prop)) { output.put(prop, JsonLdUtils.clone(element.get(prop))); continue; } - // 5.5.2.2 Otherwise, if property is not in frame, and explicit is true, processors - // MUST NOT add any values for property to output, and the following steps are skipped. + // 5.5.2.2 Otherwise, if property is not in frame, and explicit + // is true, processors + // MUST NOT add any values for property to output, and the + // following steps are skipped. if (explicitOn && !frame.containsKey(prop)) { continue; } @@ -1478,7 +1488,7 @@ private void frame(FramingContext state, Map nodes, Map value = (List) element.get(prop); - // 5.5.2.3 For each item in objects: + // 5.5.2.3 For each item in objects: for (final Object item : value) { if ((item instanceof Map) && ((Map) item).containsKey(JsonLdConsts.LIST)) { @@ -1500,7 +1510,8 @@ private void frame(FramingContext state, Map nodes, Map subframe; if (frame.containsKey(prop)) { - subframe = (Map) ((List) frame.get(prop)).get(0); + subframe = (Map) ((List) frame + .get(prop)).get(0); } else { subframe = flags; } @@ -1523,7 +1534,8 @@ else if (JsonLdUtils.isNodeReference(item)) { tmp.put(itemid, this.nodeMap.get(itemid)); Map subframe; if (frame.containsKey(prop)) { - subframe = (Map) ((List) frame.get(prop)).get(0); + subframe = (Map) ((List) frame.get(prop)) + .get(0); } else { subframe = flags; } @@ -1546,13 +1558,13 @@ else if (JsonLdUtils.isNodeReference(item)) { } final List pf = (List) frame.get(prop); - Map propertyFrame = pf.size() > 0 - ? (Map) pf.get(0) : null; + Map propertyFrame = pf.size() > 0 ? (Map) pf.get(0) + : null; if (propertyFrame == null) { propertyFrame = newMap(); } - final boolean omitDefaultOn = getFrameFlag(propertyFrame, - JsonLdConsts.OMIT_DEFAULT, state.omitDefault); + final boolean omitDefaultOn = getFrameFlag(propertyFrame, JsonLdConsts.OMIT_DEFAULT, + state.omitDefault); if (!omitDefaultOn && !output.containsKey(prop)) { Object def = "@null"; if (propertyFrame.containsKey(JsonLdConsts.DEFAULT)) { @@ -1572,7 +1584,7 @@ else if (JsonLdUtils.isNodeReference(item)) { // add output to parent addFrameOutput(state, parent, property, output); - + state.subjectStack.pop(); } } @@ -1591,7 +1603,7 @@ private Object getFrameValue(Map frame, String name) { } private Boolean getFrameFlag(Map frame, String name, boolean thedefault) { - Object value = getFrameValue(frame, name); + final Object value = getFrameValue(frame, name); if (value instanceof Boolean) { return (Boolean) value; } @@ -1599,9 +1611,10 @@ private Boolean getFrameFlag(Map frame, String name, boolean the } private Embed getFrameEmbed(Map frame, Embed thedefault) throws JsonLdError { - Object value = getFrameValue(frame, JsonLdConsts.EMBED); - if (value == null) + final Object value = getFrameValue(frame, JsonLdConsts.EMBED); + if (value == null) { return thedefault; + } if (value instanceof Boolean) { return (Boolean) value ? Embed.LAST : Embed.NEVER; } @@ -1700,20 +1713,20 @@ private boolean filterNode(FramingContext state, Map node, // blank node in the @id property in frame. if (frameIds != null) { if (frameIds instanceof String) { - Object nodeId = node.get(JsonLdConsts.ID); - if (nodeId == null) + final Object nodeId = node.get(JsonLdConsts.ID); + if (nodeId == null) { return false; + } if (JsonLdUtils.deepCompare(nodeId, frameIds)) { return true; } - } - else if (!(frameIds instanceof List)) { + } else if (!(frameIds instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "frame @id must be an array"); - } - else { - Object nodeId = node.get(JsonLdConsts.ID); - if (nodeId == null) + } else { + final Object nodeId = node.get(JsonLdConsts.ID); + if (nodeId == null) { return false; + } for (final Object j : (List) frameIds) { if (JsonLdUtils.deepCompare(nodeId, j)) { return true; @@ -1726,9 +1739,10 @@ else if (!(frameIds instanceof List)) { // 3. If requireAll is true, node matches if all non-keyword properties // (property) in frame match any of the following conditions. Or, if // requireAll is false, if any of the non-keyword properties (property) - // in frame match any of the following conditions. For the values of each - // property from frame in node: - // 3.1 If property is @type: + // in frame match any of the following conditions. For the values of + // each + // property from frame in node: + // 3.1 If property is @type: if (types != null) { if (!(types instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "frame @type must be an array"); @@ -1739,7 +1753,8 @@ else if (!(frameIds instanceof List)) { } else if (!(nodeTypes instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "node @type must be an array"); } - // 3.1.1 Property matches if the @type property in frame includes any IRI in values. + // 3.1.1 Property matches if the @type property in frame includes + // any IRI in values. for (final Object i : (List) nodeTypes) { for (final Object j : (List) types) { if (JsonLdUtils.deepCompare(i, j)) { @@ -1748,7 +1763,8 @@ else if (!(frameIds instanceof List)) { } } // TODO: 3.1.2 - // 3.1.3 Otherwise, property matches if values is empty and the @type property in frame is match none. + // 3.1.3 Otherwise, property matches if values is empty and the + // @type property in frame is match none. if (((List) types).size() == 1 && ((List) types).get(0) instanceof Map && ((Map) ((List) types).get(0)).size() == 0) { return !((List) nodeTypes).isEmpty(); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java index c692327a..9de5b76b 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java @@ -59,5 +59,7 @@ public final class JsonLdConsts { public static final String BASE = "@base"; public static final String REQUIRE_ALL = "@requireAll"; - public enum Embed { ALWAYS, NEVER, LAST, LINK; } + public enum Embed { + ALWAYS, NEVER, LAST, LINK; + } } \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 9dd5ad3f..c48f676c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -15,12 +15,12 @@ public class JsonLdOptions { public static final String JSON_LD_1_0 = "json-ld-1.0"; public static final String JSON_LD_1_1 = "json-ld-1.1"; - + public static final String JSON_LD_1_1_FRAME = "json-ld-1.1-expand-frame"; public static final boolean DEFAULT_COMPACT_ARRAYS = true; - /** + /** * Constructs an instance of JsonLdOptions using an empty base. */ public JsonLdOptions() { @@ -137,7 +137,7 @@ public Boolean getPruneBlankNodeIdentifiers() { } public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { - if(pruneBlankNodeIdentifiers) { + if (pruneBlankNodeIdentifiers) { setProcessingMode(JSON_LD_1_1); } this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 208f9402..30c632bd 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -5,14 +5,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.Map.Entry; import java.util.stream.Collectors; -import java.util.stream.Stream; import com.github.jsonldjava.core.JsonLdError.Error; import com.github.jsonldjava.impl.NQuadRDFParser; @@ -308,20 +305,24 @@ public static Map frame(Object input, Object frame, JsonLdOption } // TODO string/IO input - // 2. Set expanded input to the result of using the expand method using input and options. + // 2. Set expanded input to the result of using the expand method using + // input and options. final Object expandedInput = expand(input, opts); - - // 3. Set expanded frame to the result of using the expand method using frame and options - // with expandContext set to null and processingMode set to json-ld-1.1-expand-frame. - String savedProcessingMode = opts.getProcessingMode(); - Object savedExpandedContext = opts.getExpandContext(); + + // 3. Set expanded frame to the result of using the expand method using + // frame and options + // with expandContext set to null and processingMode set to + // json-ld-1.1-expand-frame. + final String savedProcessingMode = opts.getProcessingMode(); + final Object savedExpandedContext = opts.getExpandContext(); opts.setProcessingMode(JsonLdOptions.JSON_LD_1_1_FRAME); opts.setExpandContext(null); final List expandedFrame = expand(frame, opts); opts.setProcessingMode(savedProcessingMode); opts.setExpandContext(savedExpandedContext); - // 4. Set context to the value of @context from frame, if it exists, or to a new empty + // 4. Set context to the value of @context from frame, if it exists, or + // to a new empty // context, otherwise. final JsonLdApi api = new JsonLdApi(expandedInput, opts); final Context activeCtx = api.context @@ -338,23 +339,26 @@ public static Map frame(Object input, Object frame, JsonLdOption final Map rval = activeCtx.serialize(); rval.put(alias, compacted); - Set toPrune = opts.getPruneBlankNodeIdentifiers() ? blankNodeIdsToPrune(rval) : Collections.emptySet(); + final Set toPrune = opts.getPruneBlankNodeIdentifiers() ? blankNodeIdsToPrune(rval) + : Collections.emptySet(); JsonLdUtils.removePreserveAndPrune(activeCtx, rval, opts, toPrune); return rval; } private static Set blankNodeIdsToPrune(final Map rval) { - return countBlankNodeIds(rval, new HashMap<>()).entrySet().stream().filter(e -> e.getValue() == 1) - .map(e -> e.getKey()).collect(Collectors.toSet()); + return countBlankNodeIds(rval, new HashMap<>()).entrySet().stream() + .filter(e -> e.getValue() == 1).map(e -> e.getKey()).collect(Collectors.toSet()); } - private static Map countBlankNodeIds(Object input, Map frequencies) { + private static Map countBlankNodeIds(Object input, + Map frequencies) { if (input instanceof List) { ((List) input).forEach(e -> countBlankNodeIds(e, frequencies)); } else if (input instanceof Map) { - ((Map) input).entrySet().forEach(e -> countBlankNodeIds(e.getValue(), frequencies)); + ((Map) input).entrySet() + .forEach(e -> countBlankNodeIds(e.getValue(), frequencies)); } else if (input instanceof String) { - String p = (String) input; + final String p = (String) input; if (p.startsWith("_:")) { frequencies.put(p, frequencies.containsKey(p) ? frequencies.get(p) + 1 : 1); } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index eb9c5b4a..5c6968d0 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -1,17 +1,11 @@ package com.github.jsonldjava.core; -import static com.github.jsonldjava.utils.Obj.newMap; - import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import com.github.jsonldjava.utils.JsonLdUrl; import com.github.jsonldjava.utils.Obj; public class JsonLdUtils { @@ -37,7 +31,8 @@ static boolean isKeyword(Object key) { || "@graph".equals(key) || "@id".equals(key) || "@index".equals(key) || "@language".equals(key) || "@list".equals(key) || "@omitDefault".equals(key) || "@reverse".equals(key) || "@preserve".equals(key) || "@set".equals(key) - || "@type".equals(key) || "@value".equals(key) || "@vocab".equals(key) || "@requireAll".equals(key); + || "@type".equals(key) || "@value".equals(key) || "@vocab".equals(key) + || "@requireAll".equals(key); } public static Boolean deepCompare(Object v1, Object v2, Boolean listOrderMatters) { @@ -189,20 +184,23 @@ public static boolean isRelativeIri(String value) { } /** - * Removes the @preserve keywords and blank node IDs to prune as the last step of the framing algorithm. + * Removes the @preserve keywords and blank node IDs to prune as the last + * step of the framing algorithm. * * @param ctx * the active context used to compact the input. * @param input * the framed, compacted output. - * @param toPrune The blank node IDs to prune. + * @param toPrune + * The blank node IDs to prune. * @param options * the compaction options used. * * @return the resulting output. * @throws JsonLdError */ - static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions opts, Set toPrune) throws JsonLdError { + static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions opts, + Set toPrune) throws JsonLdError { // recurse through arrays if (isArray(input)) { final List output = new ArrayList(); @@ -230,20 +228,22 @@ static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions op // recurse through @lists if (isList(input)) { - ((Map) input).put("@list", - removePreserveAndPrune(ctx, ((Map) input).get("@list"), opts, toPrune)); + ((Map) input).put("@list", removePreserveAndPrune(ctx, + ((Map) input).get("@list"), opts, toPrune)); return input; } // recurse through properties for (final String prop : new LinkedHashSet<>(((Map) input).keySet())) { - Object result = removePreserveAndPrune(ctx, ((Map) input).get(prop), opts, toPrune); + Object result = removePreserveAndPrune(ctx, ((Map) input).get(prop), + opts, toPrune); final String container = ctx.getContainer(prop); if (opts.getCompactArrays() && isArray(result) && ((List) result).size() == 1 && container == null) { result = ((List) result).get(0); } - if(ctx.expandIri(prop, false, false, null, null).equals(JsonLdConsts.ID) && toPrune.contains(result)) { + if (ctx.expandIri(prop, false, false, null, null).equals(JsonLdConsts.ID) + && toPrune.contains(result)) { ((Map) input).remove(prop); } else { ((Map) input).put(prop, result); diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index 1c6df6d4..efb4154c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -435,10 +435,8 @@ private static String hashQuads(String id, Map bnodes, UniqueNam .get(id)).get("quads"); final List nquads = new ArrayList(); for (int i = 0; i < quads.size(); ++i) { - nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), - quads.get(i).get("name") != null - ? (String) ((Map) quads.get(i).get("name")).get("value") - : null, + nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), quads.get(i).get("name") != null + ? (String) ((Map) quads.get(i).get("name")).get("value") : null, id)); } // sort serialized quads diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 221090cc..04b72da9 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -159,7 +159,7 @@ public int compareTo(Node o) { return -1; // literals < blanknode < IRI } } - // NOTE: Literal will also need to compare + // NOTE: Literal will also need to compare // language and datatype return this.getValue().compareTo(o.getValue()); } @@ -280,7 +280,7 @@ private static int nullSafeCompare(Comparable a, Comparable b) { if (a == null && b == null) { return 0; } - if (a == null) { + if (a == null) { return 1; } if (b == null) { @@ -292,9 +292,9 @@ private static int nullSafeCompare(Comparable a, Comparable b) { @Override public int compareTo(Node o) { // NOTE: this will also compare getValue() early! - int nodeCompare = super.compareTo(o); + final int nodeCompare = super.compareTo(o); if (nodeCompare != 0) { - // null, different type or different value + // null, different type or different value return nodeCompare; } if (this.getLanguage() != null || o.getLanguage() != null) { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 6e520eae..c028640c 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -42,7 +42,7 @@ public class JarCacheStorage implements HttpCacheStorage { private final Logger log = LoggerFactory.getLogger(getClass()); private final CacheConfig cacheConfig; - + private ClassLoader classLoader; /** diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index a2c35165..7254de9c 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -32,6 +32,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.jsonldjava.core.DocumentLoader; import com.github.jsonldjava.core.JsonLdApi; import com.github.jsonldjava.core.JsonLdProcessor; @@ -47,8 +48,19 @@ public class JsonUtils { * An HTTP Accept header that prefers JSONLD. */ public static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; + + /** + * The user agent used by the default {@link CloseableHttpClient}. + * + * This will not be used if + * {@link DocumentLoader#setHttpClient(CloseableHttpClient)} is called with + * a custom client. + */ + public static final String JSONLD_JAVA_USER_AGENT = "JSONLD-Java"; + private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); private static final JsonFactory JSON_FACTORY = new JsonFactory(JSON_MAPPER); + private static volatile CloseableHttpClient DEFAULT_HTTP_CLIENT; static { @@ -123,8 +135,8 @@ public static Object fromReader(Reader reader) throws IOException { } /** - * Parses a JSON-LD document from the given {@link JsonParser} to an object that - * can be used as input for the {@link JsonLdApi} and + * Parses a JSON-LD document from the given {@link JsonParser} to an object + * that can be used as input for the {@link JsonLdApi} and * {@link JsonLdProcessor} methods. * * @param jp @@ -359,8 +371,8 @@ public static CloseableHttpClient getDefaultHttpClient() { private static CloseableHttpClient createDefaultHttpClient() { // Common CacheConfig for both the JarCacheStorage and the underlying // BasicHttpCacheStorage - final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) - .setMaxObjectSize(1024 * 128).build(); + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(500) + .setMaxObjectSize(1024 * 256).build(); final CloseableHttpClient result = CachingHttpClientBuilder.create() // allow caching @@ -369,10 +381,12 @@ private static CloseableHttpClient createDefaultHttpClient() { .setHttpCacheStorage(new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage(cacheConfig))) // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + // https://wayback.archive.org/web/20130901115452/http://hc.apache.org:80/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 .addInterceptorFirst(new RequestAcceptEncoding()) .addInterceptorFirst(new ResponseContentEncoding()) .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) + // User agent customisation + .setUserAgent(JSONLD_JAVA_USER_AGENT) // use system defaults for proxy etc. .useSystemProperties().build(); diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index fa664d10..252621e1 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -10,8 +10,6 @@ import org.junit.Test; -import com.github.jsonldjava.utils.JsonUtils; - public class ContextCompactionTest { // @Ignore("Disable until schema.org is fixed") diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 9c377dad..4e33b114 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -41,6 +41,7 @@ import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.util.EntityUtils; import org.junit.After; +import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -163,9 +164,10 @@ public void loadDocumentSchemaOrgDirect() throws Exception { assertFalse(((Map) context).isEmpty()); } + @Ignore("Caching failed without any apparent cause on the client side") @Test public void fromURLCache() throws Exception { - final URL url = new URL("http://json-ld.org/contexts/person.jsonld"); + final URL url = new URL("https://json-ld.org/contexts/person.jsonld"); JsonUtils.fromURL(url, documentLoader.getHttpClient()); // Now try to get it again and ensure it is @@ -368,14 +370,15 @@ public void testDisallowRemoteContexts() throws Exception { @Test public void injectContext() throws Exception { - final Object jsonObject = JsonUtils.fromString("{ \"@context\":\"http://nonexisting.example.com/thing\", \"pony\":5 }"); + final Object jsonObject = JsonUtils.fromString( + "{ \"@context\":\"http://nonexisting.example.com/thing\", \"pony\":5 }"); final JsonLdOptions options = new JsonLdOptions(); // Verify fails to find context by default try { JsonLdProcessor.expand(jsonObject, options); fail("Expected exception to occur"); - } catch (JsonLdError e) { + } catch (final JsonLdError e) { // Success } @@ -389,8 +392,8 @@ public void injectContext() throws Exception { final List expand = JsonLdProcessor.expand(jsonObject, options); // Verify result - Object v = ((Map) ((Map) ((List) ((Map) - expand.get(0)).get("http://nonexisting.example.com/thing/pony")).get(0))).get("@value"); + final Object v = ((Map) ((List) ((Map) expand + .get(0)).get("http://nonexisting.example.com/thing/pony")).get(0)).get("@value"); assertEquals(5, v); } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 29201791..3b67eed0 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -31,9 +31,9 @@ public void testFrame0002() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setCompactArrays(false); - final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); final Object out = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-out.jsonld")); @@ -49,7 +49,7 @@ public void testFrame0003() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setCompactArrays(false); opts.setProcessingMode("json-ld-1.1"); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); @@ -67,7 +67,7 @@ public void testFrame0004() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0004-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setCompactArrays(true); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); @@ -83,7 +83,7 @@ public void testFrame0005() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0005-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setCompactArrays(true); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); @@ -99,7 +99,7 @@ public void testFrame0006() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0006-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setCompactArrays(true); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); @@ -115,7 +115,7 @@ public void testFrame0007() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0007-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setCompactArrays(true); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); @@ -131,7 +131,7 @@ public void testFrame0008() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0008-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); opts.setEmbed("@always"); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); @@ -140,4 +140,3 @@ public void testFrame0008() throws IOException, JsonLdError { assertEquals(out, frame2); } } - diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 29945766..42c70b92 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -616,7 +616,7 @@ public final void duplicatedTriplesInAnRDFDataset() throws Exception { // System.out.println("Twice the same triple in RDFDataset:/n"); for (final Quad quad : inputRdf.getQuads("@default")) { - //System.out.println(quad); + // System.out.println(quad); } final JsonLdOptions options = new JsonLdOptions(); @@ -633,7 +633,8 @@ public final void duplicatedTriplesInAnRDFDataset() throws Exception { // System.out.println(jsonld); // System.out.println( - // "\nWouldn't be the case assuming there is no duplicated triple in RDFDataset:\n"); + // "\nWouldn't be the case assuming there is no duplicated triple in + // RDFDataset:\n"); fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf, true), inputRdf.getContext(), options); jsonld = JsonUtils.toPrettyString(fromRDF); diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index b61ea157..9ec91a31 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -243,7 +243,8 @@ public TestDocumentLoader(String base) { @Override public RemoteDocument loadDocument(String url) throws JsonLdError { if (url == null) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, "URL was null"); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, + "URL was null"); } if (url.contains(":")) { // check if the url is relative to the test base @@ -260,7 +261,8 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { } } // we can't load this remote document from the test suite - throw new JsonLdError(JsonLdError.Error.NOT_IMPLEMENTED, "URL scheme was not recognised: " + url); + throw new JsonLdError(JsonLdError.Error.NOT_IMPLEMENTED, + "URL scheme was not recognised: " + url); } public void setRedirectTo(String string) { @@ -420,7 +422,8 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { options.setProduceGeneralizedRdf((Boolean) test_opts.get("produceGeneralizedRdf")); } if (test_opts.containsKey("pruneBlankNodeIdentifiers")) { - options.setPruneBlankNodeIdentifiers((Boolean) test_opts.get("pruneBlankNodeIdentifiers")); + options.setPruneBlankNodeIdentifiers( + (Boolean) test_opts.get("pruneBlankNodeIdentifiers")); } if (test_opts.containsKey("redirectTo")) { testLoader.setRedirectTo((String) test_opts.get("redirectTo")); diff --git a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java index 8f2940c4..6b7e5b55 100644 --- a/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/NodeCompareTest.java @@ -26,15 +26,19 @@ public class NodeCompareTest { */ @Test public void ordered() throws Exception { - List expected = Arrays.asList( + final List expected = Arrays.asList( new Literal("1", JsonLdConsts.XSD_INTEGER, null), new Literal("10", JsonLdConsts.XSD_INTEGER, null), - new Literal("2", JsonLdConsts.XSD_INTEGER, null), // still ordered by string value - - new Literal("a", JsonLdConsts.RDF_LANGSTRING, "en"), - new Literal("a", JsonLdConsts.RDF_LANGSTRING, "fr"), - new Literal("a", null, null), // equivalent to xsd:string + new Literal("2", JsonLdConsts.XSD_INTEGER, null), // still + // ordered by + // string + // value + + new Literal("a", JsonLdConsts.RDF_LANGSTRING, "en"), + new Literal("a", JsonLdConsts.RDF_LANGSTRING, "fr"), new Literal("a", null, null), // equivalent + // to + // xsd:string new Literal("b", JsonLdConsts.XSD_STRING, null), new Literal("false", JsonLdConsts.XSD_BOOLEAN, null), new Literal("true", JsonLdConsts.XSD_BOOLEAN, null), @@ -42,124 +46,115 @@ public void ordered() throws Exception { new Literal("x", JsonLdConsts.XSD_STRING, null), new Literal("z", JsonLdConsts.RDF_LANGSTRING, "en"), - new Literal("z", JsonLdConsts.RDF_LANGSTRING, "fr"), - new Literal("z", null, null), - - new BlankNode("a"), - new BlankNode("f"), - new BlankNode("z"), - - new IRI("http://example.com/ex1"), - new IRI("http://example.com/ex2"), - new IRI("http://example.org/ex"), - new IRI("https://example.net/") - ); - - List shuffled = new ArrayList<>(expected); - Random rand = new Random(1337); // fixed seed + new Literal("z", JsonLdConsts.RDF_LANGSTRING, "fr"), new Literal("z", null, null), + + new BlankNode("a"), new BlankNode("f"), new BlankNode("z"), + + new IRI("http://example.com/ex1"), new IRI("http://example.com/ex2"), + new IRI("http://example.org/ex"), new IRI("https://example.net/")); + + final List shuffled = new ArrayList<>(expected); + final Random rand = new Random(1337); // fixed seed Collections.shuffle(shuffled, rand); - //System.out.println("Shuffled:"); - //shuffled.stream().forEach(System.out::println); + // System.out.println("Shuffled:"); + // shuffled.stream().forEach(System.out::println); assertNotEquals(expected, shuffled); Collections.sort(shuffled); - List sorted = shuffled; - //System.out.println("Now sorted:"); - //sorted.stream().forEach(System.out::println); + final List sorted = shuffled; + // System.out.println("Now sorted:"); + // sorted.stream().forEach(System.out::println); // Not so useful output from this - // assertEquals(expected, sorted); + // assertEquals(expected, sorted); // so we'll instead do: - for (int i=0; i quads = dataset.getQuads("http://example.com/g1"); - Quad q1 = quads.get(0); - Quad q2 = quads.get(1); + final RDFDataset dataset = new RDFDataset(); + dataset.addQuad("http://example.com/p", "http://example.com/p", "Same", null, null, + "http://example.com/g1"); + dataset.addQuad("http://example.com/p", "http://example.com/p", "Different", null, null, + "http://example.com/g1"); + final List quads = dataset.getQuads("http://example.com/g1"); + final Quad q1 = quads.get(0); + final Quad q2 = quads.get(1); assertNotEquals(q1, q2); assertNotEquals(0, q1.compareTo(q2)); assertNotEquals(0, q1.getObject().compareTo(q2.getObject())); @@ -167,8 +162,8 @@ public void literalsInDataset() throws Exception { @Test public void iriDifferentLiteral() throws Exception { - Node iri = new IRI("http://example.com/"); - Node literal = new Literal("http://example.com/", null, null); + final Node iri = new IRI("http://example.com/"); + final Node literal = new Literal("http://example.com/", null, null); assertNotEquals(iri, literal); assertNotEquals(0, iri.compareTo(literal)); assertNotEquals(0, literal.compareTo(iri)); @@ -176,37 +171,37 @@ public void iriDifferentLiteral() throws Exception { @Test public void iriDifferentNull() throws Exception { - Node iri = new IRI("http://example.com/"); + final Node iri = new IRI("http://example.com/"); assertNotEquals(0, iri.compareTo(null)); } @Test public void literalDifferentNull() throws Exception { - Node literal = new Literal("hello", null, null); + final Node literal = new Literal("hello", null, null); assertNotEquals(0, literal.compareTo(null)); - } - + } + @Test public void iriDifferentIri() throws Exception { - Node iri = new IRI("http://example.com/"); - Node other = new IRI("http://example.com/other"); + final Node iri = new IRI("http://example.com/"); + final Node other = new IRI("http://example.com/other"); assertNotEquals(iri, other); assertNotEquals(0, iri.compareTo(other)); } - + @Test public void iriSameIri() throws Exception { - Node iri = new IRI("http://example.com/same"); - Node same = new IRI("http://example.com/same"); + final Node iri = new IRI("http://example.com/same"); + final Node same = new IRI("http://example.com/same"); assertEquals(iri, same); assertEquals(0, iri.compareTo(same)); } - + @Test public void iriDifferentBlankNode() throws Exception { // We'll use a relative IRI to avoid :-issues - Node iri = new IRI("b1"); - Node bnode = new BlankNode("b1"); + final Node iri = new IRI("b1"); + final Node bnode = new BlankNode("b1"); assertNotEquals(iri, bnode); assertNotEquals(bnode, iri); assertNotEquals(0, iri.compareTo(bnode)); @@ -216,14 +211,13 @@ public void iriDifferentBlankNode() throws Exception { @Test public void literalDifferentBlankNode() throws Exception { // We'll use a relative IRI to avoid :-issues - Node literal = new Literal("b1", null, null); - Node bnode = new BlankNode("b1"); + final Node literal = new Literal("b1", null, null); + final Node bnode = new BlankNode("b1"); assertNotEquals(literal, bnode); assertNotEquals(bnode, literal); assertNotEquals(0, literal.compareTo(bnode)); assertNotEquals(0, bnode.compareTo(literal)); } - - + } diff --git a/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java b/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java index c7d4f50a..8d3a569c 100644 --- a/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/QuadCompareTest.java @@ -9,57 +9,57 @@ public class QuadCompareTest { - Quad q = new Quad("http://example.com/s1", "http://example.com/p1", - "http://example.com/o1", "http://example.com/g1"); - + Quad q = new Quad("http://example.com/s1", "http://example.com/p1", "http://example.com/o1", + "http://example.com/g1"); + @Test public void compareToNull() throws Exception { assertNotEquals(0, q.compareTo(null)); } - + @Test public void compareToSame() throws Exception { - Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", - "http://example.com/o1", "http://example.com/g1"); + final Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/o1", "http://example.com/g1"); assertEquals(0, q.compareTo(q2)); // Should still compare equal, even if extra attributes are added q2.put("example", "value"); assertEquals(0, q.compareTo(q2)); } - + @Test public void compareToDifferentGraph() throws Exception { - Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", - "http://example.com/o1", "http://example.com/other"); + final Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/o1", "http://example.com/other"); assertNotEquals(0, q.compareTo(q2)); } @Test public void compareToDifferentSubject() throws Exception { - Quad q2 = new Quad("http://example.com/other", "http://example.com/p1", - "http://example.com/o1", "http://example.com/g1"); + final Quad q2 = new Quad("http://example.com/other", "http://example.com/p1", + "http://example.com/o1", "http://example.com/g1"); assertNotEquals(0, q.compareTo(q2)); } @Test public void compareToDifferentPredicate() throws Exception { - Quad q2 = new Quad("http://example.com/s1", "http://example.com/other", - "http://example.com/o1", "http://example.com/g1"); + final Quad q2 = new Quad("http://example.com/s1", "http://example.com/other", + "http://example.com/o1", "http://example.com/g1"); assertNotEquals(0, q.compareTo(q2)); } @Test public void compareToDifferentObject() throws Exception { - Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", - "http://example.com/other", "http://example.com/g1"); + final Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/other", "http://example.com/g1"); assertNotEquals(0, q.compareTo(q2)); } @Test public void compareToDifferentObjectType() throws Exception { - Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", - "http://example.com/other", null, null, // literal - "http://example.com/g1"); + final Quad q2 = new Quad("http://example.com/s1", "http://example.com/p1", + "http://example.com/other", null, null, // literal + "http://example.com/g1"); assertNotEquals(0, q.compareTo(q2)); } diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index f0ceee08..55cf79e7 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertTrue; -import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.StringReader; @@ -43,13 +42,13 @@ public void fromStringTest() { @Test public void testFromJsonParser() throws Exception { - ObjectMapper jsonMapper = new ObjectMapper(); - JsonFactory jsonFactory = new JsonFactory(jsonMapper); - Reader testInputString = new StringReader("{}"); - JsonParser jp = jsonFactory.createParser(testInputString); - JsonUtils.fromJsonParser(jp ); + final ObjectMapper jsonMapper = new ObjectMapper(); + final JsonFactory jsonFactory = new JsonFactory(jsonMapper); + final Reader testInputString = new StringReader("{}"); + final JsonParser jp = jsonFactory.createParser(testInputString); + JsonUtils.fromJsonParser(jp); } - + @Test public void trailingContent_1() throws JsonParseException, IOException { trailingContent("{}"); From 538b3e557fdbc01c330fbeebcdb1894245525e63 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Fri, 27 Oct 2017 14:35:14 +1100 Subject: [PATCH 279/440] Disable email notifications to fix fork issue A fork is for some reason pushing every commit through Travis individually, which is causing emails to be sent for each build. Removing this to fix that issue --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f6961b66..9b07f505 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,6 @@ jdk: - oraclejdk8 - oraclejdk9 notifications: - email: - - ansell.peter@gmail.com - - tristan.king@gmail.com + email: false after_success: - mvn clean test jacoco:report coveralls:report From 2a761becb78bd61a3959529c0c9bf5abe82c14df Mon Sep 17 00:00:00 2001 From: christopher-johnson Date: Tue, 14 Nov 2017 19:05:41 +0100 Subject: [PATCH 280/440] adds BOMInputStream to JsonUtils.fromInputStream resolves #214 --- .../main/java/com/github/jsonldjava/utils/JsonUtils.java | 8 +++++++- .../com/github/jsonldjava/core/DocumentLoaderTest.java | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 7254de9c..79b11392 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -13,7 +13,9 @@ import java.util.List; import java.util.Map; +import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.BOMInputStream; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; @@ -89,8 +91,12 @@ public class JsonUtils { * If there was an IO error during parsing. */ public static Object fromInputStream(InputStream input) throws IOException { + //filter BOMs from InputStream + BOMInputStream bOMInputStream = new BOMInputStream(input, false, ByteOrderMark.UTF_8, + ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, + ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE); // no readers from inputstreams w.o. encoding!! - return fromInputStream(input, "UTF-8"); + return fromInputStream(bOMInputStream, "UTF-8"); } /** diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 4e33b114..b5843257 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -96,6 +96,14 @@ public void fromURLTest0002() throws Exception { assertEquals("ex:term2", term2.get("@id")); } + @Test + public void fromURLBomTest0003() throws Exception { + final URL url = new URL("http://wellcomelibrary.org/ld/iiif-ext/0/context.json"); + final Object context = JsonUtils.fromURL(url, documentLoader.getHttpClient()); + assertTrue(context instanceof Map); + assertFalse(((Map) context).isEmpty()); + } + // @Ignore("Integration test") @Test public void fromURLredirectHTTPSToHTTP() throws Exception { From be64e9152f1f9a8f5759af5bc7ed748f3d459621 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 15 Nov 2017 08:53:20 +1100 Subject: [PATCH 281/440] issue #214 : Pull test file locally to ensure it doesn't change Also can easily verify the existence of the UTF BOM this way Signed-off-by: Peter Ansell --- .../jsonldjava/core/DocumentLoaderTest.java | 7 +++-- .../resources/custom/contexttest-0004.jsonld | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 core/src/test/resources/custom/contexttest-0004.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index b5843257..e82bbefb 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -97,9 +97,10 @@ public void fromURLTest0002() throws Exception { } @Test - public void fromURLBomTest0003() throws Exception { - final URL url = new URL("http://wellcomelibrary.org/ld/iiif-ext/0/context.json"); - final Object context = JsonUtils.fromURL(url, documentLoader.getHttpClient()); + public void fromURLBomTest0004() throws Exception { + final URL contexttest = getClass().getResource("/custom/contexttest-0004.jsonld"); + assertNotNull(contexttest); + final Object context = JsonUtils.fromURL(contexttest, documentLoader.getHttpClient()); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); } diff --git a/core/src/test/resources/custom/contexttest-0004.jsonld b/core/src/test/resources/custom/contexttest-0004.jsonld new file mode 100644 index 00000000..74d28f6d --- /dev/null +++ b/core/src/test/resources/custom/contexttest-0004.jsonld @@ -0,0 +1,28 @@ +{ + "@context": [ + { + "wdl": "http://wellcomelibrary.org/iiif-ext/0#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + + "accessHint": { + "@id": "wdl:accessHint", + "@type": "@vocab" + }, + "open": { + "@id": "wdl:openAccess", + "@type": "wdl:accessHint" + }, + "clickthrough": { + "@id": "wdl:clickthrough", + "@type": "wdl:accessHint" + }, + "credentials": { + "@id": "wdl:credentials", + "@type": "wdl:accessHint" + }, + "authService": { + "@id": "wdl:suggestedAuthService" + } + } + ] +} \ No newline at end of file From 4994b958d728de60a73e9d233f18d8ae78ceb607 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 15 Nov 2017 08:55:43 +1100 Subject: [PATCH 282/440] Add note to changelog Signed-off-by: Peter Ansell --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index aa79c7b3..b645bba9 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2017-11-15 +* Ignore UTF BOM (Patch by @christopher-johnson) + ### 2017-08-26 * Release 0.11.1 * Fix @embed:@always support (Patch by @dr0i) From 9871200d84c838db3392cc1c554ad20c9150db0d Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 15 Nov 2017 09:15:50 +1100 Subject: [PATCH 283/440] Some cleanups Signed-off-by: Peter Ansell --- README.md | 2 -- .../jsonldjava/core/NormalizeUtils.java | 9 ++++--- .../github/jsonldjava/utils/JsonUtils.java | 10 ++++---- .../jsonldjava/core/DocumentLoaderTest.java | 2 +- .../jsonldjava/core/JsonLdProcessorTest.java | 24 +++++++++---------- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index b645bba9..bff2cf96 100644 --- a/README.md +++ b/README.md @@ -242,8 +242,6 @@ For Developers `jsonld-java` uses maven to compile. From the base `jsonld-java` module run `mvn clean install` to install the jar into your local maven repository. -The tests require Java-8 to compile, while the rest of the codebase is still compatible and built using the Java-6 APIs. - ### Running tests ```bash diff --git a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java index efb4154c..7b1bd5e7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java @@ -435,8 +435,10 @@ private static String hashQuads(String id, Map bnodes, UniqueNam .get(id)).get("quads"); final List nquads = new ArrayList(); for (int i = 0; i < quads.size(); ++i) { - nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), quads.get(i).get("name") != null - ? (String) ((Map) quads.get(i).get("name")).get("value") : null, + nquads.add(toNQuad((RDFDataset.Quad) quads.get(i), + quads.get(i).get("name") != null + ? (String) ((Map) quads.get(i).get("name")).get("value") + : null, id)); } // sort serialized quads @@ -492,7 +494,8 @@ private static String encodeHex(final byte[] data) { private static String getAdjacentBlankNodeName(Map node, String id) { return "blank node".equals(node.get("type")) && (!node.containsKey("value") || !Obj.equals(node.get("value"), id)) - ? (String) node.get("value") : null; + ? (String) node.get("value") + : null; } private static class Permutator { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 79b11392..6b9669d6 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -53,7 +53,7 @@ public class JsonUtils { /** * The user agent used by the default {@link CloseableHttpClient}. - * + * * This will not be used if * {@link DocumentLoader#setHttpClient(CloseableHttpClient)} is called with * a custom client. @@ -91,10 +91,10 @@ public class JsonUtils { * If there was an IO error during parsing. */ public static Object fromInputStream(InputStream input) throws IOException { - //filter BOMs from InputStream - BOMInputStream bOMInputStream = new BOMInputStream(input, false, ByteOrderMark.UTF_8, - ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, - ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE); + // filter BOMs from InputStream + final BOMInputStream bOMInputStream = new BOMInputStream(input, false, ByteOrderMark.UTF_8, + ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, + ByteOrderMark.UTF_32LE); // no readers from inputstreams w.o. encoding!! return fromInputStream(bOMInputStream, "UTF-8"); } diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index e82bbefb..ac73ebb1 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -103,7 +103,7 @@ public void fromURLBomTest0004() throws Exception { final Object context = JsonUtils.fromURL(contexttest, documentLoader.getHttpClient()); assertTrue(context instanceof Map); assertFalse(((Map) context).isEmpty()); - } + } // @Ignore("Integration test") @Test diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 9ec91a31..dcbe8f43 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -15,6 +15,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -161,16 +162,14 @@ public static void writeReport() String reportFormat = System.getProperty("report.format"); if (reportFormat != null) { reportFormat = reportFormat.toLowerCase(); - } else { - return; // nothing to do - } - - if ("application/ld+json".equals(reportFormat) || "jsonld".equals(reportFormat) - || "*".equals(reportFormat)) { - System.out.println("Generating JSON-LD Report"); - JsonUtils.writePrettyPrint( - new OutputStreamWriter(new FileOutputStream(reportOutputFile + ".jsonld")), - REPORT); + if ("application/ld+json".equals(reportFormat) || "jsonld".equals(reportFormat) + || "*".equals(reportFormat)) { + System.out.println("Generating JSON-LD Report"); + JsonUtils.writePrettyPrint( + new OutputStreamWriter(new FileOutputStream(reportOutputFile + ".jsonld"), + StandardCharsets.UTF_8), + REPORT); + } } } @@ -563,8 +562,9 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { assertTrue("\nFailed test: " + group + test.get("@id") + " " + test.get("name") + " (" + test.get("input") + "," + test.get("expect") + ")\n" + "expected: " - + JsonUtils.toPrettyString(expect) + "\nresult: " + (result instanceof JsonLdError - ? ((JsonLdError) result).toString() : JsonUtils.toPrettyString(result)), + + JsonUtils.toPrettyString(expect) + "\nresult: " + + (result instanceof JsonLdError ? ((JsonLdError) result).toString() + : JsonUtils.toPrettyString(result)), testpassed); } From 5db6f1f6a903f404e16ab85d46f973dd4c43e17a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 15 Nov 2017 10:14:44 +1100 Subject: [PATCH 284/440] Cleanups Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/Context.java | 7 +-- .../com/github/jsonldjava/core/JsonLdApi.java | 4 +- .../github/jsonldjava/core/JsonLdUtils.java | 9 ++-- .../github/jsonldjava/utils/JsonUtils.java | 53 +++++++++++++++---- .../jsonldjava/core/DocumentLoaderTest.java | 9 ++-- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 79f70b47..3f819107 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -23,6 +23,8 @@ */ public class Context extends LinkedHashMap { + private static final long serialVersionUID = 2894534897574805571L; + private JsonLdOptions options; private Map termDefinitions; public Map inverse = null; @@ -498,8 +500,7 @@ String expandIri(String value, boolean relative, boolean vocab, Map td = (LinkedHashMap) this.termDefinitions - .get(value); + final Map td = (Map) this.termDefinitions.get(value); if (td != null) { return (String) td.get(JsonLdConsts.ID); } else { @@ -523,7 +524,7 @@ String expandIri(String value, boolean relative, boolean vocab, Map) this.termDefinitions.get(prefix)) + return (String) ((Map) this.termDefinitions.get(prefix)) .get(JsonLdConsts.ID) + suffix; } // 4.5) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 6c1665ee..137ebda5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -627,7 +627,7 @@ else if (JsonLdConsts.TYPE.equals(expandedProperty)) { } // TODO: SPEC: no mention of empty map check else if (frameExpansion && value instanceof Map) { - if (((Map) value).size() != 0) { + if (!((Map) value).isEmpty()) { throw new JsonLdError(Error.INVALID_TYPE_VALUE, "@type value must be a an empty object for framing"); } @@ -919,7 +919,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) // 8.1) // TODO: is this method faster than just using containsKey for // each? - final Set keySet = new HashSet(result.keySet()); + final Set keySet = new HashSet<>(result.keySet()); keySet.remove(JsonLdConsts.VALUE); keySet.remove(JsonLdConsts.INDEX); final boolean langremoved = keySet.remove(JsonLdConsts.LANGUAGE); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 5c6968d0..4c44e582 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -328,11 +328,12 @@ static boolean isBlankNode(Object v) { // 2. If it has an @id key its value begins with '_:'. // 3. It has no keys OR is not a @value, @set, or @list. if (v instanceof Map) { - if (((Map) v).containsKey("@id")) { - return ((String) ((Map) v).get("@id")).startsWith("_:"); + final Map map = (Map) v; + if (map.containsKey("@id")) { + return ((String) map.get("@id")).startsWith("_:"); } else { - return ((Map) v).size() == 0 || !(((Map) v).containsKey("@value") - || ((Map) v).containsKey("@set") || ((Map) v).containsKey("@list")); + return map.isEmpty() || !map.containsKey("@value") || map.containsKey("@set") + || map.containsKey("@list"); } } return false; diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 6b9669d6..dc2d5074 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -10,6 +10,7 @@ import java.io.Writer; import java.net.HttpURLConnection; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; @@ -92,11 +93,22 @@ public class JsonUtils { */ public static Object fromInputStream(InputStream input) throws IOException { // filter BOMs from InputStream - final BOMInputStream bOMInputStream = new BOMInputStream(input, false, ByteOrderMark.UTF_8, - ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, - ByteOrderMark.UTF_32LE); - // no readers from inputstreams w.o. encoding!! - return fromInputStream(bOMInputStream, "UTF-8"); + try (final BOMInputStream bOMInputStream = new BOMInputStream(input, false, + ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, + ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE);) { + Charset charset = StandardCharsets.UTF_8; + // Attempt to use the BOM if it exists + if (bOMInputStream.hasBOM()) { + try { + charset = Charset.forName(bOMInputStream.getBOMCharsetName()); + } catch (final IllegalArgumentException e) { + // If there are any issues with the BOM charset, attempt to + // parse with UTF_8 + charset = StandardCharsets.UTF_8; + } + } + return fromInputStream(bOMInputStream, charset); + } } /** @@ -116,6 +128,26 @@ public static Object fromInputStream(InputStream input) throws IOException { * If there was an IO error during parsing. */ public static Object fromInputStream(InputStream input, String enc) throws IOException { + return fromInputStream(input, Charset.forName(enc)); + } + + /** + * Parses a JSON-LD document from the given {@link InputStream} to an object + * that can be used as input for the {@link JsonLdApi} and + * {@link JsonLdProcessor} methods. + * + * @param input + * The JSON-LD document in an InputStream. + * @param enc + * The character encoding to use when interpreting the characters + * in the InputStream. + * @return A JSON Object. + * @throws JsonParseException + * If there was a JSON related error during parsing. + * @throws IOException + * If there was an IO error during parsing. + */ + public static Object fromInputStream(InputStream input, Charset enc) throws IOException { try (InputStreamReader in = new InputStreamReader(input, enc); BufferedReader reader = new BufferedReader(in);) { return fromReader(reader); @@ -348,13 +380,10 @@ public static Object fromURLJavaNet(java.net.URL url) throws JsonParseException, final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.addRequestProperty("Accept", ACCEPT_HEADER); - final InputStream directStream = urlConn.getInputStream(); - final StringWriter output = new StringWriter(); - try { - IOUtils.copy(directStream, output, Charset.forName("UTF-8")); + try (final InputStream directStream = urlConn.getInputStream();) { + IOUtils.copy(directStream, output, StandardCharsets.UTF_8); } finally { - directStream.close(); output.flush(); } final Object context = JsonUtils.fromReader(new StringReader(output.toString())); @@ -398,4 +427,8 @@ private static CloseableHttpClient createDefaultHttpClient() { return result; } + + private JsonUtils() { + // Static class, no access to constructor + } } diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index ac73ebb1..643dbf76 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -143,13 +143,9 @@ public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.addRequestProperty("Accept", "application/ld+json"); - final InputStream directStream = urlConn.getInputStream(); - final StringWriter output = new StringWriter(); - try { + try (final InputStream directStream = urlConn.getInputStream();) { IOUtils.copy(directStream, output, Charset.forName("UTF-8")); - } finally { - directStream.close(); } final Object context = JsonUtils.fromReader(new StringReader(output.toString())); assertTrue(context instanceof Map); @@ -336,10 +332,13 @@ public void sharedHttpClient() throws Exception { assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); } + @SuppressWarnings("deprecation") @Test public void differentHttpClient() throws Exception { // Custom http client try { + // Only using deprecated http client to verify that the usual HTTP + // client can be overridden documentLoader.setHttpClient(new SystemDefaultHttpClient()); assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); } finally { From 03191970ae848c21550da6b5d35608c530a0f6d0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 25 Jan 2018 08:43:25 +1100 Subject: [PATCH 285/440] issue #222 : Ensure CloseableHttpResponse is closed in fromURL Signed-off-by: Peter Ansell --- README.md | 3 +++ .../java/com/github/jsonldjava/utils/JsonUtils.java | 13 ++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bff2cf96..28d1c347 100644 --- a/README.md +++ b/README.md @@ -447,6 +447,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-01-25 +* Fix resource leak in JsonUtils.fromURL on unsuccessful requests (Patch by @plaplaige) + ### 2017-11-15 * Ignore UTF BOM (Patch by @christopher-johnson) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index dc2d5074..4c18675d 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -334,6 +334,7 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) final String protocol = url.getProtocol(); // We can only use the Apache HTTPClient for HTTP/HTTPS, so use the // native java client for the others + CloseableHttpResponse response = null; InputStream in = null; try { if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { @@ -348,7 +349,7 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) // or whatever is available request.addHeader("Accept", ACCEPT_HEADER); - final CloseableHttpResponse response = httpClient.execute(request); + response = httpClient.execute(request); final int status = response.getStatusLine().getStatusCode(); if (status != 200 && status != 203) { throw new IOException("Can't retrieve " + url + ", status code: " + status); @@ -357,8 +358,14 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) } return fromInputStream(in); } finally { - if (in != null) { - in.close(); + try { + if (in != null) { + in.close(); + } + } finally { + if (response != null) { + response.close(); + } } } } From 57cb42ad299ee4d4d2f673bccfcf6f3eb686ff9e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 25 Jan 2018 08:59:51 +1100 Subject: [PATCH 286/440] Use URLConnection.getContentLengthLong now that we don't support Java-6 Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/utils/JarCacheResource.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java index 216a942c..5c76f8d4 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheResource.java @@ -23,9 +23,7 @@ public JarCacheResource(URL classpath) throws IOException { @Override public long length() { - // TODO should be getContentLengthLong() but this is not available in - // Java 6. - return connection.getContentLength(); + return connection.getContentLengthLong(); } @Override From 3f99e49dcb35e4d0da1a3f28c0c0e4cc0d1d36b0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 25 Jan 2018 09:20:44 +1100 Subject: [PATCH 287/440] issue #196 : Avoid calling ClassLoader.getResources multiple times Signed-off-by: Peter Ansell --- .../jsonldjava/utils/JarCacheStorage.java | 42 ++++++++++++------- .../github/jsonldjava/utils/JsonUtils.java | 29 +++++++++---- .../jsonldjava/core/DocumentLoaderTest.java | 4 ++ 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index c028640c..4a7f0e5b 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -7,6 +7,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; @@ -61,6 +62,8 @@ public class JarCacheStorage implements HttpCacheStorage { */ protected final ConcurrentMap> jarCaches = new ConcurrentHashMap>(); + private volatile List cachedResourceList; + public ClassLoader getClassLoader() { if (classLoader != null) { return classLoader; @@ -90,7 +93,7 @@ public void putEntry(String key, HttpCacheEntry entry) throws IOException { @Override public HttpCacheEntry getEntry(String key) throws IOException { - log.trace("Requesting " + key); + log.trace("Requesting {}", key); URI requestedUri; try { requestedUri = new URI(key); @@ -107,17 +110,13 @@ public HttpCacheEntry getEntry(String key) throws IOException { } } - final Enumeration jarcaches = getResources(); - while (jarcaches.hasMoreElements()) { - final URL url = jarcaches.nextElement(); - + for(final URL url : getResources()) { final JsonNode tree = getJarCache(url); // TODO: Cache tree per URL for (final JsonNode node : tree) { final URI uri = URI.create(node.get("Content-Location").asText()); if (uri.equals(requestedUri)) { return cacheEntry(requestedUri, url, node); - } } } @@ -126,13 +125,28 @@ public HttpCacheEntry getEntry(String key) throws IOException { return delegate.getEntry(key); } - private Enumeration getResources() throws IOException { - final ClassLoader cl = getClassLoader(); - if (cl != null) { - return cl.getResources(JARCACHE_JSON); - } else { - return ClassLoader.getSystemResources(JARCACHE_JSON); + /** + * Get all of the {@code jarcache.json} resources that exist on the classpath + * + * @return A cached list of jarcache.json classpath resources as {@link URL}s + * @throws IOException If there was an IO error while scanning the classpath + */ + private List getResources() throws IOException { + List result = cachedResourceList; + if(result == null) { + synchronized(this) { + result = cachedResourceList; + if(result == null) { + final ClassLoader cl = getClassLoader(); + if (cl != null) { + result = cachedResourceList = Collections.list(cl.getResources(JARCACHE_JSON)); + } else { + result = cachedResourceList = Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); + } + } + } } + return result; } protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingException { @@ -152,6 +166,7 @@ protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingExcept if (jarCache != null) { return jarCache; } else { + // SoftReference was Garbage Collected, remove it from cache jarCaches.remove(uri); } } @@ -178,7 +193,7 @@ protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingExcept protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cacheNode) throws MalformedURLException, IOException { final URL classpath = new URL(baseURL, cacheNode.get("X-Classpath").asText()); - log.debug("Cache hit for " + requestedUri); + log.debug("Cache hit for {}", requestedUri); log.trace("{}", cacheNode); final List
responseHeaders = new ArrayList
(); @@ -195,7 +210,6 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach while (fieldNames.hasNext()) { final String headerName = fieldNames.next(); final JsonNode header = cacheNode.get(headerName); - // TODO: Support multiple headers with [] responseHeaders.add(new BasicHeader(headerName, header.asText())); } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 4c18675d..73b93df2 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -24,6 +24,7 @@ import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultRedirectStrategy; +import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; @@ -410,13 +411,27 @@ public static CloseableHttpClient getDefaultHttpClient() { return result; } - private static CloseableHttpClient createDefaultHttpClient() { - // Common CacheConfig for both the JarCacheStorage and the underlying - // BasicHttpCacheStorage - final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(500) + public static CloseableHttpClient createDefaultHttpClient() { + final CacheConfig cacheConfig = createDefaultCacheConfig(); + + final CloseableHttpClient result = createDefaultHttpClient(cacheConfig); + + return result; + } + + public static CacheConfig createDefaultCacheConfig() { + return CacheConfig.custom().setMaxCacheEntries(500) .setMaxObjectSize(1024 * 256).build(); + } + + public static CloseableHttpClient createDefaultHttpClient(final CacheConfig cacheConfig) { + return createDefaultHttpClientBuilder(cacheConfig).build(); + } - final CloseableHttpClient result = CachingHttpClientBuilder.create() + public static HttpClientBuilder createDefaultHttpClientBuilder(final CacheConfig cacheConfig) { + // Common CacheConfig for both the JarCacheStorage and the underlying + // BasicHttpCacheStorage + return CachingHttpClientBuilder.create() // allow caching .setCacheConfig(cacheConfig) // Wrap the local JarCacheStorage around a BasicHttpCacheStorage @@ -430,9 +445,7 @@ private static CloseableHttpClient createDefaultHttpClient() { // User agent customisation .setUserAgent(JSONLD_JAVA_USER_AGENT) // use system defaults for proxy etc. - .useSystemProperties().build(); - - return result; + .useSystemProperties(); } private JsonUtils() { diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 643dbf76..4bb100f2 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -304,6 +304,8 @@ public void jarCacheMiss404() throws Exception { public void jarCacheMissThreadCtx() throws Exception { final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); Thread.currentThread().setContextClassLoader(findNothingCL); + // Must create a new CloseableHttpClient as the previous instance will not pickup the new classloader due to caching + documentLoader.setHttpClient(JsonUtils.createDefaultHttpClient()); JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), documentLoader.getHttpClient()); } @@ -321,6 +323,8 @@ public void jarCacheHitThreadCtx() throws Exception { final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); Thread.currentThread().setContextClassLoader(cl); + // Must create a new CloseableHttpClient as the previous instance will not pickup the new classloader due to caching + documentLoader.setHttpClient(JsonUtils.createDefaultHttpClient()); final Object hello = JsonUtils.fromURL(url, documentLoader.getHttpClient()); assertTrue(hello instanceof Map); assertEquals("World!", ((Map) hello).get("Hello")); From fd4b95f6451586f10705682a88e68b571ecee610 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 7 Feb 2018 08:19:49 +1100 Subject: [PATCH 288/440] Note subclassing of DocumentLoader to modify its behaviour Note that subclassing DocumentLoader is the recommended approach to change the behaviour to suit your purposes. The only method that needs to be overridden is loadDocument. Refs #222 --- .../java/com/github/jsonldjava/core/DocumentLoader.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 787dbe6f..bf4e1064 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -8,6 +8,9 @@ import com.github.jsonldjava.utils.JsonUtils; +/** + * Resolves URLs to RemoteDocuments. Subclass this class to change the behaviour of loadDocument to suit your purposes. + */ public class DocumentLoader { private final Map m_injectedDocs = new HashMap<>(); @@ -77,6 +80,9 @@ public CloseableHttpClient getHttpClient() { return result; } + /** + * Call this method to override the default CloseableHttpClient provided by JsonUtils.getDefaultHttpClient. + */ public void setHttpClient(CloseableHttpClient nextHttpClient) { httpClient = nextHttpClient; } From 43b36ae365864112d0638f01e136022a4ce66e18 Mon Sep 17 00:00:00 2001 From: Hans Date: Tue, 27 Mar 2018 23:04:53 -0500 Subject: [PATCH 289/440] force remote context caching to avoid massive performance degradation --- .../jsonldjava/utils/JarCacheStorage.java | 2 +- .../com/github/jsonldjava/utils/JsonUtils.java | 3 ++- .../jsonldjava/core/DocumentLoaderTest.java | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index c028640c..757df924 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -95,7 +95,7 @@ public HttpCacheEntry getEntry(String key) throws IOException { try { requestedUri = new URI(key); } catch (final URISyntaxException e) { - return null; + return delegate.getEntry(key); } if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) || (requestedUri.getScheme().equals("https") && requestedUri.getPort() == 443)) { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 4c18675d..79928657 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -414,7 +414,8 @@ private static CloseableHttpClient createDefaultHttpClient() { // Common CacheConfig for both the JarCacheStorage and the underlying // BasicHttpCacheStorage final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(500) - .setMaxObjectSize(1024 * 256).build(); + .setMaxObjectSize(1024 * 256).setSharedCache(false) + .setHeuristicCachingEnabled(true).setHeuristicDefaultLifetime(86400).build(); final CloseableHttpClient result = CachingHttpClientBuilder.create() // allow caching diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 643dbf76..04c96c57 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -404,4 +404,22 @@ public void injectContext() throws Exception { .get(0)).get("http://nonexisting.example.com/thing/pony")).get(0)).get("@value"); assertEquals(5, v); } + + @Test + public void testRemoteContextCaching() throws Exception { + final String[] urls = {"http://schema.org/", "http://schema.org/docs/jsonldcontext.json"}; + for (String url : urls) { + long start = System.currentTimeMillis(); + for (int i = 1; i <= 10000; i++) { + documentLoader.loadDocument(url); + + long seconds = (System.currentTimeMillis() - start) / 1000; + + if (seconds > 60) { + fail(String.format("Took %s seconds to access %s %s times", seconds, url, i)); + break; + } + } + } + } } From 7289a92415382944405fff5263bd17180b13fb7f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 11:15:35 +1000 Subject: [PATCH 290/440] Reform slightly to drop through to final case for delegate Signed-off-by: Peter Ansell --- .../jsonldjava/utils/JarCacheStorage.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 757df924..a750879e 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -11,6 +11,7 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -91,33 +92,37 @@ public void putEntry(String key, HttpCacheEntry entry) throws IOException { @Override public HttpCacheEntry getEntry(String key) throws IOException { log.trace("Requesting " + key); - URI requestedUri; + Optional parsedUri = Optional.empty(); try { - requestedUri = new URI(key); + parsedUri = Optional.of(new URI(key)); } catch (final URISyntaxException e) { - return delegate.getEntry(key); + parsedUri = Optional.empty(); } - if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) - || (requestedUri.getScheme().equals("https") && requestedUri.getPort() == 443)) { - // Strip away default http ports - try { - requestedUri = new URI(requestedUri.getScheme(), requestedUri.getHost(), - requestedUri.getPath(), requestedUri.getFragment()); - } catch (final URISyntaxException e) { + if (parsedUri.isPresent()) { + URI requestedUri = parsedUri.get(); + if ((requestedUri.getScheme().equals("http") && requestedUri.getPort() == 80) + || (requestedUri.getScheme().equals("https") + && requestedUri.getPort() == 443)) { + // Strip away default http ports + try { + requestedUri = new URI(requestedUri.getScheme(), requestedUri.getHost(), + requestedUri.getPath(), requestedUri.getFragment()); + } catch (final URISyntaxException e) { + } } - } - final Enumeration jarcaches = getResources(); - while (jarcaches.hasMoreElements()) { - final URL url = jarcaches.nextElement(); + final Enumeration jarcaches = getResources(); + while (jarcaches.hasMoreElements()) { + final URL url = jarcaches.nextElement(); - final JsonNode tree = getJarCache(url); - // TODO: Cache tree per URL - for (final JsonNode node : tree) { - final URI uri = URI.create(node.get("Content-Location").asText()); - if (uri.equals(requestedUri)) { - return cacheEntry(requestedUri, url, node); + final JsonNode tree = getJarCache(url); + // TODO: Cache tree per URL + for (final JsonNode node : tree) { + final URI uri = URI.create(node.get("Content-Location").asText()); + if (uri.equals(requestedUri)) { + return cacheEntry(requestedUri, url, node); + } } } } From 7a9040f42465de2ba1f32345350039301a40ed27 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 11:20:55 +1000 Subject: [PATCH 291/440] Reduce unit test from 10000 to 1000 1000 cache accesses should still trigger the test to fail if caching is not actually occurring, but is less likely to trigger a false test failure on shared test infrastructure with low resources. Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/core/DocumentLoaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 04c96c57..b2668a74 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -410,7 +410,7 @@ public void testRemoteContextCaching() throws Exception { final String[] urls = {"http://schema.org/", "http://schema.org/docs/jsonldcontext.json"}; for (String url : urls) { long start = System.currentTimeMillis(); - for (int i = 1; i <= 10000; i++) { + for (int i = 1; i <= 1000; i++) { documentLoader.loadDocument(url); long seconds = (System.currentTimeMillis() - start) / 1000; From 25ae9525d0c9f942404ef1f133ab27d135e499ad Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 11:39:11 +1000 Subject: [PATCH 292/440] Bump dependency and plugin versions Signed-off-by: Peter Ansell --- pom.xml | 53 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 999c6210..43c08c47 100755 --- a/pom.xml +++ b/pom.xml @@ -39,9 +39,9 @@ UTF-8 UTF-8 - 4.5.3 - 4.4.8 - 2.9.1 + 4.5.5 + 4.4.9 + 2.9.5 4.12 1.7.25 @@ -50,6 +50,13 @@ + + com.fasterxml.jackson + jackson-bom + ${jackson.version} + pom + import + com.fasterxml.jackson.core jackson-core @@ -190,7 +197,7 @@ org.mockito mockito-core - 2.11.0 + 2.17.0 commons-io @@ -253,7 +260,7 @@ org.codehaus.mojo extra-enforcer-rules - 1.0-beta-6 + 1.0-beta-7 @@ -266,10 +273,25 @@ 1.8 + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-dependency-plugin + 3.0.2 + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 + 3.0.0 org.apache.maven.plugins @@ -281,6 +303,11 @@ maven-resources-plugin 3.0.2 + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + org.apache.maven.plugins maven-install-plugin @@ -332,6 +359,11 @@ maven-surefire-plugin 2.20.1 + + org.apache.maven.plugins + maven-site-plugin + 3.7 + org.codehaus.mojo animal-sniffer-maven-plugin @@ -356,7 +388,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.11.0 + 0.11.1 @@ -392,7 +424,7 @@ org.apache.felix maven-bundle-plugin - 3.3.0 + 3.5.0 @@ -403,7 +435,7 @@ org.jacoco jacoco-maven-plugin - 0.7.9 + 0.8.1 prepare-agent @@ -453,7 +485,6 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 attach-sources @@ -466,7 +497,6 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 attach-javadocs @@ -479,7 +509,6 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 sign-artifacts From fa899d532d1c941fdf921d85e0a48e3e4c0d1e92 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 12:50:34 +1000 Subject: [PATCH 293/440] Narrow from Exception to IOException for readability Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/utils/JarCacheStorage.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 34c0b198..9437b628 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -1,7 +1,6 @@ package com.github.jsonldjava.utils; import java.io.IOException; -import java.lang.ref.SoftReference; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -12,7 +11,6 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; @@ -74,7 +72,7 @@ public class JarCacheStorage implements HttpCacheStorage { .concurrencyLevel(4).maximumSize(100).softValues() .build(new CacheLoader() { @Override - public JsonNode load(URL url) throws Exception { + public JsonNode load(URL url) throws IOException { return mapper.readTree(url); } }); From 45d5ce0f437032bb625463e1995bd4467c6ddbd7 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 12:53:03 +1000 Subject: [PATCH 294/440] Hide jarCaches as an implementation specific detail Can be accessed or avoided using getJarCache. Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/utils/JarCacheStorage.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 9437b628..3712efec 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -68,7 +68,7 @@ public class JarCacheStorage implements HttpCacheStorage { * * @see #getJarCache(URL) */ - protected final LoadingCache jarCaches = CacheBuilder.newBuilder() + private final LoadingCache jarCaches = CacheBuilder.newBuilder() .concurrencyLevel(4).maximumSize(100).softValues() .build(new CacheLoader() { @Override @@ -85,8 +85,9 @@ public JsonNode load(URL url) throws IOException { .concurrencyLevel(4).weakKeys().makeMap(); public ClassLoader getClassLoader() { - if (classLoader != null) { - return classLoader; + ClassLoader nextClassLoader = classLoader; + if (nextClassLoader != null) { + return nextClassLoader; } return Thread.currentThread().getContextClassLoader(); } From 3bca2909af6a93ae6a3b8c5d6e48879dafb3ced0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 13:00:53 +1000 Subject: [PATCH 295/440] Bump version number to reflect API change Signed-off-by: Peter Ansell --- README.md | 7 +++++++ core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 28d1c347..56e9bfd3 100644 --- a/README.md +++ b/README.md @@ -447,6 +447,13 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-04-03 +* Fix performance issue caused by not caching schema.org and others that use ``Cache-Control: private`` (Patch by @HansBrende) +* Cache classpath scans for jarcache.json to fix a similar performance issue +* Add internal shaded dependency on Google Guava to use maintained soft and weak reference maps rather than adhoc versions +* Make JsonLdError a RuntimeException to improve its use in closures +* Bump minor version to 0.12 to reflect the API incompatibility caused by JsonLdError and protected field change and hiding in JarCacheStorage + ### 2018-01-25 * Fix resource leak in JsonUtils.fromURL on unsuccessful requests (Patch by @plaplaige) diff --git a/core/pom.xml b/core/pom.xml index 86a3e48d..7ac4c4c9 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.11.2-SNAPSHOT + 0.12.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 9252d150..e03e0e9d 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.11.2-SNAPSHOT + 0.12.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From 7af4f6978625c2bf714c98599b8cf5fac53366d0 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 14:36:04 +1000 Subject: [PATCH 296/440] Make cache across ClassLoader's static ClassLoader map uses identity along with weak references, so no static memory leaks in this case. Also remove redundant assignment in URI parse case Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/utils/JarCacheStorage.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 3712efec..af9aab10 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -78,10 +78,13 @@ public JsonNode load(URL url) throws IOException { }); /** - * Create a Guava concurrent weak reference key map to avoid holding onto + * Cached URLs from the given ClassLoader to identified locations of + * jarcache.json resources on the classpath + * + * Uses a Guava concurrent weak reference key map to avoid holding onto * ClassLoader instances after they are otherwise unavailable. */ - private final ConcurrentMap> cachedResourceList = new MapMaker() + private static final ConcurrentMap> cachedResourceList = new MapMaker() .concurrencyLevel(4).weakKeys().makeMap(); public ClassLoader getClassLoader() { @@ -128,7 +131,7 @@ public HttpCacheEntry getEntry(String key) throws IOException { try { parsedUri = Optional.of(new URI(key)); } catch (final URISyntaxException e) { - parsedUri = Optional.empty(); + // Ignore, will delegate this request } if (parsedUri.isPresent()) { URI requestedUri = parsedUri.get(); From 5462af2355fd8cba08c729682366015342e10a36 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 14:45:45 +1000 Subject: [PATCH 297/440] Fix shading Signed-off-by: Peter Ansell --- core/pom.xml | 1 - pom.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 7ac4c4c9..6b1a9fe6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -46,7 +46,6 @@ com.google.guava guava - provided junit diff --git a/pom.xml b/pom.xml index e03e0e9d..2decd067 100755 --- a/pom.xml +++ b/pom.xml @@ -209,7 +209,6 @@ com.google.guava guava 24.1-jre - provided From 24e7d4c3b2f1df08d4931c82c947daf6a7125c07 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 14:50:05 +1000 Subject: [PATCH 298/440] Minimize the shaded jar to reduce bloat associated with shading Shading still necessary as we don't want user error reports due to the use of incompatible Guava versions across their classpath Signed-off-by: Peter Ansell --- .gitignore | 1 + core/pom.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b429e1ac..aeafccd3 100755 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ target/ .idea *~ pom.xml.versionsBackup +dependency-reduced-pom.xml diff --git a/core/pom.xml b/core/pom.xml index 6b1a9fe6..e2e38e04 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -80,6 +80,7 @@ com.github.jsonldjava.shaded.com.google.common + true From 95f74aa7e7c3f3d9936c9a5f6ca8cde7478b4652 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 14:58:10 +1000 Subject: [PATCH 299/440] Remove guava maven auxiliary files and fix version number Version was accidentally a release instead of snapshot Signed-off-by: Peter Ansell --- core/pom.xml | 10 +++++++++- pom.xml | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index e2e38e04..1c1b1677 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.0 + 0.12.0-SNAPSHOT 4.0.0 jsonld-java @@ -81,6 +81,14 @@ true + + + com.google.guava:guava + + META-INF/maven/** + + + diff --git a/pom.xml b/pom.xml index 2decd067..39770548 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.0 + 0.12.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 3f9e7984bca70f05bce2aa8613fe24a9865ceed5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 15:16:07 +1000 Subject: [PATCH 300/440] Format pom.xml files Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 1c1b1677..6fcf90f6 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -88,7 +88,7 @@ META-INF/maven/** - + diff --git a/pom.xml b/pom.xml index 39770548..e54ba293 100755 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,8 @@ commons-io 2.6 - + com.google.guava guava From 3340f2c9112eb6e8769cef9b273a6979f90e2bb1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 15:21:09 +1000 Subject: [PATCH 301/440] Remove DocumentLoaderTest hacks Fixing the ClassLoader cache has fixed the issue which caused the changes to DocumentLoaderTest originally Now, replacing the ClassLoader will be picked up seamlessly and the new classpath will be scanned and cached (using a WeakReference) Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/core/DocumentLoaderTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 7364e73b..84a64abc 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -304,8 +304,6 @@ public void jarCacheMiss404() throws Exception { public void jarCacheMissThreadCtx() throws Exception { final URLClassLoader findNothingCL = new URLClassLoader(new URL[] {}, null); Thread.currentThread().setContextClassLoader(findNothingCL); - // Must create a new CloseableHttpClient as the previous instance will not pickup the new classloader due to caching - documentLoader.setHttpClient(JsonUtils.createDefaultHttpClient()); JsonUtils.fromURL(new URL("http://nonexisting.example.com/context"), documentLoader.getHttpClient()); } @@ -323,8 +321,6 @@ public void jarCacheHitThreadCtx() throws Exception { final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); Thread.currentThread().setContextClassLoader(cl); - // Must create a new CloseableHttpClient as the previous instance will not pickup the new classloader due to caching - documentLoader.setHttpClient(JsonUtils.createDefaultHttpClient()); final Object hello = JsonUtils.fromURL(url, documentLoader.getHttpClient()); assertTrue(hello instanceof Map); assertEquals("World!", ((Map) hello).get("Hello")); @@ -411,7 +407,7 @@ public void injectContext() throws Exception { @Test public void testRemoteContextCaching() throws Exception { - final String[] urls = {"http://schema.org/", "http://schema.org/docs/jsonldcontext.json"}; + final String[] urls = { "http://schema.org/", "http://schema.org/docs/jsonldcontext.json" }; for (String url : urls) { long start = System.currentTimeMillis(); for (int i = 1; i <= 1000; i++) { From 7887372fbef8e1cf4b39b64ad2516ae7c3445742 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 15:28:44 +1000 Subject: [PATCH 302/440] Revert to throwing IOException Horrible hack, but necessary to use computeIfAbsent to simplify and improve performance on the classpath scanning code Signed-off-by: Peter Ansell --- .../jsonldjava/utils/JarCacheStorage.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index af9aab10..066eeb53 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -173,17 +173,23 @@ public HttpCacheEntry getEntry(String key) throws IOException { */ private List getResources() throws IOException { final ClassLoader cl = getClassLoader(); - return cachedResourceList.computeIfAbsent(cl, nextCl -> { - try { - if (nextCl != null) { - return Collections.list(nextCl.getResources(JARCACHE_JSON)); - } else { - return Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); + try { + return cachedResourceList.computeIfAbsent(cl, nextCl -> { + try { + if (nextCl != null) { + return Collections.list(nextCl.getResources(JARCACHE_JSON)); + } else { + return Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); + } + } catch (IOException e) { + throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, e); } - } catch (IOException e) { - throw new JsonLdError(JsonLdError.Error.LOADING_INJECTED_CONTEXT_FAILED, e); - } - }); + }); + } catch (JsonLdError e) { + // Horrible hack to enable the use of computeIfAbsent to simplify + // creation of new cached resource lists + throw (IOException) e.getCause(); + } } protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingException { From 3592ae781253f8e83440e1abdc283b4e3de605d8 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 15:44:34 +1000 Subject: [PATCH 303/440] Javadoc for the private jarcache.json constant Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/utils/JarCacheStorage.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 066eeb53..b72febba 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -42,6 +42,12 @@ public class JarCacheStorage implements HttpCacheStorage { + /** + * The classpath location that is searched inside of the classloader set for + * this cache. Note this search is also done on the Thread + * contextClassLoader if none is explicitly set, and the System classloader + * if there is no contextClassLoader. + */ private static final String JARCACHE_JSON = "jarcache.json"; private final Logger log = LoggerFactory.getLogger(getClass()); From 9d08056ae93dce675d68270247910289ea3b739b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 3 Apr 2018 16:18:42 +1000 Subject: [PATCH 304/440] Add test and fix for a null context classloader Signed-off-by: Peter Ansell --- .../jsonldjava/utils/JarCacheStorage.java | 20 +++++++++++++++++-- .../jsonldjava/core/DocumentLoaderTest.java | 8 ++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index b72febba..78a1ae1a 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -60,6 +60,15 @@ public class JarCacheStorage implements HttpCacheStorage { */ private ClassLoader classLoader = null; + /** + * A holder for the case where the System class loader needs to be used, but + * cannot be directly identified in another way. + * + * Used as a key in cachedResourceList. + */ + private final ClassLoader NULL_CLASS_LOADER = new ClassLoader() { + }; + /** * All live caching that is not found locally is delegated to this * implementation. @@ -178,11 +187,18 @@ public HttpCacheEntry getEntry(String key) throws IOException { * If there was an IO error while scanning the classpath */ private List getResources() throws IOException { - final ClassLoader cl = getClassLoader(); + ClassLoader cl = getClassLoader(); + + // ConcurrentHashMap doesn't support null keys, so substitute a pseudo + // key + if (cl == null) { + cl = NULL_CLASS_LOADER; + } + try { return cachedResourceList.computeIfAbsent(cl, nextCl -> { try { - if (nextCl != null) { + if (nextCl != NULL_CLASS_LOADER) { return Collections.list(nextCl.getResources(JARCACHE_JSON)); } else { return Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index 84a64abc..b7c30bba 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -319,6 +319,14 @@ public void jarCacheHitThreadCtx() throws Exception { // expected } + Thread.currentThread().setContextClassLoader(null); + try { + JsonUtils.fromURL(url, documentLoader.getHttpClient()); + fail("Should not be able to find nested/hello yet"); + } catch (final IOException ex) { + // expected + } + final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); Thread.currentThread().setContextClassLoader(cl); final Object hello = JsonUtils.fromURL(url, documentLoader.getHttpClient()); From 20a7de0d432c927c1bf29960f18e7ec0f05ad010 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 4 Apr 2018 22:31:08 -0500 Subject: [PATCH 305/440] Remove possibility of SecurityException --- .../jsonldjava/utils/JarCacheStorage.java | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 78a1ae1a..c785d6b6 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -34,7 +34,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.jsonldjava.core.JsonLdError; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -66,8 +65,7 @@ public class JarCacheStorage implements HttpCacheStorage { * * Used as a key in cachedResourceList. */ - private final ClassLoader NULL_CLASS_LOADER = new ClassLoader() { - }; + private static final Object NULL_CLASS_LOADER = new Object(); /** * All live caching that is not found locally is delegated to this @@ -99,7 +97,7 @@ public JsonNode load(URL url) throws IOException { * Uses a Guava concurrent weak reference key map to avoid holding onto * ClassLoader instances after they are otherwise unavailable. */ - private static final ConcurrentMap> cachedResourceList = new MapMaker() + private static final ConcurrentMap> cachedResourceList = new MapMaker() .concurrencyLevel(4).weakKeys().makeMap(); public ClassLoader getClassLoader() { @@ -191,27 +189,21 @@ private List getResources() throws IOException { // ConcurrentHashMap doesn't support null keys, so substitute a pseudo // key - if (cl == null) { - cl = NULL_CLASS_LOADER; + Object key = cl == null ? NULL_CLASS_LOADER : cl; + + List newValue = cachedResourceList.get(key); + if (newValue != null) { + return newValue; } - try { - return cachedResourceList.computeIfAbsent(cl, nextCl -> { - try { - if (nextCl != NULL_CLASS_LOADER) { - return Collections.list(nextCl.getResources(JARCACHE_JSON)); - } else { - return Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); - } - } catch (IOException e) { - throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR, e); - } - }); - } catch (JsonLdError e) { - // Horrible hack to enable the use of computeIfAbsent to simplify - // creation of new cached resource lists - throw (IOException) e.getCause(); + if (cl != null) { + newValue = Collections.list(cl.getResources(JARCACHE_JSON)); + } else { + newValue = Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); } + + List oldValue = cachedResourceList.putIfAbsent(key, newValue); + return oldValue != null ? oldValue : newValue; } protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingException { From fbb821847e37ce5b066ce013eedebf459e8cbc98 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:01:01 +1000 Subject: [PATCH 306/440] issue #196 : Cleanup and documentation in JarCacheStorage Signed-off-by: Peter Ansell --- .../jsonldjava/utils/JarCacheStorage.java | 90 ++++++++++++------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index c785d6b6..b210b012 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -10,6 +10,7 @@ import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; @@ -39,13 +40,21 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.MapMaker; +/** + * Implementation of the Apache HttpClient {@link HttpCacheStorage} interface + * using {@code jarcache.json} files on the classpath to identify static JSON-LD + * resources on the classpath, to avoid retrieving them. + * + * @author Stian Soiland-Reyes + * @author Peter Ansell p_ansell@yahoo.com + */ public class JarCacheStorage implements HttpCacheStorage { /** * The classpath location that is searched inside of the classloader set for - * this cache. Note this search is also done on the Thread - * contextClassLoader if none is explicitly set, and the System classloader - * if there is no contextClassLoader. + * this cache. Note this search is also done on the Thread contextClassLoader if + * none is explicitly set, and the System classloader if there is no + * contextClassLoader. */ private static final String JARCACHE_JSON = "jarcache.json"; @@ -54,8 +63,8 @@ public class JarCacheStorage implements HttpCacheStorage { private final CacheConfig cacheConfig; /** - * The classloader to use, defaults to null which will use the thread - * context classloader. + * The classloader to use, defaults to null which will use the thread context + * classloader. */ private ClassLoader classLoader = null; @@ -77,7 +86,7 @@ public class JarCacheStorage implements HttpCacheStorage { /** * Map from uri of jarcache.json (e.g. jar://blab.jar!jarcache.json) to a - * SoftReference to its content as JsonNode. + * SoftReference to its parsed content as JsonNode. * * @see #getJarCache(URL) */ @@ -100,6 +109,17 @@ public JsonNode load(URL url) throws IOException { private static final ConcurrentMap> cachedResourceList = new MapMaker() .concurrencyLevel(4).weakKeys().makeMap(); + public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig) { + this(classLoader, cacheConfig, new BasicHttpCacheStorage(cacheConfig)); + } + + public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig, + HttpCacheStorage delegate) { + setClassLoader(classLoader); + this.cacheConfig = Objects.requireNonNull(cacheConfig, "Cache config cannot be null"); + this.delegate = Objects.requireNonNull(delegate, "Delegate cannot be null"); + } + public ClassLoader getClassLoader() { ClassLoader nextClassLoader = classLoader; if (nextClassLoader != null) { @@ -110,8 +130,8 @@ public ClassLoader getClassLoader() { /** * Sets the ClassLoader used internally to a new value, or null to use - * {@link Thread#currentThread()} and {@link Thread#getContextClassLoader()} - * for each access. + * {@link Thread#currentThread()} and {@link Thread#getContextClassLoader()} for + * each access. * * @param classLoader * The classloader to use, or null to use the thread context @@ -121,17 +141,6 @@ public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } - public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig) { - this(classLoader, cacheConfig, new BasicHttpCacheStorage(cacheConfig)); - } - - public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig, - HttpCacheStorage delegate) { - setClassLoader(classLoader); - this.cacheConfig = cacheConfig; - this.delegate = delegate; - } - @Override public void putEntry(String key, HttpCacheEntry entry) throws IOException { delegate.putEntry(key, entry); @@ -156,12 +165,23 @@ public HttpCacheEntry getEntry(String key) throws IOException { requestedUri = new URI(requestedUri.getScheme(), requestedUri.getHost(), requestedUri.getPath(), requestedUri.getFragment()); } catch (final URISyntaxException e) { + if (log.isTraceEnabled()) { + log.trace( + "Failed to normalise URI before looking in cache: " + requestedUri, + e); + } + // Ignore syntax error and use the original URI directly instead + // This shouldn't happen as we already attempted to parse the URI earlier and + // would not come here if that failed } } + // getResources uses a cache to avoid scanning the classpath again for the + // current classloader for (final URL url : getResources()) { + // getJarCache attempts to use already parsed in-memory locations to avoid + // retrieving and parsing again final JsonNode tree = getJarCache(url); - // TODO: Cache tree per URL for (final JsonNode node : tree) { final URI uri = URI.create(node.get("Content-Location").asText()); if (uri.equals(requestedUri)) { @@ -176,33 +196,37 @@ public HttpCacheEntry getEntry(String key) throws IOException { } /** - * Get all of the {@code jarcache.json} resources that exist on the - * classpath + * Get all of the {@code jarcache.json} resources that exist on the classpath * - * @return A cached list of jarcache.json classpath resources as - * {@link URL}s + * @return A cached list of jarcache.json classpath resources as {@link URL}s * @throws IOException * If there was an IO error while scanning the classpath */ private List getResources() throws IOException { - ClassLoader cl = getClassLoader(); + final ClassLoader cl = getClassLoader(); // ConcurrentHashMap doesn't support null keys, so substitute a pseudo // key - Object key = cl == null ? NULL_CLASS_LOADER : cl; + final Object key = cl == null ? NULL_CLASS_LOADER : cl; + // computeIfAbsent requires unchecked exceptions for the creation process, so we + // cannot easily use it directly, instead using get and putIfAbsent List newValue = cachedResourceList.get(key); if (newValue != null) { return newValue; } if (cl != null) { - newValue = Collections.list(cl.getResources(JARCACHE_JSON)); + newValue = Collections + .unmodifiableList(Collections.list(cl.getResources(JARCACHE_JSON))); } else { - newValue = Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON)); + newValue = Collections.unmodifiableList( + Collections.list(ClassLoader.getSystemResources(JARCACHE_JSON))); } - List oldValue = cachedResourceList.putIfAbsent(key, newValue); + final List oldValue = cachedResourceList.putIfAbsent(key, newValue); + // We are not synchronising access to the ConcurrentMap, so if there were + // multiple classpath scans, we always choose the first one return oldValue != null ? oldValue : newValue; } @@ -217,8 +241,8 @@ protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingExcept protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cacheNode) throws MalformedURLException, IOException { final URL classpath = new URL(baseURL, cacheNode.get("X-Classpath").asText()); - log.debug("Cache hit for {}", requestedUri); - log.trace("{}", cacheNode); + log.debug("Cache hit for: {}", requestedUri); + log.trace("Parsed cache entry: {}", cacheNode); final List
responseHeaders = new ArrayList
(); if (!cacheNode.has(HTTP.DATE_HEADER)) { @@ -234,7 +258,9 @@ protected HttpCacheEntry cacheEntry(URI requestedUri, URL baseURL, JsonNode cach while (fieldNames.hasNext()) { final String headerName = fieldNames.next(); final JsonNode header = cacheNode.get(headerName); - responseHeaders.add(new BasicHeader(headerName, header.asText())); + if (header != null) { + responseHeaders.add(new BasicHeader(headerName, header.asText())); + } } return new HttpCacheEntry(new Date(), new Date(), From f4ce15156c62f2ba97b78c5f88b1944514002a86 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:11:17 +1000 Subject: [PATCH 307/440] Specifically normalising the port number Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/utils/JarCacheStorage.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index b210b012..dfd9ac47 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -166,9 +166,8 @@ public HttpCacheEntry getEntry(String key) throws IOException { requestedUri.getPath(), requestedUri.getFragment()); } catch (final URISyntaxException e) { if (log.isTraceEnabled()) { - log.trace( - "Failed to normalise URI before looking in cache: " + requestedUri, - e); + log.trace("Failed to normalise URI port before looking in cache: " + + requestedUri, e); } // Ignore syntax error and use the original URI directly instead // This shouldn't happen as we already attempted to parse the URI earlier and From e2647452cd07a3a2c19d4851ea64f352a3d1a335 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:13:09 +1000 Subject: [PATCH 308/440] All JsonProcessingException instances are wrapped in IOException This is despite JsonProcessingException being a subclass of IOException, because we want to wrap all of the cache failures to add the URL we were trying to fetch at the time to the message. Signed-off-by: Peter Ansell --- .../main/java/com/github/jsonldjava/utils/JarCacheStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index dfd9ac47..dd7fb84a 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -229,7 +229,7 @@ private List getResources() throws IOException { return oldValue != null ? oldValue : newValue; } - protected JsonNode getJarCache(URL url) throws IOException, JsonProcessingException { + protected JsonNode getJarCache(URL url) throws IOException { try { return jarCaches.get(url); } catch (ExecutionException e) { From c85b705e4927df8af49b77c6e8794cff0224260d Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:19:01 +1000 Subject: [PATCH 309/440] Note Guava shading Signed-off-by: Peter Ansell --- core/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/pom.xml b/core/pom.xml index 6fcf90f6..1a2f5881 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -65,6 +65,8 @@ + org.apache.maven.plugins maven-shade-plugin From d243dffd8a0d59e7a7b84ffdf61dcc9fec327731 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:31:55 +1000 Subject: [PATCH 310/440] DocumentLoader javadoc Signed-off-by: Peter Ansell --- .../jsonldjava/core/DocumentLoader.java | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index bf4e1064..35fa102a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -9,18 +9,31 @@ import com.github.jsonldjava.utils.JsonUtils; /** - * Resolves URLs to RemoteDocuments. Subclass this class to change the behaviour of loadDocument to suit your purposes. + * Resolves URLs to {@link RemoteDocument}s. Subclass this class to change the + * behaviour of loadDocument to suit your purposes. */ public class DocumentLoader { private final Map m_injectedDocs = new HashMap<>(); /** - * Identifies a system property that can be set to "true" in order to - * disallow remote context loading. + * Identifies a system property that can be set to "true" in order to disallow + * remote context loading. */ public static final String DISALLOW_REMOTE_CONTEXT_LOADING = "com.github.jsonldjava.disallowRemoteContextLoading"; + /** + * Avoid resolving a document by instead using the given serialised + * representation. + * + * @param url + * The URL this document represents. + * @param doc + * The serialised document as a String + * @return This object for fluent addition of other injected documents. + * @throws JsonLdError + * If loading of the document failed for any reason. + */ public DocumentLoader addInjectedDoc(String url, String doc) throws JsonLdError { try { m_injectedDocs.put(url, JsonUtils.fromString(doc)); @@ -30,6 +43,16 @@ public DocumentLoader addInjectedDoc(String url, String doc) throws JsonLdError } } + /** + * Loads the URL if possible, returning it as a RemoteDocument. + * + * @param url + * The URL to load + * @return The resolved URL as a RemoteDocument + * @throws JsonLdError + * If there are errors loading or remote context loading has been + * disallowed. + */ public RemoteDocument loadDocument(String url) throws JsonLdError { final RemoteDocument doc = new RemoteDocument(url, null); @@ -67,6 +90,12 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { private volatile CloseableHttpClient httpClient; + /** + * Get the {@link CloseableHttpClient} which will be used by this DocumentLoader + * to resolve HTTP and HTTPS resources. + * + * @return The {@link CloseableHttpClient} which this DocumentLoader uses. + */ public CloseableHttpClient getHttpClient() { CloseableHttpClient result = httpClient; if (result == null) { @@ -81,7 +110,11 @@ public CloseableHttpClient getHttpClient() { } /** - * Call this method to override the default CloseableHttpClient provided by JsonUtils.getDefaultHttpClient. + * Call this method to override the default CloseableHttpClient provided by + * JsonUtils.getDefaultHttpClient. + * + * @param nextHttpClient + * The {@link CloseableHttpClient} to replace the default with. */ public void setHttpClient(CloseableHttpClient nextHttpClient) { httpClient = nextHttpClient; From 9f35ceadd88cce5c295f1e353ac62af6febc1b0d Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:45:53 +1000 Subject: [PATCH 311/440] Remove unused context from RemoteDocument and make it immutable RemoteDocument had no local uses for the context parameter, as it is actually used transparently for both contexts and other JSON-LD documents. Also makes RemoteDocument immutable and encapsulates the fields to require the use of the accessors. Signed-off-by: Peter Ansell --- README.md | 3 + .../com/github/jsonldjava/core/Context.java | 2 +- .../jsonldjava/core/DocumentLoader.java | 30 ++++----- .../jsonldjava/core/JsonLdProcessor.java | 2 +- .../jsonldjava/core/RemoteDocument.java | 62 ++++++++++--------- 5 files changed, 50 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 56e9bfd3..3a21f204 100644 --- a/README.md +++ b/README.md @@ -447,6 +447,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-04-08 +* Encapsulate RemoteDocument and make it immutable. Part of new minor version 0.12 + ### 2018-04-03 * Fix performance issue caused by not caching schema.org and others that use ``Cache-Control: private`` (Patch by @HansBrende) * Cache classpath scans for jarcache.json to fix a similar performance issue diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 3f819107..3edb2150 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -195,7 +195,7 @@ else if (context instanceof String) { // 3.2.3: Dereference context final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); - final Object remoteContext = rd.document; + final Object remoteContext = rd.getDocument(); if (!(remoteContext instanceof Map) || !((Map) remoteContext) .containsKey(JsonLdConsts.CONTEXT)) { // If the dereferenced document has no top-level JSON object diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 35fa102a..7007204e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -54,30 +54,26 @@ public DocumentLoader addInjectedDoc(String url, String doc) throws JsonLdError * disallowed. */ public RemoteDocument loadDocument(String url) throws JsonLdError { - final RemoteDocument doc = new RemoteDocument(url, null); - if (m_injectedDocs.containsKey(url)) { try { - doc.setDocument(m_injectedDocs.get(url)); + return new RemoteDocument(url, m_injectedDocs.get(url)); } catch (final Exception e) { throw new JsonLdError(JsonLdError.Error.LOADING_INJECTED_CONTEXT_FAILED, url, e); } - return doc; - } - - final String disallowRemote = System - .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); - if ("true".equalsIgnoreCase(disallowRemote)) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, - "Remote context loading has been disallowed (url was " + url + ")"); - } + } else { + final String disallowRemote = System + .getProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING); + if ("true".equalsIgnoreCase(disallowRemote)) { + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, + "Remote context loading has been disallowed (url was " + url + ")"); + } - try { - doc.setDocument(JsonUtils.fromURL(new URL(url), getHttpClient())); - } catch (final Exception e) { - throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url, e); + try { + return new RemoteDocument(url, JsonUtils.fromURL(new URL(url), getHttpClient())); + } catch (final Exception e) { + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url, e); + } } - return doc; } /** diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 30c632bd..506f5cb6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -115,7 +115,7 @@ public static List expand(Object input, JsonLdOptions opts) throws JsonL if (input instanceof String && ((String) input).contains(":")) { try { final RemoteDocument tmp = opts.getDocumentLoader().loadDocument((String) input); - input = tmp.document; + input = tmp.getDocument(); // TODO: figure out how to deal with remote context } catch (final Exception e) { throw new JsonLdError(Error.LOADING_DOCUMENT_FAILED, e); diff --git a/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java b/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java index 66fb9aad..3350bb3c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java +++ b/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java @@ -1,41 +1,43 @@ package com.github.jsonldjava.core; +/** + * Encapsulates a URL along with the parsed resource matching the URL. + * + * @author Tristan King + */ public class RemoteDocument { - public String getDocumentUrl() { - return documentUrl; + private final String documentUrl; + private final Object document; + + /** + * Create a new RemoteDocument with the URL and the parsed resource for the + * document. + * + * @param url + * The URL + * @param document + * The parsed resource for the document + */ + public RemoteDocument(String url, Object document) { + this.documentUrl = url; + this.document = document; } - public void setDocumentUrl(String documentUrl) { - this.documentUrl = documentUrl; + /** + * Get the URL for this document. + * + * @return The URL for this document, as a String + */ + public String getDocumentUrl() { + return documentUrl; } + /** + * Get the parsed resource for this document. + * + * @return The parsed resource for this document + */ public Object getDocument() { return document; } - - public void setDocument(Object document) { - this.document = document; - } - - public String getContextUrl() { - return contextUrl; - } - - public void setContextUrl(String contextUrl) { - this.contextUrl = contextUrl; - } - - String documentUrl; - Object document; - String contextUrl; - - public RemoteDocument(String url, Object document) { - this(url, document, null); - } - - public RemoteDocument(String url, Object document, String context) { - this.documentUrl = url; - this.document = document; - this.contextUrl = context; - } } From 08ec2d9d1ab460778b77528b851676d00f533b10 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 13:51:26 +1000 Subject: [PATCH 312/440] Remove long deprecated field from DocumentLoader Signed-off-by: Peter Ansell --- .../java/com/github/jsonldjava/core/DocumentLoader.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index 7007204e..eb0456b4 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -76,14 +76,6 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { } } - /** - * An HTTP Accept header that prefers JSONLD. - * - * @deprecated Use {@link JsonUtils#ACCEPT_HEADER} instead. - */ - @Deprecated - public static final String ACCEPT_HEADER = JsonUtils.ACCEPT_HEADER; - private volatile CloseableHttpClient httpClient; /** From 6239e546d47accb52abb38621214870a764fcb6a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 14:04:17 +1000 Subject: [PATCH 313/440] Remove deprecated elements and fix other warnings Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/JsonLdApi.java | 4 ---- .../com/github/jsonldjava/core/RDFDataset.java | 3 +-- .../github/jsonldjava/utils/JarCacheStorage.java | 1 - .../jsonldjava/core/DocumentLoaderTest.java | 6 +----- .../jsonldjava/core/JsonLdPerformanceTest.java | 15 ++++++--------- .../jsonldjava/core/JsonLdProcessorTest.java | 1 - 6 files changed, 8 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 137ebda5..9a49252e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1930,11 +1930,7 @@ public List fromRDF(final RDFDataset dataset) throws JsonLdError { * @return A list of JSON-LD objects found in the given dataset. * @throws JsonLdError * If there was an error during conversion from RDF to JSON-LD. - * @deprecated Experimental method, only use if you are sure you need to use - * this method. Most users will need to use - * {@link #fromRDF(RDFDataset)}. */ - @Deprecated public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInDataset) throws JsonLdError { // 1) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 04b72da9..bcaec385 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -275,8 +275,7 @@ public boolean isBlankNode() { return false; } - @SuppressWarnings("rawtypes") - private static int nullSafeCompare(Comparable a, Comparable b) { + private static int nullSafeCompare(String a, String b) { if (a == null && b == null) { return 0; } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index dd7fb84a..9f20d97e 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -32,7 +32,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.cache.CacheBuilder; diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index b7c30bba..b0350f76 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -38,7 +38,6 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.SystemDefaultHttpClient; import org.apache.http.util.EntityUtils; import org.junit.After; import org.junit.Ignore; @@ -340,14 +339,11 @@ public void sharedHttpClient() throws Exception { assertSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); } - @SuppressWarnings("deprecation") @Test public void differentHttpClient() throws Exception { // Custom http client try { - // Only using deprecated http client to verify that the usual HTTP - // client can be overridden - documentLoader.setHttpClient(new SystemDefaultHttpClient()); + documentLoader.setHttpClient(JsonUtils.createDefaultHttpClient()); assertNotSame(documentLoader.getHttpClient(), new DocumentLoader().getHttpClient()); } finally { // Use default again diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 42c70b92..0f9cf502 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -622,23 +622,20 @@ public final void duplicatedTriplesInAnRDFDataset() throws Exception { final JsonLdOptions options = new JsonLdOptions(); options.useNamespaces = true; - Object fromRDF; - String jsonld; - // System.out.println("\nJSON-LD output is OK:\n"); - fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + Object fromRDF1 = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); - jsonld = JsonUtils.toPrettyString(fromRDF); - // System.out.println(jsonld); + String jsonld1 = JsonUtils.toPrettyString(fromRDF1); + // System.out.println(jsonld1); // System.out.println( // "\nWouldn't be the case assuming there is no duplicated triple in // RDFDataset:\n"); - fromRDF = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf, true), + Object fromRDF2 = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf, true), inputRdf.getContext(), options); - jsonld = JsonUtils.toPrettyString(fromRDF); - // System.out.println(jsonld); + String jsonld2 = JsonUtils.toPrettyString(fromRDF2); + // System.out.println(jsonld2); } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index dcbe8f43..3d70b32b 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -202,7 +202,6 @@ public boolean accept(File dir, String name) { })); final Collection rdata = new ArrayList(); - final int count = 0; for (final File in : manifestfiles) { // System.out.println("Reading: " + in.getCanonicalPath()); final FileInputStream manifestfile = new FileInputStream(in); From 54b57415e62421a30357a4adc6ea380d6af1d14c Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 14:16:42 +1000 Subject: [PATCH 314/440] Hide internal only classes Signed-off-by: Peter Ansell --- core/src/main/java/com/github/jsonldjava/core/Regex.java | 2 +- core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Regex.java b/core/src/main/java/com/github/jsonldjava/core/Regex.java index 7a6236a7..33f43759 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Regex.java +++ b/core/src/main/java/com/github/jsonldjava/core/Regex.java @@ -2,7 +2,7 @@ import java.util.regex.Pattern; -public class Regex { +class Regex { final public static Pattern TRICKY_UTF_CHARS = Pattern.compile( // ("1.7".equals(System.getProperty("java.specification.version")) ? // "[\\x{10000}-\\x{EFFFF}]" : diff --git a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java index 98e2fb45..a55f45a2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java +++ b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java @@ -3,7 +3,7 @@ import java.util.LinkedHashMap; import java.util.Map; -public class UniqueNamer { +class UniqueNamer { private final String prefix; private int counter; private Map existing; From 36b54053750e5a51b39ee2328ecc8cd19039131a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 14:22:15 +1000 Subject: [PATCH 315/440] Fix line endings on some files Signed-off-by: Peter Ansell --- .../github/jsonldjava/core/JsonLdOptions.java | 448 ++++++------- .../com/github/jsonldjava/core/RDFParser.java | 94 +-- .../github/jsonldjava/core/UniqueNamer.java | 142 ++-- .../github/jsonldjava/utils/JsonLdUrl.java | 630 +++++++++--------- core/src/test/resources/log4j.properties | 10 +- 5 files changed, 662 insertions(+), 662 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index c48f676c..03e85309 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -1,224 +1,224 @@ -package com.github.jsonldjava.core; - -import com.github.jsonldjava.core.JsonLdConsts.Embed; - -/** - * The JsonLdOptions type as specified in the - * JSON-LD- - * API specification. - * - * @author tristan - * - */ -public class JsonLdOptions { - - public static final String JSON_LD_1_0 = "json-ld-1.0"; - - public static final String JSON_LD_1_1 = "json-ld-1.1"; - - public static final String JSON_LD_1_1_FRAME = "json-ld-1.1-expand-frame"; - - public static final boolean DEFAULT_COMPACT_ARRAYS = true; - - /** - * Constructs an instance of JsonLdOptions using an empty base. - */ - public JsonLdOptions() { - this(""); - } - - /** - * Constructs an instance of JsonLdOptions using the given base. - * - * @param base - * The base IRI for the document. - */ - public JsonLdOptions(String base) { - this.setBase(base); - } - - // Base options : http://www.w3.org/TR/json-ld-api/#idl-def-JsonLdOptions - - /** - * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-base - */ - private String base = null; - - /** - * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-compactArrays - */ - private Boolean compactArrays = DEFAULT_COMPACT_ARRAYS; - /** - * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-expandContext - */ - private Object expandContext = null; - /** - * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-processingMode - */ - private String processingMode = JSON_LD_1_0; - /** - * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-documentLoader - */ - private DocumentLoader documentLoader = new DocumentLoader(); - - // Frame options : http://json-ld.org/spec/latest/json-ld-framing/ - - private Embed embed = Embed.LAST; - private Boolean explicit = null; - private Boolean omitDefault = null; - private Boolean pruneBlankNodeIdentifiers = true; - private Boolean requireAll = false; - - // RDF conversion options : - // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm - - Boolean useRdfType = false; - Boolean useNativeTypes = false; - private boolean produceGeneralizedRdf = false; - - public String getEmbed() { - switch (this.embed) { - case ALWAYS: - return "@always"; - case NEVER: - return "@never"; - case LINK: - return "@link"; - default: - return "@last"; - } - } - - Embed getEmbedVal() { - return this.embed; - } - - public void setEmbed(Boolean embed) { - this.embed = embed ? Embed.LAST : Embed.NEVER; - } - - public void setEmbed(String embed) throws JsonLdError { - switch (embed) { - case "@always": - this.embed = Embed.ALWAYS; - break; - case "@never": - this.embed = Embed.NEVER; - break; - case "@last": - this.embed = Embed.LAST; - break; - case "@link": - this.embed = Embed.LINK; - break; - default: - throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); - } - } - - public Boolean getExplicit() { - return explicit; - } - - public void setExplicit(Boolean explicit) { - this.explicit = explicit; - } - - public Boolean getOmitDefault() { - return omitDefault; - } - - public void setOmitDefault(Boolean omitDefault) { - this.omitDefault = omitDefault; - } - - public Boolean getPruneBlankNodeIdentifiers() { - return pruneBlankNodeIdentifiers && getProcessingMode().equals(JSON_LD_1_1); - } - - public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { - if (pruneBlankNodeIdentifiers) { - setProcessingMode(JSON_LD_1_1); - } - this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; - } - - public Boolean getRequireAll() { - return this.requireAll; - } - - public void setRequireAll(Boolean requireAll) { - this.requireAll = requireAll; - } - - public Boolean getCompactArrays() { - return compactArrays; - } - - public void setCompactArrays(Boolean compactArrays) { - this.compactArrays = compactArrays; - } - - public Object getExpandContext() { - return expandContext; - } - - public void setExpandContext(Object expandContext) { - this.expandContext = expandContext; - } - - public String getProcessingMode() { - return processingMode; - } - - public void setProcessingMode(String processingMode) { - this.processingMode = processingMode; - } - - public String getBase() { - return base; - } - - public void setBase(String base) { - this.base = base; - } - - public Boolean getUseRdfType() { - return useRdfType; - } - - public void setUseRdfType(Boolean useRdfType) { - this.useRdfType = useRdfType; - } - - public Boolean getUseNativeTypes() { - return useNativeTypes; - } - - public void setUseNativeTypes(Boolean useNativeTypes) { - this.useNativeTypes = useNativeTypes; - } - - public boolean getProduceGeneralizedRdf() { - return this.produceGeneralizedRdf; - } - - public void setProduceGeneralizedRdf(Boolean produceGeneralizedRdf) { - this.produceGeneralizedRdf = produceGeneralizedRdf; - } - - public DocumentLoader getDocumentLoader() { - return documentLoader; - } - - public void setDocumentLoader(DocumentLoader documentLoader) { - this.documentLoader = documentLoader; - } - - // TODO: THE FOLLOWING ONLY EXIST SO I DON'T HAVE TO DELETE A LOT OF CODE, - // REMOVE IT WHEN DONE - public String format = null; - public Boolean useNamespaces = false; - public String outputForm = null; - -} +package com.github.jsonldjava.core; + +import com.github.jsonldjava.core.JsonLdConsts.Embed; + +/** + * The JsonLdOptions type as specified in the + * JSON-LD- + * API specification. + * + * @author tristan + * + */ +public class JsonLdOptions { + + public static final String JSON_LD_1_0 = "json-ld-1.0"; + + public static final String JSON_LD_1_1 = "json-ld-1.1"; + + public static final String JSON_LD_1_1_FRAME = "json-ld-1.1-expand-frame"; + + public static final boolean DEFAULT_COMPACT_ARRAYS = true; + + /** + * Constructs an instance of JsonLdOptions using an empty base. + */ + public JsonLdOptions() { + this(""); + } + + /** + * Constructs an instance of JsonLdOptions using the given base. + * + * @param base + * The base IRI for the document. + */ + public JsonLdOptions(String base) { + this.setBase(base); + } + + // Base options : http://www.w3.org/TR/json-ld-api/#idl-def-JsonLdOptions + + /** + * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-base + */ + private String base = null; + + /** + * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-compactArrays + */ + private Boolean compactArrays = DEFAULT_COMPACT_ARRAYS; + /** + * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-expandContext + */ + private Object expandContext = null; + /** + * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-processingMode + */ + private String processingMode = JSON_LD_1_0; + /** + * http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-documentLoader + */ + private DocumentLoader documentLoader = new DocumentLoader(); + + // Frame options : http://json-ld.org/spec/latest/json-ld-framing/ + + private Embed embed = Embed.LAST; + private Boolean explicit = null; + private Boolean omitDefault = null; + private Boolean pruneBlankNodeIdentifiers = true; + private Boolean requireAll = false; + + // RDF conversion options : + // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm + + Boolean useRdfType = false; + Boolean useNativeTypes = false; + private boolean produceGeneralizedRdf = false; + + public String getEmbed() { + switch (this.embed) { + case ALWAYS: + return "@always"; + case NEVER: + return "@never"; + case LINK: + return "@link"; + default: + return "@last"; + } + } + + Embed getEmbedVal() { + return this.embed; + } + + public void setEmbed(Boolean embed) { + this.embed = embed ? Embed.LAST : Embed.NEVER; + } + + public void setEmbed(String embed) throws JsonLdError { + switch (embed) { + case "@always": + this.embed = Embed.ALWAYS; + break; + case "@never": + this.embed = Embed.NEVER; + break; + case "@last": + this.embed = Embed.LAST; + break; + case "@link": + this.embed = Embed.LINK; + break; + default: + throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); + } + } + + public Boolean getExplicit() { + return explicit; + } + + public void setExplicit(Boolean explicit) { + this.explicit = explicit; + } + + public Boolean getOmitDefault() { + return omitDefault; + } + + public void setOmitDefault(Boolean omitDefault) { + this.omitDefault = omitDefault; + } + + public Boolean getPruneBlankNodeIdentifiers() { + return pruneBlankNodeIdentifiers && getProcessingMode().equals(JSON_LD_1_1); + } + + public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { + if (pruneBlankNodeIdentifiers) { + setProcessingMode(JSON_LD_1_1); + } + this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; + } + + public Boolean getRequireAll() { + return this.requireAll; + } + + public void setRequireAll(Boolean requireAll) { + this.requireAll = requireAll; + } + + public Boolean getCompactArrays() { + return compactArrays; + } + + public void setCompactArrays(Boolean compactArrays) { + this.compactArrays = compactArrays; + } + + public Object getExpandContext() { + return expandContext; + } + + public void setExpandContext(Object expandContext) { + this.expandContext = expandContext; + } + + public String getProcessingMode() { + return processingMode; + } + + public void setProcessingMode(String processingMode) { + this.processingMode = processingMode; + } + + public String getBase() { + return base; + } + + public void setBase(String base) { + this.base = base; + } + + public Boolean getUseRdfType() { + return useRdfType; + } + + public void setUseRdfType(Boolean useRdfType) { + this.useRdfType = useRdfType; + } + + public Boolean getUseNativeTypes() { + return useNativeTypes; + } + + public void setUseNativeTypes(Boolean useNativeTypes) { + this.useNativeTypes = useNativeTypes; + } + + public boolean getProduceGeneralizedRdf() { + return this.produceGeneralizedRdf; + } + + public void setProduceGeneralizedRdf(Boolean produceGeneralizedRdf) { + this.produceGeneralizedRdf = produceGeneralizedRdf; + } + + public DocumentLoader getDocumentLoader() { + return documentLoader; + } + + public void setDocumentLoader(DocumentLoader documentLoader) { + this.documentLoader = documentLoader; + } + + // TODO: THE FOLLOWING ONLY EXIST SO I DON'T HAVE TO DELETE A LOT OF CODE, + // REMOVE IT WHEN DONE + public String format = null; + public Boolean useNamespaces = false; + public String outputForm = null; + +} diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFParser.java b/core/src/main/java/com/github/jsonldjava/core/RDFParser.java index 4b6fed61..db4ec692 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFParser.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFParser.java @@ -1,47 +1,47 @@ -package com.github.jsonldjava.core; - -/** - * Interface for parsing RDF into the RDF Dataset objects to be used by - * JSONLD.fromRDF - * - * @author Tristan - * - */ -public interface RDFParser { - - /** - * Parse the input into the internal RDF Dataset format The format is a Map - * with the following structure: { GRAPH_1: [ TRIPLE_1, TRIPLE_2, ..., - * TRIPLE_N ], GRAPH_2: [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ], ... GRAPH_N: - * [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ] } - * - * GRAPH: Must be the graph name/IRI. if no graph is present for a triple, - * add it to the "@default" graph TRIPLE: Must be a map with the following - * structure: { "subject" : SUBJECT "predicate" : PREDICATE "object" : - * OBJECT } - * - * Each of the values in the triple map must also be a map with the - * following key-value pairs: "value" : The value of the node. "subject" can - * be an IRI or blank node id. "predicate" should only ever be an IRI - * "object" can be and IRI or blank node id, or a literal value (represented - * as a string) "type" : "IRI" if the value is an IRI or "blank node" if the - * value is a blank node. "object" can also be "literal" in the case of - * literals. The value of "object" can also contain the following optional - * key-value pairs: "language" : the language value of a string literal - * "datatype" : the datatype of the literal. (if not set will default to - * XSD:string, if set to null, null will be used). - * - * The RDFDatasetUtils class has the following helper methods to make - * generating this format easier: result = getInitialRDFDatasetResult(); - * triple = generateTriple(s,p,o); triple = - * generateTriple(s,p,value,datatype,language); - * addTripleToRDFDatasetResult(result, graphName, triple); - * - * @param input - * The RDF library specific input to parse - * @return The input parsed using the internal RDF Dataset format - * @throws JsonLdError - * If there was an error parsing the input - */ - public RDFDataset parse(Object input) throws JsonLdError; -} +package com.github.jsonldjava.core; + +/** + * Interface for parsing RDF into the RDF Dataset objects to be used by + * JSONLD.fromRDF + * + * @author Tristan + * + */ +public interface RDFParser { + + /** + * Parse the input into the internal RDF Dataset format The format is a Map + * with the following structure: { GRAPH_1: [ TRIPLE_1, TRIPLE_2, ..., + * TRIPLE_N ], GRAPH_2: [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ], ... GRAPH_N: + * [ TRIPLE_1, TRIPLE_2, ..., TRIPLE_N ] } + * + * GRAPH: Must be the graph name/IRI. if no graph is present for a triple, + * add it to the "@default" graph TRIPLE: Must be a map with the following + * structure: { "subject" : SUBJECT "predicate" : PREDICATE "object" : + * OBJECT } + * + * Each of the values in the triple map must also be a map with the + * following key-value pairs: "value" : The value of the node. "subject" can + * be an IRI or blank node id. "predicate" should only ever be an IRI + * "object" can be and IRI or blank node id, or a literal value (represented + * as a string) "type" : "IRI" if the value is an IRI or "blank node" if the + * value is a blank node. "object" can also be "literal" in the case of + * literals. The value of "object" can also contain the following optional + * key-value pairs: "language" : the language value of a string literal + * "datatype" : the datatype of the literal. (if not set will default to + * XSD:string, if set to null, null will be used). + * + * The RDFDatasetUtils class has the following helper methods to make + * generating this format easier: result = getInitialRDFDatasetResult(); + * triple = generateTriple(s,p,o); triple = + * generateTriple(s,p,value,datatype,language); + * addTripleToRDFDatasetResult(result, graphName, triple); + * + * @param input + * The RDF library specific input to parse + * @return The input parsed using the internal RDF Dataset format + * @throws JsonLdError + * If there was an error parsing the input + */ + public RDFDataset parse(Object input) throws JsonLdError; +} diff --git a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java index a55f45a2..0d0aa760 100644 --- a/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java +++ b/core/src/main/java/com/github/jsonldjava/core/UniqueNamer.java @@ -1,72 +1,72 @@ -package com.github.jsonldjava.core; - -import java.util.LinkedHashMap; -import java.util.Map; - -class UniqueNamer { - private final String prefix; - private int counter; - private Map existing; - - /** - * Creates a new UniqueNamer. A UniqueNamer issues unique names, keeping - * track of any previously issued names. - * - * @param prefix - * the prefix to use ('<prefix><counter>'). - */ - public UniqueNamer(String prefix) { - this.prefix = prefix; - this.counter = 0; - this.existing = new LinkedHashMap(); - } - - /** - * Copies this UniqueNamer. - * - * @return a copy of this UniqueNamer. - */ - @Override - public UniqueNamer clone() { - final UniqueNamer copy = new UniqueNamer(this.prefix); - copy.counter = this.counter; - copy.existing = (Map) JsonLdUtils.clone(this.existing); - return copy; - } - - /** - * Gets the new name for the given old name, where if no old name is given a - * new name will be generated. - * - * @param oldName - * the old name to get the new name for. - * - * @return the new name. - */ - public String getName(String oldName) { - if (oldName != null && this.existing.containsKey(oldName)) { - return this.existing.get(oldName); - } - - final String name = this.prefix + this.counter; - this.counter++; - - if (oldName != null) { - this.existing.put(oldName, name); - } - - return name; - } - - public String getName() { - return getName(null); - } - - public Boolean isNamed(String oldName) { - return this.existing.containsKey(oldName); - } - - public Map existing() { - return existing; - } +package com.github.jsonldjava.core; + +import java.util.LinkedHashMap; +import java.util.Map; + +class UniqueNamer { + private final String prefix; + private int counter; + private Map existing; + + /** + * Creates a new UniqueNamer. A UniqueNamer issues unique names, keeping + * track of any previously issued names. + * + * @param prefix + * the prefix to use ('<prefix><counter>'). + */ + public UniqueNamer(String prefix) { + this.prefix = prefix; + this.counter = 0; + this.existing = new LinkedHashMap(); + } + + /** + * Copies this UniqueNamer. + * + * @return a copy of this UniqueNamer. + */ + @Override + public UniqueNamer clone() { + final UniqueNamer copy = new UniqueNamer(this.prefix); + copy.counter = this.counter; + copy.existing = (Map) JsonLdUtils.clone(this.existing); + return copy; + } + + /** + * Gets the new name for the given old name, where if no old name is given a + * new name will be generated. + * + * @param oldName + * the old name to get the new name for. + * + * @return the new name. + */ + public String getName(String oldName) { + if (oldName != null && this.existing.containsKey(oldName)) { + return this.existing.get(oldName); + } + + final String name = this.prefix + this.counter; + this.counter++; + + if (oldName != null) { + this.existing.put(oldName, name); + } + + return name; + } + + public String getName() { + return getName(null); + } + + public Boolean isNamed(String oldName) { + return this.existing.containsKey(oldName); + } + + public Map existing() { + return existing; + } } \ No newline at end of file diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java index db0fed7e..a2153831 100755 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java @@ -1,315 +1,315 @@ -package com.github.jsonldjava.utils; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class JsonLdUrl { - - public String href = ""; - public String protocol = ""; - public String host = ""; - public String auth = ""; - public String user = ""; - public String password = ""; - public String hostname = ""; - public String port = ""; - public String relative = ""; - public String path = ""; - public String directory = ""; - public String file = ""; - public String query = ""; - public String hash = ""; - - // things not populated by the regex (NOTE: i don't think it matters if - // these are null or "" to start with) - public String pathname = null; - public String normalizedPath = null; - public String authority = null; - - private static Pattern parser = Pattern.compile( - "^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"); - - public static JsonLdUrl parse(String url) { - final JsonLdUrl rval = new JsonLdUrl(); - rval.href = url; - - final Matcher matcher = parser.matcher(url); - if (matcher.matches()) { - if (matcher.group(1) != null) { - rval.protocol = matcher.group(1); - } - if (matcher.group(2) != null) { - rval.host = matcher.group(2); - } - if (matcher.group(3) != null) { - rval.auth = matcher.group(3); - } - if (matcher.group(4) != null) { - rval.user = matcher.group(4); - } - if (matcher.group(5) != null) { - rval.password = matcher.group(5); - } - if (matcher.group(6) != null) { - rval.hostname = matcher.group(6); - } - if (matcher.group(7) != null) { - rval.port = matcher.group(7); - } - if (matcher.group(8) != null) { - rval.relative = matcher.group(8); - } - if (matcher.group(9) != null) { - rval.path = matcher.group(9); - } - if (matcher.group(10) != null) { - rval.directory = matcher.group(10); - } - if (matcher.group(11) != null) { - rval.file = matcher.group(11); - } - if (matcher.group(12) != null) { - rval.query = matcher.group(12); - } - if (matcher.group(13) != null) { - rval.hash = matcher.group(13); - } - - // normalize to node.js API - if (!"".equals(rval.host) && "".equals(rval.path)) { - rval.path = "/"; - } - rval.pathname = rval.path; - parseAuthority(rval); - rval.normalizedPath = removeDotSegments(rval.pathname, !"".equals(rval.authority)); - if (!"".equals(rval.query)) { - rval.path += "?" + rval.query; - } - if (!"".equals(rval.protocol)) { - rval.protocol += ":"; - } - if (!"".equals(rval.hash)) { - rval.hash = "#" + rval.hash; - } - return rval; - } - - return rval; - } - - /** - * Removes dot segments from a JsonLdUrl path. - * - * @param path - * the path to remove dot segments from. - * @param hasAuthority - * true if the JsonLdUrl has an authority, false if not. - * @return The URL without the dot segments - */ - public static String removeDotSegments(String path, boolean hasAuthority) { - String rval = ""; - - if (path.indexOf("/") == 0) { - rval = "/"; - } - - // RFC 3986 5.2.4 (reworked) - final List input = new ArrayList(Arrays.asList(path.split("/"))); - if (path.endsWith("/")) { - // javascript .split includes a blank entry if the string ends with - // the delimiter, java .split does not so we need to add it manually - input.add(""); - } - final List output = new ArrayList(); - for (int i = 0; i < input.size(); i++) { - if (".".equals(input.get(i)) || ("".equals(input.get(i)) && input.size() - i > 1)) { - // input.remove(0); - continue; - } - if ("..".equals(input.get(i))) { - // input.remove(0); - if (hasAuthority - || (output.size() > 0 && !"..".equals(output.get(output.size() - 1)))) { - // [].pop() doesn't fail, to replicate this we need to check - // that there is something to remove - if (output.size() > 0) { - output.remove(output.size() - 1); - } - } else { - output.add(".."); - } - continue; - } - output.add(input.get(i)); - // input.remove(0); - } - - if (output.size() > 0) { - rval += output.get(0); - for (int i = 1; i < output.size(); i++) { - rval += "/" + output.get(i); - } - } - return rval; - } - - public static String removeBase(Object baseobj, String iri) { - if (baseobj == null) { - return iri; - } - - JsonLdUrl base; - if (baseobj instanceof String) { - base = JsonLdUrl.parse((String) baseobj); - } else { - base = (JsonLdUrl) baseobj; - } - - // establish base root - String root = ""; - if (!"".equals(base.href)) { - root += (base.protocol) + "//" + base.authority; - } - // support network-path reference with empty base - else if (iri.indexOf("//") != 0) { - root += "//"; - } - - // IRI not relative to base - if (iri.indexOf(root) != 0) { - return iri; - } - - // remove root from IRI and parse remainder - final JsonLdUrl rel = JsonLdUrl.parse(iri.substring(root.length())); - - // remove path segments that match - final List baseSegments = new ArrayList( - Arrays.asList(base.normalizedPath.split("/"))); - if (base.normalizedPath.endsWith("/")) { - baseSegments.add(""); - } - final List iriSegments = new ArrayList( - Arrays.asList(rel.normalizedPath.split("/"))); - if (rel.normalizedPath.endsWith("/")) { - iriSegments.add(""); - } - - while (baseSegments.size() > 0 && iriSegments.size() > 0) { - if (!baseSegments.get(0).equals(iriSegments.get(0))) { - break; - } - if (baseSegments.size() > 0) { - baseSegments.remove(0); - } - if (iriSegments.size() > 0) { - iriSegments.remove(0); - } - } - - // use '../' for each non-matching base segment - String rval = ""; - if (baseSegments.size() > 0) { - // don't count the last segment if it isn't a path (doesn't end in - // '/') - // don't count empty first segment, it means base began with '/' - if (!base.normalizedPath.endsWith("/") || "".equals(baseSegments.get(0))) { - baseSegments.remove(baseSegments.size() - 1); - } - for (int i = 0; i < baseSegments.size(); ++i) { - rval += "../"; - } - } - - // prepend remaining segments - if (iriSegments.size() > 0) { - rval += iriSegments.get(0); - } - for (int i = 1; i < iriSegments.size(); i++) { - rval += "/" + iriSegments.get(i); - } - - // add query and hash - if (!"".equals(rel.query)) { - rval += "?" + rel.query; - } - if (!"".equals(rel.hash)) { - rval += rel.hash; - } - - if ("".equals(rval)) { - rval = "./"; - } - - return rval; - } - - public static String resolve(String baseUri, String pathToResolve) { - // TODO: some input will need to be normalized to perform the expected - // result with java - // TODO: we can do this without using java URI! - if (baseUri == null) { - return pathToResolve; - } - if (pathToResolve == null || "".equals(pathToResolve.trim())) { - return baseUri; - } - try { - URI uri = new URI(baseUri); - // query string parsing - if (pathToResolve.startsWith("?")) { - // drop fragment from uri if it has one - if (uri.getFragment() != null) { - uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null); - } - // add query to the end manually (as URI.resolve does it wrong) - return uri.toString() + pathToResolve; - } - - uri = uri.resolve(pathToResolve); - // java doesn't discard unnecessary dot segments - String path = uri.getPath(); - if (path != null) { - path = JsonLdUrl.removeDotSegments(uri.getPath(), true); - } - return new URI(uri.getScheme(), uri.getAuthority(), path, uri.getQuery(), - uri.getFragment()).toString(); - } catch (final URISyntaxException e) { - return null; - } - } - - /** - * Parses the authority for the pre-parsed given JsonLdUrl. - * - * @param parsed - * the pre-parsed JsonLdUrl. - */ - private static void parseAuthority(JsonLdUrl parsed) { - // parse authority for unparsed relative network-path reference - if (parsed.href.indexOf(":") == -1 && parsed.href.indexOf("//") == 0 - && "".equals(parsed.host)) { - // must parse authority from pathname - parsed.pathname = parsed.pathname.substring(2); - final int idx = parsed.pathname.indexOf("/"); - if (idx == -1) { - parsed.authority = parsed.pathname; - parsed.pathname = ""; - } else { - parsed.authority = parsed.pathname.substring(0, idx); - parsed.pathname = parsed.pathname.substring(idx); - } - } else { - // construct authority - parsed.authority = parsed.host; - if (!"".equals(parsed.auth)) { - parsed.authority = parsed.auth + "@" + parsed.authority; - } - } - } -} +package com.github.jsonldjava.utils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class JsonLdUrl { + + public String href = ""; + public String protocol = ""; + public String host = ""; + public String auth = ""; + public String user = ""; + public String password = ""; + public String hostname = ""; + public String port = ""; + public String relative = ""; + public String path = ""; + public String directory = ""; + public String file = ""; + public String query = ""; + public String hash = ""; + + // things not populated by the regex (NOTE: i don't think it matters if + // these are null or "" to start with) + public String pathname = null; + public String normalizedPath = null; + public String authority = null; + + private static Pattern parser = Pattern.compile( + "^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"); + + public static JsonLdUrl parse(String url) { + final JsonLdUrl rval = new JsonLdUrl(); + rval.href = url; + + final Matcher matcher = parser.matcher(url); + if (matcher.matches()) { + if (matcher.group(1) != null) { + rval.protocol = matcher.group(1); + } + if (matcher.group(2) != null) { + rval.host = matcher.group(2); + } + if (matcher.group(3) != null) { + rval.auth = matcher.group(3); + } + if (matcher.group(4) != null) { + rval.user = matcher.group(4); + } + if (matcher.group(5) != null) { + rval.password = matcher.group(5); + } + if (matcher.group(6) != null) { + rval.hostname = matcher.group(6); + } + if (matcher.group(7) != null) { + rval.port = matcher.group(7); + } + if (matcher.group(8) != null) { + rval.relative = matcher.group(8); + } + if (matcher.group(9) != null) { + rval.path = matcher.group(9); + } + if (matcher.group(10) != null) { + rval.directory = matcher.group(10); + } + if (matcher.group(11) != null) { + rval.file = matcher.group(11); + } + if (matcher.group(12) != null) { + rval.query = matcher.group(12); + } + if (matcher.group(13) != null) { + rval.hash = matcher.group(13); + } + + // normalize to node.js API + if (!"".equals(rval.host) && "".equals(rval.path)) { + rval.path = "/"; + } + rval.pathname = rval.path; + parseAuthority(rval); + rval.normalizedPath = removeDotSegments(rval.pathname, !"".equals(rval.authority)); + if (!"".equals(rval.query)) { + rval.path += "?" + rval.query; + } + if (!"".equals(rval.protocol)) { + rval.protocol += ":"; + } + if (!"".equals(rval.hash)) { + rval.hash = "#" + rval.hash; + } + return rval; + } + + return rval; + } + + /** + * Removes dot segments from a JsonLdUrl path. + * + * @param path + * the path to remove dot segments from. + * @param hasAuthority + * true if the JsonLdUrl has an authority, false if not. + * @return The URL without the dot segments + */ + public static String removeDotSegments(String path, boolean hasAuthority) { + String rval = ""; + + if (path.indexOf("/") == 0) { + rval = "/"; + } + + // RFC 3986 5.2.4 (reworked) + final List input = new ArrayList(Arrays.asList(path.split("/"))); + if (path.endsWith("/")) { + // javascript .split includes a blank entry if the string ends with + // the delimiter, java .split does not so we need to add it manually + input.add(""); + } + final List output = new ArrayList(); + for (int i = 0; i < input.size(); i++) { + if (".".equals(input.get(i)) || ("".equals(input.get(i)) && input.size() - i > 1)) { + // input.remove(0); + continue; + } + if ("..".equals(input.get(i))) { + // input.remove(0); + if (hasAuthority + || (output.size() > 0 && !"..".equals(output.get(output.size() - 1)))) { + // [].pop() doesn't fail, to replicate this we need to check + // that there is something to remove + if (output.size() > 0) { + output.remove(output.size() - 1); + } + } else { + output.add(".."); + } + continue; + } + output.add(input.get(i)); + // input.remove(0); + } + + if (output.size() > 0) { + rval += output.get(0); + for (int i = 1; i < output.size(); i++) { + rval += "/" + output.get(i); + } + } + return rval; + } + + public static String removeBase(Object baseobj, String iri) { + if (baseobj == null) { + return iri; + } + + JsonLdUrl base; + if (baseobj instanceof String) { + base = JsonLdUrl.parse((String) baseobj); + } else { + base = (JsonLdUrl) baseobj; + } + + // establish base root + String root = ""; + if (!"".equals(base.href)) { + root += (base.protocol) + "//" + base.authority; + } + // support network-path reference with empty base + else if (iri.indexOf("//") != 0) { + root += "//"; + } + + // IRI not relative to base + if (iri.indexOf(root) != 0) { + return iri; + } + + // remove root from IRI and parse remainder + final JsonLdUrl rel = JsonLdUrl.parse(iri.substring(root.length())); + + // remove path segments that match + final List baseSegments = new ArrayList( + Arrays.asList(base.normalizedPath.split("/"))); + if (base.normalizedPath.endsWith("/")) { + baseSegments.add(""); + } + final List iriSegments = new ArrayList( + Arrays.asList(rel.normalizedPath.split("/"))); + if (rel.normalizedPath.endsWith("/")) { + iriSegments.add(""); + } + + while (baseSegments.size() > 0 && iriSegments.size() > 0) { + if (!baseSegments.get(0).equals(iriSegments.get(0))) { + break; + } + if (baseSegments.size() > 0) { + baseSegments.remove(0); + } + if (iriSegments.size() > 0) { + iriSegments.remove(0); + } + } + + // use '../' for each non-matching base segment + String rval = ""; + if (baseSegments.size() > 0) { + // don't count the last segment if it isn't a path (doesn't end in + // '/') + // don't count empty first segment, it means base began with '/' + if (!base.normalizedPath.endsWith("/") || "".equals(baseSegments.get(0))) { + baseSegments.remove(baseSegments.size() - 1); + } + for (int i = 0; i < baseSegments.size(); ++i) { + rval += "../"; + } + } + + // prepend remaining segments + if (iriSegments.size() > 0) { + rval += iriSegments.get(0); + } + for (int i = 1; i < iriSegments.size(); i++) { + rval += "/" + iriSegments.get(i); + } + + // add query and hash + if (!"".equals(rel.query)) { + rval += "?" + rel.query; + } + if (!"".equals(rel.hash)) { + rval += rel.hash; + } + + if ("".equals(rval)) { + rval = "./"; + } + + return rval; + } + + public static String resolve(String baseUri, String pathToResolve) { + // TODO: some input will need to be normalized to perform the expected + // result with java + // TODO: we can do this without using java URI! + if (baseUri == null) { + return pathToResolve; + } + if (pathToResolve == null || "".equals(pathToResolve.trim())) { + return baseUri; + } + try { + URI uri = new URI(baseUri); + // query string parsing + if (pathToResolve.startsWith("?")) { + // drop fragment from uri if it has one + if (uri.getFragment() != null) { + uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null); + } + // add query to the end manually (as URI.resolve does it wrong) + return uri.toString() + pathToResolve; + } + + uri = uri.resolve(pathToResolve); + // java doesn't discard unnecessary dot segments + String path = uri.getPath(); + if (path != null) { + path = JsonLdUrl.removeDotSegments(uri.getPath(), true); + } + return new URI(uri.getScheme(), uri.getAuthority(), path, uri.getQuery(), + uri.getFragment()).toString(); + } catch (final URISyntaxException e) { + return null; + } + } + + /** + * Parses the authority for the pre-parsed given JsonLdUrl. + * + * @param parsed + * the pre-parsed JsonLdUrl. + */ + private static void parseAuthority(JsonLdUrl parsed) { + // parse authority for unparsed relative network-path reference + if (parsed.href.indexOf(":") == -1 && parsed.href.indexOf("//") == 0 + && "".equals(parsed.host)) { + // must parse authority from pathname + parsed.pathname = parsed.pathname.substring(2); + final int idx = parsed.pathname.indexOf("/"); + if (idx == -1) { + parsed.authority = parsed.pathname; + parsed.pathname = ""; + } else { + parsed.authority = parsed.pathname.substring(0, idx); + parsed.pathname = parsed.pathname.substring(idx); + } + } else { + // construct authority + parsed.authority = parsed.host; + if (!"".equals(parsed.auth)) { + parsed.authority = parsed.auth + "@" + parsed.authority; + } + } + } +} diff --git a/core/src/test/resources/log4j.properties b/core/src/test/resources/log4j.properties index 136eba0c..6cebabb1 100644 --- a/core/src/test/resources/log4j.properties +++ b/core/src/test/resources/log4j.properties @@ -1,5 +1,5 @@ -log4j.rootLogger=INFO, R - -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n +log4j.rootLogger=INFO, R + +log4j.appender.R=org.apache.log4j.ConsoleAppender +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n From ada8155305e48f9b3f9c3695ad88a851b656b13e Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 14:41:27 +1000 Subject: [PATCH 316/440] Release 0.12.0 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 1a2f5881..a2d6e5d7 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.0-SNAPSHOT + 0.12.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index e54ba293..b4914569 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.0-SNAPSHOT + 0.12.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From cecf0bcbac110c1cd8c4ce95a672b28978780e31 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 15:13:05 +1000 Subject: [PATCH 317/440] Update readme Signed-off-by: Peter Ansell --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3a21f204..862c8e53 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.11.1 + 0.12.0 Code example @@ -448,7 +448,8 @@ CHANGELOG ========= ### 2018-04-08 -* Encapsulate RemoteDocument and make it immutable. Part of new minor version 0.12 +* Release 0.12.0 +* Encapsulate RemoteDocument and make it immutable ### 2018-04-03 * Fix performance issue caused by not caching schema.org and others that use ``Cache-Control: private`` (Patch by @HansBrende) From 47353f9e249ae9608781cd7eb8d04a13afd9be9b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 8 Apr 2018 15:13:30 +1000 Subject: [PATCH 318/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index a2d6e5d7..ece2ee51 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.0 + 0.12.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index b4914569..750aed13 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.0 + 0.12.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 578f4bb0206fff0cb8a3a7a91c73515c048551e6 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Fri, 8 Jun 2018 15:59:53 -0400 Subject: [PATCH 319/440] Exclude guava imports in OSGi --- core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/pom.xml b/core/pom.xml index ece2ee51..3883084f 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -112,6 +112,7 @@ + !com.google.common.*, org.slf4j.*; version="[1.0.0,2)", * From 419550899052517b2f495a6b5a08f735dc1aea65 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sun, 10 Jun 2018 08:37:02 +1000 Subject: [PATCH 320/440] Bump plugin and dependency versions Dependency bumps are on guava, which is shaded, and mockito, which is test-scope only Signed-off-by: Peter Ansell --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 750aed13..e7a658ba 100755 --- a/pom.xml +++ b/pom.xml @@ -197,7 +197,7 @@ org.mockito mockito-core - 2.17.0 + 2.18.3 commons-io @@ -209,7 +209,7 @@ com.google.guava guava - 24.1-jre + 25.1-jre @@ -288,12 +288,12 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.1.1 org.apache.maven.plugins maven-dependency-plugin - 3.0.2 + 3.1.1 org.apache.maven.plugins @@ -303,7 +303,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0 + 3.0.1 org.apache.maven.plugins @@ -313,7 +313,7 @@ org.apache.maven.plugins maven-resources-plugin - 3.0.2 + 3.1.0 org.apache.maven.plugins @@ -328,7 +328,7 @@ org.apache.maven.plugins maven-clean-plugin - 3.0.0 + 3.1.0 org.apache.maven.plugins @@ -338,7 +338,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.0.2 + 3.1.0 @@ -369,12 +369,12 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20.1 + 2.21.0 org.apache.maven.plugins maven-site-plugin - 3.7 + 3.7.1 org.codehaus.mojo @@ -400,7 +400,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.11.1 + 0.12.0 From f644932ba81e351c7b59b96f79fa1769f0a3ac5b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 4 Jul 2018 11:19:48 +1000 Subject: [PATCH 321/440] Call for maintainer and note support for 1.0 specs The project needs a maintainer who is actively still using JSON-LD to upgrade it to recent versions with new features --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 862c8e53..82a50624 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ +**JSONLD-Java is looking for a maintainer** + JSONLD-JAVA =========== -This is a Java implementation of the [JSON-LD specification](http://www.w3.org/TR/json-ld/) and the [JSON-LD-API specification](http://www.w3.org/TR/json-ld-api/). +This is a Java implementation of the [JSON-LD 1.0 specification](https://www.w3.org/TR/2014/REC-json-ld-20140116/) and the [JSON-LD-API 1.0 specification](https://www.w3.org/TR/2014/REC-json-ld-api-20140116/. [![Build Status](https://travis-ci.org/jsonld-java/jsonld-java.svg?branch=master)](https://travis-ci.org/jsonld-java/jsonld-java) [![Coverage Status](https://coveralls.io/repos/jsonld-java/jsonld-java/badge.svg?branch=master)](https://coveralls.io/r/jsonld-java/jsonld-java?branch=master) From 0fc7047f8c7e0a594c4052f8f04a3cfae48f751d Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 4 Jul 2018 11:20:37 +1000 Subject: [PATCH 322/440] Call for maintainer and note support for 1.0 specs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 82a50624..266d683a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ JSONLD-JAVA =========== -This is a Java implementation of the [JSON-LD 1.0 specification](https://www.w3.org/TR/2014/REC-json-ld-20140116/) and the [JSON-LD-API 1.0 specification](https://www.w3.org/TR/2014/REC-json-ld-api-20140116/. +This is a Java implementation of the [JSON-LD 1.0 specification](https://www.w3.org/TR/2014/REC-json-ld-20140116/) and the [JSON-LD-API 1.0 specification](https://www.w3.org/TR/2014/REC-json-ld-api-20140116/). [![Build Status](https://travis-ci.org/jsonld-java/jsonld-java.svg?branch=master)](https://travis-ci.org/jsonld-java/jsonld-java) [![Coverage Status](https://coveralls.io/repos/jsonld-java/jsonld-java/badge.svg?branch=master)](https://coveralls.io/r/jsonld-java/jsonld-java?branch=master) From c57e530d65b6688f964036458a13396fd91748f6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jul 2018 10:42:30 +1000 Subject: [PATCH 323/440] Ignore schema.org tests done specifically with HttpURLConnection The Java maintainers refuse to believe that it is safe to redirect from HTTP to HTTPS using HttpURLConnection, so disabling the tests as schema.org requires that ability, which is provided with Apache HttpClient Signed-off-by: Peter Ansell --- README.md | 3 ++ .../jsonldjava/core/DocumentLoaderTest.java | 3 +- .../core/MinimalSchemaOrgRegressionTest.java | 29 ++++++++++++++----- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 266d683a..e4caf17f 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-07-07 +* Fix tests setup for schema.org with HttpURLConnection that break because of the inability of HttpURLConnection to redirect from HTTP to HTTPS + ### 2018-04-08 * Release 0.12.0 * Encapsulate RemoteDocument and make it immutable diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index b0350f76..cc36affb 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -135,6 +135,7 @@ public void loadDocumentWf4ever() throws Exception { assertFalse(((Map) context).isEmpty()); } + @Ignore("Schema.org started to redirect from HTTP to HTTPS which breaks the Java HttpURLConnection API") @Test public void fromURLSchemaOrgNoApacheHttpClient() throws Exception { final URL url = new URL("http://schema.org/"); @@ -325,7 +326,7 @@ public void jarCacheHitThreadCtx() throws Exception { } catch (final IOException ex) { // expected } - + final ClassLoader cl = new URLClassLoader(new URL[] { nestedJar }); Thread.currentThread().setContextClassLoader(cl); final Object hello = JsonUtils.fromURL(url, documentLoader.getHttpClient()); diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index bbfafae7..eefed9a5 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -1,5 +1,7 @@ package com.github.jsonldjava.core; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -8,6 +10,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; import org.apache.http.client.methods.CloseableHttpResponse; @@ -20,6 +23,7 @@ import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; +import org.junit.Ignore; import org.junit.Test; import com.github.jsonldjava.utils.JarCacheStorage; @@ -28,20 +32,29 @@ public class MinimalSchemaOrgRegressionTest { private static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; + @Ignore("Java API does not have any way of redirecting automatically from HTTP to HTTPS, which breaks schema.org usage with it") @Test public void testHttpURLConnection() throws Exception { final URL url = new URL("http://schema.org/"); - final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); - urlConn.addRequestProperty("Accept", ACCEPT_HEADER); + boolean followRedirectsSetting = HttpURLConnection.getFollowRedirects(); + try { + HttpURLConnection.setFollowRedirects(true); + final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); + urlConn.setInstanceFollowRedirects(true); + urlConn.addRequestProperty("Accept", ACCEPT_HEADER); - final InputStream directStream = urlConn.getInputStream(); - verifyInputStream(directStream); + final InputStream directStream = urlConn.getInputStream(); + verifyInputStream(directStream); + } finally { + HttpURLConnection.setFollowRedirects(followRedirectsSetting); + } } private void verifyInputStream(InputStream directStream) throws IOException { + assertNotNull("InputStream was null", directStream); final StringWriter output = new StringWriter(); try { - IOUtils.copy(directStream, output, Charset.forName("UTF-8")); + IOUtils.copy(directStream, output, StandardCharsets.UTF_8); } finally { directStream.close(); output.flush(); @@ -50,8 +63,10 @@ private void verifyInputStream(InputStream directStream) throws IOException { // System.out.println(outputString); // Test for some basic conditions without including the JSON/JSON-LD // parsing code here - assertTrue(outputString.endsWith("}\n")); - assertTrue(outputString.length() > 100000); + // assertTrue(outputString, outputString.endsWith("}")); + assertFalse("Output string should not be empty: " + outputString.length(), + outputString.isEmpty()); + assertTrue("Unexpected length: " + outputString.length(), outputString.length() > 100000); } @Test From 25d6e91328df37a7223535d09bcde734974314ee Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jul 2018 10:49:36 +1000 Subject: [PATCH 324/440] Add testing with jdk10 Signed-off-by: Peter Ansell --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9b07f505..589b4f97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,14 @@ language: java -dist: trusty jdk: - oraclejdk8 - oraclejdk9 + - oraclejdk10 +matrix: + include: + - jdk: openjdk10 + before_install: + - rm "${JAVA_HOME}/lib/security/cacerts" + - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" notifications: email: false after_success: From c04875f2287280b6a4446b9b96d418503b5f2b41 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jul 2018 10:55:36 +1000 Subject: [PATCH 325/440] Bulk automated cleanup Signed-off-by: Peter Ansell --- .../jsonldjava/core/DocumentLoader.java | 20 +++---- .../jsonldjava/core/RemoteDocument.java | 8 +-- .../jsonldjava/utils/JarCacheStorage.java | 52 +++++++++++-------- .../github/jsonldjava/utils/JsonUtils.java | 8 +-- .../jsonldjava/core/DocumentLoaderTest.java | 6 +-- .../core/JsonLdPerformanceTest.java | 10 ++-- .../core/MinimalSchemaOrgRegressionTest.java | 3 +- 7 files changed, 57 insertions(+), 50 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java index eb0456b4..55faaac7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java +++ b/core/src/main/java/com/github/jsonldjava/core/DocumentLoader.java @@ -17,15 +17,15 @@ public class DocumentLoader { private final Map m_injectedDocs = new HashMap<>(); /** - * Identifies a system property that can be set to "true" in order to disallow - * remote context loading. + * Identifies a system property that can be set to "true" in order to + * disallow remote context loading. */ public static final String DISALLOW_REMOTE_CONTEXT_LOADING = "com.github.jsonldjava.disallowRemoteContextLoading"; /** * Avoid resolving a document by instead using the given serialised * representation. - * + * * @param url * The URL this document represents. * @param doc @@ -45,13 +45,13 @@ public DocumentLoader addInjectedDoc(String url, String doc) throws JsonLdError /** * Loads the URL if possible, returning it as a RemoteDocument. - * + * * @param url * The URL to load * @return The resolved URL as a RemoteDocument * @throws JsonLdError - * If there are errors loading or remote context loading has been - * disallowed. + * If there are errors loading or remote context loading has + * been disallowed. */ public RemoteDocument loadDocument(String url) throws JsonLdError { if (m_injectedDocs.containsKey(url)) { @@ -79,9 +79,9 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { private volatile CloseableHttpClient httpClient; /** - * Get the {@link CloseableHttpClient} which will be used by this DocumentLoader - * to resolve HTTP and HTTPS resources. - * + * Get the {@link CloseableHttpClient} which will be used by this + * DocumentLoader to resolve HTTP and HTTPS resources. + * * @return The {@link CloseableHttpClient} which this DocumentLoader uses. */ public CloseableHttpClient getHttpClient() { @@ -100,7 +100,7 @@ public CloseableHttpClient getHttpClient() { /** * Call this method to override the default CloseableHttpClient provided by * JsonUtils.getDefaultHttpClient. - * + * * @param nextHttpClient * The {@link CloseableHttpClient} to replace the default with. */ diff --git a/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java b/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java index 3350bb3c..0af7a5cd 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java +++ b/core/src/main/java/com/github/jsonldjava/core/RemoteDocument.java @@ -2,7 +2,7 @@ /** * Encapsulates a URL along with the parsed resource matching the URL. - * + * * @author Tristan King */ public class RemoteDocument { @@ -12,7 +12,7 @@ public class RemoteDocument { /** * Create a new RemoteDocument with the URL and the parsed resource for the * document. - * + * * @param url * The URL * @param document @@ -25,7 +25,7 @@ public RemoteDocument(String url, Object document) { /** * Get the URL for this document. - * + * * @return The URL for this document, as a String */ public String getDocumentUrl() { @@ -34,7 +34,7 @@ public String getDocumentUrl() { /** * Get the parsed resource for this document. - * + * * @return The parsed resource for this document */ public Object getDocument() { diff --git a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java index 9f20d97e..137daa74 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JarCacheStorage.java @@ -43,7 +43,7 @@ * Implementation of the Apache HttpClient {@link HttpCacheStorage} interface * using {@code jarcache.json} files on the classpath to identify static JSON-LD * resources on the classpath, to avoid retrieving them. - * + * * @author Stian Soiland-Reyes * @author Peter Ansell p_ansell@yahoo.com */ @@ -51,9 +51,9 @@ public class JarCacheStorage implements HttpCacheStorage { /** * The classpath location that is searched inside of the classloader set for - * this cache. Note this search is also done on the Thread contextClassLoader if - * none is explicitly set, and the System classloader if there is no - * contextClassLoader. + * this cache. Note this search is also done on the Thread + * contextClassLoader if none is explicitly set, and the System classloader + * if there is no contextClassLoader. */ private static final String JARCACHE_JSON = "jarcache.json"; @@ -62,15 +62,15 @@ public class JarCacheStorage implements HttpCacheStorage { private final CacheConfig cacheConfig; /** - * The classloader to use, defaults to null which will use the thread context - * classloader. + * The classloader to use, defaults to null which will use the thread + * context classloader. */ private ClassLoader classLoader = null; /** * A holder for the case where the System class loader needs to be used, but * cannot be directly identified in another way. - * + * * Used as a key in cachedResourceList. */ private static final Object NULL_CLASS_LOADER = new Object(); @@ -101,7 +101,7 @@ public JsonNode load(URL url) throws IOException { /** * Cached URLs from the given ClassLoader to identified locations of * jarcache.json resources on the classpath - * + * * Uses a Guava concurrent weak reference key map to avoid holding onto * ClassLoader instances after they are otherwise unavailable. */ @@ -120,7 +120,7 @@ public JarCacheStorage(ClassLoader classLoader, CacheConfig cacheConfig, } public ClassLoader getClassLoader() { - ClassLoader nextClassLoader = classLoader; + final ClassLoader nextClassLoader = classLoader; if (nextClassLoader != null) { return nextClassLoader; } @@ -129,9 +129,9 @@ public ClassLoader getClassLoader() { /** * Sets the ClassLoader used internally to a new value, or null to use - * {@link Thread#currentThread()} and {@link Thread#getContextClassLoader()} for - * each access. - * + * {@link Thread#currentThread()} and {@link Thread#getContextClassLoader()} + * for each access. + * * @param classLoader * The classloader to use, or null to use the thread context * classloader @@ -168,16 +168,20 @@ public HttpCacheEntry getEntry(String key) throws IOException { log.trace("Failed to normalise URI port before looking in cache: " + requestedUri, e); } - // Ignore syntax error and use the original URI directly instead - // This shouldn't happen as we already attempted to parse the URI earlier and + // Ignore syntax error and use the original URI directly + // instead + // This shouldn't happen as we already attempted to parse + // the URI earlier and // would not come here if that failed } } - // getResources uses a cache to avoid scanning the classpath again for the + // getResources uses a cache to avoid scanning the classpath again + // for the // current classloader for (final URL url : getResources()) { - // getJarCache attempts to use already parsed in-memory locations to avoid + // getJarCache attempts to use already parsed in-memory + // locations to avoid // retrieving and parsing again final JsonNode tree = getJarCache(url); for (final JsonNode node : tree) { @@ -194,9 +198,11 @@ public HttpCacheEntry getEntry(String key) throws IOException { } /** - * Get all of the {@code jarcache.json} resources that exist on the classpath - * - * @return A cached list of jarcache.json classpath resources as {@link URL}s + * Get all of the {@code jarcache.json} resources that exist on the + * classpath + * + * @return A cached list of jarcache.json classpath resources as + * {@link URL}s * @throws IOException * If there was an IO error while scanning the classpath */ @@ -207,7 +213,8 @@ private List getResources() throws IOException { // key final Object key = cl == null ? NULL_CLASS_LOADER : cl; - // computeIfAbsent requires unchecked exceptions for the creation process, so we + // computeIfAbsent requires unchecked exceptions for the creation + // process, so we // cannot easily use it directly, instead using get and putIfAbsent List newValue = cachedResourceList.get(key); if (newValue != null) { @@ -223,7 +230,8 @@ private List getResources() throws IOException { } final List oldValue = cachedResourceList.putIfAbsent(key, newValue); - // We are not synchronising access to the ConcurrentMap, so if there were + // We are not synchronising access to the ConcurrentMap, so if there + // were // multiple classpath scans, we always choose the first one return oldValue != null ? oldValue : newValue; } @@ -231,7 +239,7 @@ private List getResources() throws IOException { protected JsonNode getJarCache(URL url) throws IOException { try { return jarCaches.get(url); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { throw new IOException("Failed to retrieve jar cache for URL: " + url, e); } } diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 99f83b0a..f7e0581b 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -420,15 +420,15 @@ public static CloseableHttpClient createDefaultHttpClient() { } public static CacheConfig createDefaultCacheConfig() { - return CacheConfig.custom().setMaxCacheEntries(500) - .setMaxObjectSize(1024 * 256).setSharedCache(false) - .setHeuristicCachingEnabled(true).setHeuristicDefaultLifetime(86400).build(); + return CacheConfig.custom().setMaxCacheEntries(500).setMaxObjectSize(1024 * 256) + .setSharedCache(false).setHeuristicCachingEnabled(true) + .setHeuristicDefaultLifetime(86400).build(); } public static CloseableHttpClient createDefaultHttpClient(final CacheConfig cacheConfig) { return createDefaultHttpClientBuilder(cacheConfig).build(); } - + public static HttpClientBuilder createDefaultHttpClientBuilder(final CacheConfig cacheConfig) { // Common CacheConfig for both the JarCacheStorage and the underlying // BasicHttpCacheStorage diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index cc36affb..c16d40b5 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -413,12 +413,12 @@ public void injectContext() throws Exception { @Test public void testRemoteContextCaching() throws Exception { final String[] urls = { "http://schema.org/", "http://schema.org/docs/jsonldcontext.json" }; - for (String url : urls) { - long start = System.currentTimeMillis(); + for (final String url : urls) { + final long start = System.currentTimeMillis(); for (int i = 1; i <= 1000; i++) { documentLoader.loadDocument(url); - long seconds = (System.currentTimeMillis() - start) / 1000; + final long seconds = (System.currentTimeMillis() - start) / 1000; if (seconds > 60) { fail(String.format("Took %s seconds to access %s %s times", seconds, url, i)); diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java index 0f9cf502..5fce5a48 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdPerformanceTest.java @@ -623,18 +623,18 @@ public final void duplicatedTriplesInAnRDFDataset() throws Exception { options.useNamespaces = true; // System.out.println("\nJSON-LD output is OK:\n"); - Object fromRDF1 = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), + final Object fromRDF1 = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf), inputRdf.getContext(), options); - String jsonld1 = JsonUtils.toPrettyString(fromRDF1); + final String jsonld1 = JsonUtils.toPrettyString(fromRDF1); // System.out.println(jsonld1); // System.out.println( // "\nWouldn't be the case assuming there is no duplicated triple in // RDFDataset:\n"); - Object fromRDF2 = JsonLdProcessor.compact(new JsonLdApi(options).fromRDF(inputRdf, true), - inputRdf.getContext(), options); - String jsonld2 = JsonUtils.toPrettyString(fromRDF2); + final Object fromRDF2 = JsonLdProcessor.compact( + new JsonLdApi(options).fromRDF(inputRdf, true), inputRdf.getContext(), options); + final String jsonld2 = JsonUtils.toPrettyString(fromRDF2); // System.out.println(jsonld2); } diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index eefed9a5..f4c1b88d 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -9,7 +9,6 @@ import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URL; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; @@ -36,7 +35,7 @@ public class MinimalSchemaOrgRegressionTest { @Test public void testHttpURLConnection() throws Exception { final URL url = new URL("http://schema.org/"); - boolean followRedirectsSetting = HttpURLConnection.getFollowRedirects(); + final boolean followRedirectsSetting = HttpURLConnection.getFollowRedirects(); try { HttpURLConnection.setFollowRedirects(true); final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); From d801ed537a19a007de2e09e6b13b9a7fc28f1344 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jul 2018 11:02:23 +1000 Subject: [PATCH 326/440] Bump dependency versions Signed-off-by: Peter Ansell --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index e7a658ba..f4eb0525 100755 --- a/pom.xml +++ b/pom.xml @@ -40,8 +40,8 @@ UTF-8 4.5.5 - 4.4.9 - 2.9.5 + 4.4.10 + 2.9.6 4.12 1.7.25 @@ -197,7 +197,7 @@ org.mockito mockito-core - 2.18.3 + 2.19.0 commons-io @@ -267,7 +267,7 @@ org.codehaus.mojo extra-enforcer-rules - 1.0-beta-7 + 1.0-beta-9 From 79a7bcf6ee9ad59721ec8e9886835acaa675ed7d Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jul 2018 11:16:54 +1000 Subject: [PATCH 327/440] Replace StringBuffer with StringBuilder Signed-off-by: Peter Ansell --- .../main/java/com/github/jsonldjava/core/RDFDatasetUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java index 926a28b2..a2739e64 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java @@ -145,7 +145,7 @@ public static String unescape(String str) { final int w1 = 0xD800 + vh; final int w2 = 0xDC00 + v1; - final StringBuffer b = new StringBuffer(); + final StringBuilder b = new StringBuilder(); b.appendCodePoint(w1); b.appendCodePoint(w2); uni = b.toString(); @@ -185,7 +185,7 @@ public static String unescape(String str) { } } final String pat = Pattern.quote(m.group(0)); - final String x = Integer.toHexString(uni.charAt(0)); + // final String x = Integer.toHexString(uni.charAt(0)); rval = rval.replaceAll(pat, uni); } } From a694914583306481f87f7e6a32b830d1083afde6 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 7 Jul 2018 11:45:54 +1000 Subject: [PATCH 328/440] Bump some plugin versions Signed-off-by: Peter Ansell --- pom.xml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f4eb0525..a6a445e6 100755 --- a/pom.xml +++ b/pom.xml @@ -230,7 +230,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0-M1 + 3.0.0-M2 enforce-maven-3 @@ -369,7 +369,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.21.0 + 2.22.0 org.apache.maven.plugins @@ -379,7 +379,7 @@ org.codehaus.mojo animal-sniffer-maven-plugin - 1.16 + 1.17 check-jdk-compliance @@ -457,6 +457,11 @@ + + org.codehaus.mojo + versions-maven-plugin + 2.5 + From 75c7f669553816aded2af9774d4e386590bd0d5e Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Mon, 3 Sep 2018 19:13:08 +0200 Subject: [PATCH 329/440] WIP: fix 226 --- .../com/github/jsonldjava/core/JsonLdApi.java | 28 ++++---- .../github/jsonldjava/core/JsonLdOptions.java | 2 +- .../jsonldjava/core/JsonLdProcessor.java | 16 +++-- .../github/jsonldjava/core/JsonLdUtils.java | 64 ++++++++++++++----- .../jsonldjava/core/JsonLdFramingTest.java | 16 +++++ .../json-ld.org/frame-p050-frame.jsonld | 8 +++ .../json-ld.org/frame-p050-in.jsonld | 8 +++ .../json-ld.org/frame-p050-out.jsonld | 7 ++ 8 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/frame-p050-frame.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-p050-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-p050-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 9a49252e..470cfe01 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -271,7 +271,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, } if (value instanceof List) { ((List) result.get(property)) - .addAll((List) value); + .addAll((List) value); } else { ((List) result.get(property)).add(value); } @@ -373,7 +373,7 @@ else if (JsonLdConsts.INDEX.equals(expandedProperty) // true activeCtx.compactIri(JsonLdConsts.INDEX, true), ((Map) expandedItem) - .get(JsonLdConsts.INDEX)); + .get(JsonLdConsts.INDEX)); } } // 7.6.4.3) @@ -398,7 +398,7 @@ else if (result.containsKey(itemActiveProperty)) { // 7.6.5.2) if (JsonLdConsts.LANGUAGE.equals(container) && (compactedItem instanceof Map && ((Map) compactedItem) - .containsKey(JsonLdConsts.VALUE))) { + .containsKey(JsonLdConsts.VALUE))) { compactedItem = ((Map) compactedItem) .get(JsonLdConsts.VALUE); } @@ -443,7 +443,7 @@ else if (result.containsKey(itemActiveProperty)) { } if (compactedItem instanceof List) { ((List) result.get(itemActiveProperty)) - .addAll((List) compactedItem); + .addAll((List) compactedItem); } else { ((List) result.get(itemActiveProperty)).add(compactedItem); } @@ -721,7 +721,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { // 7.4.11.2.2) if (item instanceof List) { ((List) result.get(property)) - .addAll((List) item); + .addAll((List) item); } else { ((List) result.get(property)).add(item); } @@ -752,7 +752,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { if (item instanceof Map && (((Map) item) .containsKey(JsonLdConsts.VALUE) || ((Map) item) - .containsKey(JsonLdConsts.LIST))) { + .containsKey(JsonLdConsts.LIST))) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_VALUE); } // 7.4.11.3.3.1.2) @@ -893,7 +893,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) // 7.10.4.3) if (item instanceof List) { ((List) reverseMap.get(expandedProperty)) - .addAll((List) item); + .addAll((List) item); } else { ((List) reverseMap.get(expandedProperty)).add(item); } @@ -908,7 +908,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) // 7.11.2) if (expandedValue instanceof List) { ((List) result.get(expandedProperty)) - .addAll((List) expandedValue); + .addAll((List) expandedValue); } else { ((List) result.get(expandedProperty)).add(expandedValue); } @@ -1044,7 +1044,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG void generateNodeMap(Object element, Map nodeMap, String activeGraph, Object activeSubject, String activeProperty, Map list) - throws JsonLdError { + throws JsonLdError { // 1) if (element instanceof List) { // 1.1) @@ -1712,6 +1712,7 @@ private boolean filterNode(FramingContext state, Map node, // 1. Node matches if it has an @id property including any IRI or // blank node in the @id property in frame. if (frameIds != null) { + System.out.println(frameIds.getClass()); if (frameIds instanceof String) { final Object nodeId = node.get(JsonLdConsts.ID); if (nodeId == null) { @@ -1720,6 +1721,11 @@ private boolean filterNode(FramingContext state, Map node, if (JsonLdUtils.deepCompare(nodeId, frameIds)) { return true; } + } else if (frameIds instanceof LinkedHashMap) { + if (node.containsKey(JsonLdConsts.ID)) { + return true; + } + return false; } else if (!(frameIds instanceof List)) { throw new JsonLdError(Error.SYNTAX_ERROR, "frame @id must be an array"); } else { @@ -2001,7 +2007,7 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData if (object.isBlankNode() || object.isIRI()) { // 3.5.8.1-3) nodeMap.get(object.getValue()).usages - .add(new UsagesNode(node, predicate, value)); + .add(new UsagesNode(node, predicate, value)); } } } @@ -2201,7 +2207,7 @@ public Object normalize(Map dataset) throws JsonLdError { }); } ((List) ((Map) bnodes.get(id)).get("quads")) - .add(quad); + .add(quad); } } } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 03e85309..0685c647 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -133,7 +133,7 @@ public void setOmitDefault(Boolean omitDefault) { } public Boolean getPruneBlankNodeIdentifiers() { - return pruneBlankNodeIdentifiers && getProcessingMode().equals(JSON_LD_1_1); + return pruneBlankNodeIdentifiers || getProcessingMode().equals(JSON_LD_1_1); } public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 506f5cb6..46321cd3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -329,6 +329,13 @@ public static Map frame(Object input, Object frame, JsonLdOption .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); final List framed = api.frame(expandedInput, expandedFrame); + Map rval; + if (opts.getPruneBlankNodeIdentifiers()) { + rval = activeCtx.serialize(); + final Set toPrune = blankNodeIdsToPrune(rval); + JsonLdUtils.pruneBlankNodes(framed, toPrune); + } + Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); if (!(compacted instanceof List)) { final List tmp = new ArrayList(); @@ -336,12 +343,9 @@ public static Map frame(Object input, Object frame, JsonLdOption compacted = tmp; } final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); - final Map rval = activeCtx.serialize(); + rval = activeCtx.serialize(); rval.put(alias, compacted); - - final Set toPrune = opts.getPruneBlankNodeIdentifiers() ? blankNodeIdsToPrune(rval) - : Collections.emptySet(); - JsonLdUtils.removePreserveAndPrune(activeCtx, rval, opts, toPrune); + JsonLdUtils.removePreserve(activeCtx, rval, opts); return rval; } @@ -356,7 +360,7 @@ private static Map countBlankNodeIds(Object input, ((List) input).forEach(e -> countBlankNodeIds(e, frequencies)); } else if (input instanceof Map) { ((Map) input).entrySet() - .forEach(e -> countBlankNodeIds(e.getValue(), frequencies)); + .forEach(e -> countBlankNodeIds(e.getValue(), frequencies)); } else if (input instanceof String) { final String p = (String) input; if (p.startsWith("_:")) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 4c44e582..e79c157c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -191,21 +191,18 @@ public static boolean isRelativeIri(String value) { * the active context used to compact the input. * @param input * the framed, compacted output. - * @param toPrune - * The blank node IDs to prune. * @param options * the compaction options used. * * @return the resulting output. * @throws JsonLdError */ - static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions opts, - Set toPrune) throws JsonLdError { + static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) throws JsonLdError { // recurse through arrays if (isArray(input)) { final List output = new ArrayList(); for (final Object i : (List) input) { - final Object result = removePreserveAndPrune(ctx, i, opts, toPrune); + final Object result = removePreserve(ctx, i, opts); // drop nulls from arrays if (result != null) { output.add(result); @@ -228,29 +225,66 @@ static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions op // recurse through @lists if (isList(input)) { - ((Map) input).put("@list", removePreserveAndPrune(ctx, - ((Map) input).get("@list"), opts, toPrune)); + ((Map) input).put("@list", removePreserve(ctx, + ((Map) input).get("@list"), opts)); return input; } // recurse through properties for (final String prop : new LinkedHashSet<>(((Map) input).keySet())) { - Object result = removePreserveAndPrune(ctx, ((Map) input).get(prop), - opts, toPrune); + Object result = removePreserve(ctx, ((Map) input).get(prop), + opts); final String container = ctx.getContainer(prop); if (opts.getCompactArrays() && isArray(result) && ((List) result).size() == 1 && container == null) { result = ((List) result).get(0); } - if (ctx.expandIri(prop, false, false, null, null).equals(JsonLdConsts.ID) - && toPrune.contains(result)) { - ((Map) input).remove(prop); + } + } + return input; + } + + /** + * Removes the @preserve keywords and blank node IDs to prune as the last + * step of the framing algorithm. + * + * @param input + * the framed, compacted output. + * @param toPrune + * The blank node IDs to prune. + */ + static void pruneBlankNodes(Object input, Set toPrune) { + // recurse through arrays + if (isArray(input)) { + final List output = new ArrayList(); + for (final Object i : (List) input) { + pruneBlankNodes(i, toPrune); + } + input = output; + } else if (isObject(input)) { + // skip @values + if (isValue(input)) { + return; + } + + // recurse through @lists + if (isList(input)) { + pruneBlankNodes(((Map) input).get("@list"), toPrune); + return; + } + + // recurse through properties + for (final String prop : new LinkedHashSet<>(((Map) input).keySet())) { + if (prop.equals(JsonLdConsts.ID)) { + final String id = (String) ((Map) input).get(JsonLdConsts.ID); + if (toPrune.contains(id)) { + ((Map) input).remove(JsonLdConsts.ID); + } } else { - ((Map) input).put(prop, result); + pruneBlankNodes(((Map) input).get(prop), toPrune); } } } - return input; } /** @@ -307,7 +341,7 @@ static boolean compareValues(Object v1, Object v2) { if ((v1 instanceof Map && ((Map) v1).containsKey("@id")) && (v2 instanceof Map && ((Map) v2).containsKey("@id")) && ((Map) v1).get("@id") - .equals(((Map) v2).get("@id"))) { + .equals(((Map) v2).get("@id"))) { return true; } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 3b67eed0..3bc46489 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -139,4 +139,20 @@ public void testFrame0008() throws IOException, JsonLdError { .fromInputStream(getClass().getResourceAsStream("/custom/frame-0008-out.jsonld")); assertEquals(out, frame2); } + + @Test + public void testFramep050() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-in.jsonld")); + + final JsonLdOptions opts = new JsonLdOptions(); + opts.setProcessingMode("json-ld-1.1"); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-out.jsonld")); + assertEquals(out, frame2); + } } diff --git a/core/src/test/resources/json-ld.org/frame-p050-frame.jsonld b/core/src/test/resources/json-ld.org/frame-p050-frame.jsonld new file mode 100644 index 00000000..77dc5555 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p050-frame.jsonld @@ -0,0 +1,8 @@ +{ + "@context": { + "@vocab": "http://example/", + "id": "@id" + }, + "id": {}, + "name": {} +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-p050-in.jsonld b/core/src/test/resources/json-ld.org/frame-p050-in.jsonld new file mode 100644 index 00000000..fc31face --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p050-in.jsonld @@ -0,0 +1,8 @@ +{ + "@context": { + "@vocab": "http://example/", + "id": "@id" + }, + "id": "_:bnode0", + "name": "foo" +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-p050-out.jsonld b/core/src/test/resources/json-ld.org/frame-p050-out.jsonld new file mode 100644 index 00000000..ebbf9018 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-p050-out.jsonld @@ -0,0 +1,7 @@ +{ + "@context": { + "@vocab": "http://example/", + "id": "@id" + }, + "@graph": [{"name": "foo"}] +} \ No newline at end of file From a24e9d406abefd3f8357623dbacf713d5a548bf4 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Tue, 4 Sep 2018 10:09:52 +0200 Subject: [PATCH 330/440] finish implementation, add another test --- .../jsonldjava/core/JsonLdProcessor.java | 32 ++---------- .../github/jsonldjava/core/JsonLdUtils.java | 51 ++++++++++++++----- .../jsonldjava/core/JsonLdFramingTest.java | 18 +++++++ .../resources/custom/frame-0009-frame.jsonld | 7 +++ .../resources/custom/frame-0009-in.jsonld | 10 ++++ .../resources/custom/frame-0009-out.jsonld | 22 ++++++++ .../json-ld.org/frame-manifest.jsonld | 9 ++++ 7 files changed, 106 insertions(+), 43 deletions(-) create mode 100644 core/src/test/resources/custom/frame-0009-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0009-in.jsonld create mode 100644 core/src/test/resources/custom/frame-0009-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 46321cd3..7c529c9d 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -4,12 +4,9 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import com.github.jsonldjava.core.JsonLdError.Error; import com.github.jsonldjava.impl.NQuadRDFParser; @@ -329,11 +326,9 @@ public static Map frame(Object input, Object frame, JsonLdOption .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); final List framed = api.frame(expandedInput, expandedFrame); - Map rval; + if (opts.getPruneBlankNodeIdentifiers()) { - rval = activeCtx.serialize(); - final Set toPrune = blankNodeIdsToPrune(rval); - JsonLdUtils.pruneBlankNodes(framed, toPrune); + JsonLdUtils.pruneBlankNodes(framed); } Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); @@ -343,33 +338,12 @@ public static Map frame(Object input, Object frame, JsonLdOption compacted = tmp; } final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); - rval = activeCtx.serialize(); + final Map rval = activeCtx.serialize(); rval.put(alias, compacted); JsonLdUtils.removePreserve(activeCtx, rval, opts); return rval; } - private static Set blankNodeIdsToPrune(final Map rval) { - return countBlankNodeIds(rval, new HashMap<>()).entrySet().stream() - .filter(e -> e.getValue() == 1).map(e -> e.getKey()).collect(Collectors.toSet()); - } - - private static Map countBlankNodeIds(Object input, - Map frequencies) { - if (input instanceof List) { - ((List) input).forEach(e -> countBlankNodeIds(e, frequencies)); - } else if (input instanceof Map) { - ((Map) input).entrySet() - .forEach(e -> countBlankNodeIds(e.getValue(), frequencies)); - } else if (input instanceof String) { - final String p = (String) input; - if (p.startsWith("_:")) { - frequencies.put(p, frequencies.containsKey(p) ? frequencies.get(p) + 1 : 1); - } - } - return frequencies; - } - /** * A registry for RDF Parsers (in this case, JSONLDSerializers) used by * fromRDF if no specific serializer is specified and options.format is set. diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index e79c157c..61ba9ac5 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -1,10 +1,10 @@ package com.github.jsonldjava.core; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Set; import com.github.jsonldjava.utils.Obj; @@ -184,7 +184,7 @@ public static boolean isRelativeIri(String value) { } /** - * Removes the @preserve keywords and blank node IDs to prune as the last + * Removes the @preserve keywords as the last * step of the framing algorithm. * * @param ctx @@ -245,20 +245,38 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro } /** - * Removes the @preserve keywords and blank node IDs to prune as the last - * step of the framing algorithm. + * Removes the @id member of each node object where the member value + * is a blank node identifier which appears only once in any property + * value within input. * * @param input - * the framed, compacted output. + * the framed output before compaction + */ + + static void pruneBlankNodes(Object input) { + final Map toPrune = new HashMap<>(); + fillNodesToPrune(input, toPrune); + for (final Object node : toPrune.values()) { + if (node == null) + continue; + ((Map) node).remove(JsonLdConsts.ID); + } + } + + /** + * Gets the objects on which we'll prune the blank node ID + * + * @param input + * the framed output before compaction * @param toPrune - * The blank node IDs to prune. + * the resulting object. */ - static void pruneBlankNodes(Object input, Set toPrune) { + static void fillNodesToPrune(Object input, Map toPrune) { // recurse through arrays if (isArray(input)) { final List output = new ArrayList(); for (final Object i : (List) input) { - pruneBlankNodes(i, toPrune); + fillNodesToPrune(i, toPrune); } input = output; } else if (isObject(input)) { @@ -266,22 +284,27 @@ static void pruneBlankNodes(Object input, Set toPrune) { if (isValue(input)) { return; } - // recurse through @lists if (isList(input)) { - pruneBlankNodes(((Map) input).get("@list"), toPrune); + fillNodesToPrune(((Map) input).get("@list"), toPrune); return; } - // recurse through properties for (final String prop : new LinkedHashSet<>(((Map) input).keySet())) { if (prop.equals(JsonLdConsts.ID)) { final String id = (String) ((Map) input).get(JsonLdConsts.ID); - if (toPrune.contains(id)) { - ((Map) input).remove(JsonLdConsts.ID); + if (id.startsWith("_:")) { + // if toPrune contains the id already, it was already present somewhere else, + // so we just null the value + if (toPrune.containsKey(id)) { + toPrune.put(id, null); + } else { + // else we add the object as the value + toPrune.put(id, input); + } } } else { - pruneBlankNodes(((Map) input).get(prop), toPrune); + fillNodesToPrune(((Map) input).get(prop), toPrune); } } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 3bc46489..3d406ec2 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -8,6 +8,7 @@ import org.junit.Test; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.jsonldjava.utils.JsonUtils; public class JsonLdFramingTest { @@ -155,4 +156,21 @@ public void testFramep050() throws IOException, JsonLdError { .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-out.jsonld")); assertEquals(out, frame2); } + + @Test + public void testFrame0009() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0009-frame.jsonld")); + final Object in = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0009-in.jsonld")); + + final JsonLdOptions opts = new JsonLdOptions(); + opts.setProcessingMode("json-ld-1.1"); + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + ObjectMapper om = new ObjectMapper(); + om.writeValue(System.out, frame2); + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0009-out.jsonld")); + assertEquals(out, frame2); + } } diff --git a/core/src/test/resources/custom/frame-0009-frame.jsonld b/core/src/test/resources/custom/frame-0009-frame.jsonld new file mode 100644 index 00000000..8947878f --- /dev/null +++ b/core/src/test/resources/custom/frame-0009-frame.jsonld @@ -0,0 +1,7 @@ +{ + "@context": { + "@vocab": "http://example/", + "id": "@id" + }, + "id": {} +} \ No newline at end of file diff --git a/core/src/test/resources/custom/frame-0009-in.jsonld b/core/src/test/resources/custom/frame-0009-in.jsonld new file mode 100644 index 00000000..073345ec --- /dev/null +++ b/core/src/test/resources/custom/frame-0009-in.jsonld @@ -0,0 +1,10 @@ +{ + "@context": { + "@vocab": "http://example/", + "id": "@id" + }, + "id": "_:bnode0", + "name": "bar", + "prop1": { "name": "foo", "id": "_:bnode1" }, + "prop2": { "name": "foo", "id": "_:bnode1" } +} \ No newline at end of file diff --git a/core/src/test/resources/custom/frame-0009-out.jsonld b/core/src/test/resources/custom/frame-0009-out.jsonld new file mode 100644 index 00000000..01ef962d --- /dev/null +++ b/core/src/test/resources/custom/frame-0009-out.jsonld @@ -0,0 +1,22 @@ +{ + "@context": { + "@vocab": "http:\/\/example\/", + "id": "@id" + }, + "@graph": [ + { + "name": "bar", + "prop1": { + "id": "_:b1" + }, + "prop2": { + "id": "_:b1", + "name": "foo" + } + }, + { + "id": "_:b1", + "name": "foo" + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index d45f7135..3b62e63b 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -198,5 +198,14 @@ "input": "frame-0046-in.jsonld", "frame": "frame-0046-frame.jsonld", "expect": "frame-p046-out.jsonld" + }, { + "@id": "#tp050", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Prune blank nodes with alias of @id", + "purpose": "If @id is aliased in a frame, an unreferenced blank node is still pruned.", + "input": "frame-p050-in.jsonld", + "frame": "frame-p050-frame.jsonld", + "expect": "frame-p050-out.jsonld", + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"} }] } From fdd14d557acf589f36ec59d83f3fa56e1b0e4967 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Tue, 4 Sep 2018 11:22:14 +0200 Subject: [PATCH 331/440] polish --- README.md | 7 ++++++- .../main/java/com/github/jsonldjava/core/JsonLdApi.java | 3 +-- .../java/com/github/jsonldjava/core/JsonLdOptions.java | 2 +- .../java/com/github/jsonldjava/core/JsonLdProcessor.java | 3 --- .../main/java/com/github/jsonldjava/core/JsonLdUtils.java | 3 ++- .../java/com/github/jsonldjava/core/JsonLdFramingTest.java | 5 ----- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e4caf17f..6e5990c3 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ System.out.println(JsonUtils.toPrettyString(compact)); Processor options ----------------- -The Options specified by the [JSON-LD API Specification](http://json-ld.org/spec/latest/json-ld-api/#jsonldoptions) are accessible via the `com.github.jsonldjava.core.JsonLdOptions` class, and each `JsonLdProcessor.*` function has an optional input to take an instance of this class. +The Options specified by the [JSON-LD API Specification](https://json-ld.org/spec/latest/json-ld-api/#the-jsonldoptions-type) are accessible via the `com.github.jsonldjava.core.JsonLdOptions` class, and each `JsonLdProcessor.*` function has an optional input to take an instance of this class. Controlling network traffic @@ -449,6 +449,11 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-07-07 +* make pruneBlankNodeIdentifiers false by default in 1.0 mode and always true in 1.1 mode +* fix issue with blank node identifier pruning when @id is aliased +* allow wildcard {} for @id in framing + ### 2018-07-07 * Fix tests setup for schema.org with HttpURLConnection that break because of the inability of HttpURLConnection to redirect from HTTP to HTTPS diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 470cfe01..d8cf642a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1712,7 +1712,6 @@ private boolean filterNode(FramingContext state, Map node, // 1. Node matches if it has an @id property including any IRI or // blank node in the @id property in frame. if (frameIds != null) { - System.out.println(frameIds.getClass()); if (frameIds instanceof String) { final Object nodeId = node.get(JsonLdConsts.ID); if (nodeId == null) { @@ -1721,7 +1720,7 @@ private boolean filterNode(FramingContext state, Map node, if (JsonLdUtils.deepCompare(nodeId, frameIds)) { return true; } - } else if (frameIds instanceof LinkedHashMap) { + } else if (frameIds instanceof LinkedHashMap && ((LinkedHashMap) frameIds).size() == 0) { if (node.containsKey(JsonLdConsts.ID)) { return true; } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 0685c647..3c928dd2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -66,7 +66,7 @@ public JsonLdOptions(String base) { private Embed embed = Embed.LAST; private Boolean explicit = null; private Boolean omitDefault = null; - private Boolean pruneBlankNodeIdentifiers = true; + private Boolean pruneBlankNodeIdentifiers = false; private Boolean requireAll = false; // RDF conversion options : diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 7c529c9d..23d816d3 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -325,12 +325,9 @@ public static Map frame(Object input, Object frame, JsonLdOption final Context activeCtx = api.context .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); final List framed = api.frame(expandedInput, expandedFrame); - - if (opts.getPruneBlankNodeIdentifiers()) { JsonLdUtils.pruneBlankNodes(framed); } - Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); if (!(compacted instanceof List)) { final List tmp = new ArrayList(); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 61ba9ac5..89a032e1 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -231,7 +231,7 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro } // recurse through properties - for (final String prop : new LinkedHashSet<>(((Map) input).keySet())) { + for (final String prop : ((Map) input).keySet()) { Object result = removePreserve(ctx, ((Map) input).get(prop), opts); final String container = ctx.getContainer(prop); @@ -239,6 +239,7 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro && ((List) result).size() == 1 && container == null) { result = ((List) result).get(0); } + ((Map) input).put(prop, result); } } return input; diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 3d406ec2..774a234c 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -8,7 +8,6 @@ import org.junit.Test; -import com.fasterxml.jackson.databind.ObjectMapper; import com.github.jsonldjava.utils.JsonUtils; public class JsonLdFramingTest { @@ -38,8 +37,6 @@ public void testFrame0002() throws IOException, JsonLdError { final Object out = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-out.jsonld")); - // System.out.println(JsonUtils.toPrettyString(out)); - // System.out.println(JsonUtils.toPrettyString(frame2)); assertEquals(out, frame2); } @@ -167,8 +164,6 @@ public void testFrame0009() throws IOException, JsonLdError { final JsonLdOptions opts = new JsonLdOptions(); opts.setProcessingMode("json-ld-1.1"); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); - ObjectMapper om = new ObjectMapper(); - om.writeValue(System.out, frame2); final Object out = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0009-out.jsonld")); assertEquals(out, frame2); From b1b2ea6b17806ce3e8b7eb978151fa9ce635b73c Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Tue, 4 Sep 2018 12:48:04 +0200 Subject: [PATCH 332/440] fix test --- .../github/jsonldjava/core/JsonLdUtils.java | 17 ++++++++++++----- .../jsonldjava/core/JsonLdProcessorTest.java | 9 ++++----- .../json-ld.org/frame-manifest.jsonld | 19 ++++++++++--------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 89a032e1..c1130d97 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -254,10 +254,11 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro * the framed output before compaction */ - static void pruneBlankNodes(Object input) { + static void pruneBlankNodes(final Object input) { final Map toPrune = new HashMap<>(); fillNodesToPrune(input, toPrune); - for (final Object node : toPrune.values()) { + for (final String id : toPrune.keySet()) { + final Object node = toPrune.get(id); if (node == null) continue; ((Map) node).remove(JsonLdConsts.ID); @@ -272,14 +273,12 @@ static void pruneBlankNodes(Object input) { * @param toPrune * the resulting object. */ - static void fillNodesToPrune(Object input, Map toPrune) { + static void fillNodesToPrune(Object input, final Map toPrune) { // recurse through arrays if (isArray(input)) { - final List output = new ArrayList(); for (final Object i : (List) input) { fillNodesToPrune(i, toPrune); } - input = output; } else if (isObject(input)) { // skip @values if (isValue(input)) { @@ -308,6 +307,14 @@ static void fillNodesToPrune(Object input, Map toPrune) { fillNodesToPrune(((Map) input).get(prop), toPrune); } } + } else if (input instanceof String) { + // this is an id, as non-id values will have been discarded by the isValue() above + final String p = (String) input; + if (p.startsWith("_:")) { + // the id is outside of the context of an @id property, if we're in that case, + // then we're referencing a blank node id so this id should not be removed + toPrune.put(p, null); + } } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 3d70b32b..1ee25298 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -416,13 +416,12 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { if (test_opts.containsKey("useRdfType")) { options.setUseRdfType((Boolean) test_opts.get("useRdfType")); } + if (test_opts.containsKey("processingMode")) { + options.setProcessingMode((String) test_opts.get("processingMode")); + } if (test_opts.containsKey("produceGeneralizedRdf")) { options.setProduceGeneralizedRdf((Boolean) test_opts.get("produceGeneralizedRdf")); } - if (test_opts.containsKey("pruneBlankNodeIdentifiers")) { - options.setPruneBlankNodeIdentifiers( - (Boolean) test_opts.get("pruneBlankNodeIdentifiers")); - } if (test_opts.containsKey("redirectTo")) { testLoader.setRedirectTo((String) test_opts.get("redirectTo")); } @@ -553,7 +552,7 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { { put("@id", "http://json-ld.org/test-suite/tests/error-expand-manifest.jsonld" - .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); + .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); } }); } diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index 3b62e63b..3d559db3 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -151,7 +151,8 @@ "name": "Blank nodes in @type", "input": "frame-0021-in.jsonld", "frame": "frame-0021-frame.jsonld", - "expect": "frame-0021-out.jsonld" + "expect": "frame-0021-out.jsonld", + "option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.0"} } , { "@id": "#t0022", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], @@ -167,34 +168,34 @@ "frame": "frame-0030-frame.jsonld", "expect": "frame-0030-out.jsonld" }, { - "@id": "p0010", + "@id": "#tp010", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Property CURIE conflict (prune bnodes)", - "option" : {"pruneBlankNodeIdentifiers" : true}, + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, "input": "frame-0010-in.jsonld", "frame": "frame-0010-frame.jsonld", "expect": "frame-p010-out.jsonld" }, { - "@id": "p0020", + "@id": "#tp020", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Blank nodes in an array (prune bnodes)", - "option" : {"pruneBlankNodeIdentifiers" : true}, + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, "input": "frame-0020-in.jsonld", "frame": "frame-0020-frame.jsonld", "expect": "frame-p020-out.jsonld" }, { - "@id": "p0021", + "@id": "#tp021", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Blank nodes in @type (prune bnodes)", - "option" : {"pruneBlankNodeIdentifiers" : true}, + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, "input": "frame-0021-in.jsonld", "frame": "frame-0021-frame.jsonld", "expect": "frame-p021-out.jsonld" }, { - "@id": "p0046", + "@id": "#tp046", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Merge graphs if no outer @graph is used (prune bnodes)", - "option" : {"pruneBlankNodeIdentifiers" : true}, + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, "input": "frame-0046-in.jsonld", "frame": "frame-0046-frame.jsonld", "expect": "frame-p046-out.jsonld" From 90ddeb7256ba175a0bb97baf83011e0354fe07cb Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 5 Sep 2018 09:04:49 +1000 Subject: [PATCH 333/440] Automated cleanup and bump dependencies Signed-off-by: Peter Ansell --- README.md | 21 ++++++----- .../com/github/jsonldjava/core/JsonLdApi.java | 25 +++++++------ .../github/jsonldjava/core/JsonLdUtils.java | 37 ++++++++++--------- .../jsonldjava/core/JsonLdFramingTest.java | 12 +++--- .../jsonldjava/core/JsonLdProcessorTest.java | 2 +- pom.xml | 10 ++--- 6 files changed, 56 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 6e5990c3..31caa6d1 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,12 @@ From Maven com.github.jsonld-java jsonld-java - 0.12.0 + 0.12.1 Code example ------------ + ```java // Open a valid json(-ld) input file InputStream inputStream = new FileInputStream("input.json"); @@ -38,12 +39,12 @@ Object compact = JsonLdProcessor.compact(jsonObject, context, options); // Print out the result (or don't, it's your call!) System.out.println(JsonUtils.toPrettyString(compact)); ``` + Processor options ----------------- The Options specified by the [JSON-LD API Specification](https://json-ld.org/spec/latest/json-ld-api/#the-jsonldoptions-type) are accessible via the `com.github.jsonldjava.core.JsonLdOptions` class, and each `JsonLdProcessor.*` function has an optional input to take an instance of this class. - Controlling network traffic --------------------------- @@ -59,7 +60,6 @@ The default HTTP Client is wrapped with a [CachingHttpClient](https://hc.apache.org/httpcomponents-client-ga/httpclient-cache/apidocs/org/apache/http/impl/client/cache/CachingHttpClient.html) to provide a small memory-based cache (1000 objects, max 128 kB each) of regularly accessed contexts. - ### Loading contexts from classpath Your application might be parsing JSONLD documents which always use the same @@ -321,9 +321,9 @@ Here is the basic outline for what your module's pom.xml should look like xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - jsonld-java-integration - com.github.jsonld-java-parent - 0.11.0-SNAPSHOT + com.github.jsonld-java + jsonld-java-parent + 0.12.1-SNAPSHOT 4.0.0 jsonld-java-{your module} @@ -449,10 +449,11 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= -### 2018-07-07 -* make pruneBlankNodeIdentifiers false by default in 1.0 mode and always true in 1.1 mode -* fix issue with blank node identifier pruning when @id is aliased -* allow wildcard {} for @id in framing +### 2018-09-05 +* Release 0.12.1 +* Make pruneBlankNodeIdentifiers false by default in 1.0 mode and always true in 1.1 mode (Patch by @eroux) +* Fix issue with blank node identifier pruning when @id is aliased (Patch by @eroux) +* Allow wildcard {} for @id in framing (Patch by @eroux) ### 2018-07-07 * Fix tests setup for schema.org with HttpURLConnection that break because of the inability of HttpURLConnection to redirect from HTTP to HTTPS diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index d8cf642a..e902e99b 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -271,7 +271,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element, } if (value instanceof List) { ((List) result.get(property)) - .addAll((List) value); + .addAll((List) value); } else { ((List) result.get(property)).add(value); } @@ -373,7 +373,7 @@ else if (JsonLdConsts.INDEX.equals(expandedProperty) // true activeCtx.compactIri(JsonLdConsts.INDEX, true), ((Map) expandedItem) - .get(JsonLdConsts.INDEX)); + .get(JsonLdConsts.INDEX)); } } // 7.6.4.3) @@ -398,7 +398,7 @@ else if (result.containsKey(itemActiveProperty)) { // 7.6.5.2) if (JsonLdConsts.LANGUAGE.equals(container) && (compactedItem instanceof Map && ((Map) compactedItem) - .containsKey(JsonLdConsts.VALUE))) { + .containsKey(JsonLdConsts.VALUE))) { compactedItem = ((Map) compactedItem) .get(JsonLdConsts.VALUE); } @@ -443,7 +443,7 @@ else if (result.containsKey(itemActiveProperty)) { } if (compactedItem instanceof List) { ((List) result.get(itemActiveProperty)) - .addAll((List) compactedItem); + .addAll((List) compactedItem); } else { ((List) result.get(itemActiveProperty)).add(compactedItem); } @@ -721,7 +721,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { // 7.4.11.2.2) if (item instanceof List) { ((List) result.get(property)) - .addAll((List) item); + .addAll((List) item); } else { ((List) result.get(property)).add(item); } @@ -752,7 +752,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) { if (item instanceof Map && (((Map) item) .containsKey(JsonLdConsts.VALUE) || ((Map) item) - .containsKey(JsonLdConsts.LIST))) { + .containsKey(JsonLdConsts.LIST))) { throw new JsonLdError(Error.INVALID_REVERSE_PROPERTY_VALUE); } // 7.4.11.3.3.1.2) @@ -893,7 +893,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) // 7.10.4.3) if (item instanceof List) { ((List) reverseMap.get(expandedProperty)) - .addAll((List) item); + .addAll((List) item); } else { ((List) reverseMap.get(expandedProperty)).add(item); } @@ -908,7 +908,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key)) // 7.11.2) if (expandedValue instanceof List) { ((List) result.get(expandedProperty)) - .addAll((List) expandedValue); + .addAll((List) expandedValue); } else { ((List) result.get(expandedProperty)).add(expandedValue); } @@ -1044,7 +1044,7 @@ void generateNodeMap(Object element, Map nodeMap, String activeG void generateNodeMap(Object element, Map nodeMap, String activeGraph, Object activeSubject, String activeProperty, Map list) - throws JsonLdError { + throws JsonLdError { // 1) if (element instanceof List) { // 1.1) @@ -1720,7 +1720,8 @@ private boolean filterNode(FramingContext state, Map node, if (JsonLdUtils.deepCompare(nodeId, frameIds)) { return true; } - } else if (frameIds instanceof LinkedHashMap && ((LinkedHashMap) frameIds).size() == 0) { + } else if (frameIds instanceof LinkedHashMap + && ((LinkedHashMap) frameIds).size() == 0) { if (node.containsKey(JsonLdConsts.ID)) { return true; } @@ -2006,7 +2007,7 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData if (object.isBlankNode() || object.isIRI()) { // 3.5.8.1-3) nodeMap.get(object.getValue()).usages - .add(new UsagesNode(node, predicate, value)); + .add(new UsagesNode(node, predicate, value)); } } } @@ -2206,7 +2207,7 @@ public Object normalize(Map dataset) throws JsonLdError { }); } ((List) ((Map) bnodes.get(id)).get("quads")) - .add(quad); + .add(quad); } } } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index c1130d97..e0accff7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -184,8 +184,7 @@ public static boolean isRelativeIri(String value) { } /** - * Removes the @preserve keywords as the last - * step of the framing algorithm. + * Removes the @preserve keywords as the last step of the framing algorithm. * * @param ctx * the active context used to compact the input. @@ -225,15 +224,14 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro // recurse through @lists if (isList(input)) { - ((Map) input).put("@list", removePreserve(ctx, - ((Map) input).get("@list"), opts)); + ((Map) input).put("@list", + removePreserve(ctx, ((Map) input).get("@list"), opts)); return input; } // recurse through properties for (final String prop : ((Map) input).keySet()) { - Object result = removePreserve(ctx, ((Map) input).get(prop), - opts); + Object result = removePreserve(ctx, ((Map) input).get(prop), opts); final String container = ctx.getContainer(prop); if (opts.getCompactArrays() && isArray(result) && ((List) result).size() == 1 && container == null) { @@ -246,21 +244,22 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro } /** - * Removes the @id member of each node object where the member value - * is a blank node identifier which appears only once in any property - * value within input. + * Removes the @id member of each node object where the member value is a + * blank node identifier which appears only once in any property value + * within input. * * @param input * the framed output before compaction */ static void pruneBlankNodes(final Object input) { - final Map toPrune = new HashMap<>(); + final Map toPrune = new HashMap<>(); fillNodesToPrune(input, toPrune); for (final String id : toPrune.keySet()) { final Object node = toPrune.get(id); - if (node == null) + if (node == null) { continue; + } ((Map) node).remove(JsonLdConsts.ID); } } @@ -273,7 +272,7 @@ static void pruneBlankNodes(final Object input) { * @param toPrune * the resulting object. */ - static void fillNodesToPrune(Object input, final Map toPrune) { + static void fillNodesToPrune(Object input, final Map toPrune) { // recurse through arrays if (isArray(input)) { for (final Object i : (List) input) { @@ -294,7 +293,8 @@ static void fillNodesToPrune(Object input, final Map toPrune) { if (prop.equals(JsonLdConsts.ID)) { final String id = (String) ((Map) input).get(JsonLdConsts.ID); if (id.startsWith("_:")) { - // if toPrune contains the id already, it was already present somewhere else, + // if toPrune contains the id already, it was already + // present somewhere else, // so we just null the value if (toPrune.containsKey(id)) { toPrune.put(id, null); @@ -308,11 +308,14 @@ static void fillNodesToPrune(Object input, final Map toPrune) { } } } else if (input instanceof String) { - // this is an id, as non-id values will have been discarded by the isValue() above + // this is an id, as non-id values will have been discarded by the + // isValue() above final String p = (String) input; if (p.startsWith("_:")) { - // the id is outside of the context of an @id property, if we're in that case, - // then we're referencing a blank node id so this id should not be removed + // the id is outside of the context of an @id property, if we're + // in that case, + // then we're referencing a blank node id so this id should not + // be removed toPrune.put(p, null); } } @@ -372,7 +375,7 @@ static boolean compareValues(Object v1, Object v2) { if ((v1 instanceof Map && ((Map) v1).containsKey("@id")) && (v2 instanceof Map && ((Map) v2).containsKey("@id")) && ((Map) v1).get("@id") - .equals(((Map) v2).get("@id"))) { + .equals(((Map) v2).get("@id"))) { return true; } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 774a234c..86b00099 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -140,17 +140,17 @@ public void testFrame0008() throws IOException, JsonLdError { @Test public void testFramep050() throws IOException, JsonLdError { - final Object frame = JsonUtils - .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-frame.jsonld")); - final Object in = JsonUtils - .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-in.jsonld")); + final Object frame = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/json-ld.org/frame-p050-frame.jsonld")); + final Object in = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/json-ld.org/frame-p050-in.jsonld")); final JsonLdOptions opts = new JsonLdOptions(); opts.setProcessingMode("json-ld-1.1"); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); - final Object out = JsonUtils - .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-out.jsonld")); + final Object out = JsonUtils.fromInputStream( + getClass().getResourceAsStream("/json-ld.org/frame-p050-out.jsonld")); assertEquals(out, frame2); } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 1ee25298..d9c6c760 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -552,7 +552,7 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { { put("@id", "http://json-ld.org/test-suite/tests/error-expand-manifest.jsonld" - .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); + .equals(manifest) ? "earl:semiAuto" : "earl:automatic"); } }); } diff --git a/pom.xml b/pom.xml index a6a445e6..e340509c 100755 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ UTF-8 UTF-8 - 4.5.5 + 4.5.6 4.4.10 2.9.6 4.12 @@ -197,7 +197,7 @@ org.mockito mockito-core - 2.19.0 + 2.21.0 commons-io @@ -209,7 +209,7 @@ com.google.guava guava - 25.1-jre + 26.0-jre @@ -400,7 +400,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.12.0 + 0.13.0 @@ -436,7 +436,7 @@ org.apache.felix maven-bundle-plugin - 3.5.0 + 3.5.1 From befb6b82da0b7b41cc57564748ac8c1977160ca5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 5 Sep 2018 14:17:21 +1000 Subject: [PATCH 334/440] Release 0.12.1 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 3883084f..f6e6320f 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.1-SNAPSHOT + 0.12.1 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index e340509c..134e1925 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.1-SNAPSHOT + 0.12.1 JSONLD Java :: Parent Json-LD Java Parent POM pom From cfb723868eeff538ebd60e282272070a22118e0a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 5 Sep 2018 14:56:45 +1000 Subject: [PATCH 335/440] Bump to next snapshot Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index f6e6320f..439cef7a 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.1 + 0.12.2-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 134e1925..91a0a39a 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.1 + 0.12.2-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 01a2cc68f4367817cd55ca1e3cdc57921a7399a9 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Wed, 5 Sep 2018 13:11:44 +0200 Subject: [PATCH 336/440] fix #240 --- README.md | 3 ++ .../com/github/jsonldjava/core/JsonLdApi.java | 3 +- .../github/jsonldjava/core/JsonLdOptions.java | 29 +++++++++++++++---- .../jsonldjava/core/JsonLdProcessor.java | 22 +++++++------- .../jsonldjava/core/JsonLdFramingTest.java | 16 ---------- .../jsonldjava/core/JsonLdProcessorTest.java | 3 ++ .../json-ld.org/frame-manifest.jsonld | 16 ++++++++-- 7 files changed, 55 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 6e5990c3..44f7642c 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,9 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-09-05 +* handle omit graph flag + ### 2018-07-07 * make pruneBlankNodeIdentifiers false by default in 1.0 mode and always true in 1.1 mode * fix issue with blank node identifier pruning when @id is aliased diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index d8cf642a..3bf03d49 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -505,8 +505,7 @@ public Object compact(Context activeCtx, String activeProperty, Object element) */ public Object expand(Context activeCtx, String activeProperty, Object element) throws JsonLdError { - final boolean frameExpansion = this.opts.getProcessingMode() - .equals(JsonLdOptions.JSON_LD_1_1_FRAME); + final boolean frameExpansion = this.opts.getFrameExpansion(); // 1) if (element == null) { return null; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 3c928dd2..f8bf5a82 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -16,8 +16,6 @@ public class JsonLdOptions { public static final String JSON_LD_1_1 = "json-ld-1.1"; - public static final String JSON_LD_1_1_FRAME = "json-ld-1.1-expand-frame"; - public static final boolean DEFAULT_COMPACT_ARRAYS = true; /** @@ -66,6 +64,8 @@ public JsonLdOptions(String base) { private Embed embed = Embed.LAST; private Boolean explicit = null; private Boolean omitDefault = null; + private Boolean omitGraph = false; + private Boolean frameExpansion = false; private Boolean pruneBlankNodeIdentifiers = false; private Boolean requireAll = false; @@ -132,14 +132,27 @@ public void setOmitDefault(Boolean omitDefault) { this.omitDefault = omitDefault; } + public Boolean getFrameExpansion() { + return frameExpansion; + } + + public void setFrameExpansion(Boolean frameExpansion) { + this.frameExpansion = frameExpansion; + } + + public Boolean getOmitGraph() { + return omitGraph; + } + + public void setOmitGraph(Boolean omitGraph) { + this.omitGraph = omitGraph; + } + public Boolean getPruneBlankNodeIdentifiers() { - return pruneBlankNodeIdentifiers || getProcessingMode().equals(JSON_LD_1_1); + return pruneBlankNodeIdentifiers; } public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { - if (pruneBlankNodeIdentifiers) { - setProcessingMode(JSON_LD_1_1); - } this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; } @@ -173,6 +186,10 @@ public String getProcessingMode() { public void setProcessingMode(String processingMode) { this.processingMode = processingMode; + if (processingMode.equals(JSON_LD_1_1)) { + this.omitGraph = true; + this.pruneBlankNodeIdentifiers = true; + } } public String getBase() { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 23d816d3..5b46b5e6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -307,15 +307,12 @@ public static Map frame(Object input, Object frame, JsonLdOption final Object expandedInput = expand(input, opts); // 3. Set expanded frame to the result of using the expand method using - // frame and options - // with expandContext set to null and processingMode set to - // json-ld-1.1-expand-frame. - final String savedProcessingMode = opts.getProcessingMode(); + // frame and options with expandContext set to null and the + // frameExpansion option set to true. final Object savedExpandedContext = opts.getExpandContext(); - opts.setProcessingMode(JsonLdOptions.JSON_LD_1_1_FRAME); opts.setExpandContext(null); + opts.setFrameExpansion(true); final List expandedFrame = expand(frame, opts); - opts.setProcessingMode(savedProcessingMode); opts.setExpandContext(savedExpandedContext); // 4. Set context to the value of @context from frame, if it exists, or @@ -329,14 +326,19 @@ public static Map frame(Object input, Object frame, JsonLdOption JsonLdUtils.pruneBlankNodes(framed); } Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); - if (!(compacted instanceof List)) { + final Map rval = activeCtx.serialize(); + final boolean addGraph = ((!(compacted instanceof List)) && !opts.getOmitGraph()); + if (addGraph && !(compacted instanceof List)) { final List tmp = new ArrayList(); tmp.add(compacted); compacted = tmp; } - final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); - final Map rval = activeCtx.serialize(); - rval.put(alias, compacted); + if (addGraph || (compacted instanceof List)) { + final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); + rval.put(alias, compacted); + } else if (!addGraph && (compacted instanceof Map)) { + rval.putAll((Map) compacted); + } JsonLdUtils.removePreserve(activeCtx, rval, opts); return rval; } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index 774a234c..b11e2a21 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -138,22 +138,6 @@ public void testFrame0008() throws IOException, JsonLdError { assertEquals(out, frame2); } - @Test - public void testFramep050() throws IOException, JsonLdError { - final Object frame = JsonUtils - .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-frame.jsonld")); - final Object in = JsonUtils - .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-in.jsonld")); - - final JsonLdOptions opts = new JsonLdOptions(); - opts.setProcessingMode("json-ld-1.1"); - final Map frame2 = JsonLdProcessor.frame(in, frame, opts); - - final Object out = JsonUtils - .fromInputStream(getClass().getResourceAsStream("/json-ld.org/frame-p050-out.jsonld")); - assertEquals(out, frame2); - } - @Test public void testFrame0009() throws IOException, JsonLdError { final Object frame = JsonUtils diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java index 1ee25298..e9827b5b 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdProcessorTest.java @@ -419,6 +419,9 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError { if (test_opts.containsKey("processingMode")) { options.setProcessingMode((String) test_opts.get("processingMode")); } + if (test_opts.containsKey("omitGraph")) { + options.setOmitGraph((Boolean) test_opts.get("omitGraph")); + } if (test_opts.containsKey("produceGeneralizedRdf")) { options.setProduceGeneralizedRdf((Boolean) test_opts.get("produceGeneralizedRdf")); } diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index 3d559db3..2872a0d3 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -167,11 +167,21 @@ "input": "frame-0030-in.jsonld", "frame": "frame-0030-frame.jsonld", "expect": "frame-0030-out.jsonld" + }, { + "@id": "#tg001", + "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], + "name": "Library framing example with @graph and omitGraph is true.", + "purpose": "Basic example used in playground and spec examples.", + "input": "frame-g001-in.jsonld", + "frame": "frame-g001-frame.jsonld", + "expect": "frame-g001-out.jsonld", + "option": {"specVersion": "json-ld-1.1", "omitGraph": true} }, { "@id": "#tp010", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Property CURIE conflict (prune bnodes)", - "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, + "purpose": "(Not really framing) A term looking like a CURIE becomes a CURIE when framing/compacting if defined as such in frame/context.", + "option": {"processingMode": "json-ld-1.1", "omitGraph" : false, "specVersion": "json-ld-1.1"}, "input": "frame-0010-in.jsonld", "frame": "frame-0010-frame.jsonld", "expect": "frame-p010-out.jsonld" @@ -195,7 +205,7 @@ "@id": "#tp046", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Merge graphs if no outer @graph is used (prune bnodes)", - "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, + "option": {"processingMode": "json-ld-1.1", "omitGraph" : false, "specVersion": "json-ld-1.1"}, "input": "frame-0046-in.jsonld", "frame": "frame-0046-frame.jsonld", "expect": "frame-p046-out.jsonld" @@ -207,6 +217,6 @@ "input": "frame-p050-in.jsonld", "frame": "frame-p050-frame.jsonld", "expect": "frame-p050-out.jsonld", - "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"} + "option": {"processingMode": "json-ld-1.1", "omitGraph" : false, "specVersion": "json-ld-1.1"} }] } From 0e61d0c7b6750172ed319c3992ecfaef18f6f8fb Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Thu, 6 Sep 2018 09:51:16 +0200 Subject: [PATCH 337/440] fix test expectations --- .../resources/json-ld.org/frame-manifest.jsonld | 6 +++--- .../resources/json-ld.org/frame-p010-out.jsonld | 14 ++++++-------- .../resources/json-ld.org/frame-p046-out.jsonld | 8 +++----- .../resources/json-ld.org/frame-p050-out.jsonld | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/core/src/test/resources/json-ld.org/frame-manifest.jsonld b/core/src/test/resources/json-ld.org/frame-manifest.jsonld index 2872a0d3..03df4284 100644 --- a/core/src/test/resources/json-ld.org/frame-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/frame-manifest.jsonld @@ -181,7 +181,7 @@ "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Property CURIE conflict (prune bnodes)", "purpose": "(Not really framing) A term looking like a CURIE becomes a CURIE when framing/compacting if defined as such in frame/context.", - "option": {"processingMode": "json-ld-1.1", "omitGraph" : false, "specVersion": "json-ld-1.1"}, + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, "input": "frame-0010-in.jsonld", "frame": "frame-0010-frame.jsonld", "expect": "frame-p010-out.jsonld" @@ -205,7 +205,7 @@ "@id": "#tp046", "@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"], "name": "Merge graphs if no outer @graph is used (prune bnodes)", - "option": {"processingMode": "json-ld-1.1", "omitGraph" : false, "specVersion": "json-ld-1.1"}, + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"}, "input": "frame-0046-in.jsonld", "frame": "frame-0046-frame.jsonld", "expect": "frame-p046-out.jsonld" @@ -217,6 +217,6 @@ "input": "frame-p050-in.jsonld", "frame": "frame-p050-frame.jsonld", "expect": "frame-p050-out.jsonld", - "option": {"processingMode": "json-ld-1.1", "omitGraph" : false, "specVersion": "json-ld-1.1"} + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"} }] } diff --git a/core/src/test/resources/json-ld.org/frame-p010-out.jsonld b/core/src/test/resources/json-ld.org/frame-p010-out.jsonld index cddb9a62..38077e48 100644 --- a/core/src/test/resources/json-ld.org/frame-p010-out.jsonld +++ b/core/src/test/resources/json-ld.org/frame-p010-out.jsonld @@ -7,11 +7,9 @@ "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, - "@graph": [{ - "@id": "http://example.com/asset", - "@type": "ps:Asset", - "dc:creator": { - "foaf:name": "John Doe" - } - }] -} + "@id": "http://example.com/asset", + "@type": "ps:Asset", + "dc:creator": { + "foaf:name": "John Doe" + } +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-p046-out.jsonld b/core/src/test/resources/json-ld.org/frame-p046-out.jsonld index dd3b7aed..6d127277 100644 --- a/core/src/test/resources/json-ld.org/frame-p046-out.jsonld +++ b/core/src/test/resources/json-ld.org/frame-p046-out.jsonld @@ -1,8 +1,6 @@ { "@context": {"@vocab": "urn:"}, - "@graph": [{ - "@id": "urn:id-1", - "@type": "Class", - "preserve": {} - }] + "@id": "urn:id-1", + "@type": "Class", + "preserve": {} } \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-p050-out.jsonld b/core/src/test/resources/json-ld.org/frame-p050-out.jsonld index ebbf9018..75e0a23e 100644 --- a/core/src/test/resources/json-ld.org/frame-p050-out.jsonld +++ b/core/src/test/resources/json-ld.org/frame-p050-out.jsonld @@ -3,5 +3,5 @@ "@vocab": "http://example/", "id": "@id" }, - "@graph": [{"name": "foo"}] + "name": "foo" } \ No newline at end of file From d3d3b1e5e6a0d551481f6ce5796120fd512a3ab0 Mon Sep 17 00:00:00 2001 From: Elie Roux Date: Fri, 7 Sep 2018 07:50:38 +0200 Subject: [PATCH 338/440] add missing frame-g001 tests --- .../json-ld.org/frame-g001-frame.jsonld | 13 +++++++++ .../json-ld.org/frame-g001-in.jsonld | 27 +++++++++++++++++++ .../json-ld.org/frame-g001-out.jsonld | 20 ++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 core/src/test/resources/json-ld.org/frame-g001-frame.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-g001-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/frame-g001-out.jsonld diff --git a/core/src/test/resources/json-ld.org/frame-g001-frame.jsonld b/core/src/test/resources/json-ld.org/frame-g001-frame.jsonld new file mode 100644 index 00000000..16faf5bb --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-g001-frame.jsonld @@ -0,0 +1,13 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@type": "ex:Library", + "ex:contains": { + "@type": "ex:Book", + "ex:contains": { + "@type": "ex:Chapter" + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-g001-in.jsonld b/core/src/test/resources/json-ld.org/frame-g001-in.jsonld new file mode 100644 index 00000000..dcc2dfab --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-g001-in.jsonld @@ -0,0 +1,27 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#", + "ex:contains": {"@type": "@id"} + }, + "@graph": [ + { + "@id": "http://example.org/test/#library", + "@type": "ex:Library", + "ex:contains": "http://example.org/test#book" + }, + { + "@id": "http://example.org/test#book", + "@type": "ex:Book", + "dc:contributor": "Writer", + "dc:title": "My Book", + "ex:contains": "http://example.org/test#chapter" + }, + { + "@id": "http://example.org/test#chapter", + "@type": "ex:Chapter", + "dc:description": "Fun", + "dc:title": "Chapter One" + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/frame-g001-out.jsonld b/core/src/test/resources/json-ld.org/frame-g001-out.jsonld new file mode 100644 index 00000000..54356959 --- /dev/null +++ b/core/src/test/resources/json-ld.org/frame-g001-out.jsonld @@ -0,0 +1,20 @@ +{ + "@context": { + "dc": "http://purl.org/dc/elements/1.1/", + "ex": "http://example.org/vocab#" + }, + "@id": "http://example.org/test/#library", + "@type": "ex:Library", + "ex:contains": { + "@id": "http://example.org/test#book", + "@type": "ex:Book", + "dc:contributor": "Writer", + "dc:title": "My Book", + "ex:contains": { + "@id": "http://example.org/test#chapter", + "@type": "ex:Chapter", + "dc:description": "Fun", + "dc:title": "Chapter One" + } + } +} \ No newline at end of file From 2fcaa78e52cfe88430857aa7bc57ee64b380c85b Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 26 Oct 2018 13:51:46 +0200 Subject: [PATCH 339/440] Implement @type to be defined with @container: @set - add test compact-105 See w3c/json-ld-syntax#34. --- core/pom.xml | 2 +- .../java/com/github/jsonldjava/core/Context.java | 6 ++++-- .../java/com/github/jsonldjava/core/JsonLdApi.java | 13 +++++++------ .../json-ld.org/compact-0105-context.jsonld | 5 +++++ .../resources/json-ld.org/compact-0105-in.jsonld | 3 +++ .../resources/json-ld.org/compact-0105-out.jsonld | 6 ++++++ .../resources/json-ld.org/compact-manifest.jsonld | 10 ++++++++++ pom.xml | 2 +- 8 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/compact-0105-context.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0105-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0105-out.jsonld diff --git a/core/pom.xml b/core/pom.xml index 439cef7a..93fba416 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.2-SNAPSHOT + 0.12.3-SNAPSHOT 4.0.0 jsonld-java diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 3edb2150..7c7ba74a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -1044,13 +1044,15 @@ private String selectTerm(String iri, List containers, String typeLangua * * @param property * The Property to get a container mapping for. - * @return The container mapping + * @return The container mapping if any, else null */ public String getContainer(String property) { + if (property==null) return null; if (JsonLdConsts.GRAPH.equals(property)) { return JsonLdConsts.SET; } - if (JsonLdUtils.isKeyword(property)) { + if (!property.equals(JsonLdConsts.TYPE) + && JsonLdUtils.isKeyword(property)) { return property; } final Map td = (Map) termDefinitions.get(property); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index dd82e359..b383e81e 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -202,12 +202,13 @@ public Object compact(Context activeCtx, String activeProperty, Object element, Collections.sort(keys); for (final String expandedProperty : keys) { final Object expandedValue = elem.get(expandedProperty); - // 7.1) if (JsonLdConsts.ID.equals(expandedProperty) || JsonLdConsts.TYPE.equals(expandedProperty)) { + // 7.1.3) + final String alias = activeCtx.compactIri(expandedProperty, true); Object compactedValue; - + // 7.1.1) if (expandedValue instanceof String) { compactedValue = activeCtx.compactIri((String) expandedValue, @@ -221,15 +222,15 @@ public Object compact(Context activeCtx, String activeProperty, Object element, types.add(activeCtx.compactIri(expandedType, true)); } // 7.1.2.3) - if (types.size() == 1) { + if ( types.size() == 1 + // see w3c/json-ld-syntax#74 + && ! (activeCtx.getContainer(alias) != null + && activeCtx.getContainer(alias).equals(JsonLdConsts.SET)) ) { compactedValue = types.get(0); } else { compactedValue = types; } } - - // 7.1.3) - final String alias = activeCtx.compactIri(expandedProperty, true); // 7.1.4) result.put(alias, compactedValue); continue; diff --git a/core/src/test/resources/json-ld.org/compact-0105-context.jsonld b/core/src/test/resources/json-ld.org/compact-0105-context.jsonld new file mode 100644 index 00000000..bc961d55 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0105-context.jsonld @@ -0,0 +1,5 @@ +{ + "@context": { + "type": {"@id": "@type", "@container": "@set"} + } +} diff --git a/core/src/test/resources/json-ld.org/compact-0105-in.jsonld b/core/src/test/resources/json-ld.org/compact-0105-in.jsonld new file mode 100644 index 00000000..9bcd4848 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0105-in.jsonld @@ -0,0 +1,3 @@ +{ + "@type": "http://example.org/type" +} diff --git a/core/src/test/resources/json-ld.org/compact-0105-out.jsonld b/core/src/test/resources/json-ld.org/compact-0105-out.jsonld new file mode 100644 index 00000000..6ce29444 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0105-out.jsonld @@ -0,0 +1,6 @@ +{ + "@context": { + "type": {"@id": "@type", "@container": "@set"} + }, + "type": ["http://example.org/type"] +} diff --git a/core/src/test/resources/json-ld.org/compact-manifest.jsonld b/core/src/test/resources/json-ld.org/compact-manifest.jsonld index cddd412e..3d9c55fd 100644 --- a/core/src/test/resources/json-ld.org/compact-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/compact-manifest.jsonld @@ -585,6 +585,16 @@ "input": "compact-0072-in.jsonld", "context": "compact-0072-context.jsonld", "expect": "compact-0072-out.jsonld" + }, + { + "@id": "#t0105", + "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], + "name": "Compact @type with @container: @set using an alias of @type", + "purpose": "Ensures that a single @type value is represented as an array", + "input": "compact-0105-in.jsonld", + "context": "compact-0105-context.jsonld", + "expect": "compact-0105-out.jsonld", + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"} } ] } diff --git a/pom.xml b/pom.xml index 91a0a39a..e8ff948c 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.2-SNAPSHOT + 0.12.3-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 673dac2ef4c70eeed532ff69ee2399312084a483 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 26 Oct 2018 22:53:31 +0200 Subject: [PATCH 340/440] Implement @type to be defined with @container: @set - add test compact-104 See w3c/json-ld-syntax#34. --- .../main/java/com/github/jsonldjava/core/Context.java | 8 ++++++-- .../resources/json-ld.org/compact-0104-context.jsonld | 5 +++++ .../test/resources/json-ld.org/compact-0104-in.jsonld | 3 +++ .../test/resources/json-ld.org/compact-0104-out.jsonld | 6 ++++++ .../test/resources/json-ld.org/compact-manifest.jsonld | 10 ++++++++++ 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/compact-0104-context.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0104-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0104-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 7c7ba74a..5f63675f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -310,7 +310,9 @@ private void createTermDefinition(Map context, String term, defined.put(term, false); - if (JsonLdUtils.isKeyword(term)) { + if ( JsonLdUtils.isKeyword(term)// + && !(JsonLdConsts.TYPE.equals(term)// + && !(context.get(term)).toString().contains(JsonLdConsts.ID)) ) { throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); } @@ -439,7 +441,7 @@ else if (term.indexOf(":") >= 0) { // 15) } else if (this.containsKey(JsonLdConsts.VOCAB)) { definition.put(JsonLdConsts.ID, this.get(JsonLdConsts.VOCAB) + term); - } else { + } else if (!JsonLdConsts.TYPE.equals(term)) { throw new JsonLdError(Error.INVALID_IRI_MAPPING, "relative term definition without vocab mapping"); } @@ -454,6 +456,8 @@ else if (term.indexOf(":") >= 0) { "@container must be either @list, @set, @index, or @language"); } definition.put(JsonLdConsts.CONTAINER, container); + if (JsonLdConsts.TYPE.equals(term)) + definition.put(JsonLdConsts.ID,"type"); } // 17) diff --git a/core/src/test/resources/json-ld.org/compact-0104-context.jsonld b/core/src/test/resources/json-ld.org/compact-0104-context.jsonld new file mode 100644 index 00000000..dd085528 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0104-context.jsonld @@ -0,0 +1,5 @@ +{ + "@context": { + "@type": {"@container": "@set"} + } +} diff --git a/core/src/test/resources/json-ld.org/compact-0104-in.jsonld b/core/src/test/resources/json-ld.org/compact-0104-in.jsonld new file mode 100644 index 00000000..9bcd4848 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0104-in.jsonld @@ -0,0 +1,3 @@ +{ + "@type": "http://example.org/type" +} diff --git a/core/src/test/resources/json-ld.org/compact-0104-out.jsonld b/core/src/test/resources/json-ld.org/compact-0104-out.jsonld new file mode 100644 index 00000000..6ac5afcc --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0104-out.jsonld @@ -0,0 +1,6 @@ +{ + "@context": { + "@type": {"@container": "@set"} + }, + "@type": ["http://example.org/type"] +} diff --git a/core/src/test/resources/json-ld.org/compact-manifest.jsonld b/core/src/test/resources/json-ld.org/compact-manifest.jsonld index 3d9c55fd..fbf3ed6f 100644 --- a/core/src/test/resources/json-ld.org/compact-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/compact-manifest.jsonld @@ -586,6 +586,16 @@ "context": "compact-0072-context.jsonld", "expect": "compact-0072-out.jsonld" }, + { + "@id": "#t0104", + "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], + "name": "Compact @type with @container: @set", + "purpose": "Ensures that a single @type value is represented as an array", + "input": "compact-0104-in.jsonld", + "context": "compact-0104-context.jsonld", + "expect": "compact-0104-out.jsonld", + "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"} + }, { "@id": "#t0105", "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], From 287214641ec104126c67dd1ec4c4289351d1e689 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Sat, 27 Oct 2018 10:15:41 +0200 Subject: [PATCH 341/440] Implement @type to be defined with @container: @set - add test compact-106 See w3c/json-ld-syntax#34. --- .../java/com/github/jsonldjava/core/Context.java | 2 +- .../java/com/github/jsonldjava/core/JsonLdApi.java | 7 ++++--- .../com/github/jsonldjava/core/JsonLdOptions.java | 12 +++++++++++- .../json-ld.org/compact-0106-context.jsonld | 5 +++++ .../resources/json-ld.org/compact-0106-in.jsonld | 3 +++ .../resources/json-ld.org/compact-0106-out.jsonld | 6 ++++++ .../resources/json-ld.org/compact-manifest.jsonld | 10 ++++++++++ 7 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/compact-0106-context.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0106-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/compact-0106-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 5f63675f..ff09ab7f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -310,7 +310,7 @@ private void createTermDefinition(Map context, String term, defined.put(term, false); - if ( JsonLdUtils.isKeyword(term)// + if (JsonLdUtils.isKeyword(term)// && !(JsonLdConsts.TYPE.equals(term)// && !(context.get(term)).toString().contains(JsonLdConsts.ID)) ) { throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index b383e81e..3599b5e2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -222,10 +222,11 @@ public Object compact(Context activeCtx, String activeProperty, Object element, types.add(activeCtx.compactIri(expandedType, true)); } // 7.1.2.3) - if ( types.size() == 1 + if ( types.size() == 1// // see w3c/json-ld-syntax#74 - && ! (activeCtx.getContainer(alias) != null - && activeCtx.getContainer(alias).equals(JsonLdConsts.SET)) ) { + && (!opts.getAllowContainerSetOnType() || + !(activeCtx.getContainer(alias) != null + && activeCtx.getContainer(alias).equals(JsonLdConsts.SET)))) { compactedValue = types.get(0); } else { compactedValue = types; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index f8bf5a82..d499e476 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -68,6 +68,7 @@ public JsonLdOptions(String base) { private Boolean frameExpansion = false; private Boolean pruneBlankNodeIdentifiers = false; private Boolean requireAll = false; + private Boolean allowContainerSetOnType=false; // RDF conversion options : // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm @@ -163,7 +164,15 @@ public Boolean getRequireAll() { public void setRequireAll(Boolean requireAll) { this.requireAll = requireAll; } - + + public Boolean getAllowContainerSetOnType() { + return allowContainerSetOnType; + } + + public void setAllowContainerSetOnType(Boolean allowContainerSetOnType) { + this.allowContainerSetOnType = allowContainerSetOnType; + } + public Boolean getCompactArrays() { return compactArrays; } @@ -189,6 +198,7 @@ public void setProcessingMode(String processingMode) { if (processingMode.equals(JSON_LD_1_1)) { this.omitGraph = true; this.pruneBlankNodeIdentifiers = true; + this.allowContainerSetOnType=true; } } diff --git a/core/src/test/resources/json-ld.org/compact-0106-context.jsonld b/core/src/test/resources/json-ld.org/compact-0106-context.jsonld new file mode 100644 index 00000000..bc961d55 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0106-context.jsonld @@ -0,0 +1,5 @@ +{ + "@context": { + "type": {"@id": "@type", "@container": "@set"} + } +} diff --git a/core/src/test/resources/json-ld.org/compact-0106-in.jsonld b/core/src/test/resources/json-ld.org/compact-0106-in.jsonld new file mode 100644 index 00000000..9bcd4848 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0106-in.jsonld @@ -0,0 +1,3 @@ +{ + "@type": "http://example.org/type" +} diff --git a/core/src/test/resources/json-ld.org/compact-0106-out.jsonld b/core/src/test/resources/json-ld.org/compact-0106-out.jsonld new file mode 100644 index 00000000..349e0fb4 --- /dev/null +++ b/core/src/test/resources/json-ld.org/compact-0106-out.jsonld @@ -0,0 +1,6 @@ +{ + "@context": { + "type": {"@id": "@type", "@container": "@set"} + }, + "type": "http://example.org/type" +} diff --git a/core/src/test/resources/json-ld.org/compact-manifest.jsonld b/core/src/test/resources/json-ld.org/compact-manifest.jsonld index fbf3ed6f..14e06675 100644 --- a/core/src/test/resources/json-ld.org/compact-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/compact-manifest.jsonld @@ -605,6 +605,16 @@ "context": "compact-0105-context.jsonld", "expect": "compact-0105-out.jsonld", "option": {"processingMode": "json-ld-1.1", "specVersion": "json-ld-1.1"} + }, + { + "@id": "#t0106", + "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], + "name": "Do not compact @type with @container: @set to an array using an alias of @type", + "purpose": "Ensures that a single @type value is not represented as an array in 1.0", + "input": "compact-0106-in.jsonld", + "context": "compact-0106-context.jsonld", + "expect": "compact-0106-out.jsonld", + "option": {"processingMode": "json-ld-1.0", "specVersion": "json-ld-1.1"} } ] } From 3c538714cbb0d7dd25855c6f13919076068f2d75 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Sat, 27 Oct 2018 10:34:28 +0200 Subject: [PATCH 342/440] Implement @type to be defined with @container: @set - add test expand-e042 See w3c/json-ld-syntax#34. --- .../src/main/java/com/github/jsonldjava/core/Context.java | 3 ++- core/src/test/resources/json-ld.org/error-manifest.jsonld | 8 ++++++++ core/src/test/resources/json-ld.org/expand-e042-in.jsonld | 6 ++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/json-ld.org/expand-e042-in.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index ff09ab7f..48f1bc79 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -311,7 +311,8 @@ private void createTermDefinition(Map context, String term, defined.put(term, false); if (JsonLdUtils.isKeyword(term)// - && !(JsonLdConsts.TYPE.equals(term)// + && !(options.getAllowContainerSetOnType()// + && JsonLdConsts.TYPE.equals(term)// && !(context.get(term)).toString().contains(JsonLdConsts.ID)) ) { throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); } diff --git a/core/src/test/resources/json-ld.org/error-manifest.jsonld b/core/src/test/resources/json-ld.org/error-manifest.jsonld index afc16304..4b9b5c56 100644 --- a/core/src/test/resources/json-ld.org/error-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/error-manifest.jsonld @@ -308,6 +308,14 @@ "purpose": "Verifies that an exception is raised in Flattening when conflicting indexes are found", "input": "error-0043-in.jsonld", "expect": "conflicting indexes" + }, + { + "@id": "#te042", + "@type": [ "jld:NegativeEvaluationTest", "jld:ExpandTest" ], + "name": "Keywords may not be redefined", + "purpose": "Verifies that an exception is raised on expansion when processing an invalid context attempting to define @container on a keyword", + "input": "expand-e042-in.jsonld", + "expect": "keyword redefinition" } ] } diff --git a/core/src/test/resources/json-ld.org/expand-e042-in.jsonld b/core/src/test/resources/json-ld.org/expand-e042-in.jsonld new file mode 100644 index 00000000..41360255 --- /dev/null +++ b/core/src/test/resources/json-ld.org/expand-e042-in.jsonld @@ -0,0 +1,6 @@ +{ + "@context": { + "@type": {"@container": "@set"} + }, + "@type": "http://example.org/type" +} From b34f148ad2367755e188c2279e7d1fef4c45f0c8 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Sat, 27 Oct 2018 11:14:25 +0200 Subject: [PATCH 343/440] Improve coverage by removing unused code - declare JsonUtils as abstract --- .../github/jsonldjava/core/JsonLdOptions.java | 24 ------------------- .../github/jsonldjava/core/JsonLdUtils.java | 5 +--- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index d499e476..23a243ad 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -94,10 +94,6 @@ Embed getEmbedVal() { return this.embed; } - public void setEmbed(Boolean embed) { - this.embed = embed ? Embed.LAST : Embed.NEVER; - } - public void setEmbed(String embed) throws JsonLdError { switch (embed) { case "@always": @@ -129,10 +125,6 @@ public Boolean getOmitDefault() { return omitDefault; } - public void setOmitDefault(Boolean omitDefault) { - this.omitDefault = omitDefault; - } - public Boolean getFrameExpansion() { return frameExpansion; } @@ -153,26 +145,14 @@ public Boolean getPruneBlankNodeIdentifiers() { return pruneBlankNodeIdentifiers; } - public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { - this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; - } - public Boolean getRequireAll() { return this.requireAll; } - - public void setRequireAll(Boolean requireAll) { - this.requireAll = requireAll; - } public Boolean getAllowContainerSetOnType() { return allowContainerSetOnType; } - public void setAllowContainerSetOnType(Boolean allowContainerSetOnType) { - this.allowContainerSetOnType = allowContainerSetOnType; - } - public Boolean getCompactArrays() { return compactArrays; } @@ -189,10 +169,6 @@ public void setExpandContext(Object expandContext) { this.expandContext = expandContext; } - public String getProcessingMode() { - return processingMode; - } - public void setProcessingMode(String processingMode) { this.processingMode = processingMode; if (processingMode.equals(JSON_LD_1_1)) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index e0accff7..3b6b3153 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -8,10 +8,7 @@ import com.github.jsonldjava.utils.Obj; -public class JsonLdUtils { - - private static final int MAX_CONTEXT_URLS = 10; - +abstract class JsonLdUtils { /** * Returns whether or not the given value is a keyword (or a keyword alias). * From 3094ae357553bec2116811333298c43fb1f4e734 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Sat, 27 Oct 2018 11:19:15 +0200 Subject: [PATCH 344/440] Remove oraclejdk10 because it is deprecated This fixes unhappy travis. See #243. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 589b4f97..e7d32e30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: java jdk: - oraclejdk8 - oraclejdk9 - - oraclejdk10 matrix: include: - jdk: openjdk10 From 8ca1550c5f2b0caee0aa99ff0fe222f776f115c5 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 30 Oct 2018 15:04:33 +0100 Subject: [PATCH 345/440] Revert b34f148ad2367755e188c2279e7d1fef4c45f0c8 See jsonld-java/jsonld-java#243#discussion_r228773274. --- .../github/jsonldjava/core/JsonLdOptions.java | 24 +++++++++++++++++++ .../github/jsonldjava/core/JsonLdUtils.java | 5 +++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index 23a243ad..d499e476 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -94,6 +94,10 @@ Embed getEmbedVal() { return this.embed; } + public void setEmbed(Boolean embed) { + this.embed = embed ? Embed.LAST : Embed.NEVER; + } + public void setEmbed(String embed) throws JsonLdError { switch (embed) { case "@always": @@ -125,6 +129,10 @@ public Boolean getOmitDefault() { return omitDefault; } + public void setOmitDefault(Boolean omitDefault) { + this.omitDefault = omitDefault; + } + public Boolean getFrameExpansion() { return frameExpansion; } @@ -145,14 +153,26 @@ public Boolean getPruneBlankNodeIdentifiers() { return pruneBlankNodeIdentifiers; } + public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) { + this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers; + } + public Boolean getRequireAll() { return this.requireAll; } + + public void setRequireAll(Boolean requireAll) { + this.requireAll = requireAll; + } public Boolean getAllowContainerSetOnType() { return allowContainerSetOnType; } + public void setAllowContainerSetOnType(Boolean allowContainerSetOnType) { + this.allowContainerSetOnType = allowContainerSetOnType; + } + public Boolean getCompactArrays() { return compactArrays; } @@ -169,6 +189,10 @@ public void setExpandContext(Object expandContext) { this.expandContext = expandContext; } + public String getProcessingMode() { + return processingMode; + } + public void setProcessingMode(String processingMode) { this.processingMode = processingMode; if (processingMode.equals(JSON_LD_1_1)) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java index 3b6b3153..e0accff7 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java @@ -8,7 +8,10 @@ import com.github.jsonldjava.utils.Obj; -abstract class JsonLdUtils { +public class JsonLdUtils { + + private static final int MAX_CONTEXT_URLS = 10; + /** * Returns whether or not the given value is a keyword (or a keyword alias). * From 3f2021f7ab11b73a2ef04c827f0c91cc2cded36f Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 30 Oct 2018 15:05:51 +0100 Subject: [PATCH 346/440] Revert version to the yet unreleased 0.12.2-SNAPSHOT See jsonld-java/jsonld-java#243#discussion_r228773154. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e8ff948c..91a0a39a 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.3-SNAPSHOT + 0.12.2-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 7e50f2df5be149864464f809808cf1f9630c4963 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 30 Oct 2018 15:10:34 +0100 Subject: [PATCH 347/440] Revert also version of the core/pom.xml See jsonld-java/jsonld-java#243#discussion_r228773154. --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 93fba416..439cef7a 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.3-SNAPSHOT + 0.12.2-SNAPSHOT 4.0.0 jsonld-java From f42eb4f93e5bb610ddc5750ed9e3cac97e6b6046 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 3 Nov 2018 07:44:43 +1100 Subject: [PATCH 348/440] Cleanup Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/Context.java | 19 ++++++++++--------- .../com/github/jsonldjava/core/JsonLdApi.java | 13 +++++++------ .../github/jsonldjava/core/JsonLdOptions.java | 10 +++++----- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 48f1bc79..ed816e65 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -310,10 +310,9 @@ private void createTermDefinition(Map context, String term, defined.put(term, false); - if (JsonLdUtils.isKeyword(term)// - && !(options.getAllowContainerSetOnType()// - && JsonLdConsts.TYPE.equals(term)// - && !(context.get(term)).toString().contains(JsonLdConsts.ID)) ) { + if (JsonLdUtils.isKeyword(term) + && !(options.getAllowContainerSetOnType() && JsonLdConsts.TYPE.equals(term) + && !(context.get(term)).toString().contains(JsonLdConsts.ID))) { throw new JsonLdError(Error.KEYWORD_REDEFINITION, term); } @@ -457,8 +456,9 @@ else if (term.indexOf(":") >= 0) { "@container must be either @list, @set, @index, or @language"); } definition.put(JsonLdConsts.CONTAINER, container); - if (JsonLdConsts.TYPE.equals(term)) - definition.put(JsonLdConsts.ID,"type"); + if (JsonLdConsts.TYPE.equals(term)) { + definition.put(JsonLdConsts.ID, "type"); + } } // 17) @@ -1052,12 +1052,13 @@ private String selectTerm(String iri, List containers, String typeLangua * @return The container mapping if any, else null */ public String getContainer(String property) { - if (property==null) return null; + if (property == null) { + return null; + } if (JsonLdConsts.GRAPH.equals(property)) { return JsonLdConsts.SET; } - if (!property.equals(JsonLdConsts.TYPE) - && JsonLdUtils.isKeyword(property)) { + if (!property.equals(JsonLdConsts.TYPE) && JsonLdUtils.isKeyword(property)) { return property; } final Map td = (Map) termDefinitions.get(property); diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 3599b5e2..d4940930 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -205,10 +205,11 @@ public Object compact(Context activeCtx, String activeProperty, Object element, // 7.1) if (JsonLdConsts.ID.equals(expandedProperty) || JsonLdConsts.TYPE.equals(expandedProperty)) { + // TODO: Relabel these step numbers when spec changes // 7.1.3) final String alias = activeCtx.compactIri(expandedProperty, true); Object compactedValue; - + // 7.1.1) if (expandedValue instanceof String) { compactedValue = activeCtx.compactIri((String) expandedValue, @@ -222,11 +223,11 @@ public Object compact(Context activeCtx, String activeProperty, Object element, types.add(activeCtx.compactIri(expandedType, true)); } // 7.1.2.3) - if ( types.size() == 1// - // see w3c/json-ld-syntax#74 - && (!opts.getAllowContainerSetOnType() || - !(activeCtx.getContainer(alias) != null - && activeCtx.getContainer(alias).equals(JsonLdConsts.SET)))) { + if (types.size() == 1// + // see w3c/json-ld-syntax#74 + && (!opts.getAllowContainerSetOnType() + || !(activeCtx.getContainer(alias) != null && activeCtx + .getContainer(alias).equals(JsonLdConsts.SET)))) { compactedValue = types.get(0); } else { compactedValue = types; diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index d499e476..ef0bd009 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -68,7 +68,7 @@ public JsonLdOptions(String base) { private Boolean frameExpansion = false; private Boolean pruneBlankNodeIdentifiers = false; private Boolean requireAll = false; - private Boolean allowContainerSetOnType=false; + private Boolean allowContainerSetOnType = false; // RDF conversion options : // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm @@ -164,15 +164,15 @@ public Boolean getRequireAll() { public void setRequireAll(Boolean requireAll) { this.requireAll = requireAll; } - + public Boolean getAllowContainerSetOnType() { return allowContainerSetOnType; } - + public void setAllowContainerSetOnType(Boolean allowContainerSetOnType) { this.allowContainerSetOnType = allowContainerSetOnType; } - + public Boolean getCompactArrays() { return compactArrays; } @@ -198,7 +198,7 @@ public void setProcessingMode(String processingMode) { if (processingMode.equals(JSON_LD_1_1)) { this.omitGraph = true; this.pruneBlankNodeIdentifiers = true; - this.allowContainerSetOnType=true; + this.allowContainerSetOnType = true; } } From b15ffbf0301aa1ee48cca1af008b492fca1a1e5a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 3 Nov 2018 10:41:13 +1100 Subject: [PATCH 349/440] Release 0.12.2 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 439cef7a..4884ff1c 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.2-SNAPSHOT + 0.12.2 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 91a0a39a..265fd0da 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.2-SNAPSHOT + 0.12.2 JSONLD Java :: Parent Json-LD Java Parent POM pom @@ -41,7 +41,7 @@ 4.5.6 4.4.10 - 2.9.6 + 2.9.7 4.12 1.7.25 @@ -197,7 +197,7 @@ org.mockito mockito-core - 2.21.0 + 2.23.0 commons-io @@ -209,7 +209,7 @@ com.google.guava guava - 26.0-jre + 27.0-jre From 848fee87ddb1c3734090bffbe50ad75c6a321ecc Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 3 Nov 2018 10:52:04 +1100 Subject: [PATCH 350/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 4884ff1c..93fba416 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.2 + 0.12.3-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 265fd0da..c754933f 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.2 + 0.12.3-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From e33776646fef62c4616e9fa8cbbf36a39dcabe65 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 3 Nov 2018 10:59:59 +1100 Subject: [PATCH 351/440] Update readme Signed-off-by: Peter Ansell --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7559f569..b1be751f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.12.1 + 0.12.2 Code example @@ -323,10 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.12.1-SNAPSHOT + 0.12.2 4.0.0 jsonld-java-{your module} + 0.12.3-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -449,6 +450,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-11-03 +# W3c json ld syntax 34 allow container set on aliased type (Patch by @dr0i) +# Release 0.12.2 + ### 2018-09-05 * handle omit graph flag (Patch by @eroux) * Release 0.12.1 From a1c138b5b722c076becffd51b73f9a22c8ed0861 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 8 Nov 2018 08:15:49 +1100 Subject: [PATCH 352/440] Fix #244 : Make two more Context methods public Opens up Context.getTypeMapping and Context.getLanguageMapping for reuse. They both expose immutable strings, so will not have an effect on the internal operation of the Context class, so are relatively safe to open up. --- core/src/main/java/com/github/jsonldjava/core/Context.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index ed816e65..e28823c6 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -1077,7 +1077,7 @@ public Boolean isReverseProperty(String property) { return reverse != null && (Boolean) reverse; } - private String getTypeMapping(String property) { + public String getTypeMapping(String property) { final Map td = (Map) termDefinitions.get(property); if (td == null) { return null; @@ -1085,7 +1085,7 @@ private String getTypeMapping(String property) { return (String) td.get(JsonLdConsts.TYPE); } - private String getLanguageMapping(String property) { + public String getLanguageMapping(String property) { final Map td = (Map) termDefinitions.get(property); if (td == null) { return null; @@ -1188,4 +1188,4 @@ public Map serialize() { return rval; } -} \ No newline at end of file +} From 9396d1faa41ab05f052905182dfe86d01eeb61bf Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Wed, 7 Nov 2018 22:39:36 +0100 Subject: [PATCH 353/440] Added fix for wrong rdf:type to @type conversion --- .../com/github/jsonldjava/core/JsonLdApi.java | 88 ++++++++++++------- .../jsonldjava/core/JsonLdFramingTest.java | 25 ++++++ .../resources/custom/frame-0010-frame.jsonld | 6 ++ .../resources/custom/frame-0010-out.jsonld | 13 +++ .../resources/json-ld.org/fromRdf-0020-in.nq | 7 ++ .../json-ld.org/fromRdf-0020-out.jsonld | 19 ++++ .../json-ld.org/fromRdf-manifest.jsonld | 7 ++ 7 files changed, 132 insertions(+), 33 deletions(-) create mode 100644 core/src/test/resources/custom/frame-0010-frame.jsonld create mode 100644 core/src/test/resources/custom/frame-0010-out.jsonld create mode 100644 core/src/test/resources/json-ld.org/fromRdf-0020-in.nq create mode 100644 core/src/test/resources/json-ld.org/fromRdf-0020-out.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index d4940930..20f839f9 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1861,6 +1861,15 @@ public UsagesNode(NodeMapNode node, String property, Map value) public Map value = null; } + private class Node { + private String predicate; + private RDFDataset.Node object; + public Node(String predicate, RDFDataset.Node object) { + this.predicate = predicate; + this.object = object; + } + } + private class NodeMapNode extends LinkedHashMap { public List usages = new ArrayList(4); @@ -1968,48 +1977,61 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData } // 3.5) + final Map> nodes = new HashMap<>(); + for (final RDFDataset.Quad triple : graph) { final String subject = triple.getSubject().getValue(); final String predicate = triple.getPredicate().getValue(); final RDFDataset.Node object = triple.getObject(); + final List list = nodes.getOrDefault(subject, new ArrayList()); + list.add(new Node(predicate, object)); + nodes.put(subject, list); + } + for (final Map.Entry> nodeEntry : nodes.entrySet()) { + final String subject = nodeEntry.getKey(); + + for (final Node n : nodeEntry.getValue()) { + final String predicate = n.predicate; + final RDFDataset.Node object = n.object; + + // 3.5.1+3.5.2) + NodeMapNode node; + if (!nodeMap.containsKey(subject)) { + node = new NodeMapNode(subject); + nodeMap.put(subject, node); + } else { + node = nodeMap.get(subject); + } - // 3.5.1+3.5.2) - NodeMapNode node; - if (!nodeMap.containsKey(subject)) { - node = new NodeMapNode(subject); - nodeMap.put(subject, node); - } else { - node = nodeMap.get(subject); - } - - // 3.5.3) - if ((object.isIRI() || object.isBlankNode()) - && !nodeMap.containsKey(object.getValue())) { - nodeMap.put(object.getValue(), new NodeMapNode(object.getValue())); - } + // 3.5.3) + if ((object.isIRI() || object.isBlankNode()) + && !nodeMap.containsKey(object.getValue())) { + nodeMap.put(object.getValue(), new NodeMapNode(object.getValue())); + } - // 3.5.4) - if (RDF_TYPE.equals(predicate) && (object.isIRI() || object.isBlankNode()) - && !opts.getUseRdfType()) { - JsonLdUtils.mergeValue(node, JsonLdConsts.TYPE, object.getValue()); - continue; - } + // 3.5.4) + if (RDF_TYPE.equals(predicate) && (object.isIRI() || object.isBlankNode()) + && !opts.getUseRdfType() && !nodes.containsKey(object.getValue())) { + JsonLdUtils.mergeValue(node, JsonLdConsts.TYPE, object.getValue()); + continue; + } - // 3.5.5) - final Map value = object.toObject(opts.getUseNativeTypes()); + // 3.5.5) + final Map value = object.toObject(opts.getUseNativeTypes()); - // 3.5.6+7) - if (noDuplicatesInDataset) { - JsonLdUtils.laxMergeValue(node, predicate, value); - } else { - JsonLdUtils.mergeValue(node, predicate, value); - } + // 3.5.6+7) + if (noDuplicatesInDataset) { + JsonLdUtils.laxMergeValue(node, predicate, value); + } else { + JsonLdUtils.mergeValue(node, predicate, value); + } - // 3.5.8) - if (object.isBlankNode() || object.isIRI()) { - // 3.5.8.1-3) - nodeMap.get(object.getValue()).usages - .add(new UsagesNode(node, predicate, value)); + // 3.5.8) + if (object.isBlankNode() || object.isIRI()) { + // 3.5.8.1-3) + nodeMap.get(object.getValue()).usages + .add(new UsagesNode(node, predicate, value)); + } } } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index b11e2a21..847b892c 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -152,4 +152,29 @@ public void testFrame0009() throws IOException, JsonLdError { .fromInputStream(getClass().getResourceAsStream("/custom/frame-0009-out.jsonld")); assertEquals(out, frame2); } + + @Test + public void testFrame0010() throws IOException, JsonLdError { + final Object frame = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0010-frame.jsonld")); + //{ + // "@id": "http://example.com/main/id", + // "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": { + // "@id": "http://example.com/rdf/id", + // "http://www.w3.org/1999/02/22-rdf-syntax-ns#label": "someLabel" + // } + //} + final RDFDataset ds = new RDFDataset(); + ds.addTriple("http://example.com/main/id", "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://example.com/rdf/id"); + ds.addTriple("http://example.com/rdf/id", "http://www.w3.org/1999/02/22-rdf-syntax-ns#label", "someLabel", null, null); + final JsonLdOptions opts = new JsonLdOptions(); + opts.setProcessingMode(JsonLdOptions.JSON_LD_1_0); + + final Object in = new JsonLdApi(opts).fromRDF(ds, true); + + final Map frame2 = JsonLdProcessor.frame(in, frame, opts); + final Object out = JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/frame-0010-out.jsonld")); + assertEquals(out, frame2); + } } diff --git a/core/src/test/resources/custom/frame-0010-frame.jsonld b/core/src/test/resources/custom/frame-0010-frame.jsonld new file mode 100644 index 00000000..91a3ac26 --- /dev/null +++ b/core/src/test/resources/custom/frame-0010-frame.jsonld @@ -0,0 +1,6 @@ +{ + "@context" : { + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + }, + "@id" : "http://example.com/main/id" +} \ No newline at end of file diff --git a/core/src/test/resources/custom/frame-0010-out.jsonld b/core/src/test/resources/custom/frame-0010-out.jsonld new file mode 100644 index 00000000..491fa921 --- /dev/null +++ b/core/src/test/resources/custom/frame-0010-out.jsonld @@ -0,0 +1,13 @@ +{ + "@context" : { + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + }, + "@graph" : [ { + "@id" : "http://example.com/main/id", + "rdf:type" : { + "@id" : "http://example.com/rdf/id", + "rdf:label" : "someLabel" + } + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/fromRdf-0020-in.nq b/core/src/test/resources/json-ld.org/fromRdf-0020-in.nq new file mode 100644 index 00000000..ce811f51 --- /dev/null +++ b/core/src/test/resources/json-ld.org/fromRdf-0020-in.nq @@ -0,0 +1,7 @@ + . + "myLabel" . + "2012-05-12"^^ . + . + "Plain" . + "2012-05-12"^^ . + "English"@en . diff --git a/core/src/test/resources/json-ld.org/fromRdf-0020-out.jsonld b/core/src/test/resources/json-ld.org/fromRdf-0020-out.jsonld new file mode 100644 index 00000000..6f9d169f --- /dev/null +++ b/core/src/test/resources/json-ld.org/fromRdf-0020-out.jsonld @@ -0,0 +1,19 @@ +[ + { + "@id": "http://example.com/Subj1", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" : [{ + "@id": "http://example.com/Type" + }], + "http://example.com/prop1": [{"@id": "http://example.com/Obj1"}], + "http://example.com/prop2": [ + {"@value": "Plain"}, + {"@value": "2012-05-12", "@type": "http://www.w3.org/2001/XMLSchema#date"}, + {"@value": "English", "@language": "en"} + ] + }, + { + "@id": "http://example.com/Type", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#label": [{"@value": "myLabel"}], + "http://example.com/prop2": [{"@value": "2012-05-12", "@type": "http://www.w3.org/2001/XMLSchema#date"}] + } +] diff --git a/core/src/test/resources/json-ld.org/fromRdf-manifest.jsonld b/core/src/test/resources/json-ld.org/fromRdf-manifest.jsonld index 451791ab..6d9451bb 100644 --- a/core/src/test/resources/json-ld.org/fromRdf-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/fromRdf-manifest.jsonld @@ -145,6 +145,13 @@ }, "input": "fromRdf-0019-in.nq", "expect": "fromRdf-0019-out.jsonld" + }, { + "@id": "#t0020", + "@type": ["jld:PositiveEvaluationTest", "jld:FromRDFTest"], + "name": "rdf:type as an @id with values", + "purpose": "Tests the proper formatting of @type (even with useRdfType to false) into rdf:type when the object contains more triples.", + "input": "fromRdf-0020-in.nq", + "expect": "fromRdf-0020-out.jsonld" } ] } From df426482bc57990c9139e0a32b034e281bc9024e Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Wed, 7 Nov 2018 23:21:38 +0100 Subject: [PATCH 354/440] Added optimization with computeIfAbsent --- .../java/com/github/jsonldjava/core/JsonLdApi.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 20f839f9..0b7c60ad 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1983,9 +1983,7 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData final String subject = triple.getSubject().getValue(); final String predicate = triple.getPredicate().getValue(); final RDFDataset.Node object = triple.getObject(); - final List list = nodes.getOrDefault(subject, new ArrayList()); - list.add(new Node(predicate, object)); - nodes.put(subject, list); + nodes.computeIfAbsent(subject, k -> new ArrayList<>()).add(new Node(predicate, object)); } for (final Map.Entry> nodeEntry : nodes.entrySet()) { final String subject = nodeEntry.getKey(); @@ -1995,13 +1993,7 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData final RDFDataset.Node object = n.object; // 3.5.1+3.5.2) - NodeMapNode node; - if (!nodeMap.containsKey(subject)) { - node = new NodeMapNode(subject); - nodeMap.put(subject, node); - } else { - node = nodeMap.get(subject); - } + final NodeMapNode node = nodeMap.computeIfAbsent(subject, k -> new NodeMapNode(subject)); // 3.5.3) if ((object.isIRI() || object.isBlankNode()) From e86c8fcb7a318d905031495c4636e3bfa37730a5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 8 Nov 2018 10:52:33 +1100 Subject: [PATCH 355/440] Optimise some other get/put/get sequences using computeIfAbsent Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/JsonLdApi.java | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 0b7c60ad..8c9ecb31 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1864,6 +1864,7 @@ public UsagesNode(NodeMapNode node, String property, Map value) private class Node { private String predicate; private RDFDataset.Node object; + public Node(String predicate, RDFDataset.Node object) { this.predicate = predicate; this.object = object; @@ -1963,17 +1964,13 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData final List graph = dataset.getQuads(name); // 3.2+3.4) - Map nodeMap; - if (!graphMap.containsKey(name)) { - nodeMap = new LinkedHashMap(); - graphMap.put(name, nodeMap); - } else { - nodeMap = graphMap.get(name); - } + final Map nodeMap = graphMap.computeIfAbsent(name, + k -> new LinkedHashMap()); // 3.3) - if (!JsonLdConsts.DEFAULT.equals(name) && !Obj.contains(defaultGraph, name)) { - defaultGraph.put(name, new NodeMapNode(name)); + if (!JsonLdConsts.DEFAULT.equals(name)) { + // Existing entries in the default graph are not overwritten + defaultGraph.computeIfAbsent(name, k -> new NodeMapNode(k)); } // 3.5) @@ -1983,22 +1980,23 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData final String subject = triple.getSubject().getValue(); final String predicate = triple.getPredicate().getValue(); final RDFDataset.Node object = triple.getObject(); - nodes.computeIfAbsent(subject, k -> new ArrayList<>()).add(new Node(predicate, object)); + nodes.computeIfAbsent(subject, k -> new ArrayList<>()) + .add(new Node(predicate, object)); } for (final Map.Entry> nodeEntry : nodes.entrySet()) { - final String subject = nodeEntry.getKey(); + final String subject = nodeEntry.getKey(); for (final Node n : nodeEntry.getValue()) { final String predicate = n.predicate; final RDFDataset.Node object = n.object; // 3.5.1+3.5.2) - final NodeMapNode node = nodeMap.computeIfAbsent(subject, k -> new NodeMapNode(subject)); + final NodeMapNode node = nodeMap.computeIfAbsent(subject, + k -> new NodeMapNode(k)); // 3.5.3) - if ((object.isIRI() || object.isBlankNode()) - && !nodeMap.containsKey(object.getValue())) { - nodeMap.put(object.getValue(), new NodeMapNode(object.getValue())); + if ((object.isIRI() || object.isBlankNode())) { + nodeMap.computeIfAbsent(object.getValue(), k -> new NodeMapNode(k)); } // 3.5.4) @@ -2103,16 +2101,18 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData // 6.1) if (graphMap.containsKey(subject)) { // 6.1.1) - node.put(JsonLdConsts.GRAPH, new ArrayList(4)); + List nextGraph = new ArrayList(4); + node.put(JsonLdConsts.GRAPH, nextGraph); // 6.1.2) - final List keys = new ArrayList(graphMap.get(subject).keySet()); + Map nextSubjectMap = graphMap.get(subject); + final List keys = new ArrayList(nextSubjectMap.keySet()); Collections.sort(keys); for (final String s : keys) { - final NodeMapNode n = graphMap.get(subject).get(s); + final NodeMapNode n = nextSubjectMap.get(s); if (n.size() == 1 && n.containsKey(JsonLdConsts.ID)) { continue; } - ((List) node.get(JsonLdConsts.GRAPH)).add(n.serialize()); + nextGraph.add(n.serialize()); } } // 6.2) From 8eed40098041ad391d29d3ebdb598cb486694265 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 24 Nov 2018 11:49:16 +1100 Subject: [PATCH 356/440] Fix #247 : Non-finite floating point values are corrupted by RDF serialisation This isn't typically an issue, as these are not allowed by the core JSON specification, so they are usually treated as Strings rather than raw floating point types. Discovered while adding the capability to parse non-finite values using RDF4J for https://github.com/eclipse/rdf4j/issues/1162 Signed-off-by: Peter Ansell --- README.md | 14 ++++++++++---- .../com/github/jsonldjava/core/RDFDataset.java | 18 +++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b1be751f..ffaabbda 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.12.2 + 0.12.3 Code example @@ -323,7 +323,7 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.12.2 + 0.12.3 4.0.0 jsonld-java-{your module} @@ -450,9 +450,15 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2018-11-24 +* Release 0.12.3 +* Fix NaN/Inf/-Inf raw value types on conversion to RDF +* Added fix for wrong rdf:type to @type conversion (Path by @umbreak) +* Open up Context.getTypeMapping and Context.getLanguageMapping for reuse + ### 2018-11-03 -# W3c json ld syntax 34 allow container set on aliased type (Patch by @dr0i) -# Release 0.12.2 +* W3c json ld syntax 34 allow container set on aliased type (Patch by @dr0i) +* Release 0.12.2 ### 2018-09-05 * handle omit graph flag (Patch by @eroux) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index bcaec385..43e279a8 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -658,11 +658,19 @@ private Node objectToRDF(Object item) { datatype == null ? XSD_BOOLEAN : (String) datatype, null); } else if (value instanceof Double || value instanceof Float || XSD_DOUBLE.equals(datatype)) { - // canonical double representation - final DecimalFormat df = new DecimalFormat("0.0###############E0"); - df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); - return new Literal(df.format(value), - datatype == null ? XSD_DOUBLE : (String) datatype, null); + if (value instanceof Double && !Double.isFinite((double) value)) { + return new Literal(Double.toString((double) value), + datatype == null ? XSD_DOUBLE : (String) datatype, null); + } else if (value instanceof Float && !Float.isFinite((float) value)) { + return new Literal(Float.toString((float) value), + datatype == null ? XSD_DOUBLE : (String) datatype, null); + } else { + // canonical double representation + final DecimalFormat df = new DecimalFormat("0.0###############E0"); + df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); + return new Literal(df.format(value), + datatype == null ? XSD_DOUBLE : (String) datatype, null); + } } else { final DecimalFormat df = new DecimalFormat("0"); return new Literal(df.format(value), From 834e15ac46988647376ca1cab2d52402a3327629 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 24 Nov 2018 12:17:27 +1100 Subject: [PATCH 357/440] Release 0.12.3 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 93fba416..4204de98 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.3-SNAPSHOT + 0.12.3 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index c754933f..9b3bdafc 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.3-SNAPSHOT + 0.12.3 JSONLD Java :: Parent Json-LD Java Parent POM pom From 9eac6d73a2a844791ecef25c9bbdd08635edf96f Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 24 Nov 2018 12:22:11 +1100 Subject: [PATCH 358/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 4204de98..f450ddcb 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.3 + 0.12.4-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 9b3bdafc..2e56af8d 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.3 + 0.12.4-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From f406471ce89cdcf464864f3d7fde2b0105e3bfac Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Thu, 14 Feb 2019 17:20:47 +0100 Subject: [PATCH 359/440] Throw error on empty key in context (see #141) --- .../com/github/jsonldjava/core/Context.java | 13 ++++++++- .../github/jsonldjava/core/ContextTest.java | 27 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index e28823c6..8c149b08 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -40,11 +40,13 @@ public Context(JsonLdOptions opts) { public Context(Map map, JsonLdOptions opts) { super(map); + checkEmptyKey(map); init(opts); } public Context(Map map) { super(map); + checkEmptyKey(map); init(new JsonLdOptions()); } @@ -213,7 +215,7 @@ else if (context instanceof String) { // 3.3 throw new JsonLdError(Error.INVALID_LOCAL_CONTEXT, context); } - + checkEmptyKey((Map) context); // 3.4 if (!parsingARemoteContext && ((Map) context).containsKey(JsonLdConsts.BASE)) { @@ -284,6 +286,15 @@ else if (context instanceof String) { return result; } + private void checkEmptyKey(final Map map) { + if (map.containsKey("")) { + // the term MUST NOT be an empty string ("") + // https://www.w3.org/TR/json-ld/#h3_terms + throw new JsonLdError(Error.INVALID_TERM_DEFINITION, + String.format("empty key for value '%s'", map.get(""))); + } + } + public Context parse(Object localContext) throws JsonLdError { return this.parse(localContext, new ArrayList()); } diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java index 6efe820b..48e3faa7 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java @@ -2,10 +2,37 @@ import org.junit.Test; +import com.google.common.collect.ImmutableMap; + public class ContextTest { @Test public void testRemoveBase() { // TODO: test if Context.removeBase actually works } + + // See https://github.com/jsonld-java/jsonld-java/issues/141 + + @Test(expected = JsonLdError.class) + public void testIssue141_errorOnEmptyKey_compact() { + JsonLdProcessor.compact(ImmutableMap.of(), + ImmutableMap.of("","http://example.com"), new JsonLdOptions()); + } + + @Test(expected = JsonLdError.class) + public void testIssue141_errorOnEmptyKey_expand() { + JsonLdProcessor.expand(ImmutableMap.of("@context", + ImmutableMap.of("","http://example.com")), new JsonLdOptions()); + } + + @Test(expected = JsonLdError.class) + public void testIssue141_errorOnEmptyKey_newContext1() { + new Context(ImmutableMap.of("","http://example.com")); + } + + @Test(expected = JsonLdError.class) + public void testIssue141_errorOnEmptyKey_newContext2() { + new Context(ImmutableMap.of("","http://example.com"), new JsonLdOptions()); + } + } From 574062fa4fb2dd885a56cba3bd2d4ad604822cb3 Mon Sep 17 00:00:00 2001 From: Carlos Cebrecos Date: Thu, 28 Feb 2019 13:31:30 +0100 Subject: [PATCH 360/440] Update README.md Typo fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ffaabbda..43c7b25e 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ Note that if you override DocumentLoader you should also support this setting fo Your application might be parsing JSONLD documents which reference external `@context` IRIs that are not available as file URIs on the classpath. In this case, the `jarcache.json` -approch will not work. Instead you can inject the literal context file strings through +approach will not work. Instead you can inject the literal context file strings through the `JsonLdOptions` object, as follows: ```java From 7d59fe5a5fa68e932f5cc98c7415bb014592d681 Mon Sep 17 00:00:00 2001 From: Luca Roffia Date: Wed, 6 Mar 2019 18:44:43 +0100 Subject: [PATCH 361/440] Update README.md Typo in "context" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43c7b25e..492d1678 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ the `JsonLdOptions` object, as follows: DocumentLoader dl = new DocumentLoader(); JsonLdOptions options = new JsonLdOptions(); // ... the contents of "contexts/example.jsonld" -String jsonContext = "{ \"@contxt\": { ... } }"; +String jsonContext = "{ \"@context\": { ... } }"; dl.addInjectedDoc("http://www.example.com/context", jsonContext); options.setDocumentLoader(dl); From 0884873b0135d8be1c849f6379cb970db82af7f9 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Thu, 28 Mar 2019 09:34:04 +0000 Subject: [PATCH 362/440] Upgrade to Jackson 2.9.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2e56af8d..69dbc307 100755 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 4.5.6 4.4.10 - 2.9.7 + 2.9.8 4.12 1.7.25 From 29c195c03cd50d5c41f7f9c4ed3839f296265f4f Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Wed, 10 Apr 2019 16:54:03 +0200 Subject: [PATCH 363/440] Add tests to show workarounds for #248 --- .../github/jsonldjava/core/ContextTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java index 48e3faa7..b9aef604 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java @@ -1,5 +1,11 @@ package com.github.jsonldjava.core; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import org.junit.Test; import com.google.common.collect.ImmutableMap; @@ -35,4 +41,34 @@ public void testIssue141_errorOnEmptyKey_newContext2() { new Context(ImmutableMap.of("","http://example.com"), new JsonLdOptions()); } + /* schema.org documentation says some properties can be either Text or URL, + * but sets `@type : @id` in the context, e.g. for https://schema.org/roleName: + */ + Map schemaOrg = + ImmutableMap.of("roleName", ImmutableMap.of("@id", "http://schema.org/roleName", "@type", "@id")); + + // See https://github.com/jsonld-java/jsonld-java/issues/248 + + @Test(expected = IllegalArgumentException.class) + public void testCompact_uriExpected() throws Exception { + JsonLdProcessor.expand(ImmutableMap.of("roleName", "Production Company", "@context", schemaOrg)); + } + + @Test + public void testCompact_forceValue() throws Exception { + List value = Arrays.asList(ImmutableMap.of("@value", "Production Company")); + Map input = ImmutableMap.of("roleName", value, "@context", schemaOrg); + Object output = JsonLdProcessor.expand(input); + assertEquals("[{http://schema.org/roleName=[{@value=Production Company}]}]", output.toString()); + } + + @Test + public void testCompact_overrideContext() throws Exception { + List context = Arrays.asList(schemaOrg, + ImmutableMap.of("roleName", ImmutableMap.of("@id", "http://schema.org/roleName"))); + Map input = ImmutableMap.of("roleName", "Production Company", "@context", context); + Object output = JsonLdProcessor.expand(input); + assertEquals("[{http://schema.org/roleName=[{@value=Production Company}]}]", output.toString()); + } + } From d7a05901e02f52de4a9dfc44cb70ae2e499ad7d8 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Wed, 10 Apr 2019 17:06:02 +0200 Subject: [PATCH 364/440] Tweak test method signatures for #248 --- .../test/java/com/github/jsonldjava/core/ContextTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java index b9aef604..ce98a7b1 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java @@ -50,12 +50,12 @@ public void testIssue141_errorOnEmptyKey_newContext2() { // See https://github.com/jsonld-java/jsonld-java/issues/248 @Test(expected = IllegalArgumentException.class) - public void testCompact_uriExpected() throws Exception { + public void testIssue248_uriExpected() { JsonLdProcessor.expand(ImmutableMap.of("roleName", "Production Company", "@context", schemaOrg)); } @Test - public void testCompact_forceValue() throws Exception { + public void testIssue248_forceValue() { List value = Arrays.asList(ImmutableMap.of("@value", "Production Company")); Map input = ImmutableMap.of("roleName", value, "@context", schemaOrg); Object output = JsonLdProcessor.expand(input); @@ -63,7 +63,7 @@ public void testCompact_forceValue() throws Exception { } @Test - public void testCompact_overrideContext() throws Exception { + public void testIssue248_overrideContext() { List context = Arrays.asList(schemaOrg, ImmutableMap.of("roleName", ImmutableMap.of("@id", "http://schema.org/roleName"))); Map input = ImmutableMap.of("roleName", "Production Company", "@context", context); From bd3fe1f18345d9639604b1a1a458de148c435aa1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 13 Apr 2019 07:47:43 +1000 Subject: [PATCH 365/440] Bump dependency versions Signed-off-by: Peter Ansell --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 69dbc307..76b7019e 100755 --- a/pom.xml +++ b/pom.xml @@ -39,11 +39,11 @@ UTF-8 UTF-8 - 4.5.6 - 4.4.10 + 4.5.8 + 4.4.11 2.9.8 4.12 - 1.7.25 + 1.7.26 0.11.0 @@ -192,12 +192,12 @@ commons-codec commons-codec - 1.11 + 1.12 org.mockito mockito-core - 2.23.0 + 2.27.0 commons-io @@ -209,7 +209,7 @@ com.google.guava guava - 27.0-jre + 27.1-jre @@ -267,7 +267,7 @@ org.codehaus.mojo extra-enforcer-rules - 1.0-beta-9 + 1.2 From 14002e4e6de0391df04577e3bd72caf631f98024 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 13 Apr 2019 19:31:26 +1000 Subject: [PATCH 366/440] Fix #193 : Persist JsonLdOptions through normalize/toRDF Signed-off-by: Peter Ansell --- .../com/github/jsonldjava/core/JsonLdApi.java | 8 +-- .../github/jsonldjava/core/JsonLdOptions.java | 52 +++++++++++++++++++ .../jsonldjava/core/JsonLdProcessor.java | 2 +- .../github/jsonldjava/core/ContextTest.java | 45 +++++++++------- .../jsonldjava/core/JsonLdFramingTest.java | 22 ++++---- 5 files changed, 95 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 8c9ecb31..74cea926 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -1862,8 +1862,8 @@ public UsagesNode(NodeMapNode node, String property, Map value) } private class Node { - private String predicate; - private RDFDataset.Node object; + private final String predicate; + private final RDFDataset.Node object; public Node(String predicate, RDFDataset.Node object) { this.predicate = predicate; @@ -2101,10 +2101,10 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData // 6.1) if (graphMap.containsKey(subject)) { // 6.1.1) - List nextGraph = new ArrayList(4); + final List nextGraph = new ArrayList(4); node.put(JsonLdConsts.GRAPH, nextGraph); // 6.1.2) - Map nextSubjectMap = graphMap.get(subject); + final Map nextSubjectMap = graphMap.get(subject); final List keys = new ArrayList(nextSubjectMap.keySet()); Collections.sort(keys); for (final String s : keys) { diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index ef0bd009..ff0038ee 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -35,6 +35,39 @@ public JsonLdOptions(String base) { this.setBase(base); } + /** + * Creates a shallow copy of this JsonLdOptions object. + * + * It will share the same DocumentLoader unless that is overridden, and + * other mutable objects, so it isn't immutable. + * + * @return A copy of this JsonLdOptions object. + */ + public JsonLdOptions copy() { + final JsonLdOptions copy = new JsonLdOptions(base); + + copy.setCompactArrays(compactArrays); + copy.setExpandContext(expandContext); + copy.setProcessingMode(processingMode); + copy.setDocumentLoader(documentLoader); + copy.setEmbed(embed); + copy.setExplicit(explicit); + copy.setOmitDefault(omitDefault); + copy.setOmitGraph(omitGraph); + copy.setFrameExpansion(frameExpansion); + copy.setPruneBlankNodeIdentifiers(pruneBlankNodeIdentifiers); + copy.setRequireAll(requireAll); + copy.setAllowContainerSetOnType(allowContainerSetOnType); + copy.setUseRdfType(useRdfType); + copy.setUseNativeTypes(useNativeTypes); + copy.setProduceGeneralizedRdf(produceGeneralizedRdf); + copy.format = format; + copy.useNamespaces = useNamespaces; + copy.outputForm = outputForm; + + return copy; + } + // Base options : http://www.w3.org/TR/json-ld-api/#idl-def-JsonLdOptions /** @@ -117,6 +150,25 @@ public void setEmbed(String embed) throws JsonLdError { } } + public void setEmbed(Embed embed) throws JsonLdError { + switch (embed) { + case ALWAYS: + this.embed = Embed.ALWAYS; + break; + case NEVER: + this.embed = Embed.NEVER; + break; + case LAST: + this.embed = Embed.LAST; + break; + case LINK: + this.embed = Embed.LINK; + break; + default: + throw new JsonLdError(JsonLdError.Error.INVALID_EMBED_VALUE); + } + } + public Boolean getExplicit() { return explicit; } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 5b46b5e6..00fd3e16 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -603,7 +603,7 @@ public static Object toRDF(Object input) throws JsonLdError { */ public static Object normalize(Object input, JsonLdOptions options) throws JsonLdError { - final JsonLdOptions opts = new JsonLdOptions(options.getBase()); + final JsonLdOptions opts = options.copy(); opts.format = null; final RDFDataset dataset = (RDFDataset) toRDF(input, opts); diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java index ce98a7b1..2fab52c1 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextTest.java @@ -21,54 +21,61 @@ public void testRemoveBase() { @Test(expected = JsonLdError.class) public void testIssue141_errorOnEmptyKey_compact() { - JsonLdProcessor.compact(ImmutableMap.of(), - ImmutableMap.of("","http://example.com"), new JsonLdOptions()); + JsonLdProcessor.compact(ImmutableMap.of(), ImmutableMap.of("", "http://example.com"), + new JsonLdOptions()); } @Test(expected = JsonLdError.class) public void testIssue141_errorOnEmptyKey_expand() { - JsonLdProcessor.expand(ImmutableMap.of("@context", - ImmutableMap.of("","http://example.com")), new JsonLdOptions()); + JsonLdProcessor.expand( + ImmutableMap.of("@context", ImmutableMap.of("", "http://example.com")), + new JsonLdOptions()); } @Test(expected = JsonLdError.class) public void testIssue141_errorOnEmptyKey_newContext1() { - new Context(ImmutableMap.of("","http://example.com")); + new Context(ImmutableMap.of("", "http://example.com")); } @Test(expected = JsonLdError.class) public void testIssue141_errorOnEmptyKey_newContext2() { - new Context(ImmutableMap.of("","http://example.com"), new JsonLdOptions()); + new Context(ImmutableMap.of("", "http://example.com"), new JsonLdOptions()); } - /* schema.org documentation says some properties can be either Text or URL, - * but sets `@type : @id` in the context, e.g. for https://schema.org/roleName: + /* + * schema.org documentation says some properties can be either Text or URL, + * but sets `@type : @id` in the context, e.g. for + * https://schema.org/roleName: */ - Map schemaOrg = - ImmutableMap.of("roleName", ImmutableMap.of("@id", "http://schema.org/roleName", "@type", "@id")); + Map schemaOrg = ImmutableMap.of("roleName", + ImmutableMap.of("@id", "http://schema.org/roleName", "@type", "@id")); // See https://github.com/jsonld-java/jsonld-java/issues/248 @Test(expected = IllegalArgumentException.class) public void testIssue248_uriExpected() { - JsonLdProcessor.expand(ImmutableMap.of("roleName", "Production Company", "@context", schemaOrg)); + JsonLdProcessor + .expand(ImmutableMap.of("roleName", "Production Company", "@context", schemaOrg)); } @Test public void testIssue248_forceValue() { - List value = Arrays.asList(ImmutableMap.of("@value", "Production Company")); - Map input = ImmutableMap.of("roleName", value, "@context", schemaOrg); - Object output = JsonLdProcessor.expand(input); - assertEquals("[{http://schema.org/roleName=[{@value=Production Company}]}]", output.toString()); + final List value = Arrays.asList(ImmutableMap.of("@value", "Production Company")); + final Map input = ImmutableMap.of("roleName", value, "@context", schemaOrg); + final Object output = JsonLdProcessor.expand(input); + assertEquals("[{http://schema.org/roleName=[{@value=Production Company}]}]", + output.toString()); } @Test public void testIssue248_overrideContext() { - List context = Arrays.asList(schemaOrg, + final List context = Arrays.asList(schemaOrg, ImmutableMap.of("roleName", ImmutableMap.of("@id", "http://schema.org/roleName"))); - Map input = ImmutableMap.of("roleName", "Production Company", "@context", context); - Object output = JsonLdProcessor.expand(input); - assertEquals("[{http://schema.org/roleName=[{@value=Production Company}]}]", output.toString()); + final Map input = ImmutableMap.of("roleName", "Production Company", + "@context", context); + final Object output = JsonLdProcessor.expand(input); + assertEquals("[{http://schema.org/roleName=[{@value=Production Company}]}]", + output.toString()); } } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java index ad4d8299..bacec894 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdFramingTest.java @@ -157,16 +157,18 @@ public void testFrame0009() throws IOException, JsonLdError { public void testFrame0010() throws IOException, JsonLdError { final Object frame = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0010-frame.jsonld")); - //{ - // "@id": "http://example.com/main/id", - // "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": { - // "@id": "http://example.com/rdf/id", - // "http://www.w3.org/1999/02/22-rdf-syntax-ns#label": "someLabel" - // } - //} + // { + // "@id": "http://example.com/main/id", + // "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": { + // "@id": "http://example.com/rdf/id", + // "http://www.w3.org/1999/02/22-rdf-syntax-ns#label": "someLabel" + // } + // } final RDFDataset ds = new RDFDataset(); - ds.addTriple("http://example.com/main/id", "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://example.com/rdf/id"); - ds.addTriple("http://example.com/rdf/id", "http://www.w3.org/1999/02/22-rdf-syntax-ns#label", "someLabel", null, null); + ds.addTriple("http://example.com/main/id", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://example.com/rdf/id"); + ds.addTriple("http://example.com/rdf/id", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#label", "someLabel", null, null); final JsonLdOptions opts = new JsonLdOptions(); opts.setProcessingMode(JsonLdOptions.JSON_LD_1_0); @@ -185,7 +187,7 @@ public void testFrame0011() throws IOException, JsonLdError { final Object in = JsonUtils .fromInputStream(getClass().getResourceAsStream("/custom/frame-0011-in.jsonld")); - JsonLdOptions opts = new JsonLdOptions(); + final JsonLdOptions opts = new JsonLdOptions(); final Map frame2 = JsonLdProcessor.frame(in, frame, opts); final Object out = JsonUtils From 9a915cd566c65ef77634d57e5a5ec82bc5174f44 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 20 Apr 2019 07:24:08 +1000 Subject: [PATCH 367/440] Release 0.12.4 Signed-off-by: Peter Ansell --- README.md | 14 +++++++++++--- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 492d1678..a01a2ee1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.12.3 + 0.12.4 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.12.3 + 0.12.4 4.0.0 jsonld-java-{your module} - 0.12.3-SNAPSHOT + 0.12.4-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -450,6 +450,14 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2019-04-20 +* Release 0.12.4 +* Bump Jackson version to 2.9.8 +* Add a regression test for a past framing bug +* Throw error on empty key +* Add regression tests for workarounds to Text/URL dual definitions +* Persist JsonLdOptions through normalize/toRDF + ### 2018-11-24 * Release 0.12.3 * Fix NaN/Inf/-Inf raw value types on conversion to RDF diff --git a/core/pom.xml b/core/pom.xml index f450ddcb..8c818ff1 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.4-SNAPSHOT + 0.12.4 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 76b7019e..d7a43835 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.4-SNAPSHOT + 0.12.4 JSONLD Java :: Parent Json-LD Java Parent POM pom From 64d4b45f7474210c9679c0ef3348177f5ecd9836 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 20 Apr 2019 07:38:24 +1000 Subject: [PATCH 368/440] Bump to next snapshot Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 8c818ff1..30a1d02e 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.4 + 0.12.5-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index d7a43835..201bf9f1 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.4 + 0.12.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From efeef6ee96029a0011649633457035fa6be42da1 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 20 Apr 2019 07:49:38 +1000 Subject: [PATCH 369/440] Add openjdk-11 to travis list Signed-off-by: Peter Ansell --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index e7d32e30..30fd9d59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,10 @@ matrix: before_install: - rm "${JAVA_HOME}/lib/security/cacerts" - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" + - jdk: openjdk11 + before_install: + - rm "${JAVA_HOME}/lib/security/cacerts" + - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" notifications: email: false after_success: From 2540dfc4649549acc76636e1abbb09469991d80e Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Mon, 20 May 2019 11:01:15 +0200 Subject: [PATCH 370/440] Update jacoco version to fix openjdk-11 build issue See https://travis-ci.org/jsonld-java/jsonld-java/jobs/522318660 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 201bf9f1..b7a54a67 100755 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ org.jacoco jacoco-maven-plugin - 0.8.1 + 0.8.4 prepare-agent From 0f251f203649a04faf053c52beddab1d8865be5b Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Thu, 23 May 2019 20:38:19 +0100 Subject: [PATCH 371/440] Update jackson to v2.9.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b7a54a67..9ca2259d 100755 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 4.5.8 4.4.11 - 2.9.8 + 2.9.9 4.12 1.7.26 From 24cf02823be94fd0e1109746d0e4f2f086fe0df9 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Mon, 20 May 2019 10:12:01 +0200 Subject: [PATCH 372/440] Add tests for hierarchical and opaque base IRIs See https://github.com/jsonld-java/jsonld-java/issues/232 --- ...ayContextToRDFTest.java => ToRDFTest.java} | 41 ++++++++++++++++++- .../resources/custom/toRdf-0001-in.jsonld | 1 + .../test/resources/custom/toRdf-0001-out.nq | 1 + .../test/resources/custom/toRdf-0002-out.nq | 1 + .../test/resources/custom/toRdf-0003-out.nq | 1 + 5 files changed, 44 insertions(+), 1 deletion(-) rename core/src/test/java/com/github/jsonldjava/core/{ArrayContextToRDFTest.java => ToRDFTest.java} (50%) create mode 100644 core/src/test/resources/custom/toRdf-0001-in.jsonld create mode 100644 core/src/test/resources/custom/toRdf-0001-out.nq create mode 100644 core/src/test/resources/custom/toRdf-0002-out.nq create mode 100644 core/src/test/resources/custom/toRdf-0003-out.nq diff --git a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ToRDFTest.java similarity index 50% rename from core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java rename to core/src/test/java/com/github/jsonldjava/core/ToRDFTest.java index 28aa9d35..8db83857 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ToRDFTest.java @@ -4,13 +4,21 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.Ignore; import org.junit.Test; import com.github.jsonldjava.utils.JsonUtils; +import com.github.jsonldjava.utils.TestUtils; -public class ArrayContextToRDFTest { +public class ToRDFTest { @Test public void toRdfWithNamespace() throws Exception { @@ -43,4 +51,35 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { assertFalse(rdf.getNamespaces().containsKey("term1")); } + + @Test + // See https://github.com/jsonld-java/jsonld-java/issues/232 + public void toRdfWithHttpBaseIri() throws IOException, JsonLdError { + testToRdf("/custom/toRdf-0001-in.jsonld", "/custom/toRdf-0001-out.nq", "http://example.org/"); + } + + @Test + // See https://github.com/jsonld-java/jsonld-java/issues/232 + public void toRdfWithHierarchicalBaseIri() throws IOException, JsonLdError { + testToRdf("/custom/toRdf-0001-in.jsonld", "/custom/toRdf-0002-out.nq", "tag:/example/"); + } + + @Test + @Ignore + // See https://github.com/jsonld-java/jsonld-java/issues/232#issuecomment-493454096 + public void toRdfWithOpaqueBaseIri() throws IOException, JsonLdError { + testToRdf("/custom/toRdf-0001-in.jsonld", "/custom/toRdf-0003-out.nq", "tag:example/"); + } + + private void testToRdf(String inFile, String outFile, String baseIri) throws IOException { + final Object input = JsonUtils + .fromInputStream(getClass().getResourceAsStream(inFile)); + List resultLines = new BufferedReader(new InputStreamReader( + getClass().getResourceAsStream(outFile), StandardCharsets.UTF_8)).lines() + .collect(Collectors.toList()); + JsonLdOptions options = new JsonLdOptions(baseIri); + options.format = JsonLdConsts.APPLICATION_NQUADS; + Object result = JsonLdProcessor.toRDF(input, options); + assertEquals(TestUtils.join(resultLines, "\n").trim(), ((String) result).trim()); + } } diff --git a/core/src/test/resources/custom/toRdf-0001-in.jsonld b/core/src/test/resources/custom/toRdf-0001-in.jsonld new file mode 100644 index 00000000..92ec4b55 --- /dev/null +++ b/core/src/test/resources/custom/toRdf-0001-in.jsonld @@ -0,0 +1 @@ +{"@id":"relativeURIWithNoBase","@type":"http://example.org/SomeRDFSClass"} \ No newline at end of file diff --git a/core/src/test/resources/custom/toRdf-0001-out.nq b/core/src/test/resources/custom/toRdf-0001-out.nq new file mode 100644 index 00000000..d3e0b99a --- /dev/null +++ b/core/src/test/resources/custom/toRdf-0001-out.nq @@ -0,0 +1 @@ + . diff --git a/core/src/test/resources/custom/toRdf-0002-out.nq b/core/src/test/resources/custom/toRdf-0002-out.nq new file mode 100644 index 00000000..4d011703 --- /dev/null +++ b/core/src/test/resources/custom/toRdf-0002-out.nq @@ -0,0 +1 @@ + . diff --git a/core/src/test/resources/custom/toRdf-0003-out.nq b/core/src/test/resources/custom/toRdf-0003-out.nq new file mode 100644 index 00000000..8e66eba6 --- /dev/null +++ b/core/src/test/resources/custom/toRdf-0003-out.nq @@ -0,0 +1 @@ + . From 4eb40f9718cd7fde8cf99ed6b73d930a2ae3e0f0 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Fri, 24 May 2019 15:10:58 +0200 Subject: [PATCH 373/440] Tweak IRI resolution according to RFC3986 Add tests from https://github.com/w3c/json-ld-api See https://github.com/jsonld-java/jsonld-java/issues/232 --- .../github/jsonldjava/utils/JsonLdUrl.java | 12 ++-- .../json-ld.org/toRdf-0120-in.jsonld | 47 ++++++++++++++++ .../resources/json-ld.org/toRdf-0120-out.nq | 42 ++++++++++++++ .../json-ld.org/toRdf-0121-in.jsonld | 47 ++++++++++++++++ .../resources/json-ld.org/toRdf-0121-out.nq | 42 ++++++++++++++ .../json-ld.org/toRdf-0122-in.jsonld | 47 ++++++++++++++++ .../resources/json-ld.org/toRdf-0122-out.nq | 42 ++++++++++++++ .../json-ld.org/toRdf-0123-in.jsonld | 47 ++++++++++++++++ .../resources/json-ld.org/toRdf-0123-out.nq | 42 ++++++++++++++ .../json-ld.org/toRdf-0124-in.jsonld | 47 ++++++++++++++++ .../resources/json-ld.org/toRdf-0124-out.nq | 42 ++++++++++++++ .../json-ld.org/toRdf-0125-in.jsonld | 47 ++++++++++++++++ .../resources/json-ld.org/toRdf-0125-out.nq | 42 ++++++++++++++ .../json-ld.org/toRdf-0127-in.jsonld | 11 ++++ .../resources/json-ld.org/toRdf-0127-out.nq | 6 ++ .../json-ld.org/toRdf-0129-in.jsonld | 8 +++ .../resources/json-ld.org/toRdf-0129-out.nq | 3 + .../json-ld.org/toRdf-manifest.jsonld | 56 +++++++++++++++++++ 18 files changed, 625 insertions(+), 5 deletions(-) create mode 100644 core/src/test/resources/json-ld.org/toRdf-0120-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0120-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0121-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0121-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0122-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0122-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0123-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0123-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0124-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0124-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0125-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0125-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0127-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0127-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0129-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0129-out.nq diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java index a2153831..ce7c5724 100755 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java @@ -261,16 +261,18 @@ public static String resolve(String baseUri, String pathToResolve) { } try { URI uri = new URI(baseUri); + // "a base URI [...] does not allow a fragment" (https://tools.ietf.org/html/rfc3986#section-4.3) + uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), uri.getQuery(), null); // query string parsing if (pathToResolve.startsWith("?")) { - // drop fragment from uri if it has one - if (uri.getFragment() != null) { - uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null); - } + // drop query, https://tools.ietf.org/html/rfc3986#section-5.2.2: T.query = R.query; + uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null); // add query to the end manually (as URI.resolve does it wrong) return uri.toString() + pathToResolve; + } else if (pathToResolve.startsWith("#")) { + // add fragment to the end manually (as URI.resolve does it wrong) + return uri.toString() + pathToResolve; } - uri = uri.resolve(pathToResolve); // java doesn't discard unnecessary dot segments String path = uri.getPath(); diff --git a/core/src/test/resources/json-ld.org/toRdf-0120-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0120-in.jsonld new file mode 100644 index 00000000..ad2884b9 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0120-in.jsonld @@ -0,0 +1,47 @@ +{ + "@context": {"@base": "http://a/bb/ccc/d;p?q", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s001", "urn:ex:p": "g:h"}, + {"@id": "urn:ex:s002", "urn:ex:p": "g"}, + {"@id": "urn:ex:s003", "urn:ex:p": "./g"}, + {"@id": "urn:ex:s004", "urn:ex:p": "g/"}, + {"@id": "urn:ex:s005", "urn:ex:p": "/g"}, + {"@id": "urn:ex:s006", "urn:ex:p": "//g"}, + {"@id": "urn:ex:s007", "urn:ex:p": "?y"}, + {"@id": "urn:ex:s008", "urn:ex:p": "g?y"}, + {"@id": "urn:ex:s009", "urn:ex:p": "#s"}, + {"@id": "urn:ex:s010", "urn:ex:p": "g#s"}, + {"@id": "urn:ex:s011", "urn:ex:p": "g?y#s"}, + {"@id": "urn:ex:s012", "urn:ex:p": ";x"}, + {"@id": "urn:ex:s013", "urn:ex:p": "g;x"}, + {"@id": "urn:ex:s014", "urn:ex:p": "g;x?y#s"}, + {"@id": "urn:ex:s015", "urn:ex:p": ""}, + {"@id": "urn:ex:s016", "urn:ex:p": "."}, + {"@id": "urn:ex:s017", "urn:ex:p": "./"}, + {"@id": "urn:ex:s018", "urn:ex:p": ".."}, + {"@id": "urn:ex:s019", "urn:ex:p": "../"}, + {"@id": "urn:ex:s020", "urn:ex:p": "../g"}, + {"@id": "urn:ex:s021", "urn:ex:p": "../.."}, + {"@id": "urn:ex:s022", "urn:ex:p": "../../"}, + {"@id": "urn:ex:s023", "urn:ex:p": "../../g"}, + {"@id": "urn:ex:s024", "urn:ex:p": "../../../g"}, + {"@id": "urn:ex:s025", "urn:ex:p": "../../../../g"}, + {"@id": "urn:ex:s026", "urn:ex:p": "/./g"}, + {"@id": "urn:ex:s027", "urn:ex:p": "/../g"}, + {"@id": "urn:ex:s028", "urn:ex:p": "g."}, + {"@id": "urn:ex:s029", "urn:ex:p": ".g"}, + {"@id": "urn:ex:s030", "urn:ex:p": "g.."}, + {"@id": "urn:ex:s031", "urn:ex:p": "..g"}, + {"@id": "urn:ex:s032", "urn:ex:p": "./../g"}, + {"@id": "urn:ex:s033", "urn:ex:p": "./g/."}, + {"@id": "urn:ex:s034", "urn:ex:p": "g/./h"}, + {"@id": "urn:ex:s035", "urn:ex:p": "g/../h"}, + {"@id": "urn:ex:s036", "urn:ex:p": "g;x=1/./y"}, + {"@id": "urn:ex:s037", "urn:ex:p": "g;x=1/../y"}, + {"@id": "urn:ex:s038", "urn:ex:p": "g?y/./x"}, + {"@id": "urn:ex:s039", "urn:ex:p": "g?y/../x"}, + {"@id": "urn:ex:s040", "urn:ex:p": "g#s/./x"}, + {"@id": "urn:ex:s041", "urn:ex:p": "g#s/../x"}, + {"@id": "urn:ex:s042", "urn:ex:p": "http:g"} + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/toRdf-0120-out.nq b/core/src/test/resources/json-ld.org/toRdf-0120-out.nq new file mode 100644 index 00000000..8503e524 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0120-out.nq @@ -0,0 +1,42 @@ + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0121-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0121-in.jsonld new file mode 100644 index 00000000..86a197dc --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0121-in.jsonld @@ -0,0 +1,47 @@ +{ + "@context": {"@base": "http://a/bb/ccc/d/", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s043", "urn:ex:p": "g:h"}, + {"@id": "urn:ex:s044", "urn:ex:p": "g"}, + {"@id": "urn:ex:s045", "urn:ex:p": "./g"}, + {"@id": "urn:ex:s046", "urn:ex:p": "g/"}, + {"@id": "urn:ex:s047", "urn:ex:p": "/g"}, + {"@id": "urn:ex:s048", "urn:ex:p": "//g"}, + {"@id": "urn:ex:s049", "urn:ex:p": "?y"}, + {"@id": "urn:ex:s050", "urn:ex:p": "g?y"}, + {"@id": "urn:ex:s051", "urn:ex:p": "#s"}, + {"@id": "urn:ex:s052", "urn:ex:p": "g#s"}, + {"@id": "urn:ex:s053", "urn:ex:p": "g?y#s"}, + {"@id": "urn:ex:s054", "urn:ex:p": ";x"}, + {"@id": "urn:ex:s055", "urn:ex:p": "g;x"}, + {"@id": "urn:ex:s056", "urn:ex:p": "g;x?y#s"}, + {"@id": "urn:ex:s057", "urn:ex:p": ""}, + {"@id": "urn:ex:s058", "urn:ex:p": "."}, + {"@id": "urn:ex:s059", "urn:ex:p": "./"}, + {"@id": "urn:ex:s060", "urn:ex:p": ".."}, + {"@id": "urn:ex:s061", "urn:ex:p": "../"}, + {"@id": "urn:ex:s062", "urn:ex:p": "../g"}, + {"@id": "urn:ex:s063", "urn:ex:p": "../.."}, + {"@id": "urn:ex:s064", "urn:ex:p": "../../"}, + {"@id": "urn:ex:s065", "urn:ex:p": "../../g"}, + {"@id": "urn:ex:s066", "urn:ex:p": "../../../g"}, + {"@id": "urn:ex:s067", "urn:ex:p": "../../../../g"}, + {"@id": "urn:ex:s068", "urn:ex:p": "/./g"}, + {"@id": "urn:ex:s069", "urn:ex:p": "/../g"}, + {"@id": "urn:ex:s070", "urn:ex:p": "g."}, + {"@id": "urn:ex:s071", "urn:ex:p": ".g"}, + {"@id": "urn:ex:s072", "urn:ex:p": "g.."}, + {"@id": "urn:ex:s073", "urn:ex:p": "..g"}, + {"@id": "urn:ex:s074", "urn:ex:p": "./../g"}, + {"@id": "urn:ex:s075", "urn:ex:p": "./g/."}, + {"@id": "urn:ex:s076", "urn:ex:p": "g/./h"}, + {"@id": "urn:ex:s077", "urn:ex:p": "g/../h"}, + {"@id": "urn:ex:s078", "urn:ex:p": "g;x=1/./y"}, + {"@id": "urn:ex:s079", "urn:ex:p": "g;x=1/../y"}, + {"@id": "urn:ex:s080", "urn:ex:p": "g?y/./x"}, + {"@id": "urn:ex:s081", "urn:ex:p": "g?y/../x"}, + {"@id": "urn:ex:s082", "urn:ex:p": "g#s/./x"}, + {"@id": "urn:ex:s083", "urn:ex:p": "g#s/../x"}, + {"@id": "urn:ex:s084", "urn:ex:p": "http:g"} + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/toRdf-0121-out.nq b/core/src/test/resources/json-ld.org/toRdf-0121-out.nq new file mode 100644 index 00000000..b0a0231a --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0121-out.nq @@ -0,0 +1,42 @@ + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0122-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0122-in.jsonld new file mode 100644 index 00000000..f6c240c0 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0122-in.jsonld @@ -0,0 +1,47 @@ +{ + "@context": {"@base": "http://a/bb/ccc/./d;p?q", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s085", "urn:ex:p": "g:h"}, + {"@id": "urn:ex:s086", "urn:ex:p": "g"}, + {"@id": "urn:ex:s087", "urn:ex:p": "./g"}, + {"@id": "urn:ex:s088", "urn:ex:p": "g/"}, + {"@id": "urn:ex:s089", "urn:ex:p": "/g"}, + {"@id": "urn:ex:s090", "urn:ex:p": "//g"}, + {"@id": "urn:ex:s091", "urn:ex:p": "?y"}, + {"@id": "urn:ex:s092", "urn:ex:p": "g?y"}, + {"@id": "urn:ex:s093", "urn:ex:p": "#s"}, + {"@id": "urn:ex:s094", "urn:ex:p": "g#s"}, + {"@id": "urn:ex:s095", "urn:ex:p": "g?y#s"}, + {"@id": "urn:ex:s096", "urn:ex:p": ";x"}, + {"@id": "urn:ex:s097", "urn:ex:p": "g;x"}, + {"@id": "urn:ex:s098", "urn:ex:p": "g;x?y#s"}, + {"@id": "urn:ex:s099", "urn:ex:p": ""}, + {"@id": "urn:ex:s100", "urn:ex:p": "."}, + {"@id": "urn:ex:s101", "urn:ex:p": "./"}, + {"@id": "urn:ex:s102", "urn:ex:p": ".."}, + {"@id": "urn:ex:s103", "urn:ex:p": "../"}, + {"@id": "urn:ex:s104", "urn:ex:p": "../g"}, + {"@id": "urn:ex:s105", "urn:ex:p": "../.."}, + {"@id": "urn:ex:s106", "urn:ex:p": "../../"}, + {"@id": "urn:ex:s107", "urn:ex:p": "../../g"}, + {"@id": "urn:ex:s108", "urn:ex:p": "../../../g"}, + {"@id": "urn:ex:s109", "urn:ex:p": "../../../../g"}, + {"@id": "urn:ex:s110", "urn:ex:p": "/./g"}, + {"@id": "urn:ex:s111", "urn:ex:p": "/../g"}, + {"@id": "urn:ex:s112", "urn:ex:p": "g."}, + {"@id": "urn:ex:s113", "urn:ex:p": ".g"}, + {"@id": "urn:ex:s114", "urn:ex:p": "g.."}, + {"@id": "urn:ex:s115", "urn:ex:p": "..g"}, + {"@id": "urn:ex:s116", "urn:ex:p": "./../g"}, + {"@id": "urn:ex:s117", "urn:ex:p": "./g/."}, + {"@id": "urn:ex:s118", "urn:ex:p": "g/./h"}, + {"@id": "urn:ex:s119", "urn:ex:p": "g/../h"}, + {"@id": "urn:ex:s120", "urn:ex:p": "g;x=1/./y"}, + {"@id": "urn:ex:s121", "urn:ex:p": "g;x=1/../y"}, + {"@id": "urn:ex:s122", "urn:ex:p": "g?y/./x"}, + {"@id": "urn:ex:s123", "urn:ex:p": "g?y/../x"}, + {"@id": "urn:ex:s124", "urn:ex:p": "g#s/./x"}, + {"@id": "urn:ex:s125", "urn:ex:p": "g#s/../x"}, + {"@id": "urn:ex:s126", "urn:ex:p": "http:g"} + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/toRdf-0122-out.nq b/core/src/test/resources/json-ld.org/toRdf-0122-out.nq new file mode 100644 index 00000000..fd518304 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0122-out.nq @@ -0,0 +1,42 @@ + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0123-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0123-in.jsonld new file mode 100644 index 00000000..006fa689 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0123-in.jsonld @@ -0,0 +1,47 @@ +{ + "@context": {"@base": "http://a/bb/ccc/../d;p?q", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s127", "urn:ex:p": "g:h"}, + {"@id": "urn:ex:s128", "urn:ex:p": "g"}, + {"@id": "urn:ex:s129", "urn:ex:p": "./g"}, + {"@id": "urn:ex:s130", "urn:ex:p": "g/"}, + {"@id": "urn:ex:s131", "urn:ex:p": "/g"}, + {"@id": "urn:ex:s132", "urn:ex:p": "//g"}, + {"@id": "urn:ex:s133", "urn:ex:p": "?y"}, + {"@id": "urn:ex:s134", "urn:ex:p": "g?y"}, + {"@id": "urn:ex:s135", "urn:ex:p": "#s"}, + {"@id": "urn:ex:s136", "urn:ex:p": "g#s"}, + {"@id": "urn:ex:s137", "urn:ex:p": "g?y#s"}, + {"@id": "urn:ex:s138", "urn:ex:p": ";x"}, + {"@id": "urn:ex:s139", "urn:ex:p": "g;x"}, + {"@id": "urn:ex:s140", "urn:ex:p": "g;x?y#s"}, + {"@id": "urn:ex:s141", "urn:ex:p": ""}, + {"@id": "urn:ex:s142", "urn:ex:p": "."}, + {"@id": "urn:ex:s143", "urn:ex:p": "./"}, + {"@id": "urn:ex:s144", "urn:ex:p": ".."}, + {"@id": "urn:ex:s145", "urn:ex:p": "../"}, + {"@id": "urn:ex:s146", "urn:ex:p": "../g"}, + {"@id": "urn:ex:s147", "urn:ex:p": "../.."}, + {"@id": "urn:ex:s148", "urn:ex:p": "../../"}, + {"@id": "urn:ex:s149", "urn:ex:p": "../../g"}, + {"@id": "urn:ex:s150", "urn:ex:p": "../../../g"}, + {"@id": "urn:ex:s151", "urn:ex:p": "../../../../g"}, + {"@id": "urn:ex:s152", "urn:ex:p": "/./g"}, + {"@id": "urn:ex:s153", "urn:ex:p": "/../g"}, + {"@id": "urn:ex:s154", "urn:ex:p": "g."}, + {"@id": "urn:ex:s155", "urn:ex:p": ".g"}, + {"@id": "urn:ex:s156", "urn:ex:p": "g.."}, + {"@id": "urn:ex:s157", "urn:ex:p": "..g"}, + {"@id": "urn:ex:s158", "urn:ex:p": "./../g"}, + {"@id": "urn:ex:s159", "urn:ex:p": "./g/."}, + {"@id": "urn:ex:s160", "urn:ex:p": "g/./h"}, + {"@id": "urn:ex:s161", "urn:ex:p": "g/../h"}, + {"@id": "urn:ex:s162", "urn:ex:p": "g;x=1/./y"}, + {"@id": "urn:ex:s163", "urn:ex:p": "g;x=1/../y"}, + {"@id": "urn:ex:s164", "urn:ex:p": "g?y/./x"}, + {"@id": "urn:ex:s165", "urn:ex:p": "g?y/../x"}, + {"@id": "urn:ex:s166", "urn:ex:p": "g#s/./x"}, + {"@id": "urn:ex:s167", "urn:ex:p": "g#s/../x"}, + {"@id": "urn:ex:s168", "urn:ex:p": "http:g"} + ] +} \ No newline at end of file diff --git a/core/src/test/resources/json-ld.org/toRdf-0123-out.nq b/core/src/test/resources/json-ld.org/toRdf-0123-out.nq new file mode 100644 index 00000000..59af1ece --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0123-out.nq @@ -0,0 +1,42 @@ + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0124-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0124-in.jsonld new file mode 100644 index 00000000..d75b3d8c --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0124-in.jsonld @@ -0,0 +1,47 @@ +{ + "@context": {"@base": "http://a/bb/ccc/.", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s169", "urn:ex:p": "g:h"}, + {"@id": "urn:ex:s170", "urn:ex:p": "g"}, + {"@id": "urn:ex:s171", "urn:ex:p": "./g"}, + {"@id": "urn:ex:s172", "urn:ex:p": "g/"}, + {"@id": "urn:ex:s173", "urn:ex:p": "/g"}, + {"@id": "urn:ex:s174", "urn:ex:p": "//g"}, + {"@id": "urn:ex:s175", "urn:ex:p": "?y"}, + {"@id": "urn:ex:s176", "urn:ex:p": "g?y"}, + {"@id": "urn:ex:s177", "urn:ex:p": "#s"}, + {"@id": "urn:ex:s178", "urn:ex:p": "g#s"}, + {"@id": "urn:ex:s179", "urn:ex:p": "g?y#s"}, + {"@id": "urn:ex:s180", "urn:ex:p": ";x"}, + {"@id": "urn:ex:s181", "urn:ex:p": "g;x"}, + {"@id": "urn:ex:s182", "urn:ex:p": "g;x?y#s"}, + {"@id": "urn:ex:s183", "urn:ex:p": ""}, + {"@id": "urn:ex:s184", "urn:ex:p": "."}, + {"@id": "urn:ex:s185", "urn:ex:p": "./"}, + {"@id": "urn:ex:s186", "urn:ex:p": ".."}, + {"@id": "urn:ex:s187", "urn:ex:p": "../"}, + {"@id": "urn:ex:s188", "urn:ex:p": "../g"}, + {"@id": "urn:ex:s189", "urn:ex:p": "../.."}, + {"@id": "urn:ex:s190", "urn:ex:p": "../../"}, + {"@id": "urn:ex:s191", "urn:ex:p": "../../g"}, + {"@id": "urn:ex:s192", "urn:ex:p": "../../../g"}, + {"@id": "urn:ex:s193", "urn:ex:p": "../../../../g"}, + {"@id": "urn:ex:s194", "urn:ex:p": "/./g"}, + {"@id": "urn:ex:s195", "urn:ex:p": "/../g"}, + {"@id": "urn:ex:s196", "urn:ex:p": "g."}, + {"@id": "urn:ex:s197", "urn:ex:p": ".g"}, + {"@id": "urn:ex:s198", "urn:ex:p": "g.."}, + {"@id": "urn:ex:s199", "urn:ex:p": "..g"}, + {"@id": "urn:ex:s200", "urn:ex:p": "./../g"}, + {"@id": "urn:ex:s201", "urn:ex:p": "./g/."}, + {"@id": "urn:ex:s202", "urn:ex:p": "g/./h"}, + {"@id": "urn:ex:s203", "urn:ex:p": "g/../h"}, + {"@id": "urn:ex:s204", "urn:ex:p": "g;x=1/./y"}, + {"@id": "urn:ex:s205", "urn:ex:p": "g;x=1/../y"}, + {"@id": "urn:ex:s206", "urn:ex:p": "g?y/./x"}, + {"@id": "urn:ex:s207", "urn:ex:p": "g?y/../x"}, + {"@id": "urn:ex:s208", "urn:ex:p": "g#s/./x"}, + {"@id": "urn:ex:s209", "urn:ex:p": "g#s/../x"}, + {"@id": "urn:ex:s210", "urn:ex:p": "http:g"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0124-out.nq b/core/src/test/resources/json-ld.org/toRdf-0124-out.nq new file mode 100644 index 00000000..7a57e0e6 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0124-out.nq @@ -0,0 +1,42 @@ + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0125-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0125-in.jsonld new file mode 100644 index 00000000..2e1adc8b --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0125-in.jsonld @@ -0,0 +1,47 @@ +{ + "@context": {"@base": "http://a/bb/ccc/..", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s211", "urn:ex:p": "g:h"}, + {"@id": "urn:ex:s212", "urn:ex:p": "g"}, + {"@id": "urn:ex:s213", "urn:ex:p": "./g"}, + {"@id": "urn:ex:s214", "urn:ex:p": "g/"}, + {"@id": "urn:ex:s215", "urn:ex:p": "/g"}, + {"@id": "urn:ex:s216", "urn:ex:p": "//g"}, + {"@id": "urn:ex:s217", "urn:ex:p": "?y"}, + {"@id": "urn:ex:s218", "urn:ex:p": "g?y"}, + {"@id": "urn:ex:s219", "urn:ex:p": "#s"}, + {"@id": "urn:ex:s220", "urn:ex:p": "g#s"}, + {"@id": "urn:ex:s221", "urn:ex:p": "g?y#s"}, + {"@id": "urn:ex:s222", "urn:ex:p": ";x"}, + {"@id": "urn:ex:s223", "urn:ex:p": "g;x"}, + {"@id": "urn:ex:s224", "urn:ex:p": "g;x?y#s"}, + {"@id": "urn:ex:s225", "urn:ex:p": ""}, + {"@id": "urn:ex:s226", "urn:ex:p": "."}, + {"@id": "urn:ex:s227", "urn:ex:p": "./"}, + {"@id": "urn:ex:s228", "urn:ex:p": ".."}, + {"@id": "urn:ex:s229", "urn:ex:p": "../"}, + {"@id": "urn:ex:s230", "urn:ex:p": "../g"}, + {"@id": "urn:ex:s231", "urn:ex:p": "../.."}, + {"@id": "urn:ex:s232", "urn:ex:p": "../../"}, + {"@id": "urn:ex:s233", "urn:ex:p": "../../g"}, + {"@id": "urn:ex:s234", "urn:ex:p": "../../../g"}, + {"@id": "urn:ex:s235", "urn:ex:p": "../../../../g"}, + {"@id": "urn:ex:s236", "urn:ex:p": "/./g"}, + {"@id": "urn:ex:s237", "urn:ex:p": "/../g"}, + {"@id": "urn:ex:s238", "urn:ex:p": "g."}, + {"@id": "urn:ex:s239", "urn:ex:p": ".g"}, + {"@id": "urn:ex:s240", "urn:ex:p": "g.."}, + {"@id": "urn:ex:s241", "urn:ex:p": "..g"}, + {"@id": "urn:ex:s242", "urn:ex:p": "./../g"}, + {"@id": "urn:ex:s243", "urn:ex:p": "./g/."}, + {"@id": "urn:ex:s244", "urn:ex:p": "g/./h"}, + {"@id": "urn:ex:s245", "urn:ex:p": "g/../h"}, + {"@id": "urn:ex:s246", "urn:ex:p": "g;x=1/./y"}, + {"@id": "urn:ex:s247", "urn:ex:p": "g;x=1/../y"}, + {"@id": "urn:ex:s248", "urn:ex:p": "g?y/./x"}, + {"@id": "urn:ex:s249", "urn:ex:p": "g?y/../x"}, + {"@id": "urn:ex:s250", "urn:ex:p": "g#s/./x"}, + {"@id": "urn:ex:s251", "urn:ex:p": "g#s/../x"}, + {"@id": "urn:ex:s252", "urn:ex:p": "http:g"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0125-out.nq b/core/src/test/resources/json-ld.org/toRdf-0125-out.nq new file mode 100644 index 00000000..89a3f659 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0125-out.nq @@ -0,0 +1,42 @@ + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0127-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0127-in.jsonld new file mode 100644 index 00000000..eec91f99 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0127-in.jsonld @@ -0,0 +1,11 @@ +{ + "@context": {"@base": "http://abc/def/ghi", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s295", "urn:ex:p": "."}, + {"@id": "urn:ex:s296", "urn:ex:p": ".?a=b"}, + {"@id": "urn:ex:s297", "urn:ex:p": ".#a=b"}, + {"@id": "urn:ex:s298", "urn:ex:p": ".."}, + {"@id": "urn:ex:s299", "urn:ex:p": "..?a=b"}, + {"@id": "urn:ex:s300", "urn:ex:p": "..#a=b"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0127-out.nq b/core/src/test/resources/json-ld.org/toRdf-0127-out.nq new file mode 100644 index 00000000..65e26022 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0127-out.nq @@ -0,0 +1,6 @@ + . + . + . + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0129-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0129-in.jsonld new file mode 100644 index 00000000..a199895e --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0129-in.jsonld @@ -0,0 +1,8 @@ +{ + "@context": {"@base": "http://abc/d:f/ghi", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s304", "urn:ex:p": "xyz"}, + {"@id": "urn:ex:s305", "urn:ex:p": "./xyz"}, + {"@id": "urn:ex:s306", "urn:ex:p": "../xyz"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0129-out.nq b/core/src/test/resources/json-ld.org/toRdf-0129-out.nq new file mode 100644 index 00000000..31bce616 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0129-out.nq @@ -0,0 +1,3 @@ + . + . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld b/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld index 8abb3e57..9e1ceaeb 100644 --- a/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld @@ -807,6 +807,62 @@ "purpose": "Proper (re-)labeling of blank nodes if used with reverse properties.", "input": "toRdf-0119-in.jsonld", "expect": "toRdf-0119-out.nq" + }, { + "@id": "#t0120", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (0)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0120-in.jsonld", + "expect": "toRdf-0120-out.nq" + }, { + "@id": "#t0121", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (1)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0121-in.jsonld", + "expect": "toRdf-0121-out.nq" + }, { + "@id": "#t0122", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (2)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0122-in.jsonld", + "expect": "toRdf-0122-out.nq" + }, { + "@id": "#t0123", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (3)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0123-in.jsonld", + "expect": "toRdf-0123-out.nq" + }, { + "@id": "#t0124", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (4)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0124-in.jsonld", + "expect": "toRdf-0124-out.nq" + }, { + "@id": "#t0125", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (5)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0125-in.jsonld", + "expect": "toRdf-0125-out.nq" + }, { + "@id": "#t0127", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (7)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0127-in.jsonld", + "expect": "toRdf-0127-out.nq" + }, { + "@id": "#t0129", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (9)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0129-in.jsonld", + "expect": "toRdf-0129-out.nq" } ] } From fce53a4b2ea2c5f4e486ee56696bf99cbda04f49 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Tue, 11 Jun 2019 09:26:06 +0200 Subject: [PATCH 374/440] Handle opaque/path-rootless base IRIs Add new spec tests, remove custom tests See: https://github.com/jsonld-java/jsonld-java/issues/232 https://github.com/w3c/json-ld-api/pull/103 --- .../github/jsonldjava/utils/JsonLdUrl.java | 13 ++++-- ...DFTest.java => ArrayContextToRDFTest.java} | 41 +------------------ .../test/resources/custom/toRdf-0003-out.nq | 2 +- .../json-ld.org/toRdf-0130-in.jsonld | 6 +++ .../resources/json-ld.org/toRdf-0130-out.nq | 1 + .../json-ld.org/toRdf-0131-in.jsonld | 6 +++ .../resources/json-ld.org/toRdf-0131-out.nq | 1 + .../json-ld.org/toRdf-0132-in.jsonld | 6 +++ .../resources/json-ld.org/toRdf-0132-out.nq | 1 + .../json-ld.org/toRdf-manifest.jsonld | 21 ++++++++++ 10 files changed, 54 insertions(+), 44 deletions(-) rename core/src/test/java/com/github/jsonldjava/core/{ToRDFTest.java => ArrayContextToRDFTest.java} (50%) create mode 100644 core/src/test/resources/json-ld.org/toRdf-0130-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0130-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0131-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0131-out.nq create mode 100644 core/src/test/resources/json-ld.org/toRdf-0132-in.jsonld create mode 100644 core/src/test/resources/json-ld.org/toRdf-0132-out.nq diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java index ce7c5724..cf786c61 100755 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java @@ -261,23 +261,30 @@ public static String resolve(String baseUri, String pathToResolve) { } try { URI uri = new URI(baseUri); + // URI#resolve drops base scheme for opaque URIs, https://github.com/jsonld-java/jsonld-java/issues/232 + if (uri.isOpaque()) { + String basePath = uri.getPath() != null ? uri.getPath() : uri.getSchemeSpecificPart(); + // Drop the last segment, see https://tools.ietf.org/html/rfc3986#section-5.2.3 (2nd bullet point) + basePath = basePath.contains("/") ? basePath.substring(0, basePath.lastIndexOf('/') + 1) : ""; + return new URI(uri.getScheme(), basePath + pathToResolve, null).toString(); + } // "a base URI [...] does not allow a fragment" (https://tools.ietf.org/html/rfc3986#section-4.3) uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), uri.getQuery(), null); // query string parsing if (pathToResolve.startsWith("?")) { // drop query, https://tools.ietf.org/html/rfc3986#section-5.2.2: T.query = R.query; uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null); - // add query to the end manually (as URI.resolve does it wrong) + // add query to the end manually (as URI#resolve does it wrong) return uri.toString() + pathToResolve; } else if (pathToResolve.startsWith("#")) { - // add fragment to the end manually (as URI.resolve does it wrong) + // add fragment to the end manually (as URI#resolve does it wrong) return uri.toString() + pathToResolve; } uri = uri.resolve(pathToResolve); // java doesn't discard unnecessary dot segments String path = uri.getPath(); if (path != null) { - path = JsonLdUrl.removeDotSegments(uri.getPath(), true); + path = JsonLdUrl.removeDotSegments(path, true); } return new URI(uri.getScheme(), uri.getAuthority(), path, uri.getQuery(), uri.getFragment()).toString(); diff --git a/core/src/test/java/com/github/jsonldjava/core/ToRDFTest.java b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java similarity index 50% rename from core/src/test/java/com/github/jsonldjava/core/ToRDFTest.java rename to core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java index 8db83857..28aa9d35 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ToRDFTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ArrayContextToRDFTest.java @@ -4,21 +4,13 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.stream.Collectors; -import org.junit.Ignore; import org.junit.Test; import com.github.jsonldjava.utils.JsonUtils; -import com.github.jsonldjava.utils.TestUtils; -public class ToRDFTest { +public class ArrayContextToRDFTest { @Test public void toRdfWithNamespace() throws Exception { @@ -51,35 +43,4 @@ public RemoteDocument loadDocument(String url) throws JsonLdError { assertFalse(rdf.getNamespaces().containsKey("term1")); } - - @Test - // See https://github.com/jsonld-java/jsonld-java/issues/232 - public void toRdfWithHttpBaseIri() throws IOException, JsonLdError { - testToRdf("/custom/toRdf-0001-in.jsonld", "/custom/toRdf-0001-out.nq", "http://example.org/"); - } - - @Test - // See https://github.com/jsonld-java/jsonld-java/issues/232 - public void toRdfWithHierarchicalBaseIri() throws IOException, JsonLdError { - testToRdf("/custom/toRdf-0001-in.jsonld", "/custom/toRdf-0002-out.nq", "tag:/example/"); - } - - @Test - @Ignore - // See https://github.com/jsonld-java/jsonld-java/issues/232#issuecomment-493454096 - public void toRdfWithOpaqueBaseIri() throws IOException, JsonLdError { - testToRdf("/custom/toRdf-0001-in.jsonld", "/custom/toRdf-0003-out.nq", "tag:example/"); - } - - private void testToRdf(String inFile, String outFile, String baseIri) throws IOException { - final Object input = JsonUtils - .fromInputStream(getClass().getResourceAsStream(inFile)); - List resultLines = new BufferedReader(new InputStreamReader( - getClass().getResourceAsStream(outFile), StandardCharsets.UTF_8)).lines() - .collect(Collectors.toList()); - JsonLdOptions options = new JsonLdOptions(baseIri); - options.format = JsonLdConsts.APPLICATION_NQUADS; - Object result = JsonLdProcessor.toRDF(input, options); - assertEquals(TestUtils.join(resultLines, "\n").trim(), ((String) result).trim()); - } } diff --git a/core/src/test/resources/custom/toRdf-0003-out.nq b/core/src/test/resources/custom/toRdf-0003-out.nq index 8e66eba6..aee420ed 100644 --- a/core/src/test/resources/custom/toRdf-0003-out.nq +++ b/core/src/test/resources/custom/toRdf-0003-out.nq @@ -1 +1 @@ - . + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0130-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0130-in.jsonld new file mode 100644 index 00000000..bb11d1fe --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0130-in.jsonld @@ -0,0 +1,6 @@ +{ + "@context": {"@base": "tag:example", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s307", "urn:ex:p": "a"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0130-out.nq b/core/src/test/resources/json-ld.org/toRdf-0130-out.nq new file mode 100644 index 00000000..48c95173 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0130-out.nq @@ -0,0 +1 @@ + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0131-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0131-in.jsonld new file mode 100644 index 00000000..86954242 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0131-in.jsonld @@ -0,0 +1,6 @@ +{ + "@context": {"@base": "tag:example/foo", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s308", "urn:ex:p": "a"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0131-out.nq b/core/src/test/resources/json-ld.org/toRdf-0131-out.nq new file mode 100644 index 00000000..4c420b35 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0131-out.nq @@ -0,0 +1 @@ + . diff --git a/core/src/test/resources/json-ld.org/toRdf-0132-in.jsonld b/core/src/test/resources/json-ld.org/toRdf-0132-in.jsonld new file mode 100644 index 00000000..d26b45b6 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0132-in.jsonld @@ -0,0 +1,6 @@ +{ + "@context": {"@base": "tag:example/foo/", "urn:ex:p": {"@type": "@id"}}, + "@graph": [ + {"@id": "urn:ex:s309", "urn:ex:p": "a"} + ] +} diff --git a/core/src/test/resources/json-ld.org/toRdf-0132-out.nq b/core/src/test/resources/json-ld.org/toRdf-0132-out.nq new file mode 100644 index 00000000..7215f758 --- /dev/null +++ b/core/src/test/resources/json-ld.org/toRdf-0132-out.nq @@ -0,0 +1 @@ + . diff --git a/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld b/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld index 9e1ceaeb..a8d2fdf2 100644 --- a/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld +++ b/core/src/test/resources/json-ld.org/toRdf-manifest.jsonld @@ -863,6 +863,27 @@ "purpose": "IRI resolution according to RFC3986.", "input": "toRdf-0129-in.jsonld", "expect": "toRdf-0129-out.nq" + }, { + "@id": "#t0130", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (10)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0130-in.jsonld", + "expect": "toRdf-0130-out.nq" + }, { + "@id": "#t0131", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (11)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0131-in.jsonld", + "expect": "toRdf-0131-out.nq" + }, { + "@id": "#t0132", + "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"], + "name": "IRI Resolution (12)", + "purpose": "IRI resolution according to RFC3986.", + "input": "toRdf-0132-in.jsonld", + "expect": "toRdf-0132-out.nq" } ] } From b1725b7d33903327a41f6f79bc7d94f5ffcc2acf Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Fri, 26 Jul 2019 18:42:16 +0100 Subject: [PATCH 375/440] Update version of jackson-databind to 2.9.9.1 --- pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ca2259d..6c1dfe22 100755 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,8 @@ 4.5.8 4.4.11 2.9.9 + + 2.9.9.1 4.12 1.7.26 @@ -65,7 +67,7 @@ com.fasterxml.jackson.core jackson-databind - ${jackson.version} + ${jackson-databind.version} com.fasterxml.jackson.core From c1f1fa90a9a39783876618c36eec9b833b944f91 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Tue, 30 Jul 2019 08:54:08 +1000 Subject: [PATCH 376/440] Test with openjdk8 and openjdk11 --- .travis.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 30fd9d59..29a226e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,7 @@ language: java jdk: - - oraclejdk8 - - oraclejdk9 -matrix: - include: - - jdk: openjdk10 - before_install: - - rm "${JAVA_HOME}/lib/security/cacerts" - - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" - - jdk: openjdk11 - before_install: - - rm "${JAVA_HOME}/lib/security/cacerts" - - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" + - openjdk8 + - openjdk11 notifications: email: false after_success: From 66938989bc09ac8074db2bf2e6a1b2bb9d8d99c5 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Fri, 2 Aug 2019 22:08:35 +0100 Subject: [PATCH 377/440] Update version of jackson-databind to 2.9.9.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6c1dfe22..b0e71f75 100755 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ 4.4.11 2.9.9 - 2.9.9.1 + 2.9.9.2 4.12 1.7.26 From d6240539cbaf522fc95ce2c277d645e82ae4bde5 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 3 Aug 2019 11:56:51 +1000 Subject: [PATCH 378/440] Release 0.12.5 Signed-off-by: Peter Ansell --- README.md | 11 ++++++++--- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a01a2ee1..22e00a4f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.12.4 + 0.12.5 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.12.4 + 0.12.5 4.0.0 jsonld-java-{your module} - 0.12.4-SNAPSHOT + 0.12.5-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -450,6 +450,11 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2019-08-03 +* Release 0.12.5 +* Bump Jackson versions to latest for securiy updates (Patches by @afs) +* IRI resolution fixes (Patch by @fsteeg) + ### 2019-04-20 * Release 0.12.4 * Bump Jackson version to 2.9.8 diff --git a/core/pom.xml b/core/pom.xml index 30a1d02e..27823509 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.5-SNAPSHOT + 0.12.5 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index b0e71f75..cc93427d 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.5-SNAPSHOT + 0.12.5 JSONLD Java :: Parent Json-LD Java Parent POM pom From 762997918f1023edfebd26737c95e7e16ad9bf4a Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 3 Aug 2019 12:00:41 +1000 Subject: [PATCH 379/440] Bump to next snapshot Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 27823509..516b3ff8 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.5 + 0.12.6-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index cc93427d..9115e390 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.5 + 0.12.6-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 8d05be376a8b4bce72e26c44880cf31d11220644 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sat, 28 Sep 2019 21:10:49 +0100 Subject: [PATCH 380/440] Update version of jackson to 2.9.10 --- pom.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 9115e390..2ff75968 100755 --- a/pom.xml +++ b/pom.xml @@ -41,9 +41,7 @@ 4.5.8 4.4.11 - 2.9.9 - - 2.9.9.2 + 2.9.10 4.12 1.7.26 @@ -67,7 +65,7 @@ com.fasterxml.jackson.core jackson-databind - ${jackson-databind.version} + ${jackson.version} com.fasterxml.jackson.core From 0fedbe23e0c309ae748cbf5fd90506f58f01a644 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sun, 27 Oct 2019 09:24:47 +0000 Subject: [PATCH 381/440] Update to Jackson 2.10.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2ff75968..6cbf2ce7 100755 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 4.5.8 4.4.11 - 2.9.10 + 2.10.0 4.12 1.7.26 From 8bb1aca291c3bbe2b6a9413363cf315dfecb72f4 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Mon, 28 Oct 2019 07:44:48 +1100 Subject: [PATCH 382/440] Bump to 0.13.0-SNAPSHOT for jackson-2.10 code Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 516b3ff8..536f7161 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.12.6-SNAPSHOT + 0.13.0-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 6cbf2ce7..e3b1ad8e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.12.6-SNAPSHOT + 0.13.0-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 342b40b1c4801a7c309612605460fc648ac581ad Mon Sep 17 00:00:00 2001 From: Jacob Glickman Date: Wed, 27 Nov 2019 14:27:05 -0500 Subject: [PATCH 383/440] XSD_DECIMAL representation is no longer canonicalized. --- .../main/java/com/github/jsonldjava/core/RDFDataset.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java index 43e279a8..8f8e18c2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java +++ b/core/src/main/java/com/github/jsonldjava/core/RDFDataset.java @@ -6,6 +6,7 @@ import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST; import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE; import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN; +import static com.github.jsonldjava.core.JsonLdConsts.XSD_DECIMAL; import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE; import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER; import static com.github.jsonldjava.core.JsonLdConsts.XSD_STRING; @@ -665,7 +666,10 @@ private Node objectToRDF(Object item) { return new Literal(Float.toString((float) value), datatype == null ? XSD_DOUBLE : (String) datatype, null); } else { - // canonical double representation + // Only canonicalize representation if datatype is not XSD_DECIMAL + if (XSD_DECIMAL.equals(datatype)) { + return new Literal(value.toString(), XSD_DECIMAL, null); + } final DecimalFormat df = new DecimalFormat("0.0###############E0"); df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US)); return new Literal(df.format(value), From 5e73b4ffd5f0f78e92a3ec56fd21da17f8c2deba Mon Sep 17 00:00:00 2001 From: Jacob Glickman Date: Wed, 27 Nov 2019 15:43:04 -0500 Subject: [PATCH 384/440] Added unit test to improve code coverage. --- .../core/DecimalLiteralCanonicalTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/DecimalLiteralCanonicalTest.java diff --git a/core/src/test/java/com/github/jsonldjava/core/DecimalLiteralCanonicalTest.java b/core/src/test/java/com/github/jsonldjava/core/DecimalLiteralCanonicalTest.java new file mode 100644 index 00000000..0e05921a --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/DecimalLiteralCanonicalTest.java @@ -0,0 +1,34 @@ +package com.github.jsonldjava.core; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class DecimalLiteralCanonicalTest { + + @Test + public void testDecimalIsNotCanonicalized() { + double value = 6.5; + + Map innerMap = new HashMap<>(); + innerMap.put("@value", value); + innerMap.put("@type", "http://www.w3.org/2001/XMLSchema#decimal"); + + Map jsonMap = new HashMap<>(); + jsonMap.put("ex:id", innerMap); + + JsonLdApi api = new JsonLdApi(jsonMap, new JsonLdOptions("")); + RDFDataset dataset = api.toRDF(); + + List defaultList = (List) dataset.get("@default"); + Map tripleMap = (Map) defaultList.get(0); + Map objectMap = (Map) tripleMap.get("object"); + + assertEquals("http://www.w3.org/2001/XMLSchema#decimal", objectMap.get("datatype")); + assertEquals(Double.toString(value), objectMap.get("value")); + } +} From a473fcf72ee8e70c69571e77d74924fe49df0437 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 28 Nov 2019 08:56:32 +1100 Subject: [PATCH 385/440] Dependency and plugin bumps Signed-off-by: Peter Ansell --- pom.xml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/pom.xml b/pom.xml index e3b1ad8e..23483148 100755 --- a/pom.xml +++ b/pom.xml @@ -39,11 +39,11 @@ UTF-8 UTF-8 - 4.5.8 - 4.4.11 - 2.10.0 + 4.5.10 + 4.4.12 + 2.10.1 4.12 - 1.7.26 + 1.7.29 0.11.0 @@ -192,12 +192,12 @@ commons-codec commons-codec - 1.12 + 1.13 org.mockito mockito-core - 2.27.0 + 2.28.2 commons-io @@ -209,7 +209,7 @@ com.google.guava guava - 27.1-jre + 28.1-jre @@ -230,7 +230,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0-M2 + 3.0.0-M3 enforce-maven-3 @@ -274,7 +274,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.1 1.8 1.8 @@ -283,12 +283,12 @@ org.apache.maven.plugins maven-assembly-plugin - 3.1.0 + 3.2.0 org.apache.maven.plugins maven-shade-plugin - 3.1.1 + 3.2.1 org.apache.maven.plugins @@ -303,7 +303,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 3.1.1 org.apache.maven.plugins @@ -338,7 +338,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.1.0 + 3.2.0 @@ -350,7 +350,7 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.2.0 attach-source @@ -369,17 +369,17 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.0 + 2.22.2 org.apache.maven.plugins maven-site-plugin - 3.7.1 + 3.8.2 org.codehaus.mojo animal-sniffer-maven-plugin - 1.17 + 1.18 check-jdk-compliance @@ -400,7 +400,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.13.0 + 0.14.2 @@ -431,7 +431,7 @@ org.codehaus.mojo appassembler-maven-plugin - 2.0.0 + 2.1.0 org.apache.felix @@ -447,7 +447,7 @@ org.jacoco jacoco-maven-plugin - 0.8.4 + 0.8.5 prepare-agent @@ -460,7 +460,7 @@ org.codehaus.mojo versions-maven-plugin - 2.5 + 2.7 From 7a6cd6272367c6a6da41cd6b5483ea9df5277b16 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 28 Nov 2019 09:09:08 +1100 Subject: [PATCH 386/440] Release 0.13.0 Signed-off-by: Peter Ansell --- README.md | 14 ++++++++++---- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 22e00a4f..2270d45c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.12.5 + 0.13.0 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.12.5 + 0.13.0 4.0.0 jsonld-java-{your module} - 0.12.5-SNAPSHOT + 0.13.0-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -450,9 +450,15 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2019-11-28 +* Release 0.13.0 +* Bump Jackson versions to latest for security updates (Patch by @afs) +* Do not canonicalise XSD Decimal typed values (Patch by @jhg023) +* Bump dependency and plugin versions + ### 2019-08-03 * Release 0.12.5 -* Bump Jackson versions to latest for securiy updates (Patches by @afs) +* Bump Jackson versions to latest for security updates (Patches by @afs) * IRI resolution fixes (Patch by @fsteeg) ### 2019-04-20 diff --git a/core/pom.xml b/core/pom.xml index 536f7161..f0d74985 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.0-SNAPSHOT + 0.13.0 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 23483148..b5a2e05b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.0-SNAPSHOT + 0.13.0 JSONLD Java :: Parent Json-LD Java Parent POM pom From d301b3cb54f31bd29b6ec70d7c72675d2f0c37a4 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 28 Nov 2019 09:14:20 +1100 Subject: [PATCH 387/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index f0d74985..c7ca4139 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.0 + 0.13.1-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index b5a2e05b..a1bd056b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.0 + 0.13.1-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 90ccfac4581adb60faeb3f2d0571a779335e6875 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 13 Mar 2020 13:25:18 +0100 Subject: [PATCH 388/440] Ensure a slash between the authority and the path of a URL See #279. --- .../com/github/jsonldjava/utils/JsonLdUrl.java | 4 ++++ .../com/github/jsonldjava/utils/JsonUtilsTest.java | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java index cf786c61..af5da444 100755 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java @@ -280,6 +280,10 @@ public static String resolve(String baseUri, String pathToResolve) { // add fragment to the end manually (as URI#resolve does it wrong) return uri.toString() + pathToResolve; } + // ensure a slash between the authority and the path of a URL + if (uri.getSchemeSpecificPart().startsWith("//") && !uri.getSchemeSpecificPart().matches("//.*/.*")) { + uri = new URI(uri + "/"); + } uri = uri.resolve(pathToResolve); // java doesn't discard unnecessary dot segments String path = uri.getPath(); diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 55cf79e7..26ec4df9 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -15,6 +15,20 @@ import com.fasterxml.jackson.databind.ObjectMapper; public class JsonUtilsTest { + @Test + public void resolveTest() { + final String baseUri = "http://mysite.net"; + final String pathToResolve = "picture.jpg"; + String resolve = ""; + + try { + resolve = JsonLdUrl.resolve(baseUri, pathToResolve); + } catch (final Exception e) { + assertTrue(false); + } + + assertTrue(resolve.equals(baseUri + "/" + pathToResolve)); + } @SuppressWarnings("unchecked") @Test From 3c22c6812943bd21d785569f2e845e229e282133 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Wed, 18 Mar 2020 13:14:33 +0100 Subject: [PATCH 389/440] Add custom integration test, tweak assertion to handle null Add test using a full document with base and relative IDs based on the original report by @ebremer on the users@jena.apache.org list See https://github.com/jsonld-java/jsonld-java/issues/279 --- .../github/jsonldjava/core/LocalBaseTest.java | 23 +++++++++++++++++++ .../jsonldjava/utils/JsonUtilsTest.java | 5 ++-- .../test/resources/custom/base-0003-in.jsonld | 17 ++++++++++++++ .../resources/custom/base-0003-out.jsonld | 7 ++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/custom/base-0003-in.jsonld create mode 100644 core/src/test/resources/custom/base-0003-out.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java index b1a50853..22093345 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java @@ -1,12 +1,14 @@ package com.github.jsonldjava.core; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.Charset; +import java.util.List; import org.junit.Test; @@ -55,4 +57,25 @@ public void testMixedLocalRemoteBaseLocalContextFirst() throws Exception { assertEquals(expanded, output); } + @Test + public void testUriResolveWhenExpandingBase() throws Exception { + + final Reader reader = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/custom/base-0003-in.jsonld"), + Charset.forName("UTF-8"))); + final Object input = JsonUtils.fromReader(reader); + assertNotNull(input); + + final JsonLdOptions options = new JsonLdOptions(); + final List expanded = JsonLdProcessor.expand(input, options); + assertFalse("expanded form must not be empty", expanded.isEmpty()); + + final Reader outReader = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/custom/base-0003-out.jsonld"), + Charset.forName("UTF-8"))); + final Object expected = JsonLdProcessor.expand(JsonUtils.fromReader(outReader), options); + assertNotNull(expected); + assertEquals(expected, expanded); + } + } diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 26ec4df9..23a25c8e 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -1,5 +1,7 @@ package com.github.jsonldjava.utils; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -26,8 +28,7 @@ public void resolveTest() { } catch (final Exception e) { assertTrue(false); } - - assertTrue(resolve.equals(baseUri + "/" + pathToResolve)); + assertEquals(baseUri + "/" + pathToResolve, resolve); } @SuppressWarnings("unchecked") diff --git a/core/src/test/resources/custom/base-0003-in.jsonld b/core/src/test/resources/custom/base-0003-in.jsonld new file mode 100644 index 00000000..da995fd0 --- /dev/null +++ b/core/src/test/resources/custom/base-0003-in.jsonld @@ -0,0 +1,17 @@ +{ + "@context": { + "@base": "http://mysite.net", + "DataSet": "http://schema.org/DataSet", + "CreativeWork": "http://schema.org/CreativeWork" + }, + "@graph": [ + { + "@type": "CreativeWork", + "@id": "picture.jpg" + }, + { + "@id": "./", + "@type": "DataSet" + } + ] +} diff --git a/core/src/test/resources/custom/base-0003-out.jsonld b/core/src/test/resources/custom/base-0003-out.jsonld new file mode 100644 index 00000000..d925a8dc --- /dev/null +++ b/core/src/test/resources/custom/base-0003-out.jsonld @@ -0,0 +1,7 @@ +[ { + "@id" : "http://mysite.net/picture.jpg", + "@type" : [ "http://schema.org/CreativeWork" ] +}, { + "@id" : "http://mysite.net/", + "@type" : [ "http://schema.org/DataSet" ] +} ] From 9359f10b89b9a16b7670ccb0ee0beafb0295e3bd Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 20 Mar 2020 09:31:15 +0100 Subject: [PATCH 390/440] Put the assertEquals inside of the try-catch block See #279. --- .../java/com/github/jsonldjava/utils/JsonUtilsTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java index 23a25c8e..d0387b49 100644 --- a/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java +++ b/core/src/test/java/com/github/jsonldjava/utils/JsonUtilsTest.java @@ -25,10 +25,10 @@ public void resolveTest() { try { resolve = JsonLdUrl.resolve(baseUri, pathToResolve); + assertEquals(baseUri + "/" + pathToResolve, resolve); } catch (final Exception e) { assertTrue(false); } - assertEquals(baseUri + "/" + pathToResolve, resolve); } @SuppressWarnings("unchecked") @@ -40,13 +40,12 @@ public void fromStringTest() { try { obj = JsonUtils.fromString(testString); + assertTrue(((Map) obj).containsKey("seq")); + assertTrue(((Map) obj).get("seq") instanceof Number); } catch (final Exception e) { assertTrue(false); } - assertTrue(((Map) obj).containsKey("seq")); - assertTrue(((Map) obj).get("seq") instanceof Number); - try { obj = JsonUtils.fromString(testFailure); assertTrue(false); From c850eb30e8e94c469a5727b5c3d4c3634ceda51e Mon Sep 17 00:00:00 2001 From: Markus Sabadello Date: Fri, 10 Apr 2020 11:25:11 +0200 Subject: [PATCH 391/440] Shade Guava's internal failureaccess dependency. Signed-off-by: Markus Sabadello --- core/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/pom.xml b/core/pom.xml index c7ca4139..25431acb 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -74,6 +74,7 @@ com.google.guava:guava + com.google.guava:failureaccess @@ -90,6 +91,12 @@ META-INF/maven/** + + com.google.guava:failureaccess + + META-INF/maven/** + + From d310e593c31883ceca373b04706a8396b1072886 Mon Sep 17 00:00:00 2001 From: Emilio Lahr-Vivaz Date: Wed, 8 Jul 2020 11:12:47 -0400 Subject: [PATCH 392/440] Fix jarcache guava loading * Don't minimize guava shading, causes NoClassDefFoundError --- core/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 25431acb..1461c1e1 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -83,7 +83,6 @@ com.github.jsonldjava.shaded.com.google.common - true com.google.guava:guava From 2e1135dafb381fde7d508d055cad2e052dcc253d Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 24 Aug 2020 16:15:35 +0200 Subject: [PATCH 393/440] Follow alternate document location Implements https://www.w3.org/TR/json-ld11/#alternate-document-location. Resolves https://github.com/jsonld-java/jsonld-java/issues/289. --- .../github/jsonldjava/utils/JsonUtils.java | 68 +++++++++++++++---- .../core/MinimalSchemaOrgRegressionTest.java | 34 +++------- 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index f7e0581b..da210958 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -9,14 +9,17 @@ import java.io.StringWriter; import java.io.Writer; import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.net.URL; import java.util.List; import java.util.Map; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; +import org.apache.http.Header; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; @@ -344,18 +347,7 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) // Accept headers as it's likely to be file: or jar: in = url.openStream(); } else { - final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to - // application/json - // or whatever is available - request.addHeader("Accept", ACCEPT_HEADER); - - response = httpClient.execute(request); - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - in = response.getEntity().getContent(); + in = getJsonLdViaHttpUri(url, httpClient, response); } return fromInputStream(in); } finally { @@ -371,6 +363,56 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) } } + private static InputStream getJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient, + CloseableHttpResponse response) throws IOException { + final HttpUriRequest request = new HttpGet(url.toExternalForm()); + // We prefer application/ld+json, but fallback to application/json + // or whatever is available + request.addHeader("Accept", ACCEPT_HEADER); + response = httpClient.execute(request); + + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + // follow alternate document location + // https://www.w3.org/TR/json-ld11/#alternate-document-location + URL alternateLink = alternateLink(url, response); + if (alternateLink != null) { + return getJsonLdViaHttpUri(alternateLink, httpClient, response); + } + return response.getEntity().getContent(); + } + + private static URL alternateLink(URL url, CloseableHttpResponse response) + throws MalformedURLException, IOException { + if (response.getEntity().getContentLength() > 0 + && !response.getEntity().getContentType().getValue().equals("application/ld+json")) { + for (Header header : response.getAllHeaders()) { + if (header.getName().equalsIgnoreCase("link")) { + String alternateLink = ""; + boolean relAlternate = false; + boolean jsonld = false; + for (String value : header.getValue().split(";")) { + if (value.trim().startsWith("<")) { + alternateLink = value.replaceAll("<(.*)>", "$1"); + } + if (value.trim().startsWith("type=\"application/ld+json\"")) { + jsonld = true; + } + if (value.trim().startsWith("rel=\"alternate\"")) { + relAlternate = true; + } + } + if (jsonld && relAlternate && !alternateLink.isEmpty()) { + return new URL(url.getProtocol() + "://" + url.getAuthority() + alternateLink); + } + } + } + } + return null; + } + /** * Fallback method directly using the {@link java.net.HttpURLConnection} * class for cases where servers do not interoperate correctly with Apache @@ -384,7 +426,7 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) * @throws IOException * If there was an IO error during parsing. */ - public static Object fromURLJavaNet(java.net.URL url) throws JsonParseException, IOException { + public static Object fromURLJavaNet(URL url) throws JsonParseException, IOException { final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.addRequestProperty("Accept", ACCEPT_HEADER); diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index f4c1b88d..03479f76 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -26,6 +26,7 @@ import org.junit.Test; import com.github.jsonldjava.utils.JarCacheStorage; +import com.github.jsonldjava.utils.JsonUtils; public class MinimalSchemaOrgRegressionTest { @@ -59,10 +60,13 @@ private void verifyInputStream(InputStream directStream) throws IOException { output.flush(); } final String outputString = output.toString(); - // System.out.println(outputString); + checkBasicConditions(outputString); + } + + private void checkBasicConditions(final String outputString) { // Test for some basic conditions without including the JSON/JSON-LD // parsing code here - // assertTrue(outputString, outputString.endsWith("}")); + assertTrue(outputString, outputString.endsWith("}")); assertFalse("Output string should not be empty: " + outputString.length(), outputString.isEmpty()); assertTrue("Unexpected length: " + outputString.length(), outputString.length() > 100000); @@ -90,30 +94,8 @@ public void testApacheHttpClient() throws Exception { // use system defaults for proxy etc. .useSystemProperties().build(); - try { - final HttpUriRequest request = new HttpGet(url.toExternalForm()); - // We prefer application/ld+json, but fallback to application/json - // or whatever is available - request.addHeader("Accept", ACCEPT_HEADER); - - final CloseableHttpResponse response = httpClient.execute(request); - try { - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - final InputStream content = response.getEntity().getContent(); - verifyInputStream(content); - } finally { - if (response != null) { - response.close(); - } - } - } finally { - if (httpClient != null) { - httpClient.close(); - } - } + Object content = JsonUtils.fromURL(url, httpClient); + checkBasicConditions(content.toString()); } } From a2e6f8aed492fd6fb50ca920b683067a98c76c94 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 24 Aug 2020 17:59:45 +0200 Subject: [PATCH 394/440] Remove unused imports Complements the last commit. --- .../github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index 03479f76..fef53b25 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -12,9 +12,6 @@ import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; From 2ef090b451af16baccd1b51ee792c52a46231c9d Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 24 Aug 2020 18:18:16 +0200 Subject: [PATCH 395/440] Remove ignored test The ignored test would test an expected behaviour of java.net.URL.HttpURLConnection, i.e. not to automatically follow redirects when this involves a protocol switching (e.g. from HTTP to HTTPS). See #289. --- .../core/MinimalSchemaOrgRegressionTest.java | 84 ++++++------------- 1 file changed, 27 insertions(+), 57 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index fef53b25..4e3c6868 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -19,7 +19,6 @@ import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; -import org.junit.Ignore; import org.junit.Test; import com.github.jsonldjava.utils.JarCacheStorage; @@ -27,37 +26,34 @@ public class MinimalSchemaOrgRegressionTest { - private static final String ACCEPT_HEADER = "application/ld+json, application/json;q=0.9, application/javascript;q=0.5, text/javascript;q=0.5, text/plain;q=0.2, */*;q=0.1"; - - @Ignore("Java API does not have any way of redirecting automatically from HTTP to HTTPS, which breaks schema.org usage with it") + /** + * Tests getting JSON from schema.org with the HTTP Accept header set to + * {@value com.github.jsonldjava.utils.JsonUtils#ACCEPT_HEADER}? . + */ @Test - public void testHttpURLConnection() throws Exception { + public void testApacheHttpClient() throws Exception { final URL url = new URL("http://schema.org/"); - final boolean followRedirectsSetting = HttpURLConnection.getFollowRedirects(); - try { - HttpURLConnection.setFollowRedirects(true); - final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); - urlConn.setInstanceFollowRedirects(true); - urlConn.addRequestProperty("Accept", ACCEPT_HEADER); - - final InputStream directStream = urlConn.getInputStream(); - verifyInputStream(directStream); - } finally { - HttpURLConnection.setFollowRedirects(followRedirectsSetting); - } - } - - private void verifyInputStream(InputStream directStream) throws IOException { - assertNotNull("InputStream was null", directStream); - final StringWriter output = new StringWriter(); - try { - IOUtils.copy(directStream, output, StandardCharsets.UTF_8); - } finally { - directStream.close(); - output.flush(); - } - final String outputString = output.toString(); - checkBasicConditions(outputString); + // Common CacheConfig for both the JarCacheStorage and the underlying + // BasicHttpCacheStorage + final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) + .setMaxObjectSize(1024 * 128).build(); + + final CloseableHttpClient httpClient = CachingHttpClientBuilder.create() + // allow caching + .setCacheConfig(cacheConfig) + // Wrap the local JarCacheStorage around a BasicHttpCacheStorage + .setHttpCacheStorage(new JarCacheStorage(null, cacheConfig, + new BasicHttpCacheStorage(cacheConfig))) + // Support compressed data + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 + .addInterceptorFirst(new RequestAcceptEncoding()) + .addInterceptorFirst(new ResponseContentEncoding()) + .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) + // use system defaults for proxy etc. + .useSystemProperties().build(); + + Object content = JsonUtils.fromURL(url, httpClient); + checkBasicConditions(content.toString()); } private void checkBasicConditions(final String outputString) { @@ -68,31 +64,5 @@ private void checkBasicConditions(final String outputString) { outputString.isEmpty()); assertTrue("Unexpected length: " + outputString.length(), outputString.length() > 100000); } - - @Test - public void testApacheHttpClient() throws Exception { - final URL url = new URL("http://schema.org/"); - // Common CacheConfig for both the JarCacheStorage and the underlying - // BasicHttpCacheStorage - final CacheConfig cacheConfig = CacheConfig.custom().setMaxCacheEntries(1000) - .setMaxObjectSize(1024 * 128).build(); - - final CloseableHttpClient httpClient = CachingHttpClientBuilder.create() - // allow caching - .setCacheConfig(cacheConfig) - // Wrap the local JarCacheStorage around a BasicHttpCacheStorage - .setHttpCacheStorage(new JarCacheStorage(null, cacheConfig, - new BasicHttpCacheStorage(cacheConfig))) - // Support compressed data - // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html#d5e1238 - .addInterceptorFirst(new RequestAcceptEncoding()) - .addInterceptorFirst(new ResponseContentEncoding()) - .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) - // use system defaults for proxy etc. - .useSystemProperties().build(); - - Object content = JsonUtils.fromURL(url, httpClient); - checkBasicConditions(content.toString()); - } - + } From a2f3c9f7b15e26b03bc4c3137555eb5b5efd3d07 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 25 Aug 2020 10:50:42 +0200 Subject: [PATCH 396/440] Reorganize imports - remove unused imports - sorted alphabetically --- .../github/jsonldjava/utils/JsonUtils.java | 24 +++++++++---------- .../core/MinimalSchemaOrgRegressionTest.java | 13 +++------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index da210958..9e1ec875 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -10,12 +10,23 @@ import java.io.Writer; import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.net.URL; import java.util.List; import java.util.Map; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.jsonldjava.core.DocumentLoader; +import com.github.jsonldjava.core.JsonLdApi; +import com.github.jsonldjava.core.JsonLdProcessor; + import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; @@ -32,17 +43,6 @@ import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.jsonldjava.core.DocumentLoader; -import com.github.jsonldjava.core.JsonLdApi; -import com.github.jsonldjava.core.JsonLdProcessor; - /** * Functions used to make loading, parsing, and serializing JSON easy using * Jackson. diff --git a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java index 4e3c6868..4694f897 100644 --- a/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/MinimalSchemaOrgRegressionTest.java @@ -1,17 +1,13 @@ package com.github.jsonldjava.core; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.net.HttpURLConnection; import java.net.URL; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; +import com.github.jsonldjava.utils.JarCacheStorage; +import com.github.jsonldjava.utils.JsonUtils; + import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.impl.client.CloseableHttpClient; @@ -21,9 +17,6 @@ import org.apache.http.impl.client.cache.CachingHttpClientBuilder; import org.junit.Test; -import com.github.jsonldjava.utils.JarCacheStorage; -import com.github.jsonldjava.utils.JsonUtils; - public class MinimalSchemaOrgRegressionTest { /** From 776e77dc63612ef294b814e3ad5d25fddf6e8e1e Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 25 Aug 2020 14:37:27 +0200 Subject: [PATCH 397/440] Try-with on response in the submethod As proposed in https://github.com/jsonld-java/jsonld-java/pull/292#discussion_r475983912 --- .../github/jsonldjava/utils/JsonUtils.java | 57 +++++++------------ 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 9e1ec875..7ee7b85d 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -338,50 +338,35 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) final String protocol = url.getProtocol(); // We can only use the Apache HTTPClient for HTTP/HTTPS, so use the // native java client for the others - CloseableHttpResponse response = null; - InputStream in = null; - try { - if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { - // Can't use the HTTP client for those! - // Fallback to Java's built-in JsonLdUrl handler. No need for - // Accept headers as it's likely to be file: or jar: - in = url.openStream(); - } else { - in = getJsonLdViaHttpUri(url, httpClient, response); - } - return fromInputStream(in); - } finally { - try { - if (in != null) { - in.close(); - } - } finally { - if (response != null) { - response.close(); - } - } + if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) { + // Can't use the HTTP client for those! + // Fallback to Java's built-in JsonLdUrl handler. No need for + // Accept headers as it's likely to be file: or jar: + return fromInputStream(url.openStream()); + } else { + return fromInputStream(getJsonLdViaHttpUri(url, httpClient)); } } - private static InputStream getJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient, - CloseableHttpResponse response) throws IOException { + private static InputStream getJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient) + throws IOException { final HttpUriRequest request = new HttpGet(url.toExternalForm()); // We prefer application/ld+json, but fallback to application/json // or whatever is available request.addHeader("Accept", ACCEPT_HEADER); - response = httpClient.execute(request); - - final int status = response.getStatusLine().getStatusCode(); - if (status != 200 && status != 203) { - throw new IOException("Can't retrieve " + url + ", status code: " + status); - } - // follow alternate document location - // https://www.w3.org/TR/json-ld11/#alternate-document-location - URL alternateLink = alternateLink(url, response); - if (alternateLink != null) { - return getJsonLdViaHttpUri(alternateLink, httpClient, response); + try (CloseableHttpResponse response = httpClient.execute(request)) { + final int status = response.getStatusLine().getStatusCode(); + if (status != 200 && status != 203) { + throw new IOException("Can't retrieve " + url + ", status code: " + status); + } + // follow alternate document location + // https://www.w3.org/TR/json-ld11/#alternate-document-location + URL alternateLink = alternateLink(url, response); + if (alternateLink != null) { + return getJsonLdViaHttpUri(alternateLink, httpClient); + } + return response.getEntity().getContent(); } - return response.getEntity().getContent(); } private static URL alternateLink(URL url, CloseableHttpResponse response) From 818b118d23180385ad9ab667c8e1a022984e9fa5 Mon Sep 17 00:00:00 2001 From: Fabian Steeg Date: Thu, 27 Aug 2020 14:24:02 +0200 Subject: [PATCH 398/440] Avoid reading from closed stream --- .../main/java/com/github/jsonldjava/utils/JsonUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 7ee7b85d..89e2d0cb 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -344,11 +344,11 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) // Accept headers as it's likely to be file: or jar: return fromInputStream(url.openStream()); } else { - return fromInputStream(getJsonLdViaHttpUri(url, httpClient)); + return fromJsonLdViaHttpUri(url, httpClient); } } - private static InputStream getJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient) + private static Object fromJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient) throws IOException { final HttpUriRequest request = new HttpGet(url.toExternalForm()); // We prefer application/ld+json, but fallback to application/json @@ -363,9 +363,9 @@ private static InputStream getJsonLdViaHttpUri(final URL url, final CloseableHtt // https://www.w3.org/TR/json-ld11/#alternate-document-location URL alternateLink = alternateLink(url, response); if (alternateLink != null) { - return getJsonLdViaHttpUri(alternateLink, httpClient); + return fromJsonLdViaHttpUri(alternateLink, httpClient); } - return response.getEntity().getContent(); + return fromInputStream(response.getEntity().getContent()); } } From 1d675d7e1e4ccde0545b336d98342439bc73da4e Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 28 Aug 2020 11:44:06 +0200 Subject: [PATCH 399/440] Abort if to many alternate links are followed. This avoids a possible endless loop. See https://github.com/jsonld-java/jsonld-java/pull/292#discussion_r475985782. --- .../com/github/jsonldjava/utils/JsonUtils.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 89e2d0cb..5d4594e7 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -42,6 +42,8 @@ import org.apache.http.impl.client.cache.BasicHttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingHttpClientBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Functions used to make loading, parsing, and serializing JSON easy using @@ -69,6 +71,10 @@ public class JsonUtils { private static final JsonFactory JSON_FACTORY = new JsonFactory(JSON_MAPPER); private static volatile CloseableHttpClient DEFAULT_HTTP_CLIENT; + // Avoid possible endless loop when following alternate locations + private static final int MAX_LINKS_FOLLOW = 20; + private static final Logger log = LoggerFactory.getLogger(JsonUtils.class); + static { // Disable default Jackson behaviour to close @@ -344,11 +350,11 @@ public static Object fromURL(java.net.URL url, CloseableHttpClient httpClient) // Accept headers as it's likely to be file: or jar: return fromInputStream(url.openStream()); } else { - return fromJsonLdViaHttpUri(url, httpClient); + return fromJsonLdViaHttpUri(url, httpClient, 0); } } - private static Object fromJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient) + private static Object fromJsonLdViaHttpUri(final URL url, final CloseableHttpClient httpClient, int linksFollowed) throws IOException { final HttpUriRequest request = new HttpGet(url.toExternalForm()); // We prefer application/ld+json, but fallback to application/json @@ -363,7 +369,13 @@ private static Object fromJsonLdViaHttpUri(final URL url, final CloseableHttpCli // https://www.w3.org/TR/json-ld11/#alternate-document-location URL alternateLink = alternateLink(url, response); if (alternateLink != null) { - return fromJsonLdViaHttpUri(alternateLink, httpClient); + linksFollowed++; + if (linksFollowed > MAX_LINKS_FOLLOW) { + log.warn("Too many alternate links followed. This may indicate a cycle. Aborting."); + return null; + } + return linksFollowed > MAX_LINKS_FOLLOW ? null + : fromJsonLdViaHttpUri(alternateLink, httpClient, linksFollowed); } return fromInputStream(response.getEntity().getContent()); } From 1229f7353bd1f996aa1f0a6e3e6536f16cb4615b Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 28 Aug 2020 11:48:27 +0200 Subject: [PATCH 400/440] Fix missing trim(); simplify value parsing See https://github.com/jsonld-java/jsonld-java/pull/292#discussion_r475986626 and https://github.com/jsonld-java/jsonld-java/pull/292#discussion_r475987519. --- .../main/java/com/github/jsonldjava/utils/JsonUtils.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 5d4594e7..78aebb81 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -391,13 +391,14 @@ private static URL alternateLink(URL url, CloseableHttpResponse response) boolean relAlternate = false; boolean jsonld = false; for (String value : header.getValue().split(";")) { - if (value.trim().startsWith("<")) { - alternateLink = value.replaceAll("<(.*)>", "$1"); + value=value.trim(); + if (value.startsWith("<") && value.endsWith(">")) { + alternateLink = value.substring(1, value.length() - 1); } - if (value.trim().startsWith("type=\"application/ld+json\"")) { + if (value.startsWith("type=\"application/ld+json\"")) { jsonld = true; } - if (value.trim().startsWith("rel=\"alternate\"")) { + if (value.startsWith("rel=\"alternate\"")) { relAlternate = true; } } From faddb48a65b53e7541359ab0a1a6840e125c4239 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 28 Aug 2020 13:49:34 +0200 Subject: [PATCH 401/440] Fix testing if object not null It should be checked if an Entity has a contentType, not if an Entity has content. See https://github.com/jsonld-java/jsonld-java/pull/292#discussion_r475989013 and https://github.com/jsonld-java/jsonld-java/pull/292#discussion_r475989860. --- core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 78aebb81..5fcecb24 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -383,7 +383,7 @@ private static Object fromJsonLdViaHttpUri(final URL url, final CloseableHttpCli private static URL alternateLink(URL url, CloseableHttpResponse response) throws MalformedURLException, IOException { - if (response.getEntity().getContentLength() > 0 + if (response.getEntity().getContentType() != null && !response.getEntity().getContentType().getValue().equals("application/ld+json")) { for (Header header : response.getAllHeaders()) { if (header.getName().equalsIgnoreCase("link")) { From 9100b1355770734b264edf727d9cb77c1d64dd61 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 8 Sep 2020 16:21:50 +0200 Subject: [PATCH 402/440] Throw IOException instead of returning null - remove superfluous check (was always false) - remove superfluous IOException - remove logger as it is no more needed See https://github.com/jsonld-java/jsonld-java/pull/292#commitcomment-42055866. --- .../java/com/github/jsonldjava/utils/JsonUtils.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index 5fcecb24..f66cd5fd 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -73,8 +73,6 @@ public class JsonUtils { private static volatile CloseableHttpClient DEFAULT_HTTP_CLIENT; // Avoid possible endless loop when following alternate locations private static final int MAX_LINKS_FOLLOW = 20; - private static final Logger log = LoggerFactory.getLogger(JsonUtils.class); - static { // Disable default Jackson behaviour to close @@ -371,18 +369,16 @@ private static Object fromJsonLdViaHttpUri(final URL url, final CloseableHttpCli if (alternateLink != null) { linksFollowed++; if (linksFollowed > MAX_LINKS_FOLLOW) { - log.warn("Too many alternate links followed. This may indicate a cycle. Aborting."); - return null; + throw new IOException("Too many alternate links followed. This may indicate a cycle. Aborting."); } - return linksFollowed > MAX_LINKS_FOLLOW ? null - : fromJsonLdViaHttpUri(alternateLink, httpClient, linksFollowed); + return fromJsonLdViaHttpUri(alternateLink, httpClient, linksFollowed); } return fromInputStream(response.getEntity().getContent()); } } private static URL alternateLink(URL url, CloseableHttpResponse response) - throws MalformedURLException, IOException { + throws MalformedURLException { if (response.getEntity().getContentType() != null && !response.getEntity().getContentType().getValue().equals("application/ld+json")) { for (Header header : response.getAllHeaders()) { From d5e27615b27efb2f69c5d41b18df8523a503a514 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 8 Sep 2020 16:55:33 +0200 Subject: [PATCH 403/440] Close InputStream within finally block See https://github.com/jsonld-java/jsonld-java/pull/292#commitcomment-42055925. --- core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java index f66cd5fd..c24c8467 100644 --- a/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java +++ b/core/src/main/java/com/github/jsonldjava/utils/JsonUtils.java @@ -116,6 +116,10 @@ public static Object fromInputStream(InputStream input) throws IOException { } } return fromInputStream(bOMInputStream, charset); + } finally { + if (input != null) { + input.close(); + } } } From 13569221793d6149a9336806a270a2b84084a853 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 9 Sep 2020 15:44:02 +1000 Subject: [PATCH 404/440] Bump dependencies Signed-off-by: Peter Ansell --- pom.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index a1bd056b..286db81c 100755 --- a/pom.xml +++ b/pom.xml @@ -39,11 +39,11 @@ UTF-8 UTF-8 - 4.5.10 - 4.4.12 - 2.10.1 - 4.12 - 1.7.29 + 4.5.12 + 4.4.13 + 2.11.2 + 4.13 + 1.7.30 0.11.0 @@ -192,7 +192,7 @@ commons-codec commons-codec - 1.13 + 1.15 org.mockito @@ -202,14 +202,14 @@ commons-io commons-io - 2.6 + 2.7 com.google.guava guava - 28.1-jre + 29.0-jre @@ -267,7 +267,7 @@ org.codehaus.mojo extra-enforcer-rules - 1.2 + 1.3 From 71006f5ca58554ea2d1d4ccf4f589418fa4f021b Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 9 Sep 2020 15:48:46 +1000 Subject: [PATCH 405/440] Release 0.13.1 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 1461c1e1..eda28511 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.1-SNAPSHOT + 0.13.1 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 286db81c..566a566e 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.1-SNAPSHOT + 0.13.1 JSONLD Java :: Parent Json-LD Java Parent POM pom From 9d000fe0d2b468521596742a694d351dd81c5628 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Wed, 9 Sep 2020 15:53:37 +1000 Subject: [PATCH 406/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index eda28511..bf42b50c 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.1 + 0.13.2-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 566a566e..da267853 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.1 + 0.13.2-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From bed5196bb66d5a6f500ff50885ce5a0fe8f59da7 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 10 Sep 2020 06:16:03 +1000 Subject: [PATCH 407/440] issue #293 : Add com.google.thirdparty to shading Signed-off-by: Peter Ansell --- core/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/pom.xml b/core/pom.xml index bf42b50c..7317d6dc 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -82,6 +82,10 @@ com.google.common com.github.jsonldjava.shaded.com.google.common + + com.google.thirdparty + com.github.jsonldjava.shaded.com.google.thirdparty + From 47a595a8754e7e36e6d15fcdcab639b12868d221 Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Mon, 14 Sep 2020 19:58:11 +0200 Subject: [PATCH 408/440] Returned context IRI after compaction --- .../jsonldjava/core/JsonLdProcessor.java | 5 +++++ .../core/ContextCompactionTest.java | 22 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 00fd3e16..58c01a18 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -2,9 +2,11 @@ import static com.github.jsonldjava.utils.Obj.newMap; +import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -51,6 +53,9 @@ public static Map compact(Object input, Object context, JsonLdOp if (context instanceof Map && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { context = ((Map) context).get(JsonLdConsts.CONTEXT); + if(context instanceof String) { + context = new LinkedList<>(Arrays.asList((String) context)); + } } Context activeCtx = new Context(opts); activeCtx = activeCtx.parse(context); diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index 252621e1..b0ddb6ba 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -1,15 +1,17 @@ package com.github.jsonldjava.core; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; - import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import com.github.jsonldjava.utils.JsonUtils; import org.junit.Test; + public class ContextCompactionTest { // @Ignore("Disable until schema.org is fixed") @@ -49,4 +51,22 @@ public void testCompaction() throws Exception { compacted.get("@context") instanceof List); } + @Test + public void testCompactionUriSingleContext() throws Exception { + final String jsonString = "[{\"@type\": [\"http://schema.org/Person\"] } ]"; + final String ctxStr = "{\"@context\": \"http://schema.org/\"}"; + + final Object json = JsonUtils.fromString(jsonString); + final Object ctx = JsonUtils.fromString(ctxStr); + + final JsonLdOptions options = new JsonLdOptions(); + + final Map compacted = JsonLdProcessor.compact(json, ctx, options); + + // System.out.println("\n\nAfter compact:"); + // System.out.println(JsonUtils.toPrettyString(compacted)); + + assertEquals("Wrong compaction context", "http://schema.org/", compacted.get("@context")); + } + } From b784f3f48e4d3a05055e72ddaa696098e72b2f1e Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Tue, 15 Sep 2020 09:01:13 +0200 Subject: [PATCH 409/440] Returned correct @context during framing --- .../jsonldjava/core/JsonLdProcessor.java | 48 +++++++----- .../core/ContextCompactionTest.java | 4 +- .../jsonldjava/core/ContextFramingTest.java | 77 +++++++++++++++++++ 3 files changed, 109 insertions(+), 20 deletions(-) create mode 100644 core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index 58c01a18..cd4e366b 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -53,9 +53,6 @@ public static Map compact(Object input, Object context, JsonLdOp if (context instanceof Map && ((Map) context).containsKey(JsonLdConsts.CONTEXT)) { context = ((Map) context).get(JsonLdConsts.CONTEXT); - if(context instanceof String) { - context = new LinkedList<>(Arrays.asList((String) context)); - } } Context activeCtx = new Context(opts); activeCtx = activeCtx.parse(context); @@ -75,19 +72,12 @@ public static Map compact(Object input, Object context, JsonLdOp compacted = tmp; } } - if (compacted != null && context != null) { - // TODO: figure out if we can make "@context" appear at the start of - // the keySet - if ((context instanceof Map && !((Map) context).isEmpty()) - || (context instanceof List && !((List) context).isEmpty())) { - - if (context instanceof List && ((List) context).size() == 1 - && opts.getCompactArrays()) { - ((Map) compacted).put(JsonLdConsts.CONTEXT, - ((List) context).get(0)); - } else { - ((Map) compacted).put(JsonLdConsts.CONTEXT, context); - } + if (compacted != null) { + final Object returnedContext = returnedContext(context, opts); + if(returnedContext != null) { + // TODO: figure out if we can make "@context" appear at the start of + // the keySet + ((Map) compacted).put(JsonLdConsts.CONTEXT, returnedContext); } } @@ -324,14 +314,18 @@ public static Map frame(Object input, Object frame, JsonLdOption // to a new empty // context, otherwise. final JsonLdApi api = new JsonLdApi(expandedInput, opts); - final Context activeCtx = api.context - .parse(((Map) frame).get(JsonLdConsts.CONTEXT)); + final Object context = ((Map) frame).get(JsonLdConsts.CONTEXT); + final Context activeCtx = api.context.parse(context); final List framed = api.frame(expandedInput, expandedFrame); if (opts.getPruneBlankNodeIdentifiers()) { JsonLdUtils.pruneBlankNodes(framed); } Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays()); - final Map rval = activeCtx.serialize(); + final Map rval = newMap(); + final Object returnedContext = returnedContext(context, opts); + if(returnedContext != null) { + rval.put(JsonLdConsts.CONTEXT, context); + } final boolean addGraph = ((!(compacted instanceof List)) && !opts.getOmitGraph()); if (addGraph && !(compacted instanceof List)) { final List tmp = new ArrayList(); @@ -348,6 +342,22 @@ public static Map frame(Object input, Object frame, JsonLdOption return rval; } + private static Object returnedContext(Object context, JsonLdOptions opts) { + if (context != null && + ((context instanceof Map && !((Map) context).isEmpty()) + || (context instanceof List && !((List) context).isEmpty()) + || (context instanceof String && !((String) context).isEmpty()))) { + + if (context instanceof List && ((List) context).size() == 1 + && opts.getCompactArrays()) { + return ((List) context).get(0); + } + return context; + } else { + return null; + } + } + /** * A registry for RDF Parsers (in this case, JSONLDSerializers) used by * fromRDF if no specific serializer is specified and options.format is set. diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index b0ddb6ba..e56dcedb 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -52,7 +52,7 @@ public void testCompaction() throws Exception { } @Test - public void testCompactionUriSingleContext() throws Exception { + public void testCompactionSingleRemoteContext() throws Exception { final String jsonString = "[{\"@type\": [\"http://schema.org/Person\"] } ]"; final String ctxStr = "{\"@context\": \"http://schema.org/\"}"; @@ -67,6 +67,8 @@ public void testCompactionUriSingleContext() throws Exception { // System.out.println(JsonUtils.toPrettyString(compacted)); assertEquals("Wrong compaction context", "http://schema.org/", compacted.get("@context")); + assertEquals("Wrong framing type", "Person", compacted.get("type")); + assertEquals("Wrong number of Json entries",2, compacted.size()); } } diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java new file mode 100644 index 00000000..e24b9235 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java @@ -0,0 +1,77 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.github.jsonldjava.utils.JsonUtils; +import org.junit.Test; + +public class ContextFramingTest { + + // @Ignore("Disable until schema.org is fixed") + @Test + public void testFraming() throws Exception { + + final Map contextAbbrevs = new HashMap(); + contextAbbrevs.put("so", "http://schema.org/"); + + final Map json = new HashMap(); + json.put("@context", contextAbbrevs); + json.put("@id", "http://example.org/my_work"); + + final List types = new LinkedList(); + types.add("so:CreativeWork"); + + json.put("@type", types); + json.put("so:name", "My Work"); + json.put("so:url", "http://example.org/my_work"); + + final JsonLdOptions options = new JsonLdOptions(); + options.setBase("http://schema.org/"); + options.setCompactArrays(true); + options.setOmitGraph(true); + + // System.out.println("Before compact"); + // System.out.println(JsonUtils.toPrettyString(json)); + + final String frameStr = "{\"@id\": \"http://schema.org/myid\", \"@context\": \"http://schema.org/\"}"; + final Object frame = JsonUtils.fromString(frameStr); + + final Map compacted = JsonLdProcessor.frame(json, frame, options); + + // System.out.println("\n\nAfter compact:"); + // System.out.println(JsonUtils.toPrettyString(compacted)); + + assertTrue("Framing removed the context", compacted.containsKey("@context")); + assertFalse("Framing of context should be a string, not a list", + compacted.get("@context") instanceof List); + } + + @Test + public void testFramingRemoteContext() throws Exception { + final String jsonString = "{\"@id\": \"http://schema.org/myid\", \"@type\": [\"http://schema.org/Person\"]}"; + final String frameStr = "{\"@id\": \"http://schema.org/myid\", \"@context\": \"http://schema.org/\"}"; + + final Object json = JsonUtils.fromString(jsonString); + final Object frame = JsonUtils.fromString(frameStr); + + final JsonLdOptions options = new JsonLdOptions(); + options.setOmitGraph(true); + + final Map compacted = JsonLdProcessor.frame(json, frame, options); + + // System.out.println("\n\nAfter compact:"); + // System.out.println(JsonUtils.toPrettyString(compacted)); + + assertEquals("Wrong framing context", "http://schema.org/", compacted.get("@context")); + assertEquals("Wrong framing id", "schema:myid", compacted.get("id")); + assertEquals("Wrong framing type", "Person", compacted.get("type")); + assertEquals("Wrong number of Json entries",3, compacted.size()); + } + +} From e953c7cd7e1c254dda952e116545b240afe6a28d Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Tue, 15 Sep 2020 13:55:30 +0200 Subject: [PATCH 410/440] Minor documentation and variable naming changes --- .../jsonldjava/core/JsonLdProcessor.java | 6 ++++ .../jsonldjava/core/ContextFramingTest.java | 32 +++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index cd4e366b..c98106dc 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -342,6 +342,12 @@ public static Map frame(Object input, Object frame, JsonLdOption return rval; } + /** + * Builds the context to be returned in framing and compaction algorithms. + * In cases where the context is empty or from an unexpected type, it returns null. + * When JsonLdOptions compactArrays is set to true and the context contains a List with a single element, + * the element is returned instead of the list + */ private static Object returnedContext(Object context, JsonLdOptions opts) { if (context != null && ((context instanceof Map && !((Map) context).isEmpty()) diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java index e24b9235..a5e2a59f 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java @@ -17,14 +17,14 @@ public class ContextFramingTest { @Test public void testFraming() throws Exception { - final Map contextAbbrevs = new HashMap(); + final Map contextAbbrevs = new HashMap<>(); contextAbbrevs.put("so", "http://schema.org/"); - final Map json = new HashMap(); + final Map json = new HashMap<>(); json.put("@context", contextAbbrevs); json.put("@id", "http://example.org/my_work"); - final List types = new LinkedList(); + final List types = new LinkedList<>(); types.add("so:CreativeWork"); json.put("@type", types); @@ -36,20 +36,20 @@ public void testFraming() throws Exception { options.setCompactArrays(true); options.setOmitGraph(true); - // System.out.println("Before compact"); + // System.out.println("Before framing"); // System.out.println(JsonUtils.toPrettyString(json)); final String frameStr = "{\"@id\": \"http://schema.org/myid\", \"@context\": \"http://schema.org/\"}"; final Object frame = JsonUtils.fromString(frameStr); - final Map compacted = JsonLdProcessor.frame(json, frame, options); + final Map framed = JsonLdProcessor.frame(json, frame, options); - // System.out.println("\n\nAfter compact:"); - // System.out.println(JsonUtils.toPrettyString(compacted)); + // System.out.println("\n\nAfter framing:"); + // System.out.println(JsonUtils.toPrettyString(framed)); - assertTrue("Framing removed the context", compacted.containsKey("@context")); + assertTrue("Framing removed the context", framed.containsKey("@context")); assertFalse("Framing of context should be a string, not a list", - compacted.get("@context") instanceof List); + framed.get("@context") instanceof List); } @Test @@ -63,15 +63,15 @@ public void testFramingRemoteContext() throws Exception { final JsonLdOptions options = new JsonLdOptions(); options.setOmitGraph(true); - final Map compacted = JsonLdProcessor.frame(json, frame, options); + final Map framed = JsonLdProcessor.frame(json, frame, options); - // System.out.println("\n\nAfter compact:"); - // System.out.println(JsonUtils.toPrettyString(compacted)); + // System.out.println("\n\nAfter framing:"); + // System.out.println(JsonUtils.toPrettyString(framed)); - assertEquals("Wrong framing context", "http://schema.org/", compacted.get("@context")); - assertEquals("Wrong framing id", "schema:myid", compacted.get("id")); - assertEquals("Wrong framing type", "Person", compacted.get("type")); - assertEquals("Wrong number of Json entries",3, compacted.size()); + assertEquals("Wrong framing context", "http://schema.org/", framed.get("@context")); + assertEquals("Wrong framing id", "schema:myid", framed.get("id")); + assertEquals("Wrong framing type", "Person", framed.get("type")); + assertEquals("Wrong number of Json entries",3, framed.size()); } } From 99f8ae08b7f0b57043c9c32422f3b019760f7b39 Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Tue, 15 Sep 2020 14:38:27 +0200 Subject: [PATCH 411/440] Fixed flattening returned @context --- .../com/github/jsonldjava/core/Context.java | 57 +------------- .../jsonldjava/core/JsonLdProcessor.java | 8 +- .../core/ContextCompactionTest.java | 4 +- .../core/ContextFlatteningTest.java | 78 +++++++++++++++++++ .../jsonldjava/core/ContextFramingTest.java | 6 +- 5 files changed, 90 insertions(+), 63 deletions(-) create mode 100644 core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 8c149b08..84f5a2c8 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -304,9 +304,7 @@ public Context parse(Object localContext) throws JsonLdError { * * http://json-ld.org/spec/latest/json-ld-api/#create-term-definition * - * @param result * @param context - * @param key * @param defined * @throws JsonLdError */ @@ -572,7 +570,7 @@ else if (relative) { * the IRI to compact. * @param value * the value to check or null. - * @param relativeTo + * @param relativeToVocab * options for how to compact IRIs: vocab: true to split * after @vocab, false not to. * @param reverse @@ -1146,57 +1144,4 @@ else if (this.get(JsonLdConsts.LANGUAGE) != null) { } return rval; } - - public Map serialize() { - final Map ctx = newMap(); - if (this.get(JsonLdConsts.BASE) != null - && !this.get(JsonLdConsts.BASE).equals(options.getBase())) { - ctx.put(JsonLdConsts.BASE, this.get(JsonLdConsts.BASE)); - } - if (this.get(JsonLdConsts.LANGUAGE) != null) { - ctx.put(JsonLdConsts.LANGUAGE, this.get(JsonLdConsts.LANGUAGE)); - } - if (this.get(JsonLdConsts.VOCAB) != null) { - ctx.put(JsonLdConsts.VOCAB, this.get(JsonLdConsts.VOCAB)); - } - for (final String term : termDefinitions.keySet()) { - final Map definition = (Map) termDefinitions.get(term); - if (definition.get(JsonLdConsts.LANGUAGE) == null - && definition.get(JsonLdConsts.CONTAINER) == null - && definition.get(JsonLdConsts.TYPE) == null - && (definition.get(JsonLdConsts.REVERSE) == null - || Boolean.FALSE.equals(definition.get(JsonLdConsts.REVERSE)))) { - final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); - ctx.put(term, term.equals(cid) ? definition.get(JsonLdConsts.ID) : cid); - } else { - final Map defn = newMap(); - final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); - final Boolean reverseProperty = Boolean.TRUE - .equals(definition.get(JsonLdConsts.REVERSE)); - if (!(term.equals(cid) && !reverseProperty)) { - defn.put(reverseProperty ? JsonLdConsts.REVERSE : JsonLdConsts.ID, cid); - } - final String typeMapping = (String) definition.get(JsonLdConsts.TYPE); - if (typeMapping != null) { - defn.put(JsonLdConsts.TYPE, JsonLdUtils.isKeyword(typeMapping) ? typeMapping - : compactIri(typeMapping, true)); - } - if (definition.get(JsonLdConsts.CONTAINER) != null) { - defn.put(JsonLdConsts.CONTAINER, definition.get(JsonLdConsts.CONTAINER)); - } - final Object lang = definition.get(JsonLdConsts.LANGUAGE); - if (definition.get(JsonLdConsts.LANGUAGE) != null) { - defn.put(JsonLdConsts.LANGUAGE, Boolean.FALSE.equals(lang) ? null : lang); - } - ctx.put(term, defn); - } - } - - final Map rval = newMap(); - if (!(ctx == null || ctx.isEmpty())) { - rval.put(JsonLdConsts.CONTEXT, ctx); - } - return rval; - } - } diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index c98106dc..aa963199 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -245,7 +245,11 @@ public static Object flatten(Object input, Object context, JsonLdOptions opts) compacted = tmp; } final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH); - final Map rval = activeCtx.serialize(); + final Map rval = newMap(); + final Object returnedContext = returnedContext(context, opts); + if(returnedContext != null) { + rval.put(JsonLdConsts.CONTEXT, returnedContext); + } rval.put(alias, compacted); return rval; } @@ -343,7 +347,7 @@ public static Map frame(Object input, Object frame, JsonLdOption } /** - * Builds the context to be returned in framing and compaction algorithms. + * Builds the context to be returned in framing, flattening and compaction algorithms. * In cases where the context is empty or from an unexpected type, it returns null. * When JsonLdOptions compactArrays is set to true and the context contains a List with a single element, * the element is returned instead of the list diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index e56dcedb..120dbae0 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -66,8 +66,8 @@ public void testCompactionSingleRemoteContext() throws Exception { // System.out.println("\n\nAfter compact:"); // System.out.println(JsonUtils.toPrettyString(compacted)); - assertEquals("Wrong compaction context", "http://schema.org/", compacted.get("@context")); - assertEquals("Wrong framing type", "Person", compacted.get("type")); + assertEquals("Wrong returned context", "http://schema.org/", compacted.get("@context")); + assertEquals("Wrong type", "Person", compacted.get("type")); assertEquals("Wrong number of Json entries",2, compacted.size()); } diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java new file mode 100644 index 00000000..3dd49f90 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java @@ -0,0 +1,78 @@ +package com.github.jsonldjava.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.github.jsonldjava.utils.JsonUtils; +import org.junit.Test; + +public class ContextFlatteningTest { + + @Test + public void testFlatenning() throws Exception { + + final Map contextAbbrevs = new HashMap<>(); + contextAbbrevs.put("so", "http://schema.org/"); + + final Map json = new HashMap<>(); + json.put("@context", contextAbbrevs); + json.put("@id", "http://example.org/my_work"); + + final List types = new LinkedList<>(); + types.add("so:CreativeWork"); + + json.put("@type", types); + json.put("so:name", "My Work"); + json.put("so:url", "http://example.org/my_work"); + + final JsonLdOptions options = new JsonLdOptions(); + options.setBase("http://schema.org/"); + options.setCompactArrays(true); + options.setOmitGraph(true); + + // System.out.println("Before flattening"); + // System.out.println(JsonUtils.toPrettyString(json)); + + final String flattenStr = "{\"@id\": \"http://schema.org/myid\", \"@context\": \"http://schema.org/\"}"; + final Object flatten = JsonUtils.fromString(flattenStr); + + final Map flattened = ((Map)JsonLdProcessor.flatten(json, flatten, options)); + + // System.out.println("\n\nAfter flattening:"); + // System.out.println(JsonUtils.toPrettyString(flattened)); + + assertTrue("Flattening removed the context", flattened.containsKey("@context")); + assertFalse("Flattening of context should be a string, not a list", + flattened.get("@context") instanceof List); + } + + @Test + public void testFlatteningRemoteContext() throws Exception { + final String jsonString = + "{\"@context\": {\"@vocab\": \"http://schema.org/\"}, \"knows\": [{\"name\": \"a\"}, {\"name\": \"b\"}] }"; + final String flattenStr = "{\"@context\": \"http://schema.org/\"}"; + + final Object json = JsonUtils.fromString(jsonString); + final Object flatten = JsonUtils.fromString(flattenStr); + + // System.out.println("Before flattening"); + // System.out.println(JsonUtils.toPrettyString(json)); + + final JsonLdOptions options = new JsonLdOptions(); + options.setOmitGraph(true); + + final Map flattened = ((Map)JsonLdProcessor.flatten(json, flatten, options)); + + // System.out.println("\n\nAfter flattened:"); + // System.out.println(JsonUtils.toPrettyString(flattened)); + + assertEquals("Wrong returned context", "http://schema.org/", flattened.get("@context")); + assertEquals("Wrong number of Json entries",2, flattened.size()); + } + +} diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java index a5e2a59f..3c8126a0 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java @@ -68,9 +68,9 @@ public void testFramingRemoteContext() throws Exception { // System.out.println("\n\nAfter framing:"); // System.out.println(JsonUtils.toPrettyString(framed)); - assertEquals("Wrong framing context", "http://schema.org/", framed.get("@context")); - assertEquals("Wrong framing id", "schema:myid", framed.get("id")); - assertEquals("Wrong framing type", "Person", framed.get("type")); + assertEquals("Wrong returned context", "http://schema.org/", framed.get("@context")); + assertEquals("Wrong id", "schema:myid", framed.get("id")); + assertEquals("Wrong type", "Person", framed.get("type")); assertEquals("Wrong number of Json entries",3, framed.size()); } From 7c0cbaf0893fdc5eef5e55fa0265196201eeba78 Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Tue, 22 Sep 2020 19:32:29 +0200 Subject: [PATCH 412/440] Addressed feedback --- .../com/github/jsonldjava/core/JsonLdProcessor.java | 4 +--- .../jsonldjava/core/ContextCompactionTest.java | 12 +----------- .../jsonldjava/core/ContextFlatteningTest.java | 12 ------------ .../github/jsonldjava/core/ContextFramingTest.java | 10 ---------- 4 files changed, 2 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java index aa963199..fedff3d2 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java @@ -2,11 +2,9 @@ import static com.github.jsonldjava.utils.Obj.newMap; -import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -328,7 +326,7 @@ public static Map frame(Object input, Object frame, JsonLdOption final Map rval = newMap(); final Object returnedContext = returnedContext(context, opts); if(returnedContext != null) { - rval.put(JsonLdConsts.CONTEXT, context); + rval.put(JsonLdConsts.CONTEXT, returnedContext); } final boolean addGraph = ((!(compacted instanceof List)) && !opts.getOmitGraph()); if (addGraph && !(compacted instanceof List)) { diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java index 120dbae0..31bfc3ef 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextCompactionTest.java @@ -14,9 +14,8 @@ public class ContextCompactionTest { - // @Ignore("Disable until schema.org is fixed") @Test - public void testCompaction() throws Exception { + public void testCompaction() { final Map contextAbbrevs = new HashMap(); contextAbbrevs.put("so", "http://schema.org/"); @@ -36,16 +35,10 @@ public void testCompaction() throws Exception { options.setBase("http://schema.org/"); options.setCompactArrays(true); - // System.out.println("Before compact"); - // System.out.println(JsonUtils.toPrettyString(json)); - final List newContexts = new LinkedList(); newContexts.add("http://schema.org/"); final Map compacted = JsonLdProcessor.compact(json, newContexts, options); - // System.out.println("\n\nAfter compact:"); - // System.out.println(JsonUtils.toPrettyString(compacted)); - assertTrue("Compaction removed the context", compacted.containsKey("@context")); assertFalse("Compaction of context should be a string, not a list", compacted.get("@context") instanceof List); @@ -63,9 +56,6 @@ public void testCompactionSingleRemoteContext() throws Exception { final Map compacted = JsonLdProcessor.compact(json, ctx, options); - // System.out.println("\n\nAfter compact:"); - // System.out.println(JsonUtils.toPrettyString(compacted)); - assertEquals("Wrong returned context", "http://schema.org/", compacted.get("@context")); assertEquals("Wrong type", "Person", compacted.get("type")); assertEquals("Wrong number of Json entries",2, compacted.size()); diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java index 3dd49f90..8e3a1710 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextFlatteningTest.java @@ -35,17 +35,11 @@ public void testFlatenning() throws Exception { options.setCompactArrays(true); options.setOmitGraph(true); - // System.out.println("Before flattening"); - // System.out.println(JsonUtils.toPrettyString(json)); - final String flattenStr = "{\"@id\": \"http://schema.org/myid\", \"@context\": \"http://schema.org/\"}"; final Object flatten = JsonUtils.fromString(flattenStr); final Map flattened = ((Map)JsonLdProcessor.flatten(json, flatten, options)); - // System.out.println("\n\nAfter flattening:"); - // System.out.println(JsonUtils.toPrettyString(flattened)); - assertTrue("Flattening removed the context", flattened.containsKey("@context")); assertFalse("Flattening of context should be a string, not a list", flattened.get("@context") instanceof List); @@ -60,17 +54,11 @@ public void testFlatteningRemoteContext() throws Exception { final Object json = JsonUtils.fromString(jsonString); final Object flatten = JsonUtils.fromString(flattenStr); - // System.out.println("Before flattening"); - // System.out.println(JsonUtils.toPrettyString(json)); - final JsonLdOptions options = new JsonLdOptions(); options.setOmitGraph(true); final Map flattened = ((Map)JsonLdProcessor.flatten(json, flatten, options)); - // System.out.println("\n\nAfter flattened:"); - // System.out.println(JsonUtils.toPrettyString(flattened)); - assertEquals("Wrong returned context", "http://schema.org/", flattened.get("@context")); assertEquals("Wrong number of Json entries",2, flattened.size()); } diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java index 3c8126a0..73116205 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextFramingTest.java @@ -13,7 +13,6 @@ public class ContextFramingTest { - // @Ignore("Disable until schema.org is fixed") @Test public void testFraming() throws Exception { @@ -36,17 +35,11 @@ public void testFraming() throws Exception { options.setCompactArrays(true); options.setOmitGraph(true); - // System.out.println("Before framing"); - // System.out.println(JsonUtils.toPrettyString(json)); - final String frameStr = "{\"@id\": \"http://schema.org/myid\", \"@context\": \"http://schema.org/\"}"; final Object frame = JsonUtils.fromString(frameStr); final Map framed = JsonLdProcessor.frame(json, frame, options); - // System.out.println("\n\nAfter framing:"); - // System.out.println(JsonUtils.toPrettyString(framed)); - assertTrue("Framing removed the context", framed.containsKey("@context")); assertFalse("Framing of context should be a string, not a list", framed.get("@context") instanceof List); @@ -65,9 +58,6 @@ public void testFramingRemoteContext() throws Exception { final Map framed = JsonLdProcessor.frame(json, frame, options); - // System.out.println("\n\nAfter framing:"); - // System.out.println(JsonUtils.toPrettyString(framed)); - assertEquals("Wrong returned context", "http://schema.org/", framed.get("@context")); assertEquals("Wrong id", "schema:myid", framed.get("id")); assertEquals("Wrong type", "Person", framed.get("type")); From 4894387d983dd0e8a68bc8de1e05542b5d0194f9 Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Wed, 23 Sep 2020 19:00:48 +0200 Subject: [PATCH 413/440] Added back Context.serialize() with @Deprecated annotation --- .../com/github/jsonldjava/core/Context.java | 54 +++++++++++++++++++ .../core/ContextSerializationTest.java | 24 +++++++++ .../resources/custom/contexttest-0005.jsonld | 12 +++++ 3 files changed, 90 insertions(+) create mode 100644 core/src/test/java/com/github/jsonldjava/core/ContextSerializationTest.java create mode 100644 core/src/test/resources/custom/contexttest-0005.jsonld diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 84f5a2c8..bff79d8c 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -1144,4 +1144,58 @@ else if (this.get(JsonLdConsts.LANGUAGE) != null) { } return rval; } + + @Deprecated + public Map serialize() { + final Map ctx = newMap(); + if (this.get(JsonLdConsts.BASE) != null + && !this.get(JsonLdConsts.BASE).equals(options.getBase())) { + ctx.put(JsonLdConsts.BASE, this.get(JsonLdConsts.BASE)); + } + if (this.get(JsonLdConsts.LANGUAGE) != null) { + ctx.put(JsonLdConsts.LANGUAGE, this.get(JsonLdConsts.LANGUAGE)); + } + if (this.get(JsonLdConsts.VOCAB) != null) { + ctx.put(JsonLdConsts.VOCAB, this.get(JsonLdConsts.VOCAB)); + } + for (final String term : termDefinitions.keySet()) { + final Map definition = (Map) termDefinitions.get(term); + if (definition.get(JsonLdConsts.LANGUAGE) == null + && definition.get(JsonLdConsts.CONTAINER) == null + && definition.get(JsonLdConsts.TYPE) == null + && (definition.get(JsonLdConsts.REVERSE) == null + || Boolean.FALSE.equals(definition.get(JsonLdConsts.REVERSE)))) { + final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); + ctx.put(term, term.equals(cid) ? definition.get(JsonLdConsts.ID) : cid); + } else { + final Map defn = newMap(); + final String cid = this.compactIri((String) definition.get(JsonLdConsts.ID)); + final Boolean reverseProperty = Boolean.TRUE + .equals(definition.get(JsonLdConsts.REVERSE)); + if (!(term.equals(cid) && !reverseProperty)) { + defn.put(reverseProperty ? JsonLdConsts.REVERSE : JsonLdConsts.ID, cid); + } + final String typeMapping = (String) definition.get(JsonLdConsts.TYPE); + if (typeMapping != null) { + defn.put(JsonLdConsts.TYPE, JsonLdUtils.isKeyword(typeMapping) ? typeMapping + : compactIri(typeMapping, true)); + } + if (definition.get(JsonLdConsts.CONTAINER) != null) { + defn.put(JsonLdConsts.CONTAINER, definition.get(JsonLdConsts.CONTAINER)); + } + final Object lang = definition.get(JsonLdConsts.LANGUAGE); + if (definition.get(JsonLdConsts.LANGUAGE) != null) { + defn.put(JsonLdConsts.LANGUAGE, Boolean.FALSE.equals(lang) ? null : lang); + } + ctx.put(term, defn); + } + } + + final Map rval = newMap(); + if (!(ctx == null || ctx.isEmpty())) { + rval.put(JsonLdConsts.CONTEXT, ctx); + } + return rval; + } + } diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextSerializationTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextSerializationTest.java new file mode 100644 index 00000000..7077f228 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/ContextSerializationTest.java @@ -0,0 +1,24 @@ +package com.github.jsonldjava.core; + +import com.github.jsonldjava.utils.JsonUtils; +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class ContextSerializationTest { + + @Test + // Added in order to have some coverage on the serialize method since is not used anywhere. + public void serializeTest() throws IOException { + final Map json = (Map)JsonUtils + .fromInputStream(getClass().getResourceAsStream("/custom/contexttest-0005.jsonld")); + + final Map contextValue = (Map)json.get(JsonLdConsts.CONTEXT); + final Map serializedContext = new Context().parse(contextValue).serialize(); + + assertEquals("Wrong serialized context", json, serializedContext); + } +} diff --git a/core/src/test/resources/custom/contexttest-0005.jsonld b/core/src/test/resources/custom/contexttest-0005.jsonld new file mode 100644 index 00000000..f4baa06e --- /dev/null +++ b/core/src/test/resources/custom/contexttest-0005.jsonld @@ -0,0 +1,12 @@ +{ + "@context": { + "@base": "http://ex.com/base/", + "@vocab": "http://ex.com/vocab/", + "xsd": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "integer": { + "@id": "http://example.com/vocab/integer", + "@type": "xsd:integer" + }, + "@language": "en" + } +} \ No newline at end of file From e10d6b09f687b0e45417a6c6c852cf10942d3850 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Sep 2020 06:45:26 +1000 Subject: [PATCH 414/440] Prepare for release Signed-off-by: Peter Ansell --- README.md | 19 ++++++++++++++++--- pom.xml | 3 ++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2270d45c..d1f5a5cc 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.13.0 + 0.13.2 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.13.0 + 0.13.2 4.0.0 jsonld-java-{your module} - 0.13.0-SNAPSHOT + 0.13.2-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -450,6 +450,19 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2020-09-24 +* Release 0.13.2 +* Fix Guava dependency shading (Reported by @ggrasso) +* Fix @context issues when using a remote context (Patch by @umbreak) +* Deprecate Context.serialize (Patch by @umbreak) + +### 2020-09-09 +* Release 0.13.1 +* Fix java.net.URI resolution (Reported by @ebremer and @afs, Patch by @dr0i) +* Shade Guava failureaccess module (Patch by @peacekeeper) +* Don't minimize Guava class shading (Patch by @elahrvivaz) +* Follow link headers to @context files (Patch by @dr0i and @fsteeg) + ### 2019-11-28 * Release 0.13.0 * Bump Jackson versions to latest for security updates (Patch by @afs) diff --git a/pom.xml b/pom.xml index da267853..d38511c0 100755 --- a/pom.xml +++ b/pom.xml @@ -198,11 +198,12 @@ org.mockito mockito-core 2.28.2 + test commons-io commons-io - 2.7 + 2.8.0 From 69aee572c2b8c7e9bed6ab32869cc36ce17d89d7 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Sep 2020 06:50:25 +1000 Subject: [PATCH 415/440] Release 0.13.2 Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 7317d6dc..ffbfb30a 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.2-SNAPSHOT + 0.13.2 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index d38511c0..6860f6d5 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.2-SNAPSHOT + 0.13.2 JSONLD Java :: Parent Json-LD Java Parent POM pom From 6c1bf5d3daf19595ba506ef6c00dd575351f61b3 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Thu, 24 Sep 2020 06:56:30 +1000 Subject: [PATCH 416/440] Bump to next development version Signed-off-by: Peter Ansell --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index ffbfb30a..b771cbee 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.2 + 0.13.3-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 6860f6d5..5bddbf03 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.2 + 0.13.3-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 257738f850941f8abf81048b415edd01468e74d0 Mon Sep 17 00:00:00 2001 From: kishorkunal-raj Date: Fri, 6 Nov 2020 07:13:08 +0000 Subject: [PATCH 417/440] Adding ppc64le architecture support on travis-ci --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 29a226e2..df26cdc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,3 +6,6 @@ notifications: email: false after_success: - mvn clean test jacoco:report coveralls:report +arch: + - amd64 + - ppc64le From a9b22ee90e100606c238c513423ef6e3d9fc5956 Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Sat, 12 Dec 2020 14:53:41 +0100 Subject: [PATCH 418/440] Throw RECURSIVE_CONTEXT_INCLUSION only when cyclic dependency exists --- .../com/github/jsonldjava/core/Context.java | 13 ++-- .../jsonldjava/core/ContextRecursionTest.java | 75 +++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index bff79d8c..dafc43ce 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -143,6 +143,9 @@ && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) */ @SuppressWarnings("unchecked") public Context parse(Object localContext, List remoteContexts) throws JsonLdError { + if (remoteContexts == null) { + remoteContexts = new ArrayList(); + } return parse(localContext, remoteContexts, false); } @@ -163,11 +166,8 @@ public Context parse(Object localContext, List remoteContexts) throws Js * @throws JsonLdError * If there is an error parsing the contexts. */ - private Context parse(Object localContext, List remoteContexts, + private Context parse(Object localContext, final List remoteContexts, boolean parsingARemoteContext) throws JsonLdError { - if (remoteContexts == null) { - remoteContexts = new ArrayList(); - } // 1. Initialize result to the result of cloning active context. Context result = this.clone(); // TODO: clone? // 2) @@ -193,7 +193,8 @@ else if (context instanceof String) { if (remoteContexts.contains(uri)) { throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, uri); } - remoteContexts.add(uri); + List nextRemoteContexts = new ArrayList<>(remoteContexts); + nextRemoteContexts.add(uri); // 3.2.3: Dereference context final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri); @@ -208,7 +209,7 @@ else if (context instanceof String) { .get(JsonLdConsts.CONTEXT); // 3.2.4 - result = result.parse(tempContext, remoteContexts, true); + result = result.parse(tempContext, nextRemoteContexts, true); // 3.2.5 continue; } else if (!(context instanceof Map)) { diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java new file mode 100644 index 00000000..4e92bd36 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java @@ -0,0 +1,75 @@ +package com.github.jsonldjava.core; + +import com.github.jsonldjava.utils.JsonUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + + +public class ContextRecursionTest { + + @BeforeClass + public static void setup() { + System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true"); + } + + @AfterClass + public static void tearDown() { + System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "false"); + } + + @Test + public void testAllowedRecursion() throws IOException { + + final String contextB = "{\"@context\": [\"http://localhost/d\", {\"b\": \"http://localhost/b\"} ] }"; + final String contextC = "{\"@context\": [\"http://localhost/d\", {\"c\": \"http://localhost/c\"} ] }"; + final String contextD = "{\"@context\": [\"http://localhost/e\", {\"d\": \"http://localhost/d\"} ] }"; + final String contextE = "{\"@context\": {\"e\": \"http://localhost/e\"} }"; + + final DocumentLoader dl = new DocumentLoader(); + dl.addInjectedDoc("http://localhost/b", contextB); + dl.addInjectedDoc("http://localhost/c", contextC); + dl.addInjectedDoc("http://localhost/d", contextD); + dl.addInjectedDoc("http://localhost/e", contextE); + final JsonLdOptions options = new JsonLdOptions(); + options.setDocumentLoader(dl); + + final String jsonString = "{\"@context\": [\"http://localhost/d\", \"http://localhost/b\", \"http://localhost/c\", {\"a\": \"http://localhost/a\"} ], \"a\": \"A\", \"b\": \"B\", \"c\": \"C\", \"d\": \"D\"}"; + final Object json = JsonUtils.fromString(jsonString); + final Object expanded = JsonLdProcessor.expand(json, options); + assertEquals( + "[{http://localhost/a=[{@value=A}], http://localhost/b=[{@value=B}], http://localhost/c=[{@value=C}], http://localhost/d=[{@value=D}]}]", + expanded.toString()); + } + + @Test + public void testCyclicRecursion() throws IOException { + + final String contextC = "{\"@context\": [\"http://localhost/d\", {\"c\": \"http://localhost/c\"} ] }"; + final String contextD = "{\"@context\": [\"http://localhost/e\", {\"d\": \"http://localhost/d\"} ] }"; + final String contextE = "{\"@context\": [\"http://localhost/c\", {\"e\": \"http://localhost/e\"} ] }"; + + final DocumentLoader dl = new DocumentLoader(); + dl.addInjectedDoc("http://localhost/c", contextC); + dl.addInjectedDoc("http://localhost/d", contextD); + dl.addInjectedDoc("http://localhost/e", contextE); + final JsonLdOptions options = new JsonLdOptions(); + options.setDocumentLoader(dl); + + final String jsonString = "{\"@context\": [\"http://localhost/c\", {\"a\": \"http://localhost/a\"} ]}"; + final Object json = JsonUtils.fromString(jsonString); + try { + JsonLdProcessor.expand(json, options); + fail("it should throw"); + } catch(JsonLdError err) { + assertEquals(err.getType(), JsonLdError.Error.RECURSIVE_CONTEXT_INCLUSION); + assertEquals(err.getMessage(), "recursive context inclusion: http://localhost/c"); + } + } + +} From 45c29428328abb78b7468d8d339b50a9044c9fcd Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 26 Jan 2021 14:26:20 +0100 Subject: [PATCH 419/440] Ignore @base if remote context is not relative If the remote context is not relative and seems to be a http URI don't prefix the base IRI to it. The remote context is not validated nor tested if it's resolvable. It's just tested if it's not a relative URI - which is totally possible and would, in conjunction with a base IRI, made into valid remote context. See #304. --- .../java/com/github/jsonldjava/core/Context.java | 6 +++++- .../github/jsonldjava/core/DocumentLoaderTest.java | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index bff79d8c..a5277259 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -187,7 +187,11 @@ private Context parse(Object localContext, List remoteContexts, } // 3.2) else if (context instanceof String) { - String uri = (String) result.get(JsonLdConsts.BASE); + String uri = null; + // @base is ignored when processing remote contexts, https://github.com/jsonld-java/jsonld-java/issues/304 + if (!context.toString().matches("^[hH][tT][tT][pP][sS]?://.*")) { + uri = (String) result.get(JsonLdConsts.BASE); + } uri = JsonLdUrl.resolve(uri, (String) context); // 3.2.2 if (remoteContexts.contains(uri)) { diff --git a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java index c16d40b5..57b8f5ce 100644 --- a/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/DocumentLoaderTest.java @@ -381,11 +381,19 @@ public void testDisallowRemoteContexts() throws Exception { } @Test - public void injectContext() throws Exception { + public void testInjectContext() throws Exception { + injectContext(new JsonLdOptions()); + } + + @Test + public void testIssue304_remoteContextAndBaseIri() throws Exception { + injectContext(new JsonLdOptions("testing:baseIri")); + } + + private void injectContext(final JsonLdOptions options) throws Exception { final Object jsonObject = JsonUtils.fromString( "{ \"@context\":\"http://nonexisting.example.com/thing\", \"pony\":5 }"); - final JsonLdOptions options = new JsonLdOptions(); // Verify fails to find context by default try { From b6edd7b3d8b842aeeb6ad2a19fcf6a6c7e0a5d9b Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 26 Jan 2021 17:53:51 +0100 Subject: [PATCH 420/440] Fix order of assertEquals parameters - rename one test to point to the issue Complements a9b22ee90e100606c238c513423ef6e3d9fc5956. --- .../com/github/jsonldjava/core/ContextRecursionTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java b/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java index 4e92bd36..d6610121 100644 --- a/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/ContextRecursionTest.java @@ -24,7 +24,7 @@ public static void tearDown() { } @Test - public void testAllowedRecursion() throws IOException { + public void testIssue302_allowedRecursion() throws IOException { final String contextB = "{\"@context\": [\"http://localhost/d\", {\"b\": \"http://localhost/b\"} ] }"; final String contextC = "{\"@context\": [\"http://localhost/d\", {\"c\": \"http://localhost/c\"} ] }"; @@ -67,8 +67,8 @@ public void testCyclicRecursion() throws IOException { JsonLdProcessor.expand(json, options); fail("it should throw"); } catch(JsonLdError err) { - assertEquals(err.getType(), JsonLdError.Error.RECURSIVE_CONTEXT_INCLUSION); - assertEquals(err.getMessage(), "recursive context inclusion: http://localhost/c"); + assertEquals(JsonLdError.Error.RECURSIVE_CONTEXT_INCLUSION, err.getType()); + assertEquals("recursive context inclusion: http://localhost/c", err.getMessage()); } } From 9af0572b88a85fcfe5c8f35679d80d640c93e1eb Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Thu, 28 Jan 2021 16:07:09 +0100 Subject: [PATCH 421/440] Use precompiled pattern As proposed by @umbreak in #305. Complements 45c29428328abb78b7468d8d339b50a9044c9fcd. --- core/src/main/java/com/github/jsonldjava/core/Context.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index a5277259..069aaf2f 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -9,6 +9,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import com.github.jsonldjava.core.JsonLdError.Error; import com.github.jsonldjava.utils.JsonLdUrl; @@ -25,6 +26,7 @@ public class Context extends LinkedHashMap { private static final long serialVersionUID = 2894534897574805571L; + private static final Pattern URL_PATTERN = Pattern.compile("^https?://.*$", Pattern.CASE_INSENSITIVE); private JsonLdOptions options; private Map termDefinitions; public Map inverse = null; @@ -189,7 +191,7 @@ private Context parse(Object localContext, List remoteContexts, else if (context instanceof String) { String uri = null; // @base is ignored when processing remote contexts, https://github.com/jsonld-java/jsonld-java/issues/304 - if (!context.toString().matches("^[hH][tT][tT][pP][sS]?://.*")) { + if (!URL_PATTERN.matcher(context.toString()).matches()) { uri = (String) result.get(JsonLdConsts.BASE); } uri = JsonLdUrl.resolve(uri, (String) context); From 0ebe491206fc4165a21a551288f8bd8857118e0e Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Thu, 28 Jan 2021 16:11:48 +0100 Subject: [PATCH 422/440] Remove superflous @SuppressWarnings --- core/src/main/java/com/github/jsonldjava/core/Context.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/com/github/jsonldjava/core/Context.java b/core/src/main/java/com/github/jsonldjava/core/Context.java index 069aaf2f..0fad5e63 100644 --- a/core/src/main/java/com/github/jsonldjava/core/Context.java +++ b/core/src/main/java/com/github/jsonldjava/core/Context.java @@ -143,7 +143,6 @@ && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE) * @throws JsonLdError * If there is an error parsing the contexts. */ - @SuppressWarnings("unchecked") public Context parse(Object localContext, List remoteContexts) throws JsonLdError { return parse(localContext, remoteContexts, false); } From 95cbd49e901760e608247292417973cdb7060d76 Mon Sep 17 00:00:00 2001 From: Didac Montero Date: Mon, 1 Feb 2021 11:50:14 +0100 Subject: [PATCH 423/440] rdfToJson edge case when object = subject and predicate = rdf:type --- .../com/github/jsonldjava/core/JsonLdApi.java | 3 +- .../jsonldjava/core/JsonLdToRdfTest.java | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 74cea926..2195d09a 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -2001,7 +2001,8 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData // 3.5.4) if (RDF_TYPE.equals(predicate) && (object.isIRI() || object.isBlankNode()) - && !opts.getUseRdfType() && !nodes.containsKey(object.getValue())) { + && !opts.getUseRdfType() && + (!nodes.containsKey(object.getValue()) || subject.equals(object.getValue()))) { JsonLdUtils.mergeValue(node, JsonLdConsts.TYPE, object.getValue()); continue; } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java new file mode 100644 index 00000000..7586c1c6 --- /dev/null +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java @@ -0,0 +1,31 @@ +package com.github.jsonldjava.core; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JsonLdToRdfTest { + + @Test + public void testIssue301() throws JsonLdError { + final RDFDataset rdf = new RDFDataset(); + rdf.addTriple( + "http://www.w3.org/2002/07/owl#Class", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + "http://www.w3.org/2002/07/owl#Class"); + final JsonLdOptions opts = new JsonLdOptions(); + opts.setUseRdfType(Boolean.FALSE); + opts.setProcessingMode(JsonLdOptions.JSON_LD_1_0); + + final Object out = new JsonLdApi(opts).fromRDF(rdf, true); + assertEquals("[{@id=http://www.w3.org/2002/07/owl#Class, @type=[http://www.w3.org/2002/07/owl#Class]}]", + out.toString()); + + opts.setUseRdfType(Boolean.TRUE); + + final Object out2 = new JsonLdApi(opts).fromRDF(rdf, true); + assertEquals("[{@id=http://www.w3.org/2002/07/owl#Class, http://www.w3.org/1999/02/22-rdf-syntax-ns#type=[{@id=http://www.w3.org/2002/07/owl#Class}]}]", + out2.toString()); + } + +} From b2a8ac68ae85b5f304ce930d161e8d686780996c Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Sat, 6 Mar 2021 16:23:37 +0100 Subject: [PATCH 424/440] Prepare for release Signed-off-by: Pascal Christoph --- README.md | 11 ++++++++--- pom.xml | 14 +++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d1f5a5cc..c2b90600 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.13.2 + 0.13.3 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.13.2 + 0.13.3 4.0.0 jsonld-java-{your module} - 0.13.2-SNAPSHOT + 0.13.3-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -449,6 +449,11 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2021-03-06 +* Release 0.13.3 +* Fix @type when subject and object are the same (Reported by @barthanssens, Patch by @umbreak) +* Ignore @base if remote context is not relative (Reported by @whikloj, Patch by @dr0i) +* Fix throwing recursive context inclusion (Patch by @umbreak) ### 2020-09-24 * Release 0.13.2 diff --git a/pom.xml b/pom.xml index 5bddbf03..5f701d70 100755 --- a/pom.xml +++ b/pom.xml @@ -39,10 +39,10 @@ UTF-8 UTF-8 - 4.5.12 - 4.4.13 - 2.11.2 - 4.13 + 4.5.13 + 4.4.14 + 2.11.4 + 4.13.2 1.7.30 0.11.0 @@ -351,7 +351,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.0 + 3.2.1 attach-source @@ -401,7 +401,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.14.2 + 0.14.4 @@ -448,7 +448,7 @@ org.jacoco jacoco-maven-plugin - 0.8.5 + 0.8.6 prepare-agent From 2c54b02de3a8c8fb9717a8befa3318bc6e895bc6 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 5 Apr 2021 17:58:43 +0200 Subject: [PATCH 425/440] Release 0.13.3 Signed-off-by: Pascal Christoph --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index b771cbee..3e57a58c 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.3-SNAPSHOT + 0.13.3 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 5f701d70..db9fd7fa 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.3-SNAPSHOT + 0.13.3 JSONLD Java :: Parent Json-LD Java Parent POM pom From 5edb2463c3361e28a9a80d78689bc428887a1ec7 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Sun, 18 Apr 2021 15:43:39 +0200 Subject: [PATCH 426/440] Bump to next development version Signed-off-by: Pascal Christoph --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 3e57a58c..9a9e32cc 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.3 + 0.13.4-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index db9fd7fa..a6c49e1f 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.3 + 0.13.4-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 8b970246b2702f234d2527dd756aec7279b373ba Mon Sep 17 00:00:00 2001 From: Chen Zhang <340355960@qq.com> Date: Wed, 18 Aug 2021 21:57:25 +0800 Subject: [PATCH 427/440] Improve Travis CI build Performance --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index df26cdc0..a311838b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,7 @@ after_success: arch: - amd64 - ppc64le + +cache: + directories: + - $HOME/.m2 From 2473693e3f64d17cbdcab6b36510f89d21689477 Mon Sep 17 00:00:00 2001 From: Peter Ansell Date: Sat, 11 Dec 2021 11:34:32 +1100 Subject: [PATCH 428/440] issue #322 : Switch test logging from log4j to logback Signed-off-by: Peter Ansell --- core/pom.xml | 4 ++-- core/src/test/resources/log4j.properties | 5 ----- pom.xml | 9 +++++---- 3 files changed, 7 insertions(+), 11 deletions(-) delete mode 100644 core/src/test/resources/log4j.properties diff --git a/core/pom.xml b/core/pom.xml index 9a9e32cc..880e341f 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -53,8 +53,8 @@ test - org.slf4j - slf4j-log4j12 + ch.qos.logback + logback-classic test diff --git a/core/src/test/resources/log4j.properties b/core/src/test/resources/log4j.properties deleted file mode 100644 index 6cebabb1..00000000 --- a/core/src/test/resources/log4j.properties +++ /dev/null @@ -1,5 +0,0 @@ -log4j.rootLogger=INFO, R - -log4j.appender.R=org.apache.log4j.ConsoleAppender -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=[%d] %-5p (%c:%L) %m%n diff --git a/pom.xml b/pom.xml index a6c49e1f..37d130c8 100755 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,8 @@ 4.4.14 2.11.4 4.13.2 - 1.7.30 + 1.7.32 + 1.2.7 0.11.0 @@ -96,9 +97,9 @@ runtime - org.slf4j - slf4j-log4j12 - ${slf4j.version} + ch.qos.logback + logback-classic + ${logback.version} test From 0c3bac9e61cb51e1784bfe11e15767429d33453c Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 13 Dec 2021 14:38:17 +0100 Subject: [PATCH 429/440] Prepare for release Signed-off-by: christoph@hbz-nrw.de --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c2b90600..647097f8 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.13.3 + 0.13.4 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.13.3 + 0.13.4 4.0.0 jsonld-java-{your module} - 0.13.3-SNAPSHOT + 0.13.4-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -449,6 +449,11 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2021-12-13 +* Release 0.13.4 +* Switch test logging from log4j to logback (Patch by @ansell) +* Improve Travis CI build Performance (Patch by @YunLemon) + ### 2021-03-06 * Release 0.13.3 * Fix @type when subject and object are the same (Reported by @barthanssens, Patch by @umbreak) From 4a6458a684f3126c3579b8b703b5b574f60b41c1 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 13 Dec 2021 15:21:21 +0100 Subject: [PATCH 430/440] Release 0.13.4 Signed-off-by: christoph@hbz-nrw.de --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 880e341f..faac5b82 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.4-SNAPSHOT + 0.13.4 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 37d130c8..4222a722 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.4-SNAPSHOT + 0.13.4 JSONLD Java :: Parent Json-LD Java Parent POM pom From f2f1cf22dc8a9c30c47ab570c7aaa8243101ad02 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 13 Dec 2021 16:23:57 +0100 Subject: [PATCH 431/440] Bump to next development version Signed-off-by: Pascal Christoph --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index faac5b82..04547275 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.4 + 0.13.5-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 4222a722..48f6c851 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.4 + 0.13.5-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 00f0ca5269ba5754479fcb4969034c6cb7782201 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 3 Nov 2023 11:11:22 +0100 Subject: [PATCH 432/440] Ignore test because context does no more resolve (#175) --- .../test/java/com/github/jsonldjava/core/LocalBaseTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java index 22093345..e12c9a02 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java @@ -10,11 +10,13 @@ import java.nio.charset.Charset; import java.util.List; +import org.junit.Ignore; import org.junit.Test; import com.github.jsonldjava.utils.JsonUtils; public class LocalBaseTest { + @Ignore("TODO: context does no more resolve - see https://github.com/jsonld-java/jsonld-java/issues/175") @Test public void testMixedLocalRemoteBaseRemoteContextFirst() throws Exception { @@ -36,6 +38,7 @@ public void testMixedLocalRemoteBaseRemoteContextFirst() throws Exception { assertEquals(expanded, output); } + @Ignore("TODO: context does no more resolve - see https://github.com/jsonld-java/jsonld-java/issues/175") @Test public void testMixedLocalRemoteBaseLocalContextFirst() throws Exception { From 83cc4710a9168c87889b98b4a6bfeaff922ae47f Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 3 Nov 2023 11:13:32 +0100 Subject: [PATCH 433/440] Update dependencies - bump Jackson version to 2.12.7 - bump Guava version to 32.1.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 48f6c851..8e59d036 100755 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 4.5.13 4.4.14 - 2.11.4 + 2.12.7 4.13.2 1.7.32 1.2.7 @@ -211,7 +211,7 @@ com.google.guava guava - 29.0-jre + 32.1.3-jre From 25045d2aabd613a598ff09529789bd4e11e56a69 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 3 Nov 2023 11:29:31 +0100 Subject: [PATCH 434/440] Prepare for release Signed-off-by: christoph@hbz-nrw.de --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 647097f8..6e354ba5 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ From Maven com.github.jsonld-java jsonld-java - 0.13.4 + 0.13.5 Code example @@ -323,11 +323,11 @@ Here is the basic outline for what your module's pom.xml should look like com.github.jsonld-java jsonld-java-parent - 0.13.4 + 0.13.5 4.0.0 jsonld-java-{your module} - 0.13.4-SNAPSHOT + 0.13.5-SNAPSHOT JSONLD Java :: {your module name} JSON-LD Java integration module for {RDF Library your module integrates} jar @@ -449,6 +449,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2023-11-03 +* Release 0.13.5 +* Bump Jackson and Guava versions to latest for security updates + ### 2021-12-13 * Release 0.13.4 * Switch test logging from log4j to logback (Patch by @ansell) From 3ebed87283a39d8d89a5c186a5ecdd314f23a238 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 3 Nov 2023 11:32:38 +0100 Subject: [PATCH 435/440] Release 0.13.5 Signed-off-by: christoph@hbz-nrw.de --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 04547275..79d71594 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.5-SNAPSHOT + 0.13.5 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 8e59d036..7ae6629f 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.5-SNAPSHOT + 0.13.5 JSONLD Java :: Parent Json-LD Java Parent POM pom From 2c5c4108229d4e58b146ec53505136422f8a6fee Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Fri, 3 Nov 2023 13:41:18 +0100 Subject: [PATCH 436/440] Bump to next development version Signed-off-by: Pascal Christoph --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 79d71594..12a00243 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.5 + 0.13.6-SNAPSHOT 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index 7ae6629f..f724db6b 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.5 + 0.13.6-SNAPSHOT JSONLD Java :: Parent Json-LD Java Parent POM pom From 1c984b87cc8a8b8dcbafbbae7ae40337972369cd Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 6 Nov 2023 09:00:55 +0100 Subject: [PATCH 437/440] Reenable test by getting monarch-context (#175) Storing monarch-context into this repo will make the tests more stable. --- .../github/jsonldjava/core/LocalBaseTest.java | 3 - .../test/resources/custom/base-0001-in.jsonld | 7 +- .../test/resources/custom/base-0002-in.jsonld | 7 +- .../resources/custom/monarch-context.jsonld | 149 ++++++++++++++++++ 4 files changed, 157 insertions(+), 9 deletions(-) create mode 100644 core/src/test/resources/custom/monarch-context.jsonld diff --git a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java index e12c9a02..22093345 100644 --- a/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/LocalBaseTest.java @@ -10,13 +10,11 @@ import java.nio.charset.Charset; import java.util.List; -import org.junit.Ignore; import org.junit.Test; import com.github.jsonldjava.utils.JsonUtils; public class LocalBaseTest { - @Ignore("TODO: context does no more resolve - see https://github.com/jsonld-java/jsonld-java/issues/175") @Test public void testMixedLocalRemoteBaseRemoteContextFirst() throws Exception { @@ -38,7 +36,6 @@ public void testMixedLocalRemoteBaseRemoteContextFirst() throws Exception { assertEquals(expanded, output); } - @Ignore("TODO: context does no more resolve - see https://github.com/jsonld-java/jsonld-java/issues/175") @Test public void testMixedLocalRemoteBaseLocalContextFirst() throws Exception { diff --git a/core/src/test/resources/custom/base-0001-in.jsonld b/core/src/test/resources/custom/base-0001-in.jsonld index f9bd58fd..12a082af 100644 --- a/core/src/test/resources/custom/base-0001-in.jsonld +++ b/core/src/test/resources/custom/base-0001-in.jsonld @@ -1,6 +1,6 @@ { - "@context": [ -"https://raw.githubusercontent.com/monarch-initiative/monarch-app/master/conf/monarch-context.jsonld", + "@context": [ + "https://raw.githubusercontent.com/jsonld-java/jsonld-java/master/core/src/test/resources/custom/monarch-context.jsonld", { "@base": "http://example.org/base/", "ex": "http://example.org/", @@ -13,4 +13,5 @@ "ex:name": "Jim", "ex:friendOf": "1234", "@type": "Person" -} \ No newline at end of file +} + diff --git a/core/src/test/resources/custom/base-0002-in.jsonld b/core/src/test/resources/custom/base-0002-in.jsonld index 4b2e3848..d533f432 100644 --- a/core/src/test/resources/custom/base-0002-in.jsonld +++ b/core/src/test/resources/custom/base-0002-in.jsonld @@ -1,5 +1,5 @@ { - "@context": [ + "@context": [ { "@base": "http://example.org/base/", "ex": "http://example.org/", @@ -7,10 +7,11 @@ "@type": "@id" } }, - "https://raw.githubusercontent.com/monarch-initiative/monarch-app/master/conf/monarch-context.jsonld" + "https://raw.githubusercontent.com/jsonld-java/jsonld-java/master/core/src/test/resources/custom/monarch-context.jsonld" ], "@id": "3456", "ex:name": "Jim", "ex:friendOf": "1234", "@type": "Person" -} \ No newline at end of file +} + diff --git a/core/src/test/resources/custom/monarch-context.jsonld b/core/src/test/resources/custom/monarch-context.jsonld new file mode 100644 index 00000000..472f4153 --- /dev/null +++ b/core/src/test/resources/custom/monarch-context.jsonld @@ -0,0 +1,149 @@ +{ + "@context" : { + "EFO" : "http://purl.obolibrary.org/obo/EFO_", + "obo" : "http://purl.obolibrary.org/obo/", + "inheritance" : "monarch:mode_of_inheritance", + "@base" : "http://monarch-initiative.org/", + "email" : "foaf:mbox", + "BIND" : "http://identifiers.org/bind/bind:", + "morpholino" : "GENO:0000417", + "GENO" : "http://purl.obolibrary.org/obo/GENO_", + "UMLS" : "http://purl.obolibrary.org/obo/UMLS_", + "dcat" : "http://www.w3.org/ns/dcat#", + "PMID" : "http://www.ncbi.nlm.nih.gov/pubmed/", + "MP" : "http://purl.obolibrary.org/obo/MP_", + "ISBN-10" : "http://monarch-initiative.org/publications/ISBN:", + "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "title" : "dc:title", + "Class" : "owl:Class", + "FBbt" : "http://purl.obolibrary.org/obo/FBbt_", + "pathway_associations" : "rdfs:seeAlso", + "FBInternalGT" : "http://monarchinitiative.org/genotype/", + "has_genotype" : "GENO:0000222", + "genotype" : "GENO:0000000", + "void" : "http://rdfs.org/ns/void#", + "has_phenotype" : "RO:0002200", + "reference_locus" : "GENO:0000036", + "dbVar" : "http://identifiers.org/dbVar_", + "AQTLTrait" : "http://purl.obolibrary.org/obo/AQTLTrait_", + "phenotype_associations" : "rdfs:seeAlso", + "ECO" : "http://purl.obolibrary.org/obo/ECO_", + "WB" : "http://identifiers.org/WormBase:", + "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", + "variant_loci" : "GENO:0000027", + "MedGen" : "http://purl.obolibrary.org/obo/MedGen_", + "creator" : { + "@id" : "dc:creator", + "@type" : "@id" + }, + "SIO" : "http://semanticscience.org/resource/SIO_", + "DOID" : "http://purl.obolibrary.org/obo/DOID_", + "Ensembl" : "http://identifiers.org/ensembl:", + "id" : "@id", + "publisher" : "dc:publisher", + "depiction" : { + "@id" : "foaf:depiction", + "@type" : "@id" + }, + "ENSEMBL" : "http://identifiers.org/ensembl:", + "monarch" : "http://monarchinitiative.org/", + "ORPHANET" : "http://purl.obolibrary.org/obo/ORPHANET_", + "owl" : "http://www.w3.org/2002/07/owl#", + "GeneReviews" : "http://www.ncbi.nlm.nih.gov/books/", + "SNOMED_CT" : "http://purl.obolibrary.org/obo/SNOMED_", + "chromosomal_region" : "GENO:0000390", + "EOM" : "http://purl.obolibrary.org/obo/EOM_", + "type" : { + "@id" : "rdf:type", + "@type" : "@id" + }, + "FlyBase" : "http://identifiers.org/flybase:", + "DECIPHER" : "http://purl.obolibrary.org/obo/DECIPHER_", + "faldo" : "http://biohackathon.org/resource/faldo#", + "prov" : "http://www.w3.org/ns/prov#", + "MIM" : "http://purl.obolibrary.org/obo/OMIM_", + "genomic_variation_complement" : "GENO:0000009", + "evidence" : "monarch:evidence", + "BioGRID" : "http://purl.obolibrary.org/BioGRID_", + "dcterms" : "http://purl.org/dc/terms/", + "sequence_alteration" : "SO:0001059", + "RO" : "http://purl.obolibrary.org/obo/RO_", + "created" : { + "@id" : "dc:created", + "@type" : "xsd:dateTime" + }, + "Orphanet" : "http://purl.obolibrary.org/obo/ORPHANET_", + "oa" : "http://www.w3.org/ns/oa#", + "SGD" : "http://identifiers.org/mgd/sgd:", + "Gene" : "http://purl.obolibrary.org/obo/NCBIGene_", + "PomBase" : "http://identifiers.org/PomBase:", + "genotype_associations" : "rdfs:seeAlso", + "xsd" : "http://www.w3.org/2001/XMLSchema#", + "OMIABreed" : "http://purl.obolibrary.org/obo/OMIA_", + "TAIR" : "http://identifiers.org/mgd/tair:", + "oboInOwl" : "http://www.geneontology.org/formats/oboInOwl#", + "description" : "dc:description", + "disease" : "monarch:disease", + "OMIAPub" : "http://purl.obolibrary.org/obo/OMIAPub_", + "foaf" : "http://xmlns.com/foaf/0.1/", + "idot" : "http://identifiers.org/", + "subClassOf" : "owl:subClassOf", + "source" : "dc:source", + "keyword" : "dcat:keyword", + "onset" : "monarch:age_of_onset", + "genomic_background" : "GENO:0000010", + "dictyBase" : "http://identifiers.org/dictyBase:", + "OMIA" : "http://purl.obolibrary.org/obo/OMIA_", + "has_part" : "BFO:0000051", + "ClinVarVariant" : "http://identifiers.org/ClinVarVariant_", + "gene_locus" : "GENO:0000014", + "effective_genotype" : "GENO:0000525", + "VT" : "http://purl.obolibrary.org/obo/VT_", + "Association" : "SIO:000897", + "resource" : "monarch:nif-resource", + "KEGG" : "http://identifiers.org/kegg:", + "Annotation" : "oa:Annotation", + "FBdv" : "http://purl.obolibrary.org/obo/FBdv_", + "GeneID" : "http://purl.obolibrary.org/obo/NCBIGene_", + "has_background" : "GENO:0000010", + "BFO" : "http://purl.obolibrary.org/obo/BFO_", + "FB" : "http://identifiers.org/flybase:", + "frequency" : "monarch:frequency", + "ZP" : "http://purl.obolibrary.org/obo/ZP_", + "OMIM" : "http://purl.obolibrary.org/obo/OMIM_", + "MGI" : "http://identifiers.org/mgd/MGI:", + "dc" : "http://purl.org/dc/terms/", + "MONARCH" : "http://monarchinitiative.org/MONARCH_", + "ClinVarHaplotype" : "http://identifiers.org/ClinVarHaplotype_", + "homepage" : { + "@id" : "foaf:homepage", + "@type" : "@id" + }, + "RGD" : "http://identifiers.org/mgd/rgd:", + "CORIELL" : "http://purl.obolibrary.org/obo/CORIELL_", + "label" : "rdfs:label", + "NCBIGene" : "http://purl.obolibrary.org/obo/NCBIGene_", + "intrinsic_genotype" : "GENO:0000000", + "FBcv" : "http://purl.obolibrary.org/obo/FBcv_", + "WBStrain" : "http://identifiers.org/WormBase:", + "sequence_alteration_collection" : "GENO:0000025", + "reference" : "dc:publication", + "zygosity" : "GENO:0000133", + "chromosome" : "GENO:0000323", + "WormBase" : "http://identifiers.org/WormBase:", + "HPRD" : "http://identifiers.org/hprd/hprd:", + "ClinVar" : "http://purl.obolibrary.org/obo/ClinVar_", + "ISBN-13" : "http://monarch-initiative.org/publications/ISBN:", + "extrinsic_genotype" : "GENO:0000524", + "NCBITaxon" : "http://purl.obolibrary.org/obo/NCBITaxon_", + "environment" : "GENO:0000099", + "variant_locus" : "GENO:0000481", + "comment" : "rdfs:comment", + "SO" : "http://purl.obolibrary.org/obo/SO_", + "phenotype" : "monarch:phenotype", + "ZFIN" : "http://identifiers.org/zfin:", + "HP" : "http://purl.obolibrary.org/obo/HP_", + "MESH" : "http://purl.obolibrary.org/obo/MESH_", + "dbSNP" : "http://identifiers.org/dbSNP_" + } +} From 156ec3e0f3325ed3abaa62e452d3d3610d7e7f53 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 6 Nov 2023 10:03:50 +0100 Subject: [PATCH 438/440] Update dependencies - bump Jackson version to 2.12.7.1 --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f724db6b..f7662a72 100755 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ 4.5.13 4.4.14 2.12.7 + 2.12.7.1 4.13.2 1.7.32 1.2.7 @@ -66,7 +67,7 @@ com.fasterxml.jackson.core jackson-databind - ${jackson.version} + ${jackson-databind.version} com.fasterxml.jackson.core From 1cff4ce3093bce405c52b7b52737e0982119b4a0 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 6 Nov 2023 10:08:44 +0100 Subject: [PATCH 439/440] Prepare for release Signed-off-by: christoph@hbz-nrw.de --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6e354ba5..f1102e69 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,10 @@ Alternatively, we can also host your repository in the jsonld-java organisation CHANGELOG ========= +### 2023-11-06 +* Release 0.13.6 +* Bump Jackson-databind version to latest for security update + ### 2023-11-03 * Release 0.13.5 * Bump Jackson and Guava versions to latest for security updates From 01c3086a2bba620bf74ac6440797275cb41cbe86 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Mon, 6 Nov 2023 10:16:20 +0100 Subject: [PATCH 440/440] Release 0.13.6 Signed-off-by: christoph@hbz-nrw.de --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 12a00243..f14fb287 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ jsonld-java-parent com.github.jsonld-java - 0.13.6-SNAPSHOT + 0.13.6 4.0.0 jsonld-java diff --git a/pom.xml b/pom.xml index f7662a72..de5316fa 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.jsonld-java jsonld-java-parent - 0.13.6-SNAPSHOT + 0.13.6 JSONLD Java :: Parent Json-LD Java Parent POM pom