From 40e102e4a3228e25baad3897a7e00b7177c0cffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 14:07:42 +0200 Subject: [PATCH 01/10] do not run tests in parallel This is related to #34. --- .../selection/wadm/TestNormalizeAnnotation.java | 6 ++++++ .../selection/wadm/TestRewriteAnnotationHtml.java | 11 +++++++++++ .../selection/wadm/TestRewriteAnnotationTxt.java | 6 ++++++ core/src/test/resources/junit-platform.properties | 2 ++ 4 files changed, 25 insertions(+) create mode 100644 core/src/test/resources/junit-platform.properties diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java index dc752f6..b7bd175 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java @@ -20,6 +20,8 @@ import org.apache.jena.vocabulary.OA; import org.apache.jena.vocabulary.RDF; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; /** * This class is used to test all the wadm normalizers. @@ -69,6 +71,7 @@ private static RewriterConfig makeConfig(String xpath) { // normalizing XPathSelector refinedBy FragmentSelector conforming to RFC5147 character scheme + @Execution(ExecutionMode.SAME_THREAD) @Test public void testAcceptP11WithPath() { normalizerConfig = makeConfig("path(.)"); @@ -100,6 +103,7 @@ public void testAcceptP11WithPath() { .size()); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testAcceptP11WithPathParent() { normalizerConfig = makeConfig("path(parent::*)"); @@ -131,6 +135,7 @@ public void testAcceptP11WithPathParent() { .size()); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testAcceptP11WithPathParentParent() { normalizerConfig = makeConfig("path(parent::*/parent::*)"); @@ -162,6 +167,7 @@ public void testAcceptP11WithPathParentParent() { .size()); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testRewriteP11WithPath() { normalizerConfig = makeConfig("path(.)"); diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java index f0c1151..1ef3f53 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java @@ -28,6 +28,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; /** * This class tests rewriting WADM annotations with HTML images. @@ -103,6 +105,7 @@ private static RewriterConfig makeConfig(String xpath) { return new RewriterConfig(null, false, xpath, true, true); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImage() { normalizerConfig = makeConfig("path(.)"); @@ -248,6 +251,7 @@ public void testForwardInImage() { "end refinement has no extra class"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImageToParent() { normalizerConfig = makeConfig("sel:to-element(.)"); @@ -393,6 +397,7 @@ public void testForwardInImageToParent() { "end refinement has no extra class"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImage2ToElement() { normalizerConfig = makeConfig("sel:to-element(.)"); @@ -539,6 +544,7 @@ public void testForwardInImage2ToElement() { } // works, but not guarantied, since selector goes down to the text leaf + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToLeafInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -684,6 +690,7 @@ public void testBackwardToLeafInPreimage() { "end refinement has no extra class"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToElementInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -829,6 +836,7 @@ public void testBackwardToElementInPreimage() { "end refinement has no extra class"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToHigherInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -974,6 +982,7 @@ public void testBackwardToHigherInPreimage() { "end refinement has no extra class"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardNotInImage() { normalizerConfig = makeConfig("path(.)"); @@ -1118,6 +1127,7 @@ public void testForwardNotInImage() { // select exactly one node in XdmValueResource: selects 0 nodes --- This is totally logical, since this text node // was never a trace:text node. And, we cannot securely use text() here, since the content could come from string // items in the image. Facit: No guaranty about selectors that go down to the text leaf. + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToLeafNotInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -1257,6 +1267,7 @@ public void testBackwardToLeafNotInPreimage() { "end refinement is a sel:Null selector"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToElementNotInPreimage() { normalizerConfig = makeConfig("path(.)"); diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java index 4d16856..2f3278e 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java @@ -26,6 +26,8 @@ import org.apache.jena.vocabulary.RDF; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; /** * This class tests rewriting WADM annotations with HTML images. @@ -84,6 +86,7 @@ private static RewriterConfig backwardConfig(String xpath) { return new RewriterConfig(null, false, xpath, true, true, RewriterConfig.backwardDOMToTextPointClassMap()); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImage() { RewriterConfig config = @@ -197,6 +200,7 @@ public void testForwardInImage() { "end selector has no refinement"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardInPreimage() { RewriterConfig config = @@ -343,6 +347,7 @@ public void testBackwardInPreimage() { "end refinement has no extra class"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardNotInImage() { RewriterConfig config = @@ -484,6 +489,7 @@ public void testForwardNotInImage() { "end refinement is a sel:Null selector"); } + @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardNotInPreimage() { RewriterConfig config = diff --git a/core/src/test/resources/junit-platform.properties b/core/src/test/resources/junit-platform.properties new file mode 100644 index 0000000..4fc2039 --- /dev/null +++ b/core/src/test/resources/junit-platform.properties @@ -0,0 +1,2 @@ +junit.jupiter.execution.parallel.enabled = false +# junit.jupiter.execution.parallel.mode.default = concurrent From 128eeebf88c7fb8506033a188b84f25a25daf601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 14:13:14 +0200 Subject: [PATCH 02/10] updates to Apache Jena 5.6.0 This is related to #34. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0a0a989..7ad0f8f 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 4.5.1 1.4.01 3.18.0 - 5.2.0 + 5.6.0 6.0.1 3.4.0 2.90.0 From 438e707fffeaf82750896cf11b5e5bd1fcfd68f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 14:52:19 +0200 Subject: [PATCH 03/10] investigate where RiotException occurs This is related to #34. --- .../wadm/TestRewriteAnnotationHtml.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java index 1ef3f53..b7e781a 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java @@ -10,9 +10,8 @@ import de.wwu.scdh.annotation.selection.resource.ResourceBuilder; import de.wwu.scdh.annotation.selection.rewriter.BackwardMappingFactory; import de.wwu.scdh.annotation.selection.rewriter.ForwardMappingFactory; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; + +import java.io.*; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -109,14 +108,24 @@ private static RewriterConfig makeConfig(String xpath) { @Test public void testForwardInImage() { normalizerConfig = makeConfig("path(.)"); - model = NormalizeAnnotation.rewrite( - songMapped, - songIri, - songIriHtml, - forwardFactory, - normalizerConfig, - SONG_FW_IN_IMAGE_JSON, - Optional.of("jsonld")); + try { + model = NormalizeAnnotation.rewrite( + songMapped, + songIri, + songIriHtml, + forwardFactory, + normalizerConfig, + SONG_FW_IN_IMAGE_JSON, + Optional.of("jsonld")); + } catch (Exception e) { + System.err.println(e.getMessage()); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + String sStackTrace = sw.toString(); // stack trace as a string + System.err.println(sStackTrace); + throw new RuntimeException(e); + } assertEquals( 1, model.listStatements((Resource) null, OA.hasTarget, (RDFNode) null) From 374dd95088bf9e66d7ad6c81eba69c1436ff654a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 16:57:47 +0200 Subject: [PATCH 04/10] adds JSON-LD context for web annotations This is related to #34. --- core/src/main/resources/context/anno.jsonld | 126 ++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 core/src/main/resources/context/anno.jsonld diff --git a/core/src/main/resources/context/anno.jsonld b/core/src/main/resources/context/anno.jsonld new file mode 100644 index 0000000..1bd517e --- /dev/null +++ b/core/src/main/resources/context/anno.jsonld @@ -0,0 +1,126 @@ +{ + "@context": { + "oa": "http://www.w3.org/ns/oa#", + "dc": "http://purl.org/dc/elements/1.1/", + "dcterms": "http://purl.org/dc/terms/", + "dctypes": "http://purl.org/dc/dcmitype/", + "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#", + "skos": "http://www.w3.org/2004/02/skos/core#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "iana": "http://www.iana.org/assignments/relation/", + "owl": "http://www.w3.org/2002/07/owl#", + "as": "http://www.w3.org/ns/activitystreams#", + "schema": "http://schema.org/", + + "id": {"@type": "@id", "@id": "@id"}, + "type": {"@type": "@id", "@id": "@type"}, + + "Annotation": "oa:Annotation", + "Dataset": "dctypes:Dataset", + "Image": "dctypes:StillImage", + "Video": "dctypes:MovingImage", + "Audio": "dctypes:Sound", + "Text": "dctypes:Text", + "TextualBody": "oa:TextualBody", + "ResourceSelection": "oa:ResourceSelection", + "SpecificResource": "oa:SpecificResource", + "FragmentSelector": "oa:FragmentSelector", + "CssSelector": "oa:CssSelector", + "XPathSelector": "oa:XPathSelector", + "TextQuoteSelector": "oa:TextQuoteSelector", + "TextPositionSelector": "oa:TextPositionSelector", + "DataPositionSelector": "oa:DataPositionSelector", + "SvgSelector": "oa:SvgSelector", + "RangeSelector": "oa:RangeSelector", + "TimeState": "oa:TimeState", + "HttpRequestState": "oa:HttpRequestState", + "CssStylesheet": "oa:CssStyle", + "Choice": "oa:Choice", + "Person": "foaf:Person", + "Software": "as:Application", + "Organization": "foaf:Organization", + "AnnotationCollection": "as:OrderedCollection", + "AnnotationPage": "as:OrderedCollectionPage", + "Audience": "schema:Audience", + + "Motivation": "oa:Motivation", + "bookmarking": "oa:bookmarking", + "classifying": "oa:classifying", + "commenting": "oa:commenting", + "describing": "oa:describing", + "editing": "oa:editing", + "highlighting": "oa:highlighting", + "identifying": "oa:identifying", + "linking": "oa:linking", + "moderating": "oa:moderating", + "questioning": "oa:questioning", + "replying": "oa:replying", + "reviewing": "oa:reviewing", + "assessing": "oa:assessing", + "tagging": "oa:tagging", + + "auto": "oa:autoDirection", + "ltr": "oa:ltrDirection", + "rtl": "oa:rtlDirection", + + "body": {"@type": "@id", "@id": "oa:hasBody"}, + "target": {"@type": "@id", "@id": "oa:hasTarget"}, + "source": {"@type": "@id", "@id": "oa:hasSource"}, + "selector": {"@type": "@id", "@id": "oa:hasSelector"}, + "state": {"@type": "@id", "@id": "oa:hasState"}, + "scope": {"@type": "@id", "@id": "oa:hasScope"}, + "refinedBy": {"@type": "@id", "@id": "oa:refinedBy"}, + "startSelector": {"@type": "@id", "@id": "oa:hasStartSelector"}, + "endSelector": {"@type": "@id", "@id": "oa:hasEndSelector"}, + "renderedVia": {"@type": "@id", "@id": "oa:renderedVia"}, + "creator": {"@type": "@id", "@id": "dcterms:creator"}, + "generator": {"@type": "@id", "@id": "as:generator"}, + "rights": {"@type": "@id", "@id": "dcterms:rights"}, + "homepage": {"@type": "@id", "@id": "foaf:homepage"}, + "via": {"@type": "@id", "@id": "oa:via"}, + "canonical": {"@type": "@id", "@id": "oa:canonical"}, + "stylesheet": {"@type": "@id", "@id": "oa:styledBy"}, + "cached": {"@type": "@id", "@id": "oa:cachedSource"}, + "conformsTo": {"@type": "@id", "@id": "dcterms:conformsTo"}, + "items": {"@type": "@id", "@id": "as:items", "@container": "@list"}, + "partOf": {"@type": "@id", "@id": "as:partOf"}, + "first": {"@type": "@id", "@id": "as:first"}, + "last": {"@type": "@id", "@id": "as:last"}, + "next": {"@type": "@id", "@id": "as:next"}, + "prev": {"@type": "@id", "@id": "as:prev"}, + "audience": {"@type": "@id", "@id": "schema:audience"}, + "motivation": {"@type": "@vocab", "@id": "oa:motivatedBy"}, + "purpose": {"@type": "@vocab", "@id": "oa:hasPurpose"}, + "textDirection": {"@type": "@vocab", "@id": "oa:textDirection"}, + + "accessibility": "schema:accessibilityFeature", + "bodyValue": "oa:bodyValue", + "format": "dc:format", + "language": "dc:language", + "processingLanguage": "oa:processingLanguage", + "value": "rdf:value", + "exact": "oa:exact", + "prefix": "oa:prefix", + "suffix": "oa:suffix", + "styleClass": "oa:styleClass", + "name": "foaf:name", + "email": "foaf:mbox", + "email_sha1": "foaf:mbox_sha1sum", + "nickname": "foaf:nick", + "label": "rdfs:label", + + "created": {"@id": "dcterms:created", "@type": "xsd:dateTime"}, + "modified": {"@id": "dcterms:modified", "@type": "xsd:dateTime"}, + "generated": {"@id": "dcterms:issued", "@type": "xsd:dateTime"}, + "sourceDate": {"@id": "oa:sourceDate", "@type": "xsd:dateTime"}, + "sourceDateStart": {"@id": "oa:sourceDateStart", "@type": "xsd:dateTime"}, + "sourceDateEnd": {"@id": "oa:sourceDateEnd", "@type": "xsd:dateTime"}, + + "start": {"@id": "oa:start", "@type": "xsd:nonNegativeInteger"}, + "end": {"@id": "oa:end", "@type": "xsd:nonNegativeInteger"}, + "total": {"@id": "as:totalItems", "@type": "xsd:nonNegativeInteger"}, + "startIndex": {"@id": "as:startIndex", "@type": "xsd:nonNegativeInteger"} + } +} From 28094f0ce831536cdf685e2ce402b92c9bac8461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 18:27:02 +0200 Subject: [PATCH 05/10] adds JSON-LD document loader with statically cached files This is related to #34. --- .../selection/utils/StaticDocumentLoader.java | 148 ++++++++++++++++++ .../main/resources/context/context-map.json | 8 + .../utils/TestStaticDocumentLoader.java | 26 +++ 3 files changed, 182 insertions(+) create mode 100644 core/src/main/java/de/wwu/scdh/annotation/selection/utils/StaticDocumentLoader.java create mode 100644 core/src/main/resources/context/context-map.json create mode 100644 core/src/test/java/de/wwu/scdh/annotation/selection/utils/TestStaticDocumentLoader.java diff --git a/core/src/main/java/de/wwu/scdh/annotation/selection/utils/StaticDocumentLoader.java b/core/src/main/java/de/wwu/scdh/annotation/selection/utils/StaticDocumentLoader.java new file mode 100644 index 0000000..ac06cdc --- /dev/null +++ b/core/src/main/java/de/wwu/scdh/annotation/selection/utils/StaticDocumentLoader.java @@ -0,0 +1,148 @@ +package de.wwu.scdh.annotation.selection.utils; + +import com.apicatalog.jsonld.JsonLdError; +import com.apicatalog.jsonld.JsonLdOptions; +import com.apicatalog.jsonld.document.Document; +import com.apicatalog.jsonld.loader.DocumentLoader; +import com.apicatalog.jsonld.loader.DocumentLoaderOptions; +import com.apicatalog.jsonld.loader.FileLoader; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; +import jakarta.json.JsonStructure; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link StaticDocumentLoader} is a {@link DocumentLoader} that returns local assets instead of remote one. + * It is configured with a resource mapping that maps URIs to local assets. Its purpose is to speed up + * JSON-LD processing with version pinned contexts, as for Web Annotations.

+ * + * The loader delegated to a fallback loader when the requested URI is not in the resource mapping.

+ * + * The structure of the resource mapping JSON file: + * + *

+ *     {
+ *       "https://www.w3.org/ns/anno.jsonld": {
+ *         "path": "anno.jsonld"
+ *       },
+ *       "http://www.w3.org/ns/anno.jsonld": {
+ *         "path": "anno.jsonld"
+ *       }
+ *     }
+ * 
+ */ +public class StaticDocumentLoader implements DocumentLoader { + + private static final Logger LOG = LoggerFactory.getLogger(StaticDocumentLoader.class); + + /** + * A default context mapping resource. + */ + public static final URL CONTEXT_MAPPING = StaticDocumentLoader.class.getResource("/context/context-map.json"); + + private final DocumentLoader fallbackLoader; + + private final Map contextMapping; + + private final boolean delegateOnError; + + /** + * Creates a new {@link StaticDocumentLoader} from a resource mapping given by {@link File}. + * @param contextMap - a JSON {@link File>} with the resource mapping + * @param fallbackLoader - a {@link DocumentLoader} used to handle request for non-mapped resources + * @param delegateOnError - whether to delegate the request to the fallback, when loading of a local asset failed. + */ + public StaticDocumentLoader(final File contextMap, final DocumentLoader fallbackLoader, boolean delegateOnError) { + this.fallbackLoader = fallbackLoader; + this.delegateOnError = delegateOnError; + contextMapping = setup(contextMap); + } + + /** + * Creates a new {@link StaticDocumentLoader} from the {@link StaticDocumentLoader#CONTEXT_MAPPING}. + */ + public StaticDocumentLoader() { + fallbackLoader = (new JsonLdOptions()).getDocumentLoader(); // default loader + delegateOnError = true; + File defaultContextMapping = new File(CONTEXT_MAPPING.getPath()); + contextMapping = setup(defaultContextMapping); + } + + /** + * {@inheritDoc} + */ + @Override + public Document loadDocument(URI url, DocumentLoaderOptions options) throws JsonLdError { + if (contextMapping.containsKey(url)) { + URI file = contextMapping.get(url); + FileLoader fileLoader = new FileLoader(); + try { + return fileLoader.loadDocument(file, options); + } catch (JsonLdError e) { + LOG.error("failed to load static asset for {}: {}", url, e.getMessage()); + if (delegateOnError) { + return fallbackLoader.loadDocument(url, options); + } else { + throw new JsonLdError(e.getCode(), e.getMessage()); + } + } + } else { + // delegate to fallback loader + return fallbackLoader.loadDocument(url, options); + } + } + + private Map setup(File contextMap) { + Path path = contextMap.toPath().getParent(); + Map assets = new HashMap<>(); + + try { + JsonReader jsonReader = Json.createReader(new FileReader(contextMap)); + JsonStructure jsonStructure = jsonReader.read(); + JsonObject root = jsonStructure.asJsonObject(); + for (String url : root.keySet()) { + try { + URI remote = new URI(url); + String relative = root.get(url).asJsonObject().getString("path"); + File resolved = path.resolve(relative).toFile(); + if (resolved.isFile()) { + assets.put(remote, resolved.toURI()); + } else { + LOG.error( + "context map entry {} configures file {}, which resolves to {}. File not present", + url, + relative, + resolved); + } + } catch (URISyntaxException e) { + LOG.error("context map entry {} is not a valid URI. Continuing without this entry", url); + } catch (Exception e) { + LOG.error("invalid context map entry {}. Continuing without this entry", url); + } + } + } catch (FileNotFoundException e) { + LOG.error("file not found: {}\nContinuing without context map", contextMap); + } + return Map.copyOf(assets); // makes map unmodifiable + } + + /** + * Tells whether this instance has a local version for a URI. + * @param uri - the remote URI + * @return - true if a local version is available. + */ + public boolean hasLocal(URI uri) { + return contextMapping.containsKey(uri); + } +} diff --git a/core/src/main/resources/context/context-map.json b/core/src/main/resources/context/context-map.json new file mode 100644 index 0000000..22a9b71 --- /dev/null +++ b/core/src/main/resources/context/context-map.json @@ -0,0 +1,8 @@ +{ + "https://www.w3.org/ns/anno.jsonld": { + "path": "anno.jsonld" + }, + "http://www.w3.org/ns/anno.jsonld": { + "path": "anno.jsonld" + } +} \ No newline at end of file diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/utils/TestStaticDocumentLoader.java b/core/src/test/java/de/wwu/scdh/annotation/selection/utils/TestStaticDocumentLoader.java new file mode 100644 index 0000000..9ba47c4 --- /dev/null +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/utils/TestStaticDocumentLoader.java @@ -0,0 +1,26 @@ +package de.wwu.scdh.annotation.selection.utils; + +import static org.junit.jupiter.api.Assertions.*; + +import java.net.URI; +import java.net.URISyntaxException; +import org.junit.jupiter.api.Test; + +public class TestStaticDocumentLoader { + + @Test + public void testDefaultContextMapping() { + assertNotNull(StaticDocumentLoader.CONTEXT_MAPPING, "context mapping exists and is accessible"); + } + + @Test + public void testNoArgumentConstructor() throws URISyntaxException { + StaticDocumentLoader loader = new StaticDocumentLoader(); + assertTrue( + loader.hasLocal(new URI("https://www.w3.org/ns/anno.jsonld")), + "has local version of Web Annotations context (https)"); + assertTrue( + loader.hasLocal(new URI("http://www.w3.org/ns/anno.jsonld")), + "has local version of Web Annotations context (http)"); + } +} From e80d7b748adafef0d716b660e4b894e511a025e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 19:41:07 +0200 Subject: [PATCH 06/10] set JSON-LD options with static loader when parsing RDF This is closes to #34. --- .../selection/cli/NormalizeWADM.java | 33 ++++---- .../selection/wadm/NormalizeAnnotation.java | 75 +++++++++---------- .../wadm/TestRewriteAnnotationHtml.java | 1 - pom.xml | 2 +- 4 files changed, 56 insertions(+), 55 deletions(-) diff --git a/cli/src/main/java/de/wwu/scdh/annotation/selection/cli/NormalizeWADM.java b/cli/src/main/java/de/wwu/scdh/annotation/selection/cli/NormalizeWADM.java index 68eb2ef..5e2c4e6 100644 --- a/cli/src/main/java/de/wwu/scdh/annotation/selection/cli/NormalizeWADM.java +++ b/cli/src/main/java/de/wwu/scdh/annotation/selection/cli/NormalizeWADM.java @@ -1,13 +1,12 @@ package de.wwu.scdh.annotation.selection.cli; import com.apicatalog.jsonld.JsonLd; +import com.apicatalog.jsonld.JsonLdEmbed; +import com.apicatalog.jsonld.JsonLdOptions; import com.apicatalog.jsonld.api.FramingApi; -import com.apicatalog.jsonld.document.Document; import com.apicatalog.jsonld.document.JsonDocument; -import com.apicatalog.jsonld.document.RdfDocument; -import com.apicatalog.jsonld.lang.Keywords; -import com.apicatalog.rdf.RdfDataset; import de.wwu.scdh.annotation.selection.Resource; +import de.wwu.scdh.annotation.selection.utils.StaticDocumentLoader; import de.wwu.scdh.annotation.selection.wadm.NormalizeAnnotation; import jakarta.json.Json; import jakarta.json.JsonArray; @@ -30,9 +29,11 @@ import org.apache.jena.riot.RDFLanguages; import org.apache.jena.riot.RDFWriterRegistry; import org.apache.jena.riot.WriterDatasetRIOT; -import org.apache.jena.riot.system.JenaTitanium; import org.apache.jena.riot.system.PrefixMap; import org.apache.jena.riot.system.PrefixMapZero; +import org.apache.jena.riot.system.jsonld.JenaToTitanium; +import org.apache.jena.sparql.core.DatasetGraph; +import org.apache.jena.sparql.core.DatasetGraphFactory; import org.apache.jena.sparql.core.DatasetImpl; import org.apache.jena.sparql.util.Context; import picocli.CommandLine; @@ -123,17 +124,19 @@ public Integer call() throws Exception { // do the framing and serialization with Titanium try { - RdfDataset rdfds = JenaTitanium.convert(ds.asDatasetGraph()); - Document rdfdoc = RdfDocument.of(rdfds); - // The Titanium API for framing does not allow - // RdfDocuments. Thus, we make a JsonDocument - // representing the graph like for plain output - JsonArray array = JsonLd.fromRdf(rdfdoc).get(); - JsonObject jsonStructure = - Json.createObjectBuilder().add(Keywords.GRAPH, array).build(); - JsonDocument jsonDocument = JsonDocument.of(jsonStructure); + // use titanium for framing + JsonLdOptions options = new JsonLdOptions(); + // options.setBase(null); + options.setDocumentLoader(new StaticDocumentLoader()); + options.setOmitGraph(true); + options.setEmbed(JsonLdEmbed.ALWAYS); + // add more options here! + DatasetGraph dsg = DatasetGraphFactory.create(model.getGraph()); + JsonArray ja = JenaToTitanium.convert(dsg, options); + JsonDocument jDoc = JsonDocument.of(ja); // do the framing - FramingApi api = JsonLd.frame(jsonDocument, JsonDocument.of(framingUri.openStream())); + FramingApi api = JsonLd.frame(jDoc, JsonDocument.of(framingUri.openStream())); + api.loader(options.getDocumentLoader()); // important to set loader! final JsonObject output = api.get(); // JsonOutput.print(System.out, true); diff --git a/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java b/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java index 77521bd..97ba50f 100644 --- a/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java +++ b/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java @@ -1,18 +1,17 @@ package de.wwu.scdh.annotation.selection.wadm; +import com.apicatalog.jsonld.JsonLdOptions; import de.wwu.scdh.annotation.selection.*; +import de.wwu.scdh.annotation.selection.utils.StaticDocumentLoader; import java.io.InputStream; import java.net.URI; import java.util.Optional; import java.util.function.Consumer; -import org.apache.jena.ontology.OntModelSpec; -import org.apache.jena.ontology.impl.OntModelImpl; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ResIterator; import org.apache.jena.rdf.model.Resource; -import org.apache.jena.riot.Lang; -import org.apache.jena.riot.RDFDataMgr; -import org.apache.jena.riot.RDFLanguages; +import org.apache.jena.riot.*; +import org.apache.jena.riot.system.jsonld.TitaniumJsonLdOptions; import org.apache.jena.vocabulary.OA; import org.apache.jena.vocabulary.RDF; import org.slf4j.Logger; @@ -151,12 +150,10 @@ public static Model normalize( RewriterConfig normalizerConfig, String graph, Optional lang) { - Model model; - if (lang.isEmpty()) { - model = RDFDataMgr.loadModel(graph); - } else { - model = RDFDataMgr.loadModel(graph, RDFLanguages.nameToLang(lang.get())); - } + RDFParserBuilder parserBuilder = RDFParser.source(graph); + setParserOptions(parserBuilder); + lang.ifPresent(l -> parserBuilder.lang(RDFLanguages.nameToLang(l))); + Model model = parserBuilder.toModel(); return normalize(resource, iri, rewriterFactory, normalizerConfig, model); } @@ -183,12 +180,10 @@ public static Model rewrite( RewriterConfig normalizerConfig, String graph, Optional lang) { - Model model; - if (lang.isEmpty()) { - model = RDFDataMgr.loadModel(graph); - } else { - model = RDFDataMgr.loadModel(graph, RDFLanguages.nameToLang(lang.get())); - } + RDFParserBuilder parserBuilder = RDFParser.source(graph); + setParserOptions(parserBuilder); + lang.ifPresent(l -> parserBuilder.lang(RDFLanguages.nameToLang(l))); + Model model = parserBuilder.toModel(); return rewrite(resource, iri, rewriteIri, rewriterFactory, normalizerConfig, model); } @@ -213,18 +208,20 @@ public static Model normalize( InputStream input, Optional lang, Optional modelBase) { - Model model = new OntModelImpl(OntModelSpec.OWL_DL_MEM); - Lang langHint; - if (lang.isEmpty()) { - - langHint = RDFLanguages.nameToLang(lang.get()); + RDFParserBuilder parserBuilder = RDFParser.source(input); + modelBase.ifPresent(parserBuilder::base); + setParserOptions(parserBuilder); + if (lang.isPresent()) { + parserBuilder.lang(RDFLanguages.nameToLang(lang.get())); } else { - langHint = RDFLanguages.NTRIPLES; + parserBuilder.lang(Lang.NTRIPLES); } - if (modelBase.isEmpty()) { - RDFDataMgr.read(model, input, langHint); - } else { - RDFDataMgr.read(model, input, modelBase.get(), langHint); + Model model = parserBuilder.toModel(); + try { + input.close(); + LOG.warn("closed input stream"); + } catch (Exception ignored) { + LOG.warn("failed to close input stream"); } return normalize(resource, iri, rewriterFactory, normalizerConfig, model); } @@ -253,19 +250,21 @@ public static Model rewrite( InputStream input, Optional lang, Optional modelBase) { - Model model = new OntModelImpl(OntModelSpec.OWL_DL_MEM); - Lang langHint; - if (lang.isEmpty()) { - - langHint = RDFLanguages.nameToLang(lang.get()); - } else { - langHint = RDFLanguages.NTRIPLES; - } - if (modelBase.isEmpty()) { - RDFDataMgr.read(model, input, langHint); + RDFParserBuilder parserBuilder = RDFParser.source(input); + modelBase.ifPresent(parserBuilder::base); + setParserOptions(parserBuilder); + if (lang.isPresent()) { + parserBuilder.lang(RDFLanguages.nameToLang(lang.get())); } else { - RDFDataMgr.read(model, input, modelBase.get(), langHint); + parserBuilder.lang(Lang.NTRIPLES); } + Model model = parserBuilder.toModel(); return rewrite(resource, iri, rewriteIri, rewriterFactory, normalizerConfig, model); } + + private static void setParserOptions(RDFParserBuilder parserBuilder) { + JsonLdOptions options = new JsonLdOptions(); + options.setDocumentLoader(new StaticDocumentLoader()); + parserBuilder.set(TitaniumJsonLdOptions.JSONLD_OPTIONS, options); + } } diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java index b7e781a..bf19c66 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java @@ -10,7 +10,6 @@ import de.wwu.scdh.annotation.selection.resource.ResourceBuilder; import de.wwu.scdh.annotation.selection.rewriter.BackwardMappingFactory; import de.wwu.scdh.annotation.selection.rewriter.ForwardMappingFactory; - import java.io.*; import java.net.MalformedURLException; import java.net.URI; diff --git a/pom.xml b/pom.xml index 7ad0f8f..eb0354b 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 4.5.1 1.4.01 3.18.0 - 5.6.0 + 6.0.0 6.0.1 3.4.0 2.90.0 From 5ea598bee52c37ba8095057b7bb6835fdc20340b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 19:42:55 +0200 Subject: [PATCH 07/10] Revert "do not run tests in parallel" This reverts commit 40e102e4a3228e25baad3897a7e00b7177c0cffe. --- .../selection/wadm/TestNormalizeAnnotation.java | 6 ------ .../selection/wadm/TestRewriteAnnotationHtml.java | 11 ----------- .../selection/wadm/TestRewriteAnnotationTxt.java | 6 ------ core/src/test/resources/junit-platform.properties | 2 -- 4 files changed, 25 deletions(-) delete mode 100644 core/src/test/resources/junit-platform.properties diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java index b7bd175..dc752f6 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestNormalizeAnnotation.java @@ -20,8 +20,6 @@ import org.apache.jena.vocabulary.OA; import org.apache.jena.vocabulary.RDF; import org.junit.jupiter.api.*; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; /** * This class is used to test all the wadm normalizers. @@ -71,7 +69,6 @@ private static RewriterConfig makeConfig(String xpath) { // normalizing XPathSelector refinedBy FragmentSelector conforming to RFC5147 character scheme - @Execution(ExecutionMode.SAME_THREAD) @Test public void testAcceptP11WithPath() { normalizerConfig = makeConfig("path(.)"); @@ -103,7 +100,6 @@ public void testAcceptP11WithPath() { .size()); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testAcceptP11WithPathParent() { normalizerConfig = makeConfig("path(parent::*)"); @@ -135,7 +131,6 @@ public void testAcceptP11WithPathParent() { .size()); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testAcceptP11WithPathParentParent() { normalizerConfig = makeConfig("path(parent::*/parent::*)"); @@ -167,7 +162,6 @@ public void testAcceptP11WithPathParentParent() { .size()); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testRewriteP11WithPath() { normalizerConfig = makeConfig("path(.)"); diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java index bf19c66..f6d4b69 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java @@ -26,8 +26,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; /** * This class tests rewriting WADM annotations with HTML images. @@ -103,7 +101,6 @@ private static RewriterConfig makeConfig(String xpath) { return new RewriterConfig(null, false, xpath, true, true); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImage() { normalizerConfig = makeConfig("path(.)"); @@ -259,7 +256,6 @@ public void testForwardInImage() { "end refinement has no extra class"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImageToParent() { normalizerConfig = makeConfig("sel:to-element(.)"); @@ -405,7 +401,6 @@ public void testForwardInImageToParent() { "end refinement has no extra class"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImage2ToElement() { normalizerConfig = makeConfig("sel:to-element(.)"); @@ -552,7 +547,6 @@ public void testForwardInImage2ToElement() { } // works, but not guarantied, since selector goes down to the text leaf - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToLeafInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -698,7 +692,6 @@ public void testBackwardToLeafInPreimage() { "end refinement has no extra class"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToElementInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -844,7 +837,6 @@ public void testBackwardToElementInPreimage() { "end refinement has no extra class"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToHigherInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -990,7 +982,6 @@ public void testBackwardToHigherInPreimage() { "end refinement has no extra class"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardNotInImage() { normalizerConfig = makeConfig("path(.)"); @@ -1135,7 +1126,6 @@ public void testForwardNotInImage() { // select exactly one node in XdmValueResource: selects 0 nodes --- This is totally logical, since this text node // was never a trace:text node. And, we cannot securely use text() here, since the content could come from string // items in the image. Facit: No guaranty about selectors that go down to the text leaf. - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToLeafNotInPreimage() { normalizerConfig = makeConfig("path(.)"); @@ -1275,7 +1265,6 @@ public void testBackwardToLeafNotInPreimage() { "end refinement is a sel:Null selector"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardToElementNotInPreimage() { normalizerConfig = makeConfig("path(.)"); diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java index 2f3278e..4d16856 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationTxt.java @@ -26,8 +26,6 @@ import org.apache.jena.vocabulary.RDF; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; /** * This class tests rewriting WADM annotations with HTML images. @@ -86,7 +84,6 @@ private static RewriterConfig backwardConfig(String xpath) { return new RewriterConfig(null, false, xpath, true, true, RewriterConfig.backwardDOMToTextPointClassMap()); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardInImage() { RewriterConfig config = @@ -200,7 +197,6 @@ public void testForwardInImage() { "end selector has no refinement"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardInPreimage() { RewriterConfig config = @@ -347,7 +343,6 @@ public void testBackwardInPreimage() { "end refinement has no extra class"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testForwardNotInImage() { RewriterConfig config = @@ -489,7 +484,6 @@ public void testForwardNotInImage() { "end refinement is a sel:Null selector"); } - @Execution(ExecutionMode.SAME_THREAD) @Test public void testBackwardNotInPreimage() { RewriterConfig config = diff --git a/core/src/test/resources/junit-platform.properties b/core/src/test/resources/junit-platform.properties deleted file mode 100644 index 4fc2039..0000000 --- a/core/src/test/resources/junit-platform.properties +++ /dev/null @@ -1,2 +0,0 @@ -junit.jupiter.execution.parallel.enabled = false -# junit.jupiter.execution.parallel.mode.default = concurrent From a220954de36b442c13ab58dab5a3203e92b292a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 19:51:53 +0200 Subject: [PATCH 08/10] Revert "investigate where RiotException occurs" This reverts commit 438e707fffeaf82750896cf11b5e5bd1fcfd68f1. # Conflicts: # core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java --- .../wadm/TestRewriteAnnotationHtml.java | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java index f6d4b69..f0c1151 100644 --- a/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java +++ b/core/src/test/java/de/wwu/scdh/annotation/selection/wadm/TestRewriteAnnotationHtml.java @@ -10,7 +10,9 @@ import de.wwu.scdh.annotation.selection.resource.ResourceBuilder; import de.wwu.scdh.annotation.selection.rewriter.BackwardMappingFactory; import de.wwu.scdh.annotation.selection.rewriter.ForwardMappingFactory; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -104,24 +106,14 @@ private static RewriterConfig makeConfig(String xpath) { @Test public void testForwardInImage() { normalizerConfig = makeConfig("path(.)"); - try { - model = NormalizeAnnotation.rewrite( - songMapped, - songIri, - songIriHtml, - forwardFactory, - normalizerConfig, - SONG_FW_IN_IMAGE_JSON, - Optional.of("jsonld")); - } catch (Exception e) { - System.err.println(e.getMessage()); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - String sStackTrace = sw.toString(); // stack trace as a string - System.err.println(sStackTrace); - throw new RuntimeException(e); - } + model = NormalizeAnnotation.rewrite( + songMapped, + songIri, + songIriHtml, + forwardFactory, + normalizerConfig, + SONG_FW_IN_IMAGE_JSON, + Optional.of("jsonld")); assertEquals( 1, model.listStatements((Resource) null, OA.hasTarget, (RDFNode) null) From bdeaef09e4db323b4b5a5e5075f29f4eb7387f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 20:01:05 +0200 Subject: [PATCH 09/10] adds documentation about parsing options This is related to #34. --- .../selection/wadm/NormalizeAnnotation.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java b/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java index 97ba50f..dc7793a 100644 --- a/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java +++ b/core/src/main/java/de/wwu/scdh/annotation/selection/wadm/NormalizeAnnotation.java @@ -133,7 +133,12 @@ public static Model rewrite( /** * Normalize all annotations in a {@link Model} given by a URI * as {@link String} which may reference a local file (file URI) - * or an online resource. + * or an online resource.

+ * + * Note, that this method sets options to the RDF parser, e.g., the {@link StaticDocumentLoader} as JSON-LD + * document loader. If you want full control over RDF parsing, the use + * {@link NormalizeAnnotation#normalize(de.wwu.scdh.annotation.selection.Resource, URI, RewriterFactory, RewriterConfig, Model)} + * instead. * * @param resource - the resource the rewriting has to done with * @param iri - the IRI of sources (oa:hasSource) the rewriting has to done on @@ -161,7 +166,12 @@ public static Model normalize( * Rewrite all annotations in the provided {@link Model}. In contrast to * {@link NormalizeAnnotation#normalize(de.wwu.scdh.annotation.selection.Resource, URI, RewriterFactory, RewriterConfig, String, Optional)} * this method also rewrites the oa:hasSource property and is thus suitable for transforming selectors - * between representations. + * between representations.

+ * + * Note, that this method sets options to the RDF parser, e.g., the {@link StaticDocumentLoader} as JSON-LD + * document loader. If you want full control over RDF parsing, the use + * {@link NormalizeAnnotation#rewrite(de.wwu.scdh.annotation.selection.Resource, URI, URI, RewriterFactory, RewriterConfig, Model)} + * instead. * * @param resource - the resource the rewriting has to done with. Should be a {@link MappedResource}. * @param iri - the IRI of sources (oa:hasSource) the rewriting has to done on @@ -189,7 +199,12 @@ public static Model rewrite( /** * Normalize all annotations in a {@link Model} which is read from - * an {@link InputStream}. + * an {@link InputStream}.

+ * + * Note, that this method sets options to the RDF parser, e.g., the {@link StaticDocumentLoader} as JSON-LD + * document loader. If you want full control over RDF parsing, the use + * {@link NormalizeAnnotation#normalize(de.wwu.scdh.annotation.selection.Resource, URI, RewriterFactory, RewriterConfig, Model)} + * instead. * * @param resource - the resource the rewriting has to done with * @param iri - the IRI of sources (oa:hasSource) the rewriting has to done on @@ -230,8 +245,13 @@ public static Model normalize( * Rewrite all annotations in the provided {@link Model}. In contrast to * {@link NormalizeAnnotation#normalize(de.wwu.scdh.annotation.selection.Resource, URI, RewriterFactory, RewriterConfig, InputStream, Optional, Optional)} * this method also rewrites the oa:hasSource property and is thus suitable for transforming selectors - * between representations. + * between representations.

* + * Note, that this method sets options to the RDF parser, e.g., the {@link StaticDocumentLoader} as JSON-LD + * document loader. If you want full control over RDF parsing, the use + * {@link NormalizeAnnotation#rewrite(de.wwu.scdh.annotation.selection.Resource, URI, URI, RewriterFactory, RewriterConfig, Model)} + * instead. + * * * @param resource - the resource the rewriting has to done with. Should be a {@link MappedResource}. * @param iri - the IRI of sources (oa:hasSource) the rewriting has to done on * @param rewriterFactory - a factory that returns a rewriter for a point @@ -262,6 +282,10 @@ public static Model rewrite( return rewrite(resource, iri, rewriteIri, rewriterFactory, normalizerConfig, model); } + /** + * Sets RDF parser options. + * @param parserBuilder - the Apache Jena {@link RDFParserBuilder} + */ private static void setParserOptions(RDFParserBuilder parserBuilder) { JsonLdOptions options = new JsonLdOptions(); options.setDocumentLoader(new StaticDocumentLoader()); From 3321dc37cdaf8f9c8e81acc1839465389238d00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 27 Aug 2026 20:26:42 +0200 Subject: [PATCH 10/10] use JDK 21 This is related to #34. --- .github/workflows/deploy.yaml | 2 +- .github/workflows/test.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 30b7012..457e8ad 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -17,7 +17,7 @@ jobs: - name: Set up JDK, for pushing into github package registry uses: actions/setup-java@v5 with: - java-version: '25' + java-version: '21' distribution: 'temurin' cache: maven diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index df45c47..0c05581 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v5 with: - java-version: '17' + java-version: '21' distribution: 'temurin' cache: maven