From e17472908ff4460e64f5cf17f9fee813cab989eb Mon Sep 17 00:00:00 2001 From: rk Date: Tue, 14 Feb 2023 17:38:23 +0100 Subject: [PATCH 1/2] fix: build new JsonLDObject of JsonLDObject with non-empty DEFAULT_JSONLD_CONTEXTS --- pom.xml | 70 +- .../identity/jsonld/JsonLDObject.java | 764 +++++++++--------- .../identity/jsonld/JsonLDCredential.kt | 20 + .../identity/jsonld/JsonLDObjectTests.kt | 61 ++ 4 files changed, 538 insertions(+), 377 deletions(-) create mode 100644 src/test/java/foundation/identity/jsonld/JsonLDCredential.kt create mode 100644 src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt diff --git a/pom.xml b/pom.xml index 7626d46..02629a8 100644 --- a/pom.xml +++ b/pom.xml @@ -34,19 +34,11 @@ UTF-8 github 2.5.3 + 1.8.20-Beta - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 11 - true - - org.apache.maven.plugins maven-source-plugin @@ -92,6 +84,55 @@ @{project.version} + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + 11 + true + + @@ -151,6 +192,17 @@ 3.0.2 true + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + diff --git a/src/main/java/foundation/identity/jsonld/JsonLDObject.java b/src/main/java/foundation/identity/jsonld/JsonLDObject.java index d0033db..520369b 100644 --- a/src/main/java/foundation/identity/jsonld/JsonLDObject.java +++ b/src/main/java/foundation/identity/jsonld/JsonLDObject.java @@ -34,372 +34,400 @@ public class JsonLDObject { - public static final URI[] DEFAULT_JSONLD_CONTEXTS = new URI[] { }; - public static final String[] DEFAULT_JSONLD_TYPES = new String[] { }; - public static final String DEFAULT_JSONLD_PREDICATE = null; - public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = ConfigurableDocumentLoader.DOCUMENT_LOADER; - - private static final ObjectMapper objectMapper = new ObjectMapper(); - private static final ObjectWriter objectWriterDefault = objectMapper.writer(); - private static final ObjectWriter objectWriterPretty = objectMapper.writerWithDefaultPrettyPrinter(); - - private final Map jsonObject; - private DocumentLoader documentLoader; - - @JsonCreator - public JsonLDObject() { - this(new LinkedHashMap()); - } - - protected JsonLDObject(Map jsonObject) { - this.jsonObject = jsonObject; - this.documentLoader = getDefaultDocumentLoader(this.getClass()); - } - - /* - * Factory methods - */ - - public static class Builder> { - - private JsonLDObject base = null; - private boolean forceContextsArray = false; - private boolean forceTypesArray = false; - private boolean defaultContexts = false; - private boolean defaultTypes = false; - private List contexts = null; - private List types = null; - private URI id = null; - private Map properties = null; - - private boolean isBuilt = false; - protected JsonLDObject jsonLdObject; - - protected Builder(JsonLDObject jsonLdObject) { - this.jsonLdObject = jsonLdObject; - } - - public JsonLDObject build() { - - if (this.isBuilt) throw new IllegalStateException("JSON-LD object has already been built."); - this.isBuilt = true; - - // add JSON-LD properties - if (this.base != null) { JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.base.getJsonObject()); } - if (this.defaultContexts) { List contexts = new ArrayList<>(JsonLDObject.getDefaultJsonLDContexts(this.jsonLdObject.getClass())); if (this.contexts != null) contexts.addAll(this.contexts); if (! contexts.isEmpty()) this.contexts = contexts; } - if (this.defaultTypes) { List types = new ArrayList<>(JsonLDObject.getDefaultJsonLDTypes(this.jsonLdObject.getClass())); if (this.types != null) types.addAll(this.types); if (! types.isEmpty()) this.types = types; } - if (this.contexts != null) if (this.forceContextsArray) JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, Keywords.CONTEXT, this.contexts.stream().map(JsonLDUtils::uriToString).collect(Collectors.toList())); else JsonLDUtils.jsonLdAdd(this.jsonLdObject, Keywords.CONTEXT, this.contexts.stream().map(JsonLDUtils::uriToString).collect(Collectors.toList())); - if (this.types != null) if (this.forceTypesArray) JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); else JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); - if (this.id != null) JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_ID, JsonLDUtils.uriToString(this.id)); - if (this.properties != null) JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.properties); - - return this.jsonLdObject; - } - - public B base(JsonLDObject base) { - this.base = base; - return (B) this; - } - - public B forceContextsArray(boolean forceContextsArray) { - this.forceContextsArray = forceContextsArray; - return (B) this; - } - - public B forceTypesArray(boolean forceTypesArray) { - this.forceTypesArray = forceTypesArray; - return (B) this; - } - - public B defaultContexts(boolean defaultContexts) { - this.defaultContexts = defaultContexts; - return (B) this; - } - - public B defaultTypes(boolean defaultTypes) { - this.defaultTypes = defaultTypes; - return (B) this; - } - - public B contexts(List contexts) { - this.contexts = contexts; - return (B) this; - } - - public B context(URI context) { - return this.contexts(context == null ? null : Collections.singletonList(context)); - } - - public B types(List types) { - this.types = types; - return (B) this; - } - - public B type(String type) { - return this.types(type == null ? null : Collections.singletonList(type)); - } - - public B id(URI id) { - this.id = id; - return (B) this; - } - - public B properties(Map properties) { - this.properties = properties; - return (B) this; - } - } - - public static Builder> builder() { - return new Builder(new JsonLDObject()); - } - - public static JsonLDObject fromJsonObject(Map jsonObject) { - return new JsonLDObject(jsonObject); - } - - public static JsonLDObject fromJsonLDObject(JsonLDObject jsonLDObject) { return fromJsonObject(jsonLDObject.getJsonObject()); } - - public static JsonLDObject fromJson(Reader reader) { - return new JsonLDObject(readJson(reader)); - } - - public static JsonLDObject fromJson(String json) { - return new JsonLDObject(readJson(json)); - } - - public static JsonLDObject fromMap(Map jsonObject) { - return new JsonLDObject(jsonObject); - } - - /* - * Adding, getting, and removing the JSON-LD object - */ - - public void addToJsonLDObject(JsonLDObject jsonLdObject, String term) { - JsonLDUtils.jsonLdAdd(jsonLdObject, term, this.getJsonObject()); - } - - public void addToJsonLDObject(JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(this.getClass()); - addToJsonLDObject(jsonLdObject, term); - } - - public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject, String term) { - JsonLDUtils.jsonLdAddAsJsonArray(jsonLdObject, term, this.getJsonObject()); - } - - public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(this.getClass()); - addToJsonLDObjectAsJsonArray(jsonLdObject, term); - } - - public static C getFromJsonLDObject(Class cl, JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(cl); - Map jsonObject = JsonLDUtils.jsonLdGetJsonObject(jsonLdObject.getJsonObject(), term); - if (jsonObject == null) return null; - try { - Method method = cl.getMethod("fromMap", Map.class); - return (C) method.invoke(null, jsonObject); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { - throw new Error(ex); - } - } - - public static JsonLDObject getFromJsonLDObject(JsonLDObject jsonLdObject) { - return getFromJsonLDObject(JsonLDObject.class, jsonLdObject); - } - - public static void removeFromJsonLdObject(Class cl, JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(cl); - JsonLDUtils.jsonLdRemove(jsonLdObject, term); - } - - public static void removeFromJsonLdObject(JsonLDObject jsonLdObject) { - removeFromJsonLdObject(JsonLDObject.class, jsonLdObject); - } - - /* - * Getters and setters - */ - - public DocumentLoader getDocumentLoader() { - return this.documentLoader; - } - - public void setDocumentLoader(DocumentLoader documentLoader) { - this.documentLoader = documentLoader; - } - - @JsonValue - public Map getJsonObject() { - return this.jsonObject; - } - - @JsonAnySetter - public void setJsonObjectKeyValue(String key, Object value) { - - this.getJsonObject().put(key, value); - } - - public List getContexts() { - List contextStrings = JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), Keywords.CONTEXT); - return contextStrings == null ? null : contextStrings.stream().map(JsonLDUtils::stringToUri).collect(Collectors.toList()); - } - - public final List getTypes() { - return JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); - } - - public final String getType() { - return JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); - } - - public final boolean isType(String type) { - return JsonLDUtils.jsonLdContainsString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE, type); - } - - public final URI getId() { - return JsonLDUtils.stringToUri(JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_ID)); - } - - /* - * Reading the JSON-LD object - */ - - protected static Map readJson(Reader reader) { - try { - return objectMapper.readValue(reader, Map.class); - } catch (IOException ex) { - throw new RuntimeException("Cannot read JSON: " + ex.getMessage(), ex); - } - } - - protected static Map readJson(String json) { - return readJson(new StringReader(json)); - } - - /* - * Writing the JSON-LD object - */ - - public RdfDataset toDataset() throws JsonLDException { - - JsonLdOptions options = new JsonLdOptions(); - if (this.getDocumentLoader() != null) options.setDocumentLoader(this.getDocumentLoader()); - options.setOrdered(true); - - JsonDocument jsonDocument = JsonDocument.of(MediaType.JSON_LD, this.toJsonObject()); - ToRdfApi toRdfApi = JsonLd.toRdf(jsonDocument); - toRdfApi.options(options); - try { - return toRdfApi.get(); - } catch (JsonLdError ex) { - throw new JsonLDException(ex); - } - } - - public String toNQuads() throws JsonLDException, IOException { - - RdfDataset rdfDataset = this.toDataset(); - StringWriter stringWriter = new StringWriter(); - NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); - nQuadsWriter.write(rdfDataset); - return stringWriter.toString(); - } - - public String toJson(boolean pretty) { - - ObjectWriter objectWriter = pretty ? objectWriterPretty : objectWriterDefault; - try { - return objectWriter.writeValueAsString(this.getJsonObject()); - } catch (JsonProcessingException ex) { - throw new RuntimeException("Cannot write JSON: " + ex.getMessage(), ex); - } - } - - public String toJson() { - - return this.toJson(false); - } - - public String normalize(String algorithm) throws JsonLDException, NoSuchAlgorithmException, IOException { - - RdfDataset rdfDataset = this.toDataset(); - rdfDataset = RdfNormalize.normalize(rdfDataset, algorithm); - StringWriter stringWriter = new StringWriter(); - NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); - nQuadsWriter.write(rdfDataset); - return stringWriter.getBuffer().toString(); - } - - public Map toMap() { - return this.getJsonObject(); - } - - public synchronized JsonObject toJsonObject() { - return Json.createObjectBuilder(this.getJsonObject()).build(); - } - - /* - * Helper methods - */ - - public static DocumentLoader getDefaultDocumentLoader(Class cl) { - try { - Field field = cl.getField("DEFAULT_DOCUMENT_LOADER"); - return (DocumentLoader) field.get(null); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - public static List getDefaultJsonLDContexts(Class cl) { - try { - Field field = cl.getField("DEFAULT_JSONLD_CONTEXTS"); - return Arrays.asList((URI[]) field.get(null)); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - public static List getDefaultJsonLDTypes(Class cl) { - try { - Field field = cl.getField("DEFAULT_JSONLD_TYPES"); - return Arrays.asList((String[]) field.get(null)); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - public static String getDefaultJsonLDPredicate(Class cl) { - try { - Field field = cl.getField("DEFAULT_JSONLD_PREDICATE"); - return (String) field.get(null); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - /* - * Object methods - */ - - @Override - public String toString() { - return this.toJson(false); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - JsonLDObject that = (JsonLDObject) o; - return Objects.equals(this.getJsonObject(), that.getJsonObject()); - } - - @Override - public int hashCode() { - return Objects.hash(this.getJsonObject()); - } + public static final URI[] DEFAULT_JSONLD_CONTEXTS = new URI[]{}; + public static final String[] DEFAULT_JSONLD_TYPES = new String[]{}; + public static final String DEFAULT_JSONLD_PREDICATE = null; + public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = ConfigurableDocumentLoader.DOCUMENT_LOADER; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectWriter objectWriterDefault = objectMapper.writer(); + private static final ObjectWriter objectWriterPretty = objectMapper.writerWithDefaultPrettyPrinter(); + + private final Map jsonObject; + private DocumentLoader documentLoader; + + @JsonCreator + public JsonLDObject() { + this(new LinkedHashMap()); + } + + protected JsonLDObject(Map jsonObject) { + this.jsonObject = jsonObject; + this.documentLoader = getDefaultDocumentLoader(this.getClass()); + } + + /* + * Factory methods + */ + + public static class Builder> { + + private JsonLDObject base = null; + private boolean forceContextsArray = false; + private boolean forceTypesArray = false; + private boolean defaultContexts = false; + private boolean defaultTypes = false; + private List contexts = null; + private List types = null; + private URI id = null; + private Map properties = null; + + private boolean isBuilt = false; + protected JsonLDObject jsonLdObject; + + protected Builder(JsonLDObject jsonLdObject) { + this.jsonLdObject = jsonLdObject; + } + + public JsonLDObject build() { + + if (this.isBuilt) throw new IllegalStateException("JSON-LD object has already been built."); + this.isBuilt = true; + + // add JSON-LD properties + if (this.base != null) { + JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.base.getJsonObject()); + } + if (this.defaultContexts) { + List contexts = new ArrayList<>(JsonLDObject.getDefaultJsonLDContexts(this.jsonLdObject.getClass())); + if (this.contexts != null) contexts.addAll(this.contexts); + if (!contexts.isEmpty()) this.contexts = contexts; + } + if (this.defaultTypes) { + List types = new ArrayList<>(JsonLDObject.getDefaultJsonLDTypes(this.jsonLdObject.getClass())); + if (this.types != null) types.addAll(this.types); + if (!types.isEmpty()) this.types = types; + } + + if (this.contexts != null) { + List existingContexts = this.contexts.stream().map(JsonLDUtils::uriToString).collect(Collectors.toList()); + if (this.forceContextsArray) { + JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, Keywords.CONTEXT, existingContexts); + } else { + if(this.jsonLdObject.getContexts()==null || this.jsonLdObject.getContexts().isEmpty()){ + JsonLDUtils.jsonLdAdd(this.jsonLdObject, Keywords.CONTEXT, existingContexts); + }else{ + JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, Keywords.CONTEXT, existingContexts); + } + } + } + + if (this.types != null) if (this.forceTypesArray) + JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); + else JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); + if (this.id != null) + JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_ID, JsonLDUtils.uriToString(this.id)); + if (this.properties != null) JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.properties); + + return this.jsonLdObject; + } + + public B base(JsonLDObject base) { + this.base = base; + return (B) this; + } + + public B forceContextsArray(boolean forceContextsArray) { + this.forceContextsArray = forceContextsArray; + return (B) this; + } + + public B forceTypesArray(boolean forceTypesArray) { + this.forceTypesArray = forceTypesArray; + return (B) this; + } + + public B defaultContexts(boolean defaultContexts) { + this.defaultContexts = defaultContexts; + return (B) this; + } + + public B defaultTypes(boolean defaultTypes) { + this.defaultTypes = defaultTypes; + return (B) this; + } + + public B contexts(List contexts) { + this.contexts = contexts; + return (B) this; + } + + public B context(URI context) { + return this.contexts(context == null ? null : Collections.singletonList(context)); + } + + public B types(List types) { + this.types = types; + return (B) this; + } + + public B type(String type) { + return this.types(type == null ? null : Collections.singletonList(type)); + } + + public B id(URI id) { + this.id = id; + return (B) this; + } + + public B properties(Map properties) { + this.properties = properties; + return (B) this; + } + } + + public static Builder> builder() { + return new Builder(new JsonLDObject()); + } + + public static JsonLDObject fromJsonObject(Map jsonObject) { + return new JsonLDObject(jsonObject); + } + + public static JsonLDObject fromJsonLDObject(JsonLDObject jsonLDObject) { + return fromJsonObject(jsonLDObject.getJsonObject()); + } + + public static JsonLDObject fromJson(Reader reader) { + return new JsonLDObject(readJson(reader)); + } + + public static JsonLDObject fromJson(String json) { + return new JsonLDObject(readJson(json)); + } + + public static JsonLDObject fromMap(Map jsonObject) { + return new JsonLDObject(jsonObject); + } + + /* + * Adding, getting, and removing the JSON-LD object + */ + + public void addToJsonLDObject(JsonLDObject jsonLdObject, String term) { + JsonLDUtils.jsonLdAdd(jsonLdObject, term, this.getJsonObject()); + } + + public void addToJsonLDObject(JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(this.getClass()); + addToJsonLDObject(jsonLdObject, term); + } + + public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject, String term) { + JsonLDUtils.jsonLdAddAsJsonArray(jsonLdObject, term, this.getJsonObject()); + } + + public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(this.getClass()); + addToJsonLDObjectAsJsonArray(jsonLdObject, term); + } + + public static C getFromJsonLDObject(Class cl, JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(cl); + Map jsonObject = JsonLDUtils.jsonLdGetJsonObject(jsonLdObject.getJsonObject(), term); + if (jsonObject == null) return null; + try { + Method method = cl.getMethod("fromMap", Map.class); + return (C) method.invoke(null, jsonObject); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { + throw new Error(ex); + } + } + + public static JsonLDObject getFromJsonLDObject(JsonLDObject jsonLdObject) { + return getFromJsonLDObject(JsonLDObject.class, jsonLdObject); + } + + public static void removeFromJsonLdObject(Class cl, JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(cl); + JsonLDUtils.jsonLdRemove(jsonLdObject, term); + } + + public static void removeFromJsonLdObject(JsonLDObject jsonLdObject) { + removeFromJsonLdObject(JsonLDObject.class, jsonLdObject); + } + + /* + * Getters and setters + */ + + public DocumentLoader getDocumentLoader() { + return this.documentLoader; + } + + public void setDocumentLoader(DocumentLoader documentLoader) { + this.documentLoader = documentLoader; + } + + @JsonValue + public Map getJsonObject() { + return this.jsonObject; + } + + @JsonAnySetter + public void setJsonObjectKeyValue(String key, Object value) { + + this.getJsonObject().put(key, value); + } + + public List getContexts() { + List contextStrings = JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), Keywords.CONTEXT); + return contextStrings == null ? null : contextStrings.stream().map(JsonLDUtils::stringToUri).collect(Collectors.toList()); + } + + public final List getTypes() { + return JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); + } + + public final String getType() { + return JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); + } + + public final boolean isType(String type) { + return JsonLDUtils.jsonLdContainsString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE, type); + } + + public final URI getId() { + return JsonLDUtils.stringToUri(JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_ID)); + } + + /* + * Reading the JSON-LD object + */ + + protected static Map readJson(Reader reader) { + try { + return objectMapper.readValue(reader, Map.class); + } catch (IOException ex) { + throw new RuntimeException("Cannot read JSON: " + ex.getMessage(), ex); + } + } + + protected static Map readJson(String json) { + return readJson(new StringReader(json)); + } + + /* + * Writing the JSON-LD object + */ + + public RdfDataset toDataset() throws JsonLDException { + + JsonLdOptions options = new JsonLdOptions(); + if (this.getDocumentLoader() != null) options.setDocumentLoader(this.getDocumentLoader()); + options.setOrdered(true); + + JsonDocument jsonDocument = JsonDocument.of(MediaType.JSON_LD, this.toJsonObject()); + ToRdfApi toRdfApi = JsonLd.toRdf(jsonDocument); + toRdfApi.options(options); + try { + return toRdfApi.get(); + } catch (JsonLdError ex) { + throw new JsonLDException(ex); + } + } + + public String toNQuads() throws JsonLDException, IOException { + + RdfDataset rdfDataset = this.toDataset(); + StringWriter stringWriter = new StringWriter(); + NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); + nQuadsWriter.write(rdfDataset); + return stringWriter.toString(); + } + + public String toJson(boolean pretty) { + + ObjectWriter objectWriter = pretty ? objectWriterPretty : objectWriterDefault; + try { + return objectWriter.writeValueAsString(this.getJsonObject()); + } catch (JsonProcessingException ex) { + throw new RuntimeException("Cannot write JSON: " + ex.getMessage(), ex); + } + } + + public String toJson() { + + return this.toJson(false); + } + + public String normalize(String algorithm) throws JsonLDException, NoSuchAlgorithmException, IOException { + + RdfDataset rdfDataset = this.toDataset(); + rdfDataset = RdfNormalize.normalize(rdfDataset, algorithm); + StringWriter stringWriter = new StringWriter(); + NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); + nQuadsWriter.write(rdfDataset); + return stringWriter.getBuffer().toString(); + } + + public Map toMap() { + return this.getJsonObject(); + } + + public synchronized JsonObject toJsonObject() { + return Json.createObjectBuilder(this.getJsonObject()).build(); + } + + /* + * Helper methods + */ + + public static DocumentLoader getDefaultDocumentLoader(Class cl) { + try { + Field field = cl.getField("DEFAULT_DOCUMENT_LOADER"); + return (DocumentLoader) field.get(null); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + public static List getDefaultJsonLDContexts(Class cl) { + try { + Field field = cl.getField("DEFAULT_JSONLD_CONTEXTS"); + return Arrays.asList((URI[]) field.get(null)); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + public static List getDefaultJsonLDTypes(Class cl) { + try { + Field field = cl.getField("DEFAULT_JSONLD_TYPES"); + return Arrays.asList((String[]) field.get(null)); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + public static String getDefaultJsonLDPredicate(Class cl) { + try { + Field field = cl.getField("DEFAULT_JSONLD_PREDICATE"); + return (String) field.get(null); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + /* + * Object methods + */ + + @Override + public String toString() { + return this.toJson(false); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + JsonLDObject that = (JsonLDObject) o; + return Objects.equals(this.getJsonObject(), that.getJsonObject()); + } + + @Override + public int hashCode() { + return Objects.hash(this.getJsonObject()); + } } \ No newline at end of file diff --git a/src/test/java/foundation/identity/jsonld/JsonLDCredential.kt b/src/test/java/foundation/identity/jsonld/JsonLDCredential.kt new file mode 100644 index 0000000..539bf67 --- /dev/null +++ b/src/test/java/foundation/identity/jsonld/JsonLDCredential.kt @@ -0,0 +1,20 @@ +package foundation.identity.jsonld + +import foundation.identity.jsonld.JsonLDCredential +import java.net.URI + +class JsonLDCredential : JsonLDObject() { + + companion object { + @JvmField val DEFAULT_JSONLD_CONTEXTS = arrayOf(URI("https://www.w3.org/2018/credentials/v1")) + fun builder() = Builder(JsonLDCredential()) + } + + class Builder>(jsonLdObject: JsonLDObject?) : JsonLDObject.Builder(jsonLdObject) { + override fun build(): JsonLDCredential { + super.build() + return jsonLdObject as JsonLDCredential + } + } +} + diff --git a/src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt b/src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt new file mode 100644 index 0000000..24495c9 --- /dev/null +++ b/src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt @@ -0,0 +1,61 @@ +package foundation.identity.jsonld + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import java.net.URI + +class JsonLDObjectTests { + + companion object { + init { + (JsonLDObject.DEFAULT_DOCUMENT_LOADER as ConfigurableDocumentLoader).isEnableHttps = true + } + } + + @Test + fun createJsonLDObject() { + val jsonLDObject = JsonLDObject.builder().apply { + contexts( + listOf( + URI.create("https://www.w3.org/2018/credentials/v1"), + URI.create("https://w3id.org/citizenship/v1") + ) + ) + types(listOf("PermanentResident", "Person")) + properties( + mapOf( + "givenName" to "Marion", + "familyName" to "Mustermann" + ) + ) + }.build() + Assertions.assertEquals(4, jsonLDObject.toDataset().size()) + } + + @Test + fun createDerivedJsonLDObjectWithDefaultContexts() { + val jsonLDCredential = JsonLDCredential.builder().apply { + contexts( + listOf( + URI("https://w3id.org/citizenship/v1") + ) + ) + defaultContexts(true) + types(listOf("PermanentResident", "Person")) + properties( + mapOf( + "givenName" to "Marion", + "familyName" to "Mustermann" + ) + ) + }.build() + Assertions.assertEquals(4, jsonLDCredential.toDataset().size()) + Assertions.assertEquals( + jsonLDCredential.contexts, listOf( + URI("https://www.w3.org/2018/credentials/v1"), + URI("https://w3id.org/citizenship/v1") + ) + ) + } + +} \ No newline at end of file From 29d7f77c41b570629f3f5a5176adcdb3e68bf814 Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 24 Feb 2023 17:02:01 +0100 Subject: [PATCH 2/2] only src changes without any formatting changes (whitespaces and empty lines) and unit tests --- pom.xml | 70 +- .../identity/jsonld/JsonLDObject.java | 750 +++++++++--------- .../identity/jsonld/JsonLDCredential.kt | 20 - .../identity/jsonld/JsonLDObjectTests.kt | 61 -- 4 files changed, 376 insertions(+), 525 deletions(-) delete mode 100644 src/test/java/foundation/identity/jsonld/JsonLDCredential.kt delete mode 100644 src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt diff --git a/pom.xml b/pom.xml index 02629a8..7626d46 100644 --- a/pom.xml +++ b/pom.xml @@ -34,11 +34,19 @@ UTF-8 github 2.5.3 - 1.8.20-Beta + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + true + + org.apache.maven.plugins maven-source-plugin @@ -84,55 +92,6 @@ @{project.version} - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - 1.8 - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - 11 - true - - @@ -192,17 +151,6 @@ 3.0.2 true - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test - ${kotlin.version} - test - diff --git a/src/main/java/foundation/identity/jsonld/JsonLDObject.java b/src/main/java/foundation/identity/jsonld/JsonLDObject.java index 520369b..c61f320 100644 --- a/src/main/java/foundation/identity/jsonld/JsonLDObject.java +++ b/src/main/java/foundation/identity/jsonld/JsonLDObject.java @@ -34,71 +34,60 @@ public class JsonLDObject { - public static final URI[] DEFAULT_JSONLD_CONTEXTS = new URI[]{}; - public static final String[] DEFAULT_JSONLD_TYPES = new String[]{}; - public static final String DEFAULT_JSONLD_PREDICATE = null; - public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = ConfigurableDocumentLoader.DOCUMENT_LOADER; - - private static final ObjectMapper objectMapper = new ObjectMapper(); - private static final ObjectWriter objectWriterDefault = objectMapper.writer(); - private static final ObjectWriter objectWriterPretty = objectMapper.writerWithDefaultPrettyPrinter(); - - private final Map jsonObject; - private DocumentLoader documentLoader; - - @JsonCreator - public JsonLDObject() { - this(new LinkedHashMap()); - } - - protected JsonLDObject(Map jsonObject) { - this.jsonObject = jsonObject; - this.documentLoader = getDefaultDocumentLoader(this.getClass()); - } - - /* - * Factory methods - */ - - public static class Builder> { - - private JsonLDObject base = null; - private boolean forceContextsArray = false; - private boolean forceTypesArray = false; - private boolean defaultContexts = false; - private boolean defaultTypes = false; - private List contexts = null; - private List types = null; - private URI id = null; - private Map properties = null; - - private boolean isBuilt = false; - protected JsonLDObject jsonLdObject; - - protected Builder(JsonLDObject jsonLdObject) { - this.jsonLdObject = jsonLdObject; - } - - public JsonLDObject build() { - - if (this.isBuilt) throw new IllegalStateException("JSON-LD object has already been built."); - this.isBuilt = true; - - // add JSON-LD properties - if (this.base != null) { - JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.base.getJsonObject()); - } - if (this.defaultContexts) { - List contexts = new ArrayList<>(JsonLDObject.getDefaultJsonLDContexts(this.jsonLdObject.getClass())); - if (this.contexts != null) contexts.addAll(this.contexts); - if (!contexts.isEmpty()) this.contexts = contexts; - } - if (this.defaultTypes) { - List types = new ArrayList<>(JsonLDObject.getDefaultJsonLDTypes(this.jsonLdObject.getClass())); - if (this.types != null) types.addAll(this.types); - if (!types.isEmpty()) this.types = types; - } - + public static final URI[] DEFAULT_JSONLD_CONTEXTS = new URI[] { }; + public static final String[] DEFAULT_JSONLD_TYPES = new String[] { }; + public static final String DEFAULT_JSONLD_PREDICATE = null; + public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = ConfigurableDocumentLoader.DOCUMENT_LOADER; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectWriter objectWriterDefault = objectMapper.writer(); + private static final ObjectWriter objectWriterPretty = objectMapper.writerWithDefaultPrettyPrinter(); + + private final Map jsonObject; + private DocumentLoader documentLoader; + + @JsonCreator + public JsonLDObject() { + this(new LinkedHashMap()); + } + + protected JsonLDObject(Map jsonObject) { + this.jsonObject = jsonObject; + this.documentLoader = getDefaultDocumentLoader(this.getClass()); + } + + /* + * Factory methods + */ + + public static class Builder> { + + private JsonLDObject base = null; + private boolean forceContextsArray = false; + private boolean forceTypesArray = false; + private boolean defaultContexts = false; + private boolean defaultTypes = false; + private List contexts = null; + private List types = null; + private URI id = null; + private Map properties = null; + + private boolean isBuilt = false; + protected JsonLDObject jsonLdObject; + + protected Builder(JsonLDObject jsonLdObject) { + this.jsonLdObject = jsonLdObject; + } + + public JsonLDObject build() { + + if (this.isBuilt) throw new IllegalStateException("JSON-LD object has already been built."); + this.isBuilt = true; + + // add JSON-LD properties + if (this.base != null) { JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.base.getJsonObject()); } + if (this.defaultContexts) { List contexts = new ArrayList<>(JsonLDObject.getDefaultJsonLDContexts(this.jsonLdObject.getClass())); if (this.contexts != null) contexts.addAll(this.contexts); if (! contexts.isEmpty()) this.contexts = contexts; } + if (this.defaultTypes) { List types = new ArrayList<>(JsonLDObject.getDefaultJsonLDTypes(this.jsonLdObject.getClass())); if (this.types != null) types.addAll(this.types); if (! types.isEmpty()) this.types = types; } if (this.contexts != null) { List existingContexts = this.contexts.stream().map(JsonLDUtils::uriToString).collect(Collectors.toList()); if (this.forceContextsArray) { @@ -112,322 +101,317 @@ public JsonLDObject build() { } } - if (this.types != null) if (this.forceTypesArray) - JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); - else JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); - if (this.id != null) - JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_ID, JsonLDUtils.uriToString(this.id)); - if (this.properties != null) JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.properties); - - return this.jsonLdObject; - } - - public B base(JsonLDObject base) { - this.base = base; - return (B) this; - } - - public B forceContextsArray(boolean forceContextsArray) { - this.forceContextsArray = forceContextsArray; - return (B) this; - } - - public B forceTypesArray(boolean forceTypesArray) { - this.forceTypesArray = forceTypesArray; - return (B) this; - } - - public B defaultContexts(boolean defaultContexts) { - this.defaultContexts = defaultContexts; - return (B) this; - } - - public B defaultTypes(boolean defaultTypes) { - this.defaultTypes = defaultTypes; - return (B) this; - } - - public B contexts(List contexts) { - this.contexts = contexts; - return (B) this; - } - - public B context(URI context) { - return this.contexts(context == null ? null : Collections.singletonList(context)); - } - - public B types(List types) { - this.types = types; - return (B) this; - } - - public B type(String type) { - return this.types(type == null ? null : Collections.singletonList(type)); - } - - public B id(URI id) { - this.id = id; - return (B) this; - } - - public B properties(Map properties) { - this.properties = properties; - return (B) this; - } - } - - public static Builder> builder() { - return new Builder(new JsonLDObject()); - } - - public static JsonLDObject fromJsonObject(Map jsonObject) { - return new JsonLDObject(jsonObject); - } - - public static JsonLDObject fromJsonLDObject(JsonLDObject jsonLDObject) { - return fromJsonObject(jsonLDObject.getJsonObject()); - } - - public static JsonLDObject fromJson(Reader reader) { - return new JsonLDObject(readJson(reader)); - } - - public static JsonLDObject fromJson(String json) { - return new JsonLDObject(readJson(json)); - } - - public static JsonLDObject fromMap(Map jsonObject) { - return new JsonLDObject(jsonObject); - } - - /* - * Adding, getting, and removing the JSON-LD object - */ - - public void addToJsonLDObject(JsonLDObject jsonLdObject, String term) { - JsonLDUtils.jsonLdAdd(jsonLdObject, term, this.getJsonObject()); - } - - public void addToJsonLDObject(JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(this.getClass()); - addToJsonLDObject(jsonLdObject, term); - } - - public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject, String term) { - JsonLDUtils.jsonLdAddAsJsonArray(jsonLdObject, term, this.getJsonObject()); - } - - public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(this.getClass()); - addToJsonLDObjectAsJsonArray(jsonLdObject, term); - } - - public static C getFromJsonLDObject(Class cl, JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(cl); - Map jsonObject = JsonLDUtils.jsonLdGetJsonObject(jsonLdObject.getJsonObject(), term); - if (jsonObject == null) return null; - try { - Method method = cl.getMethod("fromMap", Map.class); - return (C) method.invoke(null, jsonObject); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { - throw new Error(ex); - } - } - - public static JsonLDObject getFromJsonLDObject(JsonLDObject jsonLdObject) { - return getFromJsonLDObject(JsonLDObject.class, jsonLdObject); - } - - public static void removeFromJsonLdObject(Class cl, JsonLDObject jsonLdObject) { - String term = getDefaultJsonLDPredicate(cl); - JsonLDUtils.jsonLdRemove(jsonLdObject, term); - } - - public static void removeFromJsonLdObject(JsonLDObject jsonLdObject) { - removeFromJsonLdObject(JsonLDObject.class, jsonLdObject); - } - - /* - * Getters and setters - */ - - public DocumentLoader getDocumentLoader() { - return this.documentLoader; - } - - public void setDocumentLoader(DocumentLoader documentLoader) { - this.documentLoader = documentLoader; - } - - @JsonValue - public Map getJsonObject() { - return this.jsonObject; - } - - @JsonAnySetter - public void setJsonObjectKeyValue(String key, Object value) { - - this.getJsonObject().put(key, value); - } - - public List getContexts() { - List contextStrings = JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), Keywords.CONTEXT); - return contextStrings == null ? null : contextStrings.stream().map(JsonLDUtils::stringToUri).collect(Collectors.toList()); - } - - public final List getTypes() { - return JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); - } - - public final String getType() { - return JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); - } - - public final boolean isType(String type) { - return JsonLDUtils.jsonLdContainsString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE, type); - } - - public final URI getId() { - return JsonLDUtils.stringToUri(JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_ID)); - } - - /* - * Reading the JSON-LD object - */ - - protected static Map readJson(Reader reader) { - try { - return objectMapper.readValue(reader, Map.class); - } catch (IOException ex) { - throw new RuntimeException("Cannot read JSON: " + ex.getMessage(), ex); - } - } - - protected static Map readJson(String json) { - return readJson(new StringReader(json)); - } - - /* - * Writing the JSON-LD object - */ - - public RdfDataset toDataset() throws JsonLDException { - - JsonLdOptions options = new JsonLdOptions(); - if (this.getDocumentLoader() != null) options.setDocumentLoader(this.getDocumentLoader()); - options.setOrdered(true); - - JsonDocument jsonDocument = JsonDocument.of(MediaType.JSON_LD, this.toJsonObject()); - ToRdfApi toRdfApi = JsonLd.toRdf(jsonDocument); - toRdfApi.options(options); - try { - return toRdfApi.get(); - } catch (JsonLdError ex) { - throw new JsonLDException(ex); - } - } - - public String toNQuads() throws JsonLDException, IOException { - - RdfDataset rdfDataset = this.toDataset(); - StringWriter stringWriter = new StringWriter(); - NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); - nQuadsWriter.write(rdfDataset); - return stringWriter.toString(); - } - - public String toJson(boolean pretty) { - - ObjectWriter objectWriter = pretty ? objectWriterPretty : objectWriterDefault; - try { - return objectWriter.writeValueAsString(this.getJsonObject()); - } catch (JsonProcessingException ex) { - throw new RuntimeException("Cannot write JSON: " + ex.getMessage(), ex); - } - } - - public String toJson() { - - return this.toJson(false); - } - - public String normalize(String algorithm) throws JsonLDException, NoSuchAlgorithmException, IOException { - - RdfDataset rdfDataset = this.toDataset(); - rdfDataset = RdfNormalize.normalize(rdfDataset, algorithm); - StringWriter stringWriter = new StringWriter(); - NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); - nQuadsWriter.write(rdfDataset); - return stringWriter.getBuffer().toString(); - } - - public Map toMap() { - return this.getJsonObject(); - } - - public synchronized JsonObject toJsonObject() { - return Json.createObjectBuilder(this.getJsonObject()).build(); - } - - /* - * Helper methods - */ - - public static DocumentLoader getDefaultDocumentLoader(Class cl) { - try { - Field field = cl.getField("DEFAULT_DOCUMENT_LOADER"); - return (DocumentLoader) field.get(null); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - public static List getDefaultJsonLDContexts(Class cl) { - try { - Field field = cl.getField("DEFAULT_JSONLD_CONTEXTS"); - return Arrays.asList((URI[]) field.get(null)); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - public static List getDefaultJsonLDTypes(Class cl) { - try { - Field field = cl.getField("DEFAULT_JSONLD_TYPES"); - return Arrays.asList((String[]) field.get(null)); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - public static String getDefaultJsonLDPredicate(Class cl) { - try { - Field field = cl.getField("DEFAULT_JSONLD_PREDICATE"); - return (String) field.get(null); - } catch (IllegalAccessException | NoSuchFieldException ex) { - throw new Error(ex); - } - } - - /* - * Object methods - */ - - @Override - public String toString() { - return this.toJson(false); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - JsonLDObject that = (JsonLDObject) o; - return Objects.equals(this.getJsonObject(), that.getJsonObject()); - } - - @Override - public int hashCode() { - return Objects.hash(this.getJsonObject()); - } + if (this.types != null) if (this.forceTypesArray) JsonLDUtils.jsonLdAddAsJsonArray(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); else JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_TYPE, this.types); + if (this.id != null) JsonLDUtils.jsonLdAdd(this.jsonLdObject, JsonLDKeywords.JSONLD_TERM_ID, JsonLDUtils.uriToString(this.id)); + if (this.properties != null) JsonLDUtils.jsonLdAddAll(this.jsonLdObject, this.properties); + + return this.jsonLdObject; + } + + public B base(JsonLDObject base) { + this.base = base; + return (B) this; + } + + public B forceContextsArray(boolean forceContextsArray) { + this.forceContextsArray = forceContextsArray; + return (B) this; + } + + public B forceTypesArray(boolean forceTypesArray) { + this.forceTypesArray = forceTypesArray; + return (B) this; + } + + public B defaultContexts(boolean defaultContexts) { + this.defaultContexts = defaultContexts; + return (B) this; + } + + public B defaultTypes(boolean defaultTypes) { + this.defaultTypes = defaultTypes; + return (B) this; + } + + public B contexts(List contexts) { + this.contexts = contexts; + return (B) this; + } + + public B context(URI context) { + return this.contexts(context == null ? null : Collections.singletonList(context)); + } + + public B types(List types) { + this.types = types; + return (B) this; + } + + public B type(String type) { + return this.types(type == null ? null : Collections.singletonList(type)); + } + + public B id(URI id) { + this.id = id; + return (B) this; + } + + public B properties(Map properties) { + this.properties = properties; + return (B) this; + } + } + + public static Builder> builder() { + return new Builder(new JsonLDObject()); + } + + public static JsonLDObject fromJsonObject(Map jsonObject) { + return new JsonLDObject(jsonObject); + } + + public static JsonLDObject fromJsonLDObject(JsonLDObject jsonLDObject) { return fromJsonObject(jsonLDObject.getJsonObject()); } + + public static JsonLDObject fromJson(Reader reader) { + return new JsonLDObject(readJson(reader)); + } + + public static JsonLDObject fromJson(String json) { + return new JsonLDObject(readJson(json)); + } + + public static JsonLDObject fromMap(Map jsonObject) { + return new JsonLDObject(jsonObject); + } + + /* + * Adding, getting, and removing the JSON-LD object + */ + + public void addToJsonLDObject(JsonLDObject jsonLdObject, String term) { + JsonLDUtils.jsonLdAdd(jsonLdObject, term, this.getJsonObject()); + } + + public void addToJsonLDObject(JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(this.getClass()); + addToJsonLDObject(jsonLdObject, term); + } + + public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject, String term) { + JsonLDUtils.jsonLdAddAsJsonArray(jsonLdObject, term, this.getJsonObject()); + } + + public void addToJsonLDObjectAsJsonArray(JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(this.getClass()); + addToJsonLDObjectAsJsonArray(jsonLdObject, term); + } + + public static C getFromJsonLDObject(Class cl, JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(cl); + Map jsonObject = JsonLDUtils.jsonLdGetJsonObject(jsonLdObject.getJsonObject(), term); + if (jsonObject == null) return null; + try { + Method method = cl.getMethod("fromMap", Map.class); + return (C) method.invoke(null, jsonObject); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { + throw new Error(ex); + } + } + + public static JsonLDObject getFromJsonLDObject(JsonLDObject jsonLdObject) { + return getFromJsonLDObject(JsonLDObject.class, jsonLdObject); + } + + public static void removeFromJsonLdObject(Class cl, JsonLDObject jsonLdObject) { + String term = getDefaultJsonLDPredicate(cl); + JsonLDUtils.jsonLdRemove(jsonLdObject, term); + } + + public static void removeFromJsonLdObject(JsonLDObject jsonLdObject) { + removeFromJsonLdObject(JsonLDObject.class, jsonLdObject); + } + + /* + * Getters and setters + */ + + public DocumentLoader getDocumentLoader() { + return this.documentLoader; + } + + public void setDocumentLoader(DocumentLoader documentLoader) { + this.documentLoader = documentLoader; + } + + @JsonValue + public Map getJsonObject() { + return this.jsonObject; + } + + @JsonAnySetter + public void setJsonObjectKeyValue(String key, Object value) { + + this.getJsonObject().put(key, value); + } + + public List getContexts() { + List contextStrings = JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), Keywords.CONTEXT); + return contextStrings == null ? null : contextStrings.stream().map(JsonLDUtils::stringToUri).collect(Collectors.toList()); + } + + public final List getTypes() { + return JsonLDUtils.jsonLdGetStringList(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); + } + + public final String getType() { + return JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE); + } + + public final boolean isType(String type) { + return JsonLDUtils.jsonLdContainsString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_TYPE, type); + } + + public final URI getId() { + return JsonLDUtils.stringToUri(JsonLDUtils.jsonLdGetString(this.getJsonObject(), JsonLDKeywords.JSONLD_TERM_ID)); + } + + /* + * Reading the JSON-LD object + */ + + protected static Map readJson(Reader reader) { + try { + return objectMapper.readValue(reader, Map.class); + } catch (IOException ex) { + throw new RuntimeException("Cannot read JSON: " + ex.getMessage(), ex); + } + } + + protected static Map readJson(String json) { + return readJson(new StringReader(json)); + } + + /* + * Writing the JSON-LD object + */ + + public RdfDataset toDataset() throws JsonLDException { + + JsonLdOptions options = new JsonLdOptions(); + if (this.getDocumentLoader() != null) options.setDocumentLoader(this.getDocumentLoader()); + options.setOrdered(true); + + JsonDocument jsonDocument = JsonDocument.of(MediaType.JSON_LD, this.toJsonObject()); + ToRdfApi toRdfApi = JsonLd.toRdf(jsonDocument); + toRdfApi.options(options); + try { + return toRdfApi.get(); + } catch (JsonLdError ex) { + throw new JsonLDException(ex); + } + } + + public String toNQuads() throws JsonLDException, IOException { + + RdfDataset rdfDataset = this.toDataset(); + StringWriter stringWriter = new StringWriter(); + NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); + nQuadsWriter.write(rdfDataset); + return stringWriter.toString(); + } + + public String toJson(boolean pretty) { + + ObjectWriter objectWriter = pretty ? objectWriterPretty : objectWriterDefault; + try { + return objectWriter.writeValueAsString(this.getJsonObject()); + } catch (JsonProcessingException ex) { + throw new RuntimeException("Cannot write JSON: " + ex.getMessage(), ex); + } + } + + public String toJson() { + + return this.toJson(false); + } + + public String normalize(String algorithm) throws JsonLDException, NoSuchAlgorithmException, IOException { + + RdfDataset rdfDataset = this.toDataset(); + rdfDataset = RdfNormalize.normalize(rdfDataset, algorithm); + StringWriter stringWriter = new StringWriter(); + NQuadsWriter nQuadsWriter = new NQuadsWriter(stringWriter); + nQuadsWriter.write(rdfDataset); + return stringWriter.getBuffer().toString(); + } + + public Map toMap() { + return this.getJsonObject(); + } + + public synchronized JsonObject toJsonObject() { + return Json.createObjectBuilder(this.getJsonObject()).build(); + } + + /* + * Helper methods + */ + + public static DocumentLoader getDefaultDocumentLoader(Class cl) { + try { + Field field = cl.getField("DEFAULT_DOCUMENT_LOADER"); + return (DocumentLoader) field.get(null); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + public static List getDefaultJsonLDContexts(Class cl) { + try { + Field field = cl.getField("DEFAULT_JSONLD_CONTEXTS"); + return Arrays.asList((URI[]) field.get(null)); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + public static List getDefaultJsonLDTypes(Class cl) { + try { + Field field = cl.getField("DEFAULT_JSONLD_TYPES"); + return Arrays.asList((String[]) field.get(null)); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + public static String getDefaultJsonLDPredicate(Class cl) { + try { + Field field = cl.getField("DEFAULT_JSONLD_PREDICATE"); + return (String) field.get(null); + } catch (IllegalAccessException | NoSuchFieldException ex) { + throw new Error(ex); + } + } + + /* + * Object methods + */ + + @Override + public String toString() { + return this.toJson(false); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + JsonLDObject that = (JsonLDObject) o; + return Objects.equals(this.getJsonObject(), that.getJsonObject()); + } + + @Override + public int hashCode() { + return Objects.hash(this.getJsonObject()); + } } \ No newline at end of file diff --git a/src/test/java/foundation/identity/jsonld/JsonLDCredential.kt b/src/test/java/foundation/identity/jsonld/JsonLDCredential.kt deleted file mode 100644 index 539bf67..0000000 --- a/src/test/java/foundation/identity/jsonld/JsonLDCredential.kt +++ /dev/null @@ -1,20 +0,0 @@ -package foundation.identity.jsonld - -import foundation.identity.jsonld.JsonLDCredential -import java.net.URI - -class JsonLDCredential : JsonLDObject() { - - companion object { - @JvmField val DEFAULT_JSONLD_CONTEXTS = arrayOf(URI("https://www.w3.org/2018/credentials/v1")) - fun builder() = Builder(JsonLDCredential()) - } - - class Builder>(jsonLdObject: JsonLDObject?) : JsonLDObject.Builder(jsonLdObject) { - override fun build(): JsonLDCredential { - super.build() - return jsonLdObject as JsonLDCredential - } - } -} - diff --git a/src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt b/src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt deleted file mode 100644 index 24495c9..0000000 --- a/src/test/java/foundation/identity/jsonld/JsonLDObjectTests.kt +++ /dev/null @@ -1,61 +0,0 @@ -package foundation.identity.jsonld - -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test -import java.net.URI - -class JsonLDObjectTests { - - companion object { - init { - (JsonLDObject.DEFAULT_DOCUMENT_LOADER as ConfigurableDocumentLoader).isEnableHttps = true - } - } - - @Test - fun createJsonLDObject() { - val jsonLDObject = JsonLDObject.builder().apply { - contexts( - listOf( - URI.create("https://www.w3.org/2018/credentials/v1"), - URI.create("https://w3id.org/citizenship/v1") - ) - ) - types(listOf("PermanentResident", "Person")) - properties( - mapOf( - "givenName" to "Marion", - "familyName" to "Mustermann" - ) - ) - }.build() - Assertions.assertEquals(4, jsonLDObject.toDataset().size()) - } - - @Test - fun createDerivedJsonLDObjectWithDefaultContexts() { - val jsonLDCredential = JsonLDCredential.builder().apply { - contexts( - listOf( - URI("https://w3id.org/citizenship/v1") - ) - ) - defaultContexts(true) - types(listOf("PermanentResident", "Person")) - properties( - mapOf( - "givenName" to "Marion", - "familyName" to "Mustermann" - ) - ) - }.build() - Assertions.assertEquals(4, jsonLDCredential.toDataset().size()) - Assertions.assertEquals( - jsonLDCredential.contexts, listOf( - URI("https://www.w3.org/2018/credentials/v1"), - URI("https://w3id.org/citizenship/v1") - ) - ) - } - -} \ No newline at end of file