From 9769788d93f47772c96a0fa4f18b565820df80b9 Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Mon, 8 Dec 2025 17:09:59 +0100
Subject: [PATCH 01/12] Adding an S
---
.../io/serialization/LineEndingOptions.java | 6 +++
.../io/serialization/PrettyPrintOptions.java | 39 ++++++++++++++++
.../io/serialization/UsesPrefixOptions.java | 32 +++++++++++++
.../canonical/RDFC10SerializerOptions.java | 8 ++--
.../nquads/NQuadsSerializerOptions.java | 8 ++--
.../ntriples/NTriplesSerializerOptions.java | 8 ++--
...tion.java => RDFXMLSerializerOptions.java} | 34 ++++++++------
.../trig/TriGSerializerOptions.java | 8 ++--
.../turtle/TurtleSerializerOptions.java | 8 ++--
.../io/parser/rdfxml/RDFXMLCircularTest.java | 4 +-
.../rdfxml/RDFXMLSerializerTest.java | 30 ++++++------
.../serialization/rdfxml/XmlConfigTest.java | 46 +++++++++----------
12 files changed, 157 insertions(+), 74 deletions(-)
create mode 100644 src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java
create mode 100644 src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
create mode 100644 src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
rename src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/{RDFXMLSerializerOption.java => RDFXMLSerializerOptions.java} (93%)
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java
new file mode 100644
index 000000000..6fedb34f4
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java
@@ -0,0 +1,6 @@
+package fr.inria.corese.core.next.api.io.serialization;
+
+public interface LineEndingOptions {
+
+ String getLineEnding();
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
new file mode 100644
index 000000000..b7ab0c79b
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
@@ -0,0 +1,39 @@
+package fr.inria.corese.core.next.api.io.serialization;
+
+public interface PrettyPrintOptions {
+
+ /**
+ * Returns the string used for indentation when pretty-printing.
+ *
+ * @return The indentation string.
+ */
+ String getIndent();
+
+ /**
+ * Checks if human-readable formatting (pretty-printing) is enabled.
+ *
+ * @return {@code true} if pretty-printing is enabled, {@code false} otherwise.
+ */
+ boolean prettyPrint();
+
+ /**
+ * Returns the maximum desired line length before the serializer attempts to break lines.
+ *
+ * @return The maximum line length.
+ */
+ int getMaxLineLength();
+
+ /**
+ * Checks if subjects should be sorted alphabetically in the output.
+ *
+ * @return {@code true} if subject sorting is enabled, {@code false} otherwise.
+ */
+ boolean sortSubjects();
+
+ /**
+ * Checks if predicates should be sorted alphabetically within a subject group.
+ *
+ * @return {@code true} if predicate sorting is enabled, {@code false} otherwise.
+ */
+ boolean sortPredicates();
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
new file mode 100644
index 000000000..7ccbbb3b7
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
@@ -0,0 +1,32 @@
+package fr.inria.corese.core.next.api.io.serialization;
+
+import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
+import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
+
+public interface UsesPrefixOptions {
+
+ /**
+ * Checks if prefix declarations should be used for compact IRIs.
+ *
+ * @return {@code true} if prefixes are used, {@code false} otherwise.
+ */
+ boolean usePrefixes();
+ /**
+ * Checks if the serializer should automatically discover and declare prefixes.
+ *
+ * @return {@code true} if auto-declaration is enabled, {@code false} otherwise.
+ */
+ boolean autoDeclarePrefixes();
+ /**
+ * Returns the policy for ordering prefix declarations.
+ *
+ * @return The {@link PrefixOrderingEnum} for prefix ordering.
+ */
+ public PrefixOrderingEnum getPrefixOrdering();
+ /**
+ * Returns an unmodifiable map of custom URI prefixes.
+ *
+ * @return The {@link PrefixHandler} managing all prefix mappings.
+ */
+ public PrefixHandler getPrefixHandler();
+}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerOptions.java
index afc6ef596..5615d78a4 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerOptions.java
@@ -1,17 +1,17 @@
package fr.inria.corese.core.next.impl.io.serialization.canonical;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
/**
* Configuration for Canonical RDF serialization format (RDFC-1.0).
- * This class extends {@link AbstractSerializerOption} and provides specific defaults
+ * This class extends {@link AbstractSerializerOptions} and provides specific defaults
* and options tailored for the RDFC-10 canonicalization algorithm.
* It includes options relevant to blank node canonicalization, such as the hashing algorithm
* to use, the depth factor for graph isomorphism, and the permutation limit.
* Use the {@link Builder} class to create instances of {@code CanonicalOption}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class RDFC10SerializerOptions extends AbstractSerializerOption {
+public class RDFC10SerializerOptions extends AbstractSerializerOptions {
/**
* Enumeration for the supported hashing algorithms.
@@ -74,7 +74,7 @@ public int getPermutationLimit() {
* Provides a fluent API for constructing {@code CanonicalOption} instances with default values
* specific to the Canonical RDF format.
*/
- public static class Builder extends AbstractSerializerOption.AbstractBuilder {
+ public static class Builder extends AbstractSerializerOptions.AbstractBuilder {
private HashAlgorithm hashAlgorithm = HashAlgorithm.SHA_256;
private int depthFactor = 5;
private int permutationLimit = 50000;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializerOptions.java
index 1367d6697..935f2f752 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializerOptions.java
@@ -1,16 +1,16 @@
package fr.inria.corese.core.next.impl.io.serialization.nquads;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOptions;
/**
* Configuration for N-Quads serialization format.
- * This class extends {@link AbstractNFamilyOption} and provides specific defaults
+ * This class extends {@link AbstractNFamilyOptions} and provides specific defaults
* and options tailored for N-Quads, which extends N-Quads with named graphs.
*
* Use the {@link Builder} class to create instances of {@code NQuadsConfig}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class NQuadsSerializerOptions extends AbstractNFamilyOption {
+public class NQuadsSerializerOptions extends AbstractNFamilyOptions {
/**
* Protected constructor to be used by the {@link Builder}.
@@ -26,7 +26,7 @@ protected NQuadsSerializerOptions(Builder builder) {
* Provides a fluent API for constructing {@code NQuadsConfig} instances with default values
* specific to the N-Quads format.
*/
- public static class Builder extends AbstractNFamilyOption.AbstractNFamilyBuilder {
+ public static class Builder extends AbstractNFamilyOptions.AbstractNFamilyBuilder {
/**
* Default constructor initializes all options with their default values for N-Quads.
*/
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializerOptions.java
index b611d2425..4cdec4029 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializerOptions.java
@@ -1,16 +1,16 @@
package fr.inria.corese.core.next.impl.io.serialization.ntriples;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOptions;
/**
* Configuration for N-Triples serialization format.
- * This class extends {@link AbstractNFamilyOption} and provides specific defaults
+ * This class extends {@link AbstractNFamilyOptions} and provides specific defaults
* and options tailored for N-Triples, which is a simple, line-oriented format.
*
* Use the {@link Builder} class to create instances of {@code NTriplesConfig}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class NTriplesSerializerOptions extends AbstractNFamilyOption {
+public class NTriplesSerializerOptions extends AbstractNFamilyOptions {
/**
* Protected constructor to be used by the {@link Builder}.
@@ -26,7 +26,7 @@ protected NTriplesSerializerOptions(Builder builder) {
* Provides a fluent API for constructing {@code NTriplesConfig} instances with default values
* specific to the N-Triples format.
*/
- public static class Builder extends AbstractNFamilyOption.AbstractNFamilyBuilder {
+ public static class Builder extends AbstractNFamilyOptions.AbstractNFamilyBuilder {
/**
* Default constructor initializes all options with their default values for N-Triples.
*/
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOption.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
similarity index 93%
rename from src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOption.java
rename to src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
index b6855b61b..eb4a03fd0 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOption.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
@@ -1,7 +1,8 @@
package fr.inria.corese.core.next.impl.io.serialization.rdfxml;
+import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
@@ -11,13 +12,13 @@
/**
* Configuration for RDF/XML serialization format.
- * This class extends {@link AbstractSerializerOption} directly as RDF/XML has
+ * This class extends {@link AbstractSerializerOptions} directly as RDF/XML has
* distinct serialization characteristics not shared by the Turtle or N-Family formats.
*
- * Use the {@link Builder} class to create instances of {@code RDFXMLSerializerOption}.
+ *
Use the {@link Builder} class to create instances of {@code RDFXMLSerializerOptions}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class RDFXMLSerializerOption extends AbstractSerializerOption {
+public class RDFXMLSerializerOptions extends AbstractSerializerOptions implements PrettyPrintOptions {
/**
* Whether prefix declarations (e.g., `xmlns:prefix="uri"`) should be used for compact IRIs.
@@ -76,7 +77,7 @@ public class RDFXMLSerializerOption extends AbstractSerializerOption {
*
* @param builder The builder instance containing the desired configuration values.
*/
- protected RDFXMLSerializerOption(Builder builder) {
+ protected RDFXMLSerializerOptions(Builder builder) {
super(builder);
this.usePrefixes = builder.usePrefixes;
@@ -144,6 +145,7 @@ public Map getCustomPrefixes() {
*
* @return {@code true} if pretty-printing is enabled, {@code false} otherwise.
*/
+ @Override
public boolean prettyPrint() {
return prettyPrint;
}
@@ -153,6 +155,7 @@ public boolean prettyPrint() {
*
* @return The indentation string.
*/
+ @Override
public String getIndent() {
return indent;
}
@@ -162,6 +165,7 @@ public String getIndent() {
*
* @return The maximum line length.
*/
+ @Override
public int getMaxLineLength() {
return maxLineLength;
}
@@ -171,6 +175,7 @@ public int getMaxLineLength() {
*
* @return {@code true} if subject sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortSubjects() {
return sortSubjects;
}
@@ -180,6 +185,7 @@ public boolean sortSubjects() {
*
* @return {@code true} if predicate sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortPredicates() {
return sortPredicates;
}
@@ -194,11 +200,11 @@ public boolean useMultilineLiterals() {
}
/**
- * Public Builder for {@link RDFXMLSerializerOption}.
- * Provides a fluent API for constructing {@code RDFXMLSerializerOption} instances with default values
+ * Public Builder for {@link RDFXMLSerializerOptions}.
+ * Provides a fluent API for constructing {@code RDFXMLSerializerOptions} instances with default values
* specific to the RDF/XML format.
*/
- public static class Builder extends AbstractSerializerOption.AbstractBuilder {
+ public static class Builder extends AbstractSerializerOptions.AbstractBuilder {
protected boolean usePrefixes = true;
protected boolean autoDeclarePrefixes = true;
protected PrefixOrderingEnum prefixOrdering = PrefixOrderingEnum.ALPHABETICAL;
@@ -364,13 +370,13 @@ public Builder useMultilineLiterals(boolean useMultilineLiterals) {
}
/**
- * Builds and returns a new {@link RDFXMLSerializerOption} instance with the current builder settings.
+ * Builds and returns a new {@link RDFXMLSerializerOptions} instance with the current builder settings.
*
- * @return A new {@code RDFXMLSerializerOption} instance.
+ * @return A new {@code RDFXMLSerializerOptions} instance.
*/
@Override
- public RDFXMLSerializerOption build() {
- return new RDFXMLSerializerOption(this);
+ public RDFXMLSerializerOptions build() {
+ return new RDFXMLSerializerOptions(this);
}
}
@@ -379,9 +385,9 @@ public RDFXMLSerializerOption build() {
* This provides a convenient way to get a standard RDF/XML configuration without
* manually building it.
*
- * @return A {@code RDFXMLSerializerOption} instance with default settings.
+ * @return A {@code RDFXMLSerializerOptions} instance with default settings.
*/
- public static RDFXMLSerializerOption defaultConfig() {
+ public static RDFXMLSerializerOptions defaultConfig() {
return new Builder().build();
}
}
\ No newline at end of file
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerOptions.java
index 02633159c..31adeb113 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerOptions.java
@@ -1,17 +1,17 @@
package fr.inria.corese.core.next.impl.io.serialization.trig;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.BlankNodeStyleEnum;
/**
* Configuration for TriG serialization format.
- * This class extends {@link AbstractTFamilyOption} and provides specific defaults
+ * This class extends {@link AbstractTFamilyOptions} and provides specific defaults
* and options tailored for TriG, which extends Turtle with named graphs.
*
* Use the {@link Builder} class to create instances of {@code TriGConfig}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class TriGSerializerOptions extends AbstractTFamilyOption {
+public class TriGSerializerOptions extends AbstractTFamilyOptions {
/**
* Protected constructor to be used by the {@link Builder}.
@@ -27,7 +27,7 @@ protected TriGSerializerOptions(Builder builder) {
* Provides a fluent API for constructing {@code TriGConfig} instances with default values
* specific to the TriG format.
*/
- public static class Builder extends AbstractTFamilyOption.AbstractTFamilyBuilder {
+ public static class Builder extends AbstractTFamilyOptions.AbstractTFamilyBuilder {
/**
* Default constructor initializes all options with their default values for TriG.
*/
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java
index bfbc71624..d20f960f9 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java
@@ -1,17 +1,17 @@
package fr.inria.corese.core.next.impl.io.serialization.turtle;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.BlankNodeStyleEnum;
/**
* Configuration for Turtle serialization format.
- * This class extends {@link AbstractTFamilyOption} and provides specific defaults
+ * This class extends {@link AbstractTFamilyOptions} and provides specific defaults
* and options tailored for Turtle, such as using collections and anonymous blank nodes.
*
* Use the {@link Builder} class to create instances of {@code TurtleConfig}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class TurtleSerializerOptions extends AbstractTFamilyOption {
+public class TurtleSerializerOptions extends AbstractTFamilyOptions {
/**
* Protected constructor to be used by the {@link Builder}.
@@ -27,7 +27,7 @@ protected TurtleSerializerOptions(Builder builder) {
* Provides a fluent API for constructing {@code TurtleConfig} instances with default values
* specific to the Turtle format.
*/
- public static class Builder extends AbstractTFamilyOption.AbstractTFamilyBuilder {
+ public static class Builder extends AbstractTFamilyOptions.AbstractTFamilyBuilder {
/**
* Default constructor initializes all options with their default values for Turtle.
*/
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java
index 997cc0a64..1f77ec85e 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java
@@ -38,7 +38,7 @@ class RDFXMLCircularTest {
private ValueFactory valueFactory;
private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
- private RDFXMLSerializerOption defaultConfig;
+ private RDFXMLSerializerOptions defaultConfig;
// Test data constants
private static final String EXAMPLE_NS = "http://example.org/";
@@ -60,7 +60,7 @@ void setUp() {
valueFactory = new CoreseAdaptedValueFactory();
serializerFactory = new SerializerFactory();
parserFactory = new ParserFactory();
- defaultConfig = RDFXMLSerializerOption.defaultConfig();
+ defaultConfig = RDFXMLSerializerOptions.defaultConfig();
}
/**
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
index 777d0bf5a..6713b69e1 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
@@ -28,7 +28,7 @@ class RDFXMLSerializerTest {
@Mock
private Model mockModel;
- RDFXMLSerializerOption mockConfig;
+ RDFXMLSerializerOptions mockConfig;
private TestStatementFactory factory;
private StringWriter writer;
private AutoCloseable closeable;
@@ -58,7 +58,7 @@ void shouldSerializeSimpleIriTriple() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.autoDeclarePrefixes(true)
.usePrefixes(true)
.addPrefix("foaf", "http://xmlns.com/foaf/0.1/")
@@ -93,7 +93,7 @@ void shouldHandleBlankNodeSubject() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.stableBlankNodeIds(true)
.addPrefix("foaf", "http://xmlns.com/foaf/0.1/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -126,7 +126,7 @@ void shouldHandleBlankNodeObject() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.stableBlankNodeIds(true)
.addPrefix("dc", "http://purl.org/dc/elements/1.1/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -159,7 +159,7 @@ void shouldSerializeLiteralWithStringDatatypeMinimalPolicy() throws Serializatio
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.literalDatatypePolicy(LiteralDatatypePolicyEnum.MINIMAL)
.addPrefix("foaf", "http://xmlns.com/foaf/0.1/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -190,7 +190,7 @@ void shouldSerializeLiteralWithCustomDatatypeMinimalPolicy() throws Serializatio
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.literalDatatypePolicy(LiteralDatatypePolicyEnum.MINIMAL)
.addPrefix("ex", "http://example.org/vocabulary/")
.addPrefix("xsd", "http://www.w3.org/2001/XMLSchema#")
@@ -222,7 +222,7 @@ void shouldSerializeLiteralWithLanguage() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.addPrefix("dc", "http://purl.org/dc/elements/1.1/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
@@ -259,7 +259,7 @@ void shouldRespectPrefixOrderingDefault() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt1, stmt2));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.addPrefix("exorg", "http://ex.org/")
.addPrefix("excom", "http://ex.com/")
.prefixOrdering(PrefixOrderingEnum.USAGE_ORDER)
@@ -301,7 +301,7 @@ void shouldSortSubjectsAlphabetically() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt1, stmt2));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.sortSubjects(true)
.addPrefix("ex", "http://ex.org/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -337,7 +337,7 @@ void shouldEscapeXmlAttributeValues() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
@@ -367,7 +367,7 @@ void shouldEscapeXmlContentValues() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.literalDatatypePolicy(LiteralDatatypePolicyEnum.ALWAYS_TYPED)
.addPrefix("ex", "http://example.org/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -401,7 +401,7 @@ void shouldNotAutoDeclarePrefixesIfDisabled() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.autoDeclarePrefixes(false)
.usePrefixes(true)
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -433,7 +433,7 @@ void shouldNotUsePrefixesIfDisabled() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.usePrefixes(false)
.autoDeclarePrefixes(true)
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
@@ -471,7 +471,7 @@ void shouldNotGenerateStableBlankNodeIds() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.of(stmt1, stmt2));
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.stableBlankNodeIds(false)
.sortSubjects(true)
.addPrefix("ex", "http://example.org/")
@@ -502,7 +502,7 @@ void shouldNotGenerateStableBlankNodeIds() throws SerializationException {
void shouldHandleEmptyModel() throws SerializationException {
when(mockModel.stream()).thenReturn(Stream.empty());
- RDFXMLSerializerOption testConfig = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions testConfig = new RDFXMLSerializerOptions.Builder()
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/XmlConfigTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/XmlConfigTest.java
index 126406e5e..dbf9085f2 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/XmlConfigTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/XmlConfigTest.java
@@ -17,7 +17,7 @@
import static org.junit.jupiter.api.Assertions.*;
/**
- * Unit tests for the {@link RDFXMLSerializerOption} class.
+ * Unit tests for the {@link RDFXMLSerializerOptions} class.
* These tests verify the default configuration settings and the functionality
* of the builder pattern for customizing RDF/XML serialization options.
*/
@@ -26,7 +26,7 @@ class XmlConfigTest {
@Test
@DisplayName("defaultConfig() should return a config with expected RDF/XML defaults")
void defaultConfig_shouldReturnExpectedDefaults() {
- RDFXMLSerializerOption config = RDFXMLSerializerOption.defaultConfig();
+ RDFXMLSerializerOptions config = RDFXMLSerializerOptions.defaultConfig();
assertNotNull(config, "Default config should not be null");
@@ -64,7 +64,7 @@ void defaultConfig_shouldReturnExpectedDefaults() {
@Test
@DisplayName("Builder should allow overriding usePrefixes")
void builder_shouldAllowOverridingUsePrefixes() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.usePrefixes(false)
.build();
assertFalse(config.usePrefixes(), "usePrefixes should be overridden to false");
@@ -73,7 +73,7 @@ void builder_shouldAllowOverridingUsePrefixes() {
@Test
@DisplayName("Builder should allow overriding autoDeclarePrefixes")
void builder_shouldAllowOverridingAutoDeclarePrefixes() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.autoDeclarePrefixes(false)
.build();
assertFalse(config.autoDeclarePrefixes(), "autoDeclarePrefixes should be overridden to false");
@@ -82,7 +82,7 @@ void builder_shouldAllowOverridingAutoDeclarePrefixes() {
@Test
@DisplayName("Builder should allow overriding prefixOrdering")
void builder_shouldAllowOverridingPrefixOrdering() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.prefixOrdering(PrefixOrderingEnum.USAGE_ORDER)
.build();
assertEquals(PrefixOrderingEnum.USAGE_ORDER, config.getPrefixOrdering(), "prefixOrdering should be overridden to USAGE_ORDER");
@@ -94,7 +94,7 @@ void builder_shouldAllowAddingCustomPrefixes() {
String customPrefix = "my";
String customNamespace = "http://my.example.org/";
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.addPrefix(customPrefix, customNamespace)
.build();
@@ -114,7 +114,7 @@ void builder_shouldAllowSettingCustomPrefixHandler() {
customHandler.setPrefix("ex", "http://example.org/");
customHandler.setPrefix("custom", "http://custom.org/");
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.prefixHandler(customHandler)
.build();
@@ -132,7 +132,7 @@ void builder_shouldAllowAddingMultiplePrefixes() {
customPrefixes.put("ex", "http://example.org/");
customPrefixes.put("custom", "http://custom.org/");
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.addPrefixes(customPrefixes)
.build();
@@ -146,7 +146,7 @@ void builder_shouldAllowAddingMultiplePrefixes() {
@Test
@DisplayName("Builder should allow overriding prettyPrint")
void builder_shouldAllowOverridingPrettyPrint() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.prettyPrint(false)
.build();
assertFalse(config.prettyPrint(), "prettyPrint should be overridden to false");
@@ -156,7 +156,7 @@ void builder_shouldAllowOverridingPrettyPrint() {
@DisplayName("Builder should allow overriding indent")
void builder_shouldAllowOverridingIndent() {
String customIndent = "\t";
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.indent(customIndent)
.build();
assertEquals(customIndent, config.getIndent(), "indent should be overridden to custom value");
@@ -166,7 +166,7 @@ void builder_shouldAllowOverridingIndent() {
@DisplayName("Builder should allow overriding maxLineLength")
void builder_shouldAllowOverridingMaxLineLength() {
int customLength = 120;
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.maxLineLength(customLength)
.build();
assertEquals(customLength, config.getMaxLineLength(), "maxLineLength should be overridden to custom value");
@@ -175,7 +175,7 @@ void builder_shouldAllowOverridingMaxLineLength() {
@Test
@DisplayName("Builder should allow overriding sortSubjects")
void builder_shouldAllowOverridingSortSubjects() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.sortSubjects(true)
.build();
assertTrue(config.sortSubjects(), "sortSubjects should be overridden to true");
@@ -184,7 +184,7 @@ void builder_shouldAllowOverridingSortSubjects() {
@Test
@DisplayName("Builder should allow overriding sortPredicates")
void builder_shouldAllowOverridingSortPredicates() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.sortPredicates(true)
.build();
assertTrue(config.sortPredicates(), "sortPredicates should be overridden to true");
@@ -193,7 +193,7 @@ void builder_shouldAllowOverridingSortPredicates() {
@Test
@DisplayName("Builder should allow overriding useMultilineLiterals")
void builder_shouldAllowOverridingUseMultilineLiterals() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.useMultilineLiterals(false)
.build();
assertFalse(config.useMultilineLiterals(), "useMultilineLiterals should be overridden to false");
@@ -202,7 +202,7 @@ void builder_shouldAllowOverridingUseMultilineLiterals() {
@Test
@DisplayName("Builder should allow overriding strictMode")
void builder_shouldAllowOverridingStrictMode() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.strictMode(false)
.build();
assertFalse(config.isStrictMode(), "strictMode should be overridden to false");
@@ -211,7 +211,7 @@ void builder_shouldAllowOverridingStrictMode() {
@Test
@DisplayName("Builder should allow overriding escapeUnicode")
void builder_shouldAllowOverridingEscapeUnicode() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.escapeUnicode(true)
.build();
assertTrue(config.escapeUnicode(), "escapeUnicode should be overridden to true");
@@ -220,7 +220,7 @@ void builder_shouldAllowOverridingEscapeUnicode() {
@Test
@DisplayName("Builder should allow overriding literalDatatypePolicy")
void builder_shouldAllowOverridingLiteralDatatypePolicy() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.literalDatatypePolicy(LiteralDatatypePolicyEnum.MINIMAL)
.build();
assertEquals(LiteralDatatypePolicyEnum.MINIMAL, config.getLiteralDatatypePolicy(), "literalDatatypePolicy should be overridden to MINIMAL");
@@ -230,7 +230,7 @@ void builder_shouldAllowOverridingLiteralDatatypePolicy() {
@DisplayName("Builder should allow setting baseIRI")
void builder_shouldAllowSettingBaseIRI() {
String testBaseIRI = "http://example.org/base/";
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.baseIRI(testBaseIRI)
.build();
assertEquals(testBaseIRI, config.getBaseIRI(), "baseIRI should be set correctly");
@@ -240,7 +240,7 @@ void builder_shouldAllowSettingBaseIRI() {
@DisplayName("Builder should allow overriding lineEnding")
void builder_shouldAllowOverridingLineEnding() {
String customLineEnding = "\r\n";
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.lineEnding(customLineEnding)
.build();
assertEquals(customLineEnding, config.getLineEnding(), "lineEnding should be overridden to custom value");
@@ -249,7 +249,7 @@ void builder_shouldAllowOverridingLineEnding() {
@Test
@DisplayName("Builder should allow overriding validateURIs")
void builder_shouldAllowOverridingValidateURIs() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.validateURIs(true)
.build();
assertTrue(config.validateURIs(), "validateURIs should be overridden to true");
@@ -258,7 +258,7 @@ void builder_shouldAllowOverridingValidateURIs() {
@Test
@DisplayName("Builder should allow overriding stableBlankNodeIds")
void builder_shouldAllowOverridingStableBlankNodeIds() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.stableBlankNodeIds(false)
.build();
assertFalse(config.stableBlankNodeIds(), "stableBlankNodeIds should be overridden to false");
@@ -267,7 +267,7 @@ void builder_shouldAllowOverridingStableBlankNodeIds() {
@Test
@DisplayName("Builder should allow overriding includeContext")
void builder_shouldAllowOverridingIncludeContext() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.includeContext(true)
.build();
assertTrue(config.includeContext(), "includeContext should be overridden to true");
@@ -276,7 +276,7 @@ void builder_shouldAllowOverridingIncludeContext() {
@Test
@DisplayName("Builder should maintain default prefixes when adding custom ones")
void builder_shouldMaintainDefaultPrefixesWhenAddingCustomOnes() {
- RDFXMLSerializerOption config = new RDFXMLSerializerOption.Builder()
+ RDFXMLSerializerOptions config = new RDFXMLSerializerOptions.Builder()
.addPrefix("ex", "http://example.org/")
.build();
From f8b6860c95a1038e4694f3433eb5738dedd42a7b Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Mon, 8 Dec 2025 17:10:51 +0100
Subject: [PATCH 02/12] Changing the config behaviour to interface-based checks
---
.../base/AbstractGraphSerializer.java | 117 +++++++-----------
.../base/AbstractLineBasedSerializer.java | 9 +-
...ption.java => AbstractNFamilyOptions.java} | 16 +--
...on.java => AbstractSerializerOptions.java} | 13 +-
...ption.java => AbstractTFamilyOptions.java} | 25 ++--
.../io/serialization/trig/TriGSerializer.java | 78 +++++++-----
.../turtle/TurtleSerializer.java | 26 +++-
7 files changed, 150 insertions(+), 134 deletions(-)
rename src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/{AbstractNFamilyOption.java => AbstractNFamilyOptions.java} (82%)
rename src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/{AbstractSerializerOption.java => AbstractSerializerOptions.java} (96%)
rename src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/{AbstractTFamilyOption.java => AbstractTFamilyOptions.java} (96%)
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
index 83c88aa40..356e877dc 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
@@ -1,6 +1,8 @@
package fr.inria.corese.core.next.impl.io.serialization.base;
import fr.inria.corese.core.next.api.*;
+import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
@@ -28,8 +30,8 @@
*
* Note: Many features related to compact syntax, pretty-printing, and advanced
* prefix management are specific to Turtle Trig formats and require the
- * provided {@link AbstractSerializerOption} to be an instance of
- * {@link AbstractSerializerOption} at runtime. An {@link IllegalStateException}
+ * provided {@link AbstractSerializerOptions} to be an instance of
+ * {@link AbstractSerializerOptions} at runtime. An {@link IllegalStateException}
* will be thrown if an incompatible configuration is used for such features.
*/
public abstract class AbstractGraphSerializer implements RDFSerializer {
@@ -40,7 +42,7 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
protected static final Logger logger = LoggerFactory.getLogger(AbstractGraphSerializer.class);
protected final Model model;
- protected final AbstractSerializerOption option;
+ protected AbstractSerializerOptions option;
protected final Map iriToPrefixMapping;
protected final Map prefixToIriMapping;
protected final Set consumedBlankNodes;
@@ -50,10 +52,10 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
* Constructs a new abstract TriG/Turtle serializer instance.
*
* @param model the {@link Model} to serialize. Must not be null.
- * @param option the {@link AbstractSerializerOption} to use for serialization. Must not be null.
+ * @param option the {@link AbstractSerializerOptions} to use for serialization. Must not be null.
* @throws NullPointerException if the provided model or configuration is null.
*/
- protected AbstractGraphSerializer(Model model, AbstractSerializerOption option) {
+ protected AbstractGraphSerializer(Model model, AbstractSerializerOptions option) {
this.model = Objects.requireNonNull(model, "The model cannot be null");
this.option = Objects.requireNonNull(option, "The configuration cannot be null");
this.iriToPrefixMapping = new HashMap<>();
@@ -63,28 +65,12 @@ protected AbstractGraphSerializer(Model model, AbstractSerializerOption option)
initializePrefixes();
}
- /**
- * Helper method to safely cast the generic config to AbstractTFamilyConfig.
- * This should be called before accessing any methods specific to AbstractTFamilyConfig.
- *
- * @return The config cast to AbstractTFamilyConfig.
- * @throws SerializationException if the config is not an instance of AbstractTFamilyConfig.
- */
- private AbstractTFamilyOption getTFamilyOption() {
- if (!(option instanceof AbstractTFamilyOption)) {
- throw new SerializationException("Current serializer configuration is not an instance of AbstractTFamilyOption. " +
- "Features like prefixes, compact syntax, and pretty-printing are only available for T-Family formats.", this.getFormatName());
- }
- return (AbstractTFamilyOption) option;
- }
-
/**
* Initializes prefix mappings by adding custom prefixes from the configuration.
*/
private void initializePrefixes() {
- if (option instanceof AbstractTFamilyOption && getTFamilyOption().usePrefixes()) {
- AbstractTFamilyOption tFamilyOption = getTFamilyOption();
- PrefixHandler prefixHandler = tFamilyOption.getPrefixHandler();
+ if (option instanceof UsesPrefixOptions prefixOptions && prefixOptions.usePrefixes()) {
+ PrefixHandler prefixHandler = prefixOptions.getPrefixHandler();
for (String prefix : prefixHandler.getPrefixes()) {
String namespace = prefixHandler.getNamespace(prefix);
@@ -142,9 +128,9 @@ protected void writeHeader(Writer writer) throws IOException {
option.getLineEnding()));
}
- if (option instanceof AbstractSerializerOption
- && getTFamilyOption().usePrefixes()
- && getTFamilyOption().autoDeclarePrefixes()) {
+ if (option instanceof UsesPrefixOptions prefixOptions
+ && prefixOptions.usePrefixes()
+ && prefixOptions.autoDeclarePrefixes()) {
collectUsedNamespaces();
}
@@ -191,23 +177,23 @@ protected void collectUsedNamespaces() {
* @throws IOException if an I/O error occurs.
*/
protected void writePrefixDeclarations(Writer writer) throws IOException {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
-
- List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
+ if(this.option instanceof UsesPrefixOptions prefixOptions) {
+ List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
- if (tFamilyConfig.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
- Collections.sort(prefixes);
- }
+ if (prefixOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
+ Collections.sort(prefixes);
+ }
- for (String prefix : prefixes) {
- writer.write(String.format("@prefix %s: <%s> .%s",
- prefix,
- prefixToIriMapping.get(prefix),
- option.getLineEnding()));
- }
+ for (String prefix : prefixes) {
+ writer.write(String.format("@prefix %s: <%s> .%s",
+ prefix,
+ prefixToIriMapping.get(prefix),
+ option.getLineEnding()));
+ }
- if (!prefixes.isEmpty() || option.getBaseIRI() != null) {
- writer.write(option.getLineEnding());
+ if (!prefixes.isEmpty() || option.getBaseIRI() != null) {
+ writer.write(option.getLineEnding());
+ }
}
}
@@ -236,9 +222,7 @@ protected void writeSimpleStatements(Writer writer) throws IOException {
* @throws IOException if an I/O error occurs.
*/
protected void writeStatement(Writer writer, Statement stmt) throws IOException {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
-
- String indent = tFamilyConfig.prettyPrint() ? tFamilyConfig.getIndent() : SerializationConstants.EMPTY_STRING;
+ String indent = this.option instanceof PrettyPrintOptions prettyOptions && prettyOptions.prettyPrint() ? prettyOptions.getIndent() : SerializationConstants.EMPTY_STRING;
writer.write(indent);
// Subject
@@ -264,8 +248,7 @@ protected void writeStatement(Writer writer, Statement stmt) throws IOException
* @throws IOException if an I/O error occurs.
*/
protected void writePredicate(Writer writer, Value predicate) throws IOException {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
- if (tFamilyConfig.useRdfTypeShortcut() && predicate.equals(RDF.type.getIRI())) {
+ if (this.option instanceof AbstractTFamilyOptions tFamilyOptions && tFamilyOptions.useRdfTypeShortcut() && predicate.equals(RDF.type.getIRI())) {
writer.write(SerializationConstants.RDF_TYPE_SHORTCUT);
} else {
writeValue(writer, predicate);
@@ -303,12 +286,12 @@ protected void writeValue(Writer writer, Value value) throws IOException {
boolean isSubject = model.stream().anyMatch(stmt -> stmt.getSubject().equals(bNode));
- if (!isSubject && option instanceof AbstractSerializerOption) {
- if (getTFamilyOption().useCollections() && bNode.isBNode()) {
+ if (!isSubject && option instanceof AbstractTFamilyOptions abstractTFOptions) {
+ if (abstractTFOptions.useCollections() && bNode.isBNode()) {
handled = writeRDFList(writer, bNode);
}
- if (!handled && getTFamilyOption().getBlankNodeStyle() == BlankNodeStyleEnum.ANONYMOUS && bNode.isBNode()) {
+ if (!handled && abstractTFOptions.getBlankNodeStyle() == BlankNodeStyleEnum.ANONYMOUS && bNode.isBNode()) {
List properties = model.stream()
.filter(stmt -> stmt.getSubject().equals(bNode))
.toList();
@@ -345,7 +328,7 @@ protected void writeIRI(Writer writer, IRI iri) throws IOException {
}
String prefixed = null;
- if (option instanceof AbstractSerializerOption && getTFamilyOption().usePrefixes()) {
+ if (option instanceof UsesPrefixOptions prefixOptions && prefixOptions.usePrefixes()) {
prefixed = getPrefixedName(iri.stringValue());
}
@@ -369,8 +352,8 @@ protected void writeLiteral(Writer writer, Literal literal) throws IOException {
String value = literal.stringValue();
boolean useTripleQuotes = false;
- if (option instanceof AbstractTFamilyOption) {
- useTripleQuotes = getTFamilyOption().useMultilineLiterals() &&
+ if (option instanceof AbstractTFamilyOptions tFamilyOptions) {
+ useTripleQuotes = tFamilyOptions.useMultilineLiterals() &&
(value.contains(SerializationConstants.LINE_FEED) || value.contains(SerializationConstants.CARRIAGE_RETURN) || value.contains("\"\"\""));
}
@@ -436,10 +419,8 @@ protected boolean shouldWriteDatatype(Literal literal) {
* @throws IOException if an I/O error occurs.
*/
protected void writeInlineBlankNode(Writer writer, List properties) throws IOException {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
-
- String currentIndent = tFamilyConfig.prettyPrint() ? tFamilyConfig.getIndent() : SerializationConstants.EMPTY_STRING;
- String propIndent = tFamilyConfig.prettyPrint() ? currentIndent + tFamilyConfig.getIndent() : "";
+ String currentIndent = this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint() ? prettyPrintOptions.getIndent() : SerializationConstants.EMPTY_STRING;
+ String propIndent = this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint() ? currentIndent + prettyPrintOptions.getIndent() : "";
writer.write(SerializationConstants.BLANK_NODE_START);
@@ -455,7 +436,7 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
}
firstProperty = false;
- if (tFamilyConfig.prettyPrint()) {
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint()) {
writer.write(option.getLineEnding() + propIndent);
} else {
writer.write(SerializationConstants.SPACE);
@@ -466,7 +447,7 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
writeValue(writer, stmt.getObject());
}
- if (tFamilyConfig.prettyPrint() && !properties.isEmpty() && !firstProperty) {
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint() && !properties.isEmpty() && !firstProperty) {
writer.write(option.getLineEnding() + currentIndent);
}
@@ -482,9 +463,7 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
* @throws IOException if an I/O error occurs.
*/
protected void writeOptimizedStatements(Writer writer) throws IOException {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
-
- Map> bySubject = tFamilyConfig.sortSubjects() ?
+ Map> bySubject = this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.sortSubjects() ?
new TreeMap<>(Comparator.comparing(Resource::stringValue)) :
new HashMap<>();
@@ -493,12 +472,12 @@ protected void writeOptimizedStatements(Writer writer) throws IOException {
.forEach(stmt -> bySubject.computeIfAbsent(stmt.getSubject(), k -> new ArrayList<>()).add(stmt));
for (Map.Entry> subjectEntry : bySubject.entrySet()) {
- String indent = tFamilyConfig.prettyPrint() ? tFamilyConfig.getIndent() : SerializationConstants.EMPTY_STRING;
+ String indent = this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint() ? prettyPrintOptions.getIndent() : SerializationConstants.EMPTY_STRING;
writer.write(indent);
writeValue(writer, subjectEntry.getKey());
writer.write(SerializationConstants.SPACE);
- Map> byPredicate = tFamilyConfig.sortPredicates() ?
+ Map> byPredicate = this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.sortPredicates() ?
new TreeMap<>(Comparator.comparing(IRI::stringValue)) :
new HashMap<>();
@@ -508,8 +487,8 @@ protected void writeOptimizedStatements(Writer writer) throws IOException {
for (Map.Entry> predicateEntry : byPredicate.entrySet()) {
if (!firstPredicate) {
writer.write(SerializationConstants.SEMICOLON);
- if (tFamilyConfig.prettyPrint()) {
- writer.write(option.getLineEnding() + indent + tFamilyConfig.getIndent());
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint()) {
+ writer.write(option.getLineEnding() + indent + prettyPrintOptions.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -523,8 +502,8 @@ protected void writeOptimizedStatements(Writer writer) throws IOException {
for (Statement stmt : predicateEntry.getValue()) {
if (!firstObject) {
writer.write(SerializationConstants.COMMA);
- if (tFamilyConfig.prettyPrint()) {
- writer.write(option.getLineEnding() + indent + tFamilyConfig.getIndent() + tFamilyConfig.getIndent());
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint()) {
+ writer.write(option.getLineEnding() + indent + prettyPrintOptions.getIndent() + prettyPrintOptions.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -638,19 +617,17 @@ protected boolean isConsumed(Value value) {
* @return A {@link Set} of {@link Resource} representing the blank nodes that will be serialized inline.
*/
protected Set precomputeInlineBlankNodesAndLists() {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
-
Set precomputed = new HashSet<>();
for (Statement stmt : model) {
if (stmt.getSubject().isBNode()) {
Resource bNodeSubject = stmt.getSubject();
- if (tFamilyConfig.useCollections() && isRDFListHead(bNodeSubject)) {
+ if (this.option instanceof AbstractTFamilyOptions tFamilyOptions && tFamilyOptions.useCollections() && isRDFListHead(bNodeSubject)) {
Set listNodes = detectListNodes(bNodeSubject);
if (!listNodes.isEmpty()) {
precomputed.addAll(listNodes);
}
}
- if (tFamilyConfig.getBlankNodeStyle() == BlankNodeStyleEnum.ANONYMOUS) {
+ if (this.option instanceof AbstractTFamilyOptions tFamilyOptions && tFamilyOptions.getBlankNodeStyle() == BlankNodeStyleEnum.ANONYMOUS) {
List properties = model.stream()
.filter(s -> s.getSubject().equals(bNodeSubject))
.toList();
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
index 48081413f..061baf8e8 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
@@ -2,13 +2,13 @@
import java.io.BufferedWriter;
import java.io.IOException;
-import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import fr.inria.corese.core.next.impl.common.literal.XSD;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,7 +21,6 @@
import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
import fr.inria.corese.core.next.impl.common.literal.RDF;
import fr.inria.corese.core.next.impl.exception.SerializationException;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOption;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
@@ -38,16 +37,16 @@ public abstract class AbstractLineBasedSerializer implements RDFSerializer {
private static final Logger logger = LoggerFactory.getLogger(AbstractLineBasedSerializer.class);
protected final Model model;
- protected final AbstractSerializerOption config;
+ protected final AbstractSerializerOptions config;
/**
* Constructs a new line-based serializer.
*
* @param model the {@link Model} to be serialized. Must not be null.
- * @param config the {@link AbstractSerializerOption} to use for serialization. Must not be null.
+ * @param config the {@link AbstractSerializerOptions} to use for serialization. Must not be null.
* @throws NullPointerException if the provided model or config is null.
*/
- protected AbstractLineBasedSerializer(Model model, AbstractSerializerOption config) {
+ protected AbstractLineBasedSerializer(Model model, AbstractSerializerOptions config) {
this.model = Objects.requireNonNull(model, "Model cannot be null");
this.config = Objects.requireNonNull(config, "Configuration cannot be null");
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractNFamilyOption.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractNFamilyOptions.java
similarity index 82%
rename from src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractNFamilyOption.java
rename to src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractNFamilyOptions.java
index 0ebf8efc3..a43616d09 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractNFamilyOption.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractNFamilyOptions.java
@@ -2,7 +2,7 @@
/**
* An abstract base class for serialization configurations of N-Family RDF formats (e.g., N-Triples, N-Quads).
- * This class extends {@link AbstractSerializerOption} and provides a common foundation
+ * This class extends {@link AbstractSerializerOptions} and provides a common foundation
* for formats that typically have simpler, line-based structures and specific default behaviors
* regarding literal datatypes and character escaping.
*
@@ -10,7 +10,7 @@
* nested {@link AbstractNFamilyBuilder}. Subclasses are expected to extend this
* configuration and its builder to add format-specific options.
*/
-public abstract class AbstractNFamilyOption extends AbstractSerializerOption {
+public abstract class AbstractNFamilyOptions extends AbstractSerializerOptions {
/**
* Protected constructor to be used by concrete builder implementations.
@@ -19,14 +19,14 @@ public abstract class AbstractNFamilyOption extends AbstractSerializerOption {
*
* @param builder The builder instance containing the desired configuration values.
*/
- protected AbstractNFamilyOption(AbstractNFamilyBuilder> builder) {
+ protected AbstractNFamilyOptions(AbstractNFamilyBuilder> builder) {
super(builder);
}
/**
- * An abstract base builder for {@link AbstractNFamilyOption}.
+ * An abstract base builder for {@link AbstractNFamilyOptions}.
* This builder provides methods for setting N-Family serialization configuration options.
- * It extends {@link AbstractSerializerOption.AbstractBuilder} and uses a recursive type
+ * It extends {@link AbstractSerializerOptions.AbstractBuilder} and uses a recursive type
* parameter (`S`) to allow concrete subclass builders to return their own specific type,
* enabling fluent API chaining.
*
@@ -36,7 +36,7 @@ protected AbstractNFamilyOption(AbstractNFamilyBuilder> builder) {
* @param The type of the concrete builder extending this abstract builder.
*/
public abstract static class AbstractNFamilyBuilder>
- extends AbstractSerializerOption.AbstractBuilder {
+ extends AbstractSerializerOptions.AbstractBuilder {
/**
* Default constructor for the builder.
@@ -52,11 +52,11 @@ protected AbstractNFamilyBuilder() {
}
/**
- * Builds and returns a new {@link AbstractNFamilyOption} instance with the current builder settings.
+ * Builds and returns a new {@link AbstractNFamilyOptions} instance with the current builder settings.
* This method must be implemented by concrete builder subclasses to return their specific configuration type.
*
* @return A new {@code AbstractNFamilyConfig} instance or a subclass instance.
*/
- public abstract AbstractNFamilyOption build();
+ public abstract AbstractNFamilyOptions build();
}
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOption.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
similarity index 96%
rename from src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOption.java
rename to src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
index 353c229b5..c1da6edab 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOption.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
@@ -2,6 +2,7 @@
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
import java.util.Objects;
@@ -15,7 +16,7 @@
* nested {@link AbstractBuilder}. Subclasses are expected to extend this
* configuration and its builder to add format-specific options.
*/
-public abstract class AbstractSerializerOption implements IOOptions , BaseIRIOptions {
+public abstract class AbstractSerializerOptions implements IOOptions, BaseIRIOptions, LineEndingOptions {
/**
* The policy for how literal datatypes are printed.
@@ -72,7 +73,7 @@ public abstract class AbstractSerializerOption implements IOOptions , BaseIRIOpt
* @param builder The builder instance containing the desired configuration values.
* @throws NullPointerException if any required field from the builder is null.
*/
- protected AbstractSerializerOption(AbstractBuilder> builder) {
+ protected AbstractSerializerOptions(AbstractBuilder> builder) {
this.literalDatatypePolicy = Objects.requireNonNull(builder.literalDatatypePolicy, "Literal datatype policy cannot be null");
this.escapeUnicode = builder.escapeUnicode;
this.trailingDot = builder.trailingDot;
@@ -119,6 +120,7 @@ public boolean trailingDot() {
*
* @return The base IRI string, or {@code null} if no base IRI is specified.
*/
+ @Override
public String getBaseIRI() {
return baseIRI;
}
@@ -137,6 +139,7 @@ public boolean stableBlankNodeIds() {
*
* @return The line ending string (e.g., `"\n"` for Unix, `"\r\n"` for Windows).
*/
+ @Override
public String getLineEnding() {
return lineEnding;
}
@@ -169,7 +172,7 @@ public boolean includeContext() {
}
/**
- * An abstract base builder for {@link AbstractSerializerOption}.
+ * An abstract base builder for {@link AbstractSerializerOptions}.
* This builder provides methods for setting common serialization configuration options.
* It uses a recursive type parameter (`S`) to allow concrete subclass builders
* to return their own specific type, enabling fluent API chaining.
@@ -290,12 +293,12 @@ public S includeContext(boolean include) {
}
/**
- * Builds and returns a new {@link AbstractSerializerOption} instance with the current builder settings.
+ * Builds and returns a new {@link AbstractSerializerOptions} instance with the current builder settings.
* This method must be implemented by concrete builder subclasses to return their specific configuration type.
*
* @return A new {@code AbstractSerializerConfig} instance or a subclass instance.
*/
- public abstract AbstractSerializerOption build();
+ public abstract AbstractSerializerOptions build();
/**
* Helper method to return the concrete builder instance for fluent API chaining.
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOption.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
similarity index 96%
rename from src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOption.java
rename to src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
index 735ec7edf..c2be59d44 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOption.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
@@ -1,5 +1,7 @@
package fr.inria.corese.core.next.impl.io.serialization.option;
+import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
@@ -8,14 +10,14 @@
/**
* An abstract base class for serialization configurations of Turtle Trig RDF formats (e.g., Turtle, TriG).
- * This class extends {@link AbstractSerializerOption} and introduces parameters specific to
+ * This class extends {@link AbstractSerializerOptions} and introduces parameters specific to
* formats that utilize syntax sugar, pretty-printing, and collection syntax.
*
* It enforces the use of the Builder pattern for construction through its
* nested {@link AbstractTFamilyBuilder}. Subclasses are expected to extend this
* configuration and its builder to add format-specific options.
*/
-public abstract class AbstractTFamilyOption extends AbstractSerializerOption {
+public abstract class AbstractTFamilyOptions extends AbstractSerializerOptions implements UsesPrefixOptions, PrettyPrintOptions {
/**
* Whether prefix declarations (e.g., `@prefix`, `PREFIX`) should be used for compact IRIs.
@@ -105,7 +107,7 @@ public abstract class AbstractTFamilyOption extends AbstractSerializerOption {
* @throws NullPointerException if any required field from the builder is null.
* @throws IllegalArgumentException if incompatible options (e.g., escapeUnicode and useMultilineLiterals) are enabled.
*/
- protected AbstractTFamilyOption(AbstractTFamilyBuilder> builder) {
+ protected AbstractTFamilyOptions(AbstractTFamilyBuilder> builder) {
super(builder);
this.usePrefixes = builder.usePrefixes;
@@ -135,6 +137,7 @@ protected AbstractTFamilyOption(AbstractTFamilyBuilder> builder) {
*
* @return {@code true} if prefixes are used, {@code false} otherwise.
*/
+ @Override
public boolean usePrefixes() {
return usePrefixes;
}
@@ -144,6 +147,7 @@ public boolean usePrefixes() {
*
* @return {@code true} if auto-declaration is enabled, {@code false} otherwise.
*/
+ @Override
public boolean autoDeclarePrefixes() {
return autoDeclarePrefixes;
}
@@ -153,6 +157,7 @@ public boolean autoDeclarePrefixes() {
*
* @return The {@link PrefixOrderingEnum} for prefix ordering.
*/
+ @Override
public PrefixOrderingEnum getPrefixOrdering() {
return prefixOrdering;
}
@@ -162,6 +167,7 @@ public PrefixOrderingEnum getPrefixOrdering() {
*
* @return The {@link PrefixHandler} managing all prefix mappings.
*/
+ @Override
public PrefixHandler getPrefixHandler() {
return prefixHandler;
}
@@ -216,6 +222,7 @@ public boolean useMultilineLiterals() {
*
* @return {@code true} if pretty-printing is enabled, {@code false} otherwise.
*/
+ @Override
public boolean prettyPrint() {
return prettyPrint;
}
@@ -225,6 +232,7 @@ public boolean prettyPrint() {
*
* @return The indentation string.
*/
+ @Override
public String getIndent() {
return indent;
}
@@ -234,6 +242,7 @@ public String getIndent() {
*
* @return The maximum line length.
*/
+ @Override
public int getMaxLineLength() {
return maxLineLength;
}
@@ -252,6 +261,7 @@ public boolean groupBySubject() {
*
* @return {@code true} if subject sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortSubjects() {
return sortSubjects;
}
@@ -261,12 +271,13 @@ public boolean sortSubjects() {
*
* @return {@code true} if predicate sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortPredicates() {
return sortPredicates;
}
/**
- * An abstract base builder for {@link AbstractTFamilyOption}.
+ * An abstract base builder for {@link AbstractTFamilyOptions}.
* This builder provides methods for setting Turtle Trig serialization configuration options.
* parameter (`S`) to allow concrete subclass builders to return their own specific type,
* enabling fluent API chaining.
@@ -493,11 +504,11 @@ public S sortPredicates(boolean sortPredicates) {
}
/**
- * Builds and returns a new {@link AbstractTFamilyOption} instance with the current builder settings.
+ * Builds and returns a new {@link AbstractTFamilyOptions} instance with the current builder settings.
* This method must be implemented by concrete builder subclasses to return their specific configuration type.
*
- * @return A new {@code AbstractTFamilyOption} instance or a subclass instance.
+ * @return A new {@code AbstractTFamilyOptions} instance or a subclass instance.
*/
- public abstract AbstractTFamilyOption build();
+ public abstract AbstractTFamilyOptions build();
}
}
\ No newline at end of file
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
index 7177757b6..1e11e8688 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
@@ -15,7 +15,13 @@
import fr.inria.corese.core.next.api.Resource;
import fr.inria.corese.core.next.api.Statement;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
+import fr.inria.corese.core.next.api.io.IOOptions;
+import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
import fr.inria.corese.core.next.impl.io.serialization.base.AbstractGraphSerializer;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
/**
@@ -50,7 +56,7 @@ public class TriGSerializer extends AbstractGraphSerializer {
* @throws NullPointerException if the provided model is null.
*/
public TriGSerializer(Model model) {
- this(model, TriGSerializerOptions.defaultConfig());
+ super(model, TriGSerializerOptions.defaultConfig());
}
/**
@@ -61,24 +67,21 @@ public TriGSerializer(Model model) {
* This config object should be an instance of {@code TriGConfig} or a subclass thereof.
* @throws NullPointerException if the provided model or configuration is null.
*/
- public TriGSerializer(Model model, TriGSerializerOptions config) {
- super(model, config);
+ public TriGSerializer(Model model, IOOptions config) {
+ this(model);
Objects.requireNonNull(config, "TriGConfig cannot be null");
- }
-
- /**
- * Helper method to safely cast the generic config to TriGConfig.
- * This should be called before accessing any methods specific to TriGConfig.
- *
- * @return The config cast to TriGConfig.
- * @throws IllegalStateException if the config is not an instance of TriGConfig.
- */
- private TriGSerializerOptions getTriGConfig() {
- if (!(option instanceof TriGSerializerOptions)) {
- throw new IllegalStateException("Current serializer configuration is not an instance of TriGConfig. " +
- "TriGSerializer requires a TriGConfig instance.");
+ if(config instanceof AbstractSerializerOptions turtleSerializerOptions) {
+ this.option = turtleSerializerOptions;
+ } else {
+ TriGSerializerOptions.Builder optionBuilder = new TriGSerializerOptions.Builder();
+ if(config instanceof BaseIRIOptions baseIRIOptions) {
+ optionBuilder.baseIRI(baseIRIOptions.getBaseIRI());
+ }
+ if(config instanceof LineEndingOptions lineEndingOptions) {
+ optionBuilder.lineEnding(lineEndingOptions.getLineEnding());
+ }
+ this.option = optionBuilder.build();
}
- return (TriGSerializerOptions) option;
}
/**
@@ -90,11 +93,9 @@ private TriGSerializerOptions getTriGConfig() {
*/
@Override
protected void doWriteStatements(Writer writer) throws IOException {
- TriGSerializerOptions trigConfig = getTriGConfig();
-
- if (trigConfig.includeContext()) {
+ if (this.option instanceof AbstractTFamilyOptions trigConfig && trigConfig.includeContext()) {
writeStatementsWithContext(writer);
- } else if (trigConfig.useCompactTriples() && trigConfig.groupBySubject()) {
+ } else if (this.option instanceof AbstractTFamilyOptions trigConfig && trigConfig.useCompactTriples() && trigConfig.groupBySubject()) {
writeOptimizedStatements(writer);
} else {
writeSimpleStatements(writer);
@@ -110,19 +111,18 @@ protected void doWriteStatements(Writer writer) throws IOException {
* @throws IOException if an I/O error occurs.
*/
private void writeStatementsWithContext(Writer writer) throws IOException {
- TriGSerializerOptions trigConfig = getTriGConfig();
-
Map> byContext = new HashMap<>();
model.stream()
.filter(stmt -> !isConsumed(stmt.getSubject()))
.forEach(stmt -> byContext.computeIfAbsent(stmt.getContext(), k -> new ArrayList<>()).add(stmt));
+
for (Map.Entry> contextEntry : byContext.entrySet()) {
Resource context = contextEntry.getKey();
List statementsInContext = contextEntry.getValue();
String initialIndent = "";
- String graphIndent = trigConfig.prettyPrint() ? trigConfig.getIndent() : "";
+ String graphIndent = this.option instanceof PrettyPrintOptions prettyConfig && prettyConfig.prettyPrint() ? prettyConfig.getIndent() : "";
if (context != null) {
if (context.isIRI()) {
@@ -132,11 +132,13 @@ private void writeStatementsWithContext(Writer writer) throws IOException {
}
writer.write(SerializationConstants.SPACE);
writer.write(SerializationConstants.OPEN_BRACE);
- writer.write(trigConfig.getLineEnding());
+ if(this.option instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
initialIndent = graphIndent;
}
- Map> bySubject = trigConfig.sortSubjects()
+ Map> bySubject = this.option instanceof PrettyPrintOptions prettyConfig && prettyConfig.sortSubjects()
? new TreeMap<>(Comparator.nullsFirst(Comparator.comparing(Resource::stringValue)))
: new HashMap<>();
@@ -147,7 +149,7 @@ private void writeStatementsWithContext(Writer writer) throws IOException {
writeValue(writer, subjectEntry.getKey());
writer.write(SerializationConstants.SPACE);
- Map> byPredicate = trigConfig.sortPredicates() ?
+ Map> byPredicate = this.option instanceof PrettyPrintOptions prettyConfig && prettyConfig.sortPredicates() ?
new TreeMap<>(Comparator.comparing(IRI::stringValue)) :
new HashMap<>();
@@ -157,8 +159,8 @@ private void writeStatementsWithContext(Writer writer) throws IOException {
for (Map.Entry> predicateEntry : byPredicate.entrySet()) {
if (!firstPredicate) {
writer.write(SerializationConstants.SEMICOLON);
- if (trigConfig.prettyPrint()) {
- writer.write(trigConfig.getLineEnding() + initialIndent + trigConfig.getIndent());
+ if (this.option instanceof PrettyPrintOptions prettyConfig && this.option instanceof LineEndingOptions lineEndingOptions && prettyConfig.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + initialIndent + prettyConfig.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -172,8 +174,10 @@ private void writeStatementsWithContext(Writer writer) throws IOException {
for (Statement stmt : predicateEntry.getValue()) {
if (!firstObject) {
writer.write(SerializationConstants.COMMA);
- if (trigConfig.prettyPrint()) {
- writer.write(trigConfig.getLineEnding() + initialIndent + trigConfig.getIndent() + trigConfig.getIndent());
+ if (this.option instanceof PrettyPrintOptions prettyConfig
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyConfig.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + initialIndent + prettyConfig.getIndent() + prettyConfig.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -183,14 +187,20 @@ private void writeStatementsWithContext(Writer writer) throws IOException {
}
}
writer.write(SerializationConstants.SPACE + SerializationConstants.POINT);
- writer.write(trigConfig.getLineEnding());
+ if(this.option instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
}
if (context != null) {
writer.write(SerializationConstants.CLOSE_BRACE);
- writer.write(trigConfig.getLineEnding());
+ if(this.option instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
+ }
+ if(this.option instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
}
- writer.write(trigConfig.getLineEnding());
}
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
index 917c4f664..112672059 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
@@ -5,13 +5,17 @@
import java.util.Objects;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
+import fr.inria.corese.core.next.api.io.IOOptions;
+import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.Statement;
import fr.inria.corese.core.next.impl.io.serialization.base.AbstractGraphSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOption;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
/**
@@ -47,7 +51,7 @@ public class TurtleSerializer extends AbstractGraphSerializer {
* @throws NullPointerException if the provided model is null.
*/
public TurtleSerializer(Model model) {
- this(model, TurtleSerializerOptions.defaultConfig());
+ super(model, TurtleSerializerOptions.defaultConfig());
}
/**
@@ -57,9 +61,21 @@ public TurtleSerializer(Model model) {
* @param config the {@link TurtleSerializerOptions} to use for serialization. Must not be null.
* @throws NullPointerException if the provided model or configuration is null.
*/
- public TurtleSerializer(Model model, TurtleSerializerOptions config) {
- super(model, config);
+ public TurtleSerializer(Model model, IOOptions config) {
+ this(model);
Objects.requireNonNull(config, "TurtleConfig cannot be null");
+ if(config instanceof AbstractSerializerOptions turtleSerializerOptions) {
+ this.option = turtleSerializerOptions;
+ } else {
+ TurtleSerializerOptions.Builder optionBuilder = new TurtleSerializerOptions.Builder();
+ if(config instanceof BaseIRIOptions baseIRIOptions) {
+ optionBuilder.baseIRI(baseIRIOptions.getBaseIRI());
+ }
+ if(config instanceof LineEndingOptions lineEndingOptions) {
+ optionBuilder.lineEnding(lineEndingOptions.getLineEnding());
+ }
+ this.option = optionBuilder.build();
+ }
}
/**
* Retrieves the RDF format supported by this serializer, which is Turtle
@@ -81,7 +97,7 @@ public RDFFormat getRDFFormat() {
*/
@Override
protected void doWriteStatements(Writer writer) throws IOException {
- AbstractTFamilyOption tFamilyConfig = (AbstractTFamilyOption) option;
+ AbstractTFamilyOptions tFamilyConfig = (AbstractTFamilyOptions) option;
if (tFamilyConfig.useCompactTriples() && tFamilyConfig.groupBySubject()) {
writeOptimizedStatements(writer);
From 61b231eb179739e4601a13527aec52800b451ede Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Tue, 9 Dec 2025 11:07:27 +0100
Subject: [PATCH 03/12] RDFXML done
---
.../BlankNodeIdGenerationOptions.java | 11 +++
.../serialization/DatatypePolicyOptions.java | 14 +++
.../io/serialization/PrettyPrintOptions.java | 9 ++
.../io/serialization/UsesPrefixOptions.java | 4 +-
.../option/AbstractSerializerOptions.java | 4 +-
.../rdfxml/RDFXMLSerializer.java | 85 ++++++++++++-------
.../rdfxml/RDFXMLSerializerOptions.java | 11 ---
7 files changed, 92 insertions(+), 46 deletions(-)
create mode 100644 src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java
create mode 100644 src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java
new file mode 100644
index 000000000..479401450
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java
@@ -0,0 +1,11 @@
+package fr.inria.corese.core.next.api.io.serialization;
+
+public interface BlankNodeIdGenerationOptions {
+
+ /**
+ * Checks if deterministic blank node IDs should be generated.
+ *
+ * @return {@code true} if stable blank node IDs are enabled, {@code false} otherwise.
+ */
+ boolean stableBlankNodeIds();
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java
new file mode 100644
index 000000000..1abab55e3
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java
@@ -0,0 +1,14 @@
+package fr.inria.corese.core.next.api.io.serialization;
+
+import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
+
+public interface DatatypePolicyOptions {
+
+
+ /**
+ * Returns the policy for how literal datatypes are printed.
+ *
+ * @return The {@link LiteralDatatypePolicyEnum} indicating the literal datatype serialization policy.
+ */
+ LiteralDatatypePolicyEnum getLiteralDatatypePolicy();
+}
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
index b7ab0c79b..f26935083 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
@@ -1,5 +1,7 @@
package fr.inria.corese.core.next.api.io.serialization;
+import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
+
public interface PrettyPrintOptions {
/**
@@ -36,4 +38,11 @@ public interface PrettyPrintOptions {
* @return {@code true} if predicate sorting is enabled, {@code false} otherwise.
*/
boolean sortPredicates();
+
+ /**
+ * Returns the policy for ordering prefix declarations.
+ *
+ * @return The {@link PrefixOrderingEnum} for prefix ordering.
+ */
+ PrefixOrderingEnum getPrefixOrdering();
}
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
index 7ccbbb3b7..c7723b31d 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
@@ -22,11 +22,11 @@ public interface UsesPrefixOptions {
*
* @return The {@link PrefixOrderingEnum} for prefix ordering.
*/
- public PrefixOrderingEnum getPrefixOrdering();
+ PrefixOrderingEnum getPrefixOrdering();
/**
* Returns an unmodifiable map of custom URI prefixes.
*
* @return The {@link PrefixHandler} managing all prefix mappings.
*/
- public PrefixHandler getPrefixHandler();
+ PrefixHandler getPrefixHandler();
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
index c1da6edab..4a86244fc 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
@@ -2,6 +2,8 @@
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serialization.BlankNodeIdGenerationOptions;
+import fr.inria.corese.core.next.api.io.serialization.DatatypePolicyOptions;
import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
@@ -16,7 +18,7 @@
* nested {@link AbstractBuilder}. Subclasses are expected to extend this
* configuration and its builder to add format-specific options.
*/
-public abstract class AbstractSerializerOptions implements IOOptions, BaseIRIOptions, LineEndingOptions {
+public abstract class AbstractSerializerOptions implements IOOptions, BaseIRIOptions, LineEndingOptions, BlankNodeIdGenerationOptions, DatatypePolicyOptions {
/**
* The policy for how literal datatypes are printed.
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
index 5e794fa24..f97b2afdb 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
@@ -16,6 +16,8 @@
import java.util.stream.Collectors;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
+import fr.inria.corese.core.next.api.io.IOOptions;
+import fr.inria.corese.core.next.api.io.serialization.*;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,7 +28,6 @@
import fr.inria.corese.core.next.api.Resource;
import fr.inria.corese.core.next.api.Statement;
import fr.inria.corese.core.next.api.Value;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
@@ -53,7 +54,7 @@ public class RDFXMLSerializer implements RDFSerializer {
private static final Logger logger = LoggerFactory.getLogger(RDFXMLSerializer.class);
private final Model model;
- private final RDFXMLSerializerOption config;
+ private final IOOptions config;
private final Map iriToPrefixMapping;
private final Map prefixToIriMapping;
private final Map blankNodeIds;
@@ -62,23 +63,23 @@ public class RDFXMLSerializer implements RDFSerializer {
/**
* Constructs a new {@code XmlSerializer} instance with the specified model and default configuration.
- * The default configuration is obtained from {@link RDFXMLSerializerOption#defaultConfig()}.
+ * The default configuration is obtained from {@link RDFXMLSerializerOptions#defaultConfig()}.
*
* @param model the {@link Model} to serialize. Must not be null.
* @throws NullPointerException if the provided model is null.
*/
public RDFXMLSerializer(Model model) {
- this(model, RDFXMLSerializerOption.defaultConfig());
+ this(model, RDFXMLSerializerOptions.defaultConfig());
}
/**
* Constructs a new {@code XmlSerializer} instance with the specified model and custom configuration.
*
* @param model the {@link Model} to serialize. Must not be null.
- * @param config the {@link RDFXMLSerializerOption} to use for serialization. Must not be null.
+ * @param config the {@link RDFXMLSerializerOptions} to use for serialization. Must not be null.
* @throws NullPointerException if the provided model or configuration is null.
*/
- public RDFXMLSerializer(Model model, RDFXMLSerializerOption config) {
+ public RDFXMLSerializer(Model model, IOOptions config) {
this.model = Objects.requireNonNull(model, "Model cannot be null");
this.config = Objects.requireNonNull(config, "Configuration cannot be null");
this.iriToPrefixMapping = new HashMap<>();
@@ -92,8 +93,8 @@ public RDFXMLSerializer(Model model, RDFXMLSerializerOption config) {
* The custom prefixes map in XmlConfig is expected to be {prefix: namespaceURI}.
*/
private void initializePrefixes() {
- if (config.usePrefixes()) {
- for (Map.Entry entry : config.getCustomPrefixes().entrySet()) {
+ if (this.config instanceof UsesPrefixOptions usesPrefixOptions && usesPrefixOptions.usePrefixes()) {
+ for (Map.Entry entry : usesPrefixOptions.getPrefixHandler().getPrefixMap().entrySet()) {
addPrefixMapping(entry.getValue(), entry.getKey());
}
}
@@ -132,7 +133,9 @@ public RDFFormat getRDFFormat() {
*/
private void writeXmlDeclaration(Writer writer) throws IOException {
writer.write(SerializationConstants.XML_DECLARATION_START);
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
}
/**
@@ -143,30 +146,39 @@ private void writeXmlDeclaration(Writer writer) throws IOException {
* @throws IOException if an I/O error occurs.
*/
private void writeRdfRootElement(Writer writer) throws IOException {
- if (config.usePrefixes() && config.autoDeclarePrefixes()) {
+ if (this.config instanceof UsesPrefixOptions usesPrefixOptions && usesPrefixOptions.usePrefixes() && usesPrefixOptions.autoDeclarePrefixes()) {
collectUsedNamespaces();
}
writer.write(SerializationConstants.RDF_ROOT_START);
writeNamespaceAttributes(writer);
writer.write(">");
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
Map> statementsBySubject = cachedStatements.stream()
.collect(Collectors.groupingBy(Statement::getSubject));
List sortedSubjects = new ArrayList<>(statementsBySubject.keySet());
- if (config.sortSubjects()) {
+ if (this.config instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.sortSubjects()) {
Collections.sort(sortedSubjects, Comparator.comparing(Value::stringValue));
}
+ String zeroIndent = "";
for (Resource subject : sortedSubjects) {
- writeDescriptionElement(writer, subject, statementsBySubject.get(subject), config.getIndent());
+ if(this.config instanceof PrettyPrintOptions prettyPrintOptions) {
+ writeDescriptionElement(writer, subject, statementsBySubject.get(subject), prettyPrintOptions.getIndent());
+ } else {
+ writeDescriptionElement(writer, subject, statementsBySubject.get(subject), zeroIndent);
+ }
}
writer.write(SerializationConstants.RDF_ROOT_END);
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
}
/**
@@ -181,7 +193,7 @@ private void writeNamespaceAttributes(Writer writer) throws IOException {
}
List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
- if (config.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
+ if (this.config instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
Collections.sort(prefixes);
}
@@ -319,7 +331,10 @@ private String generateUniquePrefix(String basePrefix) {
* @throws IOException if an I/O error occurs.
*/
private void writeDescriptionElement(Writer writer, Resource subject, List statements, String currentIndent) throws IOException {
- String nextIndent = currentIndent + config.getIndent();
+ String nextIndent = currentIndent;
+ if(this.config instanceof PrettyPrintOptions prettyPrintOptions) {
+ nextIndent = currentIndent + prettyPrintOptions.getIndent();
+ }
writer.write(currentIndent);
if (subject.isIRI()) {
@@ -327,13 +342,15 @@ private void writeDescriptionElement(Writer writer, Resource subject, List", SerializationConstants.RDF_DESCRIPTION_START, SerializationConstants.RDF_NODEID_ATTRIBUTE, getBlankNodeId(subject)));
}
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
Map> statementsByPredicate = statements.stream()
.collect(Collectors.groupingBy(Statement::getPredicate));
List sortedPredicates = new ArrayList<>(statementsByPredicate.keySet());
- if (config.sortPredicates()) {
+ if (this.config instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.sortPredicates()) {
Collections.sort(sortedPredicates, Comparator.comparing(Value::stringValue));
}
@@ -345,7 +362,9 @@ private void writeDescriptionElement(Writer writer, Resource subject, List", SerializationConstants.RDF_RESOURCE_ATTRIBUTE, escapeXmlAttribute(object.stringValue())));
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
} else if (object.isBNode()) {
writer.write(String.format(" %s=\"%s\"/>", SerializationConstants.RDF_NODEID_ATTRIBUTE, getBlankNodeId((Resource) object)));
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
} else if (object.isLiteral()) {
Literal literal = (Literal) object;
@@ -397,15 +420,12 @@ private void writePropertyElement(Writer writer, IRI predicate, Value object, St
writer.write(">");
}
- if (config.useMultilineLiterals() && (literal.stringValue().contains(SerializationConstants.LINE_FEED) || literal.stringValue().contains(SerializationConstants.CARRIAGE_RETURN))) {
-
- writer.write(escapeXmlContent(literal.stringValue()));
- } else {
- writer.write(escapeXmlContent(literal.stringValue()));
- }
+ writer.write(escapeXmlContent(literal.stringValue()));
writer.write(String.format("%s>", elementName));
- writer.write(config.getLineEnding());
+ if(this.config instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
} else {
throw new IllegalArgumentException("Unsupported value type for RDF/XML serialization: " + object.getClass().getName());
}
@@ -419,7 +439,7 @@ private void writePropertyElement(Writer writer, IRI predicate, Value object, St
*/
private String getBlankNodeId(Resource bNode) {
return blankNodeIds.computeIfAbsent(bNode, k -> {
- if (config.stableBlankNodeIds()) {
+ if (this.config instanceof BlankNodeIdGenerationOptions bnGenOptions && bnGenOptions.stableBlankNodeIds()) {
return "b" + (blankNodeCounter++);
} else {
return bNode.stringValue().substring(2);
@@ -443,9 +463,10 @@ private boolean shouldWriteDatatype(Literal literal) {
return false;
}
- return config.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.ALWAYS_TYPED ||
- (!datatype.equals(XSD.xsdString.getIRI()) &&
- config.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.MINIMAL);
+ return config instanceof DatatypePolicyOptions datatypePolicyOptions
+ && (datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.ALWAYS_TYPED
+ || (!datatype.equals(XSD.xsdString.getIRI())
+ && datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.MINIMAL));
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
index eb4a03fd0..9c2f00231 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
@@ -129,17 +129,6 @@ public PrefixHandler getPrefixHandler() {
return prefixHandler;
}
- /**
- * Returns an unmodifiable map of custom URI prefixes for backward compatibility.
- *
- * @return A map where keys are prefix names and values are namespace URIs.
- * @deprecated Use {@link #getPrefixHandler()} instead for full prefix management capabilities.
- */
- @Deprecated
- public Map getCustomPrefixes() {
- return prefixHandler.getPrefixMap();
- }
-
/**
* Checks if human-readable formatting (pretty-printing) is enabled.
*
From 3022d9b6ed6788c7ec3fd591527d5905a99cb0e4 Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Tue, 9 Dec 2025 11:20:24 +0100
Subject: [PATCH 04/12] NQuads NTriples done
---
.../base/AbstractLineBasedSerializer.java | 2 +-
.../nquads/NQuadsSerializer.java | 27 ++++++++++++++++---
.../ntriples/NTriplesSerializer.java | 27 ++++++++++++++++---
3 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
index 061baf8e8..a998a7975 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
@@ -37,7 +37,7 @@ public abstract class AbstractLineBasedSerializer implements RDFSerializer {
private static final Logger logger = LoggerFactory.getLogger(AbstractLineBasedSerializer.class);
protected final Model model;
- protected final AbstractSerializerOptions config;
+ protected AbstractSerializerOptions config;
/**
* Constructs a new line-based serializer.
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java
index 5de866837..fe99a41b9 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java
@@ -4,7 +4,13 @@
import fr.inria.corese.core.next.api.Resource;
import fr.inria.corese.core.next.api.Statement;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
+import fr.inria.corese.core.next.api.io.IOOptions;
+import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serialization.BlankNodeIdGenerationOptions;
+import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.base.AbstractLineBasedSerializer;
+import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializerOptions;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,7 +39,7 @@ public class NQuadsSerializer extends AbstractLineBasedSerializer {
* @throws NullPointerException if the provided model is null.
*/
public NQuadsSerializer(Model model) {
- this(model, NQuadsSerializerOptions.defaultConfig());
+ super(model, NQuadsSerializerOptions.defaultConfig());
}
/**
@@ -44,9 +50,24 @@ public NQuadsSerializer(Model model) {
* This config object should be an instance of {@code NQuadsConfig} or a subclass thereof.
* @throws NullPointerException if the provided model or config is null.
*/
- public NQuadsSerializer(Model model, NQuadsSerializerOptions config) {
- super(model, config);
+ public NQuadsSerializer(Model model, IOOptions config) {
+ this(model);
Objects.requireNonNull(config, "NQuadsConfig cannot be null");
+ if(config instanceof AbstractNFamilyOptions nFamilyOptions) {
+ this.config = nFamilyOptions;
+ } else {
+ NTriplesSerializerOptions.Builder optionBuilder = new NTriplesSerializerOptions.Builder();
+ if(config instanceof BaseIRIOptions baseIRIOptions) {
+ optionBuilder.baseIRI(baseIRIOptions.getBaseIRI());
+ }
+ if(config instanceof LineEndingOptions lineEndingOptions) {
+ optionBuilder.lineEnding(lineEndingOptions.getLineEnding());
+ }
+ if(config instanceof BlankNodeIdGenerationOptions blankNodeIdGenerationOptions) {
+ optionBuilder.stableBlankNodeIds(blankNodeIdGenerationOptions.stableBlankNodeIds());
+ }
+ this.config = optionBuilder.build();
+ }
}
/**
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
index d4b1370e7..45a318800 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
@@ -5,6 +5,12 @@
import java.util.Objects;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
+import fr.inria.corese.core.next.api.io.IOOptions;
+import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serialization.BlankNodeIdGenerationOptions;
+import fr.inria.corese.core.next.api.io.serialization.DatatypePolicyOptions;
+import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,7 +39,7 @@ public class NTriplesSerializer extends AbstractLineBasedSerializer {
* @throws NullPointerException if the provided model is null.
*/
public NTriplesSerializer(Model model) {
- this(model, NTriplesSerializerOptions.defaultConfig());
+ super(model, NTriplesSerializerOptions.defaultConfig());
}
/**
@@ -44,9 +50,24 @@ public NTriplesSerializer(Model model) {
* This config object should be an instance of {@code NTriplesConfig} or a subclass thereof.
* @throws NullPointerException if the provided model or config is null.
*/
- public NTriplesSerializer(Model model, NTriplesSerializerOptions config) {
- super(model, config);
+ public NTriplesSerializer(Model model, IOOptions config) {
+ this(model);
Objects.requireNonNull(config, "NTriplesConfig cannot be null");
+ if(config instanceof AbstractNFamilyOptions nFamilyOptions) {
+ this.config = nFamilyOptions;
+ } else {
+ NTriplesSerializerOptions.Builder optionBuilder = new NTriplesSerializerOptions.Builder();
+ if(config instanceof BaseIRIOptions baseIRIOptions) {
+ optionBuilder.baseIRI(baseIRIOptions.getBaseIRI());
+ }
+ if(config instanceof LineEndingOptions lineEndingOptions) {
+ optionBuilder.lineEnding(lineEndingOptions.getLineEnding());
+ }
+ if(config instanceof BlankNodeIdGenerationOptions blankNodeIdGenerationOptions) {
+ optionBuilder.stableBlankNodeIds(blankNodeIdGenerationOptions.stableBlankNodeIds());
+ }
+ this.config = optionBuilder.build();
+ }
}
/**
* Retrieves the RDF format supported by this serializer, which is N-TRIPLES.
From 24b013cd4462e76fa3b6d5f6299f9932ce58113b Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Wed, 10 Dec 2025 15:42:53 +0100
Subject: [PATCH 05/12] Turtle and Trig fixed
---
.../corese/core/next/api/IPrefixHandler.java | 8 +
.../impl/common/prefix/PrefixHandler.java | 25 ++-
.../base/AbstractGraphSerializer.java | 145 ++++++++----------
.../option/AbstractSerializerOptions.java | 25 +++
.../option/AbstractTFamilyOptions.java | 31 ++++
.../io/serialization/trig/TriGSerializer.java | 18 +--
.../turtle/TurtleSerializer.java | 20 +--
.../turtle/TurtleSerializerOptions.java | 19 +++
.../io/parser/rdfxml/RDFXMLCircularTest.java | 2 +-
.../trig/TriGSerializerTest.java | 33 +---
.../turtle/TurtleSerializerTest.java | 39 +----
11 files changed, 180 insertions(+), 185 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java b/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java
index 8a205fba5..29742fee9 100644
--- a/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java
+++ b/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java
@@ -37,6 +37,14 @@ public interface IPrefixHandler {
*/
boolean hasPrefix(String prefix);
+ /**
+ * Checks if a namespace has a prefix
+ *
+ * @param namespace the namespace to check
+ * @return true if the namespace exists in mappings, false otherwise
+ */
+ boolean hasNamespace(String namespace);
+
/**
* Returns all registered prefixes.
* Order of iteration is implementation-dependent but should be consistent
diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java b/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
index 321ede195..0403836a8 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
@@ -45,6 +45,12 @@ public PrefixHandler(boolean includeStandardVocabularies) {
}
}
+ public PrefixHandler(PrefixHandler oHandler) {
+ this.prefixToNamespace = new ConcurrentHashMap<>(oHandler.prefixToNamespace);
+ this.namespaceToPrefix = new ConcurrentHashMap<>(oHandler.namespaceToPrefix);
+ this.defaultNamespace = oHandler.defaultNamespace;
+ }
+
/**
* Initializes the handler with standard W3C vocabulary prefixes by using the
* dedicated Vocabulary enum classes.
@@ -57,14 +63,11 @@ private void initializeStandardVocabularies() {
OWL.class,
FOAF.class
);
-
- for (Class extends Enum extends Vocabulary>> vocabClass : vocabularyClasses) {
- Enum extends Vocabulary>[] constants = vocabClass.getEnumConstants();
- if (constants.length > 0) {
- Vocabulary vocabInstance = (Vocabulary) constants[0];
- setPrefix(vocabInstance.getPreferredPrefix(), vocabInstance.getNamespace());
- }
- }
+ setPrefix(RDF.getVocabularyPreferredPrefix(), RDF.getVocabularyNamespace());
+ setPrefix(RDFS.getVocabularyPreferredPrefix(), RDFS.getVocabularyNamespace());
+ setPrefix(XSD.getVocabularyPreferredPrefix(), XSD.getVocabularyNamespace());
+ setPrefix(OWL.getVocabularyPreferredPrefix(), OWL.getVocabularyNamespace());
+ setPrefix(FOAF.getVocabularyPreferredPrefix(), FOAF.getVocabularyNamespace());
}
/**
@@ -89,6 +92,7 @@ public void setPrefix(String prefix, String namespace) {
String oldNamespace = prefixToNamespace.get(prefix);
if (oldNamespace != null && !oldNamespace.equals(namespace)) {
namespaceToPrefix.remove(oldNamespace);
+ prefixToNamespace.remove(prefix);
}
prefixToNamespace.put(prefix, namespace);
@@ -142,6 +146,11 @@ public boolean hasPrefix(String prefix) {
return prefixToNamespace.containsKey(prefix);
}
+ @Override
+ public boolean hasNamespace(String namespace) {
+ return namespaceToPrefix.containsKey(namespace);
+ }
+
/**
* Gets the default namespace
*
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
index 356e877dc..9a0becb38 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
@@ -1,13 +1,16 @@
package fr.inria.corese.core.next.impl.io.serialization.base;
import fr.inria.corese.core.next.api.*;
+import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
+import fr.inria.corese.core.next.impl.common.util.IRIUtils;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.option.*;
+import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,8 +46,7 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
protected final Model model;
protected AbstractSerializerOptions option;
- protected final Map iriToPrefixMapping;
- protected final Map prefixToIriMapping;
+ protected PrefixHandler prefixHandler;
protected final Set consumedBlankNodes;
protected final Set currentlyWritingBlankNodes;
@@ -52,33 +54,24 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
* Constructs a new abstract TriG/Turtle serializer instance.
*
* @param model the {@link Model} to serialize. Must not be null.
- * @param option the {@link AbstractSerializerOptions} to use for serialization. Must not be null.
+ * @param config the {@link AbstractSerializerOptions} to use for serialization. Must not be null.
* @throws NullPointerException if the provided model or configuration is null.
*/
- protected AbstractGraphSerializer(Model model, AbstractSerializerOptions option) {
+ protected AbstractGraphSerializer(Model model, IOOptions config) {
this.model = Objects.requireNonNull(model, "The model cannot be null");
- this.option = Objects.requireNonNull(option, "The configuration cannot be null");
- this.iriToPrefixMapping = new HashMap<>();
- this.prefixToIriMapping = new HashMap<>();
+ Objects.requireNonNull(config, "The configuration cannot be null");
+ if(config instanceof AbstractSerializerOptions abstractSerializerOptions) {
+ this.option = abstractSerializerOptions;
+ } else {
+ throw new IllegalArgumentException("AbstractGraphSerializer expect option object to extend AbstractSerializerOptions. Inheritor class should have taken care of that.");
+ }
+ if(config instanceof UsesPrefixOptions usesPrefixOptions) {
+ this.prefixHandler = usesPrefixOptions.getPrefixHandler();
+ } else {
+ this.prefixHandler = new PrefixHandler(false);
+ }
this.consumedBlankNodes = new HashSet<>();
this.currentlyWritingBlankNodes = new HashSet<>();
- initializePrefixes();
- }
-
- /**
- * Initializes prefix mappings by adding custom prefixes from the configuration.
- */
- private void initializePrefixes() {
- if (option instanceof UsesPrefixOptions prefixOptions && prefixOptions.usePrefixes()) {
- PrefixHandler prefixHandler = prefixOptions.getPrefixHandler();
-
- for (String prefix : prefixHandler.getPrefixes()) {
- String namespace = prefixHandler.getNamespace(prefix);
- if (namespace != null) {
- addPrefixMapping(namespace, prefix);
- }
- }
- }
}
/**
@@ -128,21 +121,21 @@ protected void writeHeader(Writer writer) throws IOException {
option.getLineEnding()));
}
+ Set actuallyUsedNamespaces = Set.of();
if (option instanceof UsesPrefixOptions prefixOptions
&& prefixOptions.usePrefixes()
&& prefixOptions.autoDeclarePrefixes()) {
- collectUsedNamespaces();
+ actuallyUsedNamespaces = collectUsedNamespaces();
}
- writePrefixDeclarations(writer);
+ writePrefixDeclarations(writer, actuallyUsedNamespaces);
}
/**
* Collects all namespaces used in the model and attempts to assign prefixes to them
* if auto-declaration is enabled and they are not already mapped.
*/
- protected void collectUsedNamespaces() {
-
+ protected Set collectUsedNamespaces() {
Set namespaces = model.stream()
.flatMap(stmt -> {
List values = new ArrayList<>(Arrays.asList(
@@ -153,21 +146,27 @@ protected void collectUsedNamespaces() {
if (stmt.getContext() != null) {
values.add(stmt.getContext());
}
+ if(stmt.getObject().isLiteral()
+ && ((Literal) stmt.getObject()).getDatatype() != null) {
+ values.add(((Literal) stmt.getObject()).getDatatype());
+ }
return values.stream();
})
.filter(Objects::nonNull)
.filter(Value::isIRI)
- .map(v -> getNamespace(v.stringValue()))
+ .map(v -> IRIUtils.guessNamespace(v.stringValue()))
.collect(Collectors.toSet());
namespaces.forEach(namespace -> {
- if (!iriToPrefixMapping.containsKey(namespace)) {
+ if (!this.prefixHandler.hasNamespace(namespace)) {
String prefix = getSuggestedPrefix(namespace);
if (prefix != null) {
addPrefixMapping(namespace, prefix);
}
}
});
+
+ return namespaces;
}
/**
@@ -176,9 +175,10 @@ protected void collectUsedNamespaces() {
* @param writer the {@link Writer} to which prefixes will be written.
* @throws IOException if an I/O error occurs.
*/
- protected void writePrefixDeclarations(Writer writer) throws IOException {
- if(this.option instanceof UsesPrefixOptions prefixOptions) {
- List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
+ protected void writePrefixDeclarations(Writer writer, Set actuallyUsedNamespaces) throws IOException {
+ if(this.option instanceof UsesPrefixOptions prefixOptions
+ && prefixOptions.usePrefixes()) {
+ List prefixes = new ArrayList<>(actuallyUsedNamespaces.stream().map(namespace -> this.prefixHandler.getPrefix(namespace)).toList());
if (prefixOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
Collections.sort(prefixes);
@@ -187,7 +187,7 @@ protected void writePrefixDeclarations(Writer writer) throws IOException {
for (String prefix : prefixes) {
writer.write(String.format("@prefix %s: <%s> .%s",
prefix,
- prefixToIriMapping.get(prefix),
+ this.prefixHandler.getNamespace(prefix),
option.getLineEnding()));
}
@@ -197,6 +197,16 @@ protected void writePrefixDeclarations(Writer writer) throws IOException {
}
}
+ /**
+ * Writes prefix declarations to the writer, sorted if configured.
+ *
+ * @param writer the {@link Writer} to which prefixes will be written.
+ * @throws IOException if an I/O error occurs.
+ */
+ protected void writePrefixDeclarations(Writer writer) throws IOException {
+ writePrefixDeclarations(writer, Set.of());
+ }
+
/**
* Serializes the model's statements in a simple manner, one per line, without grouping.
* Triples already "consumed" by inline serialization are ignored.
@@ -222,7 +232,10 @@ protected void writeSimpleStatements(Writer writer) throws IOException {
* @throws IOException if an I/O error occurs.
*/
protected void writeStatement(Writer writer, Statement stmt) throws IOException {
- String indent = this.option instanceof PrettyPrintOptions prettyOptions && prettyOptions.prettyPrint() ? prettyOptions.getIndent() : SerializationConstants.EMPTY_STRING;
+ String indent = this.option instanceof PrettyPrintOptions prettyOptions
+ && prettyOptions.prettyPrint()
+ ? prettyOptions.getIndent()
+ : SerializationConstants.EMPTY_STRING;
writer.write(indent);
// Subject
@@ -248,7 +261,9 @@ protected void writeStatement(Writer writer, Statement stmt) throws IOException
* @throws IOException if an I/O error occurs.
*/
protected void writePredicate(Writer writer, Value predicate) throws IOException {
- if (this.option instanceof AbstractTFamilyOptions tFamilyOptions && tFamilyOptions.useRdfTypeShortcut() && predicate.equals(RDF.type.getIRI())) {
+ if (this.option instanceof AbstractTFamilyOptions tFamilyOptions
+ && tFamilyOptions.useRdfTypeShortcut()
+ && predicate.equals(RDF.type.getIRI())) {
writer.write(SerializationConstants.RDF_TYPE_SHORTCUT);
} else {
writeValue(writer, predicate);
@@ -729,17 +744,17 @@ protected boolean isRDFListHead(Resource bNode) {
* @param prefix The associated prefix.
*/
protected void addPrefixMapping(String namespaceURI, String prefix) {
- if (iriToPrefixMapping.containsKey(namespaceURI)) {
- if (logger.isWarnEnabled() && !iriToPrefixMapping.get(namespaceURI).equals(prefix)) {
+ if (this.prefixHandler.hasNamespace(namespaceURI)) {
+ if (logger.isWarnEnabled() && !this.prefixHandler.getPrefix(namespaceURI).equals(prefix)) {
logger.warn("Namespace URI '{}' is already mapped to prefix '{}'. Cannot map to new prefix '{}'.",
- namespaceURI, iriToPrefixMapping.get(namespaceURI), prefix);
+ namespaceURI, this.prefixHandler.getPrefix(namespaceURI), prefix);
}
return;
}
- if (prefixToIriMapping.containsKey(prefix)) {
- if (logger.isWarnEnabled() && !prefixToIriMapping.get(prefix).equals(namespaceURI)) {
- String originalNamespace = prefixToIriMapping.get(prefix);
+ if (this.prefixHandler.hasPrefix(prefix)) {
+ if (logger.isWarnEnabled() && !this.prefixHandler.getNamespace(prefix).equals(namespaceURI)) {
+ String originalNamespace = this.prefixHandler.getNamespace(prefix);
logger.warn("Prefix '{}' is already mapped to namespace '{}'. Cannot map to new namespace '{}'. " +
"A new unique prefix will be generated for '{}'.",
prefix, originalNamespace, namespaceURI, namespaceURI);
@@ -747,31 +762,7 @@ protected void addPrefixMapping(String namespaceURI, String prefix) {
return;
}
- iriToPrefixMapping.put(namespaceURI, prefix);
- prefixToIriMapping.put(prefix, namespaceURI);
- }
-
- /**
- * Extracts the namespace URI part from an IRI string.
- * This is a common heuristic for RDF IRIs.
- *
- * @param iriString The full IRI.
- * @return The namespace URI part.
- */
- protected String getNamespace(String iriString) {
- int hashIdx = iriString.lastIndexOf(SerializationConstants.HASH);
- int slashIdx = iriString.lastIndexOf(SerializationConstants.SLASH);
-
- if (hashIdx > -1) {
- return iriString.substring(0, hashIdx + 1);
- } else if (slashIdx > -1 && slashIdx < iriString.length() - 1) {
- int dotIdx = iriString.lastIndexOf(SerializationConstants.POINT);
- if (dotIdx > slashIdx) {
- return iriString.substring(0, slashIdx + 1);
- }
- return iriString.substring(0, slashIdx + 1);
- }
- return iriString;
+ this.prefixHandler.setPrefix(prefix, namespaceURI);
}
/**
@@ -781,11 +772,9 @@ protected String getNamespace(String iriString) {
* @return The prefixed name (e.g., "ex:someResource") or null if no suitable prefix is found.
*/
protected String getPrefixedName(String iriString) {
- for (Map.Entry entry : iriToPrefixMapping.entrySet()) {
- String namespace = entry.getKey();
- String prefix = entry.getValue();
-
+ for (String namespace : this.prefixHandler.getNamespaces()) {
if (iriString.startsWith(namespace)) {
+ String prefix = this.prefixHandler.getPrefix(namespace);
String localName = iriString.substring(namespace.length());
if (localName.isEmpty()) {
if (!prefix.isEmpty()) {
@@ -808,12 +797,6 @@ protected String getPrefixedName(String iriString) {
* @return A suggested prefix, or null if suggestion is not possible.
*/
protected String getSuggestedPrefix(String namespace) {
- if (namespace.equals(RDF.getVocabularyNamespace())) return RDF.getVocabularyPreferredPrefix();
- if (namespace.equals(RDFS.getVocabularyNamespace())) return RDFS.getVocabularyPreferredPrefix();
- if (namespace.equals(XSD.getVocabularyNamespace())) return XSD.getVocabularyPreferredPrefix();
- if (namespace.equals(OWL.getVocabularyNamespace())) return OWL.getVocabularyPreferredPrefix();
- if (namespace.equals(FOAF.getVocabularyNamespace())) return FOAF.getVocabularyPreferredPrefix();
-
String base = namespace;
if (base.endsWith(SerializationConstants.HASH) || base.endsWith(SerializationConstants.SLASH)) {
base = base.substring(0, base.length() - 1);
@@ -838,13 +821,13 @@ protected String getSuggestedPrefix(String namespace) {
base = base.replaceAll("[^a-zA-Z0-9]", SerializationConstants.EMPTY_STRING).toLowerCase();
if (base.isEmpty()) base = "p";
- String candidate = base;
+ String candidatePrefix = base;
int i = 0;
- while (prefixToIriMapping.containsKey(candidate) && !prefixToIriMapping.get(candidate).equals(namespace)) {
- candidate = base + (++i);
+ while (this.prefixHandler.hasPrefix(candidatePrefix) && !this.prefixHandler.getNamespace(candidatePrefix).equals(namespace)) {
+ candidatePrefix = base + (++i);
}
- return candidate;
+ return candidatePrefix;
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
index 4a86244fc..73def386e 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
@@ -193,6 +193,31 @@ public abstract static class AbstractBuilder> {
protected boolean validateURIs = true;
protected boolean includeContext = false;
+ protected AbstractBuilder(IOOptions otherOptions) {
+ if(otherOptions instanceof AbstractSerializerOptions abstractSerializerOptions) {
+ this.escapeUnicode(abstractSerializerOptions.escapeUnicode());
+ this.trailingDot(abstractSerializerOptions.trailingDot());
+ this.strictMode(abstractSerializerOptions.isStrictMode());
+ this.validateURIs(abstractSerializerOptions.validateURIs());
+ this.includeContext(abstractSerializerOptions.includeContext());
+ }
+ if(otherOptions instanceof BaseIRIOptions baseIRIOptions) {
+ this.baseIRI(baseIRIOptions.getBaseIRI());
+ }
+ if(otherOptions instanceof LineEndingOptions lineEndingOptions) {
+ this.lineEnding(lineEndingOptions.getLineEnding());
+ }
+ if(otherOptions instanceof BlankNodeIdGenerationOptions blankNodeIdGenerationOptions) {
+ this.stableBlankNodeIds(blankNodeIdGenerationOptions.stableBlankNodeIds());
+ }
+ if(otherOptions instanceof DatatypePolicyOptions datatypePolicyOptions) {
+ this.literalDatatypePolicy(datatypePolicyOptions.getLiteralDatatypePolicy());
+ }
+ }
+
+ protected AbstractBuilder() {
+ }
+
/**
* Sets the policy for how literal datatypes are printed.
*
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
index c2be59d44..66d47d0f6 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
@@ -1,9 +1,12 @@
package fr.inria.corese.core.next.impl.io.serialization.option;
+import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.Objects;
@@ -306,6 +309,34 @@ public abstract static class AbstractTFamilyBuilder .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
ns:person1 ns:hasName "John Doe" .
@@ -114,10 +110,7 @@ void testRdfTypeShortcut() throws SerializationException {
String expected = """
@prefix foaf: .
@prefix ns: .
- @prefix owl: .
@prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
ns:person1 a foaf:Person .
@@ -164,10 +157,7 @@ void testLiteralWithLanguageTag() throws SerializationException {
String expected = """
@prefix 11: .
@prefix data: .
- @prefix owl: .
@prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
data:book1 11:title "The Odyssey"@en .
@@ -213,9 +203,6 @@ void testLiteralWithExplicitXsdStringType() throws SerializationException {
String expected = """
@prefix 11: .
@prefix data: .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
@prefix xsd: .
data:book2 11:creator "Homer"^^xsd:string .
@@ -260,10 +247,6 @@ void testBaseIRI() throws SerializationException {
String expected = """
@base .
@prefix base: .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
base:resource1 base:prop "Test" .
@@ -297,13 +280,7 @@ void testEmptyModel() throws SerializationException {
verify(emptyModel, times(2)).stream();
- String expected = """
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
-
- """;
+ String expected = "";
String actual = writer.toString().replace("\r\n", "\n");
assertEquals(expected, actual);
}
@@ -413,11 +390,7 @@ void testMultilineLiteralSerialization() throws SerializationException {
String expected = """
@prefix book: .
- @prefix owl: .
@prefix properties: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
book:1 properties:description\s""" + "\"\"\"" + multilineText + "\"\"\"" + " .\n\n";
@@ -455,10 +428,6 @@ void testBasicTrigSerializationWithNamedGraph() throws SerializationException {
String expected = """
@prefix data: .
@prefix graph: .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
graph:g1 {
data:person1 data:name "Alice" .
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
index 2ab5eb370..2309c1da1 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
@@ -70,10 +70,6 @@ void testBasicTurtleSerialization() throws SerializationException {
String expected = """
@prefix ns: .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
ns:person1 ns:hasName "John Doe" .
""";
@@ -104,6 +100,9 @@ void testRdfTypeShortcut() throws SerializationException {
.thenReturn(Stream.of(mockStatement));
StringWriter writer = new StringWriter();
+ TurtleSerializerOptions options = TurtleSerializerOptions.builder()
+ .prefixHandler(new PrefixHandler(true))
+ .build();
TurtleSerializer turtleSerializer = new TurtleSerializer(mockModel, defaultConfig);
@@ -114,10 +113,7 @@ void testRdfTypeShortcut() throws SerializationException {
String expected = """
@prefix foaf: .
@prefix ns: .
- @prefix owl: .
@prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
ns:person1 a foaf:Person .
""";
@@ -172,10 +168,7 @@ void testLiteralWithLanguageTag() throws SerializationException {
String expected = """
@prefix 11: .
@prefix data: .
- @prefix owl: .
@prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
data:book1 11:title "The Odyssey"@en .
""";
@@ -209,15 +202,12 @@ void testLiteralWithExplicitXsdStringType() throws SerializationException {
StringWriter writer = new StringWriter();
- PrefixHandler prefixHandler = new PrefixHandler(true);
- prefixHandler.setPrefix("data", "http://example.org/data/");
- prefixHandler.setPrefix("dc", "http://purl.org/dc/elements/1.1/");
-
TurtleSerializerOptions config = new TurtleSerializerOptions.Builder()
.literalDatatypePolicy(LiteralDatatypePolicyEnum.ALWAYS_TYPED)
.usePrefixes(true)
.autoDeclarePrefixes(true)
- .prefixHandler(prefixHandler)
+ .addPrefix("data", "http://example.org/data/")
+ .addPrefix("dc", "http://purl.org/dc/elements/1.1/")
.build();
TurtleSerializer turtleSerializer = new TurtleSerializer(mockModel, config);
@@ -229,9 +219,6 @@ void testLiteralWithExplicitXsdStringType() throws SerializationException {
String expected = """
@prefix data: .
@prefix dc: .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
@prefix xsd: .
data:book2 dc:creator "Homer"^^xsd:string .
@@ -396,10 +383,6 @@ void testBaseIRI() throws SerializationException {
String expected = """
@base .
@prefix base: .
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
base:resource1 base:prop "Test" .
""";
@@ -432,13 +415,7 @@ void testEmptyModel() throws SerializationException {
verify(emptyModel, times(2)).stream();
- String expected = """
- @prefix owl: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
-
- """;
+ String expected = "";
String actual = writer.toString().replace("\r\n", "\n");
assertEquals(expected, actual);
}
@@ -546,11 +523,7 @@ void testMultilineLiteralSerialization() throws SerializationException {
String expected = """
@prefix book: .
- @prefix owl: .
@prefix properties: .
- @prefix rdf: .
- @prefix rdfs: .
- @prefix xsd: .
book:1 properties:description\s""" + "\"\"\"" + multilineText + "\"\"\"" + " .\n";
From 545c3dd910b759140ef4dc7e2a3123103b4b1598 Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Thu, 11 Dec 2025 16:01:58 +0100
Subject: [PATCH 06/12] Fix NS ordering
---
.../BlankNodeIdGenerationOptions.java | 2 +-
.../DatatypePolicyOptions.java | 2 +-
.../LineEndingOptions.java | 2 +-
.../PrettyPrintOptions.java | 2 +-
.../RDFSerializer.java | 2 +-
.../SerializerFactory.java | 2 +-
.../UsesPrefixOptions.java | 2 +-
.../io/serialization/SerializerFactory.java | 8 +-
.../base/AbstractGraphSerializer.java | 7 +-
.../base/AbstractLineBasedSerializer.java | 2 +-
.../jsonld/JSONLDSerializer.java | 2 +-
.../nquads/NQuadsSerializer.java | 4 +-
.../ntriples/NTriplesSerializer.java | 5 +-
.../option/AbstractSerializerOptions.java | 6 +-
.../option/AbstractTFamilyOptions.java | 6 +-
.../rdfxml/RDFXMLSerializer.java | 189 +++++++++---------
.../rdfxml/RDFXMLSerializerOptions.java | 5 +-
.../io/serialization/trig/TriGSerializer.java | 6 +-
.../turtle/TurtleSerializer.java | 4 -
.../turtle/TurtleSerializerOptions.java | 4 +-
.../io/parser/jsonld/JSONLDCircularTest.java | 5 +-
.../io/parser/nquads/NQuadsCircularTest.java | 4 +-
.../parser/ntriples/NTriplesCircularTest.java | 4 +-
.../io/parser/rdfxml/RDFXMLCircularTest.java | 4 +-
.../impl/io/parser/trig/TriGCircularTest.java | 4 +-
.../io/parser/turtle/TurtleCircularTest.java | 4 +-
.../serialization/SerializerFactoryTest.java | 7 +-
.../canonical/RDFC10SerializerTest.java | 2 +-
.../jsonld/JSONLDSerializerTest.java | 2 +-
.../rdfxml/RDFXMLSerializerTest.java | 33 +--
.../turtle/TurtleSerializerTest.java | 3 +
31 files changed, 155 insertions(+), 179 deletions(-)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/BlankNodeIdGenerationOptions.java (82%)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/DatatypePolicyOptions.java (87%)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/LineEndingOptions.java (55%)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/PrettyPrintOptions.java (95%)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/RDFSerializer.java (96%)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/SerializerFactory.java (96%)
rename src/main/java/fr/inria/corese/core/next/api/io/{serialization => serializer}/UsesPrefixOptions.java (94%)
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
similarity index 82%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
index 479401450..91842391b 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/BlankNodeIdGenerationOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
public interface BlankNodeIdGenerationOptions {
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
similarity index 87%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
index 1abab55e3..0f55c34a2 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/DatatypePolicyOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
similarity index 55%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
index 6fedb34f4..64b226796 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/LineEndingOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
public interface LineEndingOptions {
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
similarity index 95%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
index f26935083..6ad5685af 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/PrettyPrintOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/RDFSerializer.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java
similarity index 96%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/RDFSerializer.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java
index 1e1501e4f..5e4868522 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/RDFSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
import java.io.Writer;
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/SerializerFactory.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/SerializerFactory.java
similarity index 96%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/SerializerFactory.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/SerializerFactory.java
index 2deb675b4..7560ff072 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/SerializerFactory.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/SerializerFactory.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
similarity index 94%
rename from src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
rename to src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
index c7723b31d..fd0bb51f9 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serialization/UsesPrefixOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
@@ -1,4 +1,4 @@
-package fr.inria.corese.core.next.api.io.serialization;
+package fr.inria.corese.core.next.api.io.serializer;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
index b06573298..3ac796b4d 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
@@ -4,9 +4,7 @@
import fr.inria.corese.core.next.api.ValueFactory;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
-import fr.inria.corese.core.next.impl.exception.SerializationException;
-import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Canonicalizer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Serializer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10SerializerOptions;
@@ -31,7 +29,7 @@
import java.util.function.Function;
/**
- * Default implementation of {@link fr.inria.corese.core.next.api.io.serialization.SerializerFactory}.
+ * Default implementation of {@link fr.inria.corese.core.next.api.io.serializer.SerializerFactory}.
* This factory is responsible for creating instances of {@link RDFSerializer}
* based on the requested {@link RDFFormat}. It uses a registry pattern
* to map each format to its corresponding serializer constructor,
@@ -44,7 +42,7 @@
* to default configurations if an incompatible type is provided.
*
*/
-public class SerializerFactory implements fr.inria.corese.core.next.api.io.serialization.SerializerFactory {
+public class SerializerFactory implements fr.inria.corese.core.next.api.io.serializer.SerializerFactory {
private final Map> registry;
private final Map> defaultRegistry;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
index 9a0becb38..66f1e60b3 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
@@ -2,15 +2,14 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
-import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serializer.UsesPrefixOptions;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.common.util.IRIUtils;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.option.*;
-import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
index a998a7975..6d9298ed9 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
@@ -18,7 +18,7 @@
import fr.inria.corese.core.next.api.Resource;
import fr.inria.corese.core.next.api.Statement;
import fr.inria.corese.core.next.api.Value;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.common.literal.RDF;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializer.java
index ef4b03477..5f12daec1 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializer.java
@@ -6,7 +6,7 @@
import com.apicatalog.jsonld.document.RdfDocument;
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java
index fe99a41b9..9c9134460 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/nquads/NQuadsSerializer.java
@@ -6,8 +6,8 @@
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
-import fr.inria.corese.core.next.api.io.serialization.BlankNodeIdGenerationOptions;
-import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.api.io.serializer.BlankNodeIdGenerationOptions;
+import fr.inria.corese.core.next.api.io.serializer.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.base.AbstractLineBasedSerializer;
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOptions;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
index 45a318800..eb6c50840 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
@@ -7,9 +7,8 @@
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
-import fr.inria.corese.core.next.api.io.serialization.BlankNodeIdGenerationOptions;
-import fr.inria.corese.core.next.api.io.serialization.DatatypePolicyOptions;
-import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.api.io.serializer.BlankNodeIdGenerationOptions;
+import fr.inria.corese.core.next.api.io.serializer.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.AbstractNFamilyOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
index 73def386e..3e137c881 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
@@ -2,9 +2,9 @@
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
-import fr.inria.corese.core.next.api.io.serialization.BlankNodeIdGenerationOptions;
-import fr.inria.corese.core.next.api.io.serialization.DatatypePolicyOptions;
-import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.api.io.serializer.BlankNodeIdGenerationOptions;
+import fr.inria.corese.core.next.api.io.serializer.DatatypePolicyOptions;
+import fr.inria.corese.core.next.api.io.serializer.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
import java.util.Objects;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
index 66d47d0f6..c1ed6d9b1 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
@@ -1,12 +1,10 @@
package fr.inria.corese.core.next.impl.io.serialization.option;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
-import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
+import fr.inria.corese.core.next.api.io.serializer.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serializer.UsesPrefixOptions;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.Objects;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
index f97b2afdb..70c968d3a 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
@@ -4,20 +4,14 @@
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
import java.util.stream.Collectors;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serialization.*;
+import fr.inria.corese.core.next.api.io.serializer.*;
+import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
+import fr.inria.corese.core.next.impl.common.util.IRIUtils;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,8 +49,7 @@ public class RDFXMLSerializer implements RDFSerializer {
private final Model model;
private final IOOptions config;
- private final Map iriToPrefixMapping;
- private final Map prefixToIriMapping;
+ private final PrefixHandler prefixHandler;
private final Map blankNodeIds;
private int blankNodeCounter = 0;
private List cachedStatements;
@@ -82,22 +75,15 @@ public RDFXMLSerializer(Model model) {
public RDFXMLSerializer(Model model, IOOptions config) {
this.model = Objects.requireNonNull(model, "Model cannot be null");
this.config = Objects.requireNonNull(config, "Configuration cannot be null");
- this.iriToPrefixMapping = new HashMap<>();
- this.prefixToIriMapping = new HashMap<>();
- this.blankNodeIds = new HashMap<>();
- initializePrefixes();
- }
- /**
- * Initializes prefix mappings by adding custom prefixes from the configuration.
- * The custom prefixes map in XmlConfig is expected to be {prefix: namespaceURI}.
- */
- private void initializePrefixes() {
- if (this.config instanceof UsesPrefixOptions usesPrefixOptions && usesPrefixOptions.usePrefixes()) {
- for (Map.Entry entry : usesPrefixOptions.getPrefixHandler().getPrefixMap().entrySet()) {
- addPrefixMapping(entry.getValue(), entry.getKey());
- }
+ if(config instanceof UsesPrefixOptions usesPrefixOptions
+ && usesPrefixOptions.usePrefixes()) {
+ this.prefixHandler = usesPrefixOptions.getPrefixHandler();
+ } else {
+ this.prefixHandler = new PrefixHandler(false);
+ this.prefixHandler.setPrefix(RDF.getVocabularyPreferredPrefix(), RDF.getVocabularyNamespace());
}
+ this.blankNodeIds = new HashMap<>();
}
/**
@@ -146,12 +132,16 @@ private void writeXmlDeclaration(Writer writer) throws IOException {
* @throws IOException if an I/O error occurs.
*/
private void writeRdfRootElement(Writer writer) throws IOException {
- if (this.config instanceof UsesPrefixOptions usesPrefixOptions && usesPrefixOptions.usePrefixes() && usesPrefixOptions.autoDeclarePrefixes()) {
- collectUsedNamespaces();
+ Set actuallyUsedNamespaces = new HashSet<>();
+ actuallyUsedNamespaces.add(RDF.getVocabularyNamespace());
+ if (this.config instanceof UsesPrefixOptions usesPrefixOptions
+ && usesPrefixOptions.usePrefixes()
+ && usesPrefixOptions.autoDeclarePrefixes()) {
+ actuallyUsedNamespaces.addAll(collectUsedNamespaces());
}
writer.write(SerializationConstants.RDF_ROOT_START);
- writeNamespaceAttributes(writer);
+ writeNamespaceAttributes(writer, actuallyUsedNamespaces);
writer.write(">");
if(this.config instanceof LineEndingOptions lineEndingOptions) {
writer.write(lineEndingOptions.getLineEnding());
@@ -162,7 +152,8 @@ private void writeRdfRootElement(Writer writer) throws IOException {
List sortedSubjects = new ArrayList<>(statementsBySubject.keySet());
- if (this.config instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.sortSubjects()) {
+ if (this.config instanceof PrettyPrintOptions prettyPrintOptions
+ && prettyPrintOptions.sortSubjects()) {
Collections.sort(sortedSubjects, Comparator.comparing(Value::stringValue));
}
@@ -187,19 +178,19 @@ private void writeRdfRootElement(Writer writer) throws IOException {
* @param writer the {@link Writer} to which attributes will be written.
* @throws IOException if an I/O error occurs.
*/
- private void writeNamespaceAttributes(Writer writer) throws IOException {
- if (!iriToPrefixMapping.containsKey(RDF.getVocabularyNamespace())) {
- addPrefixMapping(RDF.getVocabularyNamespace(), RDF.getVocabularyPreferredPrefix());
+ private void writeNamespaceAttributes(Writer writer, Set actuallyUsedNamespaces) throws IOException {
+ logger.info("actually used Namespaces: {}", actuallyUsedNamespaces);
+ ArrayList namespacelist = new ArrayList<>(actuallyUsedNamespaces);
+ if (this.config instanceof PrettyPrintOptions prettyPrintOptions
+ && prettyPrintOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
+ namespacelist.sort(
+ (ns1, ns2) ->
+ prefixHandler.getPrefix(ns1).compareTo(prefixHandler.getPrefix(ns2)));
}
- List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
- if (this.config instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
- Collections.sort(prefixes);
- }
-
- for (String prefix : prefixes) {
- String namespaceURI = prefixToIriMapping.get(prefix);
- writer.write(String.format(" %s%s=\"%s\"", SerializationConstants.XMLNS_PREFIX, prefix, escapeXmlAttribute(namespaceURI)));
+ for(String namespace : namespacelist) {
+ String prefix = this.prefixHandler.getPrefix(namespace);
+ writer.write(String.format(" %s%s=\"%s\"", SerializationConstants.XMLNS_PREFIX, prefix, escapeXmlAttribute(namespace)));
}
}
@@ -207,26 +198,55 @@ private void writeNamespaceAttributes(Writer writer) throws IOException {
* Collects all namespaces used in the model (subjects, predicates, objects, contexts)
* and attempts to assign prefixes if auto-declaration is enabled and they are not already mapped.
*/
- private void collectUsedNamespaces() {
- Set namespaces = this.cachedStatements.stream()
- .flatMap(stmt -> Arrays.asList(
- stmt.getSubject(),
- stmt.getPredicate(),
- stmt.getObject()
- ).stream())
+ private Set collectUsedNamespaces() {
+ // Collecting namespaces of all IRIs in the data
+ Set potentialNamespaces = this.cachedStatements.stream()
+ .flatMap(stmt -> {
+ List values = new ArrayList<>(Arrays.asList(
+ stmt.getSubject(),
+ stmt.getPredicate(),
+ stmt.getObject()
+ ));
+ if (stmt.getContext() != null) {
+ values.add(stmt.getContext());
+ }
+ if(stmt.getObject().isLiteral()
+ && ((Literal) stmt.getObject()).getDatatype() != null) {
+ values.add(((Literal) stmt.getObject()).getDatatype());
+ }
+ return values.stream();
+ })
+ .filter(Objects::nonNull)
.filter(Value::isIRI)
- .map(v -> getNamespace(v.stringValue()))
+ .map(v -> IRIUtils.guessNamespace(v.stringValue()))
.collect(Collectors.toSet());
-
-
- namespaces.forEach(namespace -> {
- if (!iriToPrefixMapping.containsKey(namespace)) {
+ logger.info("{}", potentialNamespaces);
+
+ // potential namespaces can contain different candidates that are based on each other. We keep the shortest
+ Set copyPotentialNamespaces = Set.copyOf(potentialNamespaces);
+ potentialNamespaces = potentialNamespaces
+ .stream()
+ .filter(potentialNamespace -> copyPotentialNamespaces
+ .stream()
+ .noneMatch(otherPotentialNamespace -> (! otherPotentialNamespace.equals(potentialNamespace)) && potentialNamespace.startsWith(otherPotentialNamespace)))
+ .collect(Collectors.toSet());
+ logger.info("{}", potentialNamespaces);
+
+ potentialNamespaces.forEach(namespace -> {
+ logger.info("{} is in PrefixHandler = {}", namespace, this.prefixHandler.hasNamespace(namespace));
+ if (! this.prefixHandler.hasNamespace(namespace) &&
+ // removing known namespaces from the list of potential namespaces
+ this.prefixHandler.getNamespaces()
+ .stream()
+ .noneMatch(knownNamespace -> (knownNamespace.startsWith(namespace)))) {
String prefix = getSuggestedPrefix(namespace);
if (prefix != null) {
addPrefixMapping(namespace, prefix);
}
}
});
+
+ return potentialNamespaces;
}
@@ -238,15 +258,17 @@ private void collectUsedNamespaces() {
* @return The prefixed name (e.g., "foaf:name") or null if no suitable prefix is found.
*/
private String getPrefixedNameInternal(String iriString) {
+ logger.info("getPrefixedNameInternal({})", iriString);
String longestMatchingNamespace = null;
String correspondingPrefix = null;
int longestMatchLength = -1;
- for (Map.Entry entry : iriToPrefixMapping.entrySet()) {
- String namespace = entry.getKey();
- String prefix = entry.getValue();
-
+ logger.info("{}", this.prefixHandler.getPrefixMap());
+ for (String namespace : this.prefixHandler.getNamespaces()) {
+ logger.info("{} contains {} ? {}", iriString, namespace, iriString.startsWith(namespace));
if (iriString.startsWith(namespace)) {
+ String prefix = this.prefixHandler.getPrefix(namespace);
+ logger.info("{} = {}", namespace, prefix);
if (namespace.length() > longestMatchLength) {
longestMatchLength = namespace.length();
longestMatchingNamespace = namespace;
@@ -257,7 +279,7 @@ private String getPrefixedNameInternal(String iriString) {
if (longestMatchingNamespace != null) {
String localName = iriString.substring(longestMatchingNamespace.length());
-
+ logger.info("{} = {} : {}", iriString, longestMatchingNamespace, localName);
if (localName.isEmpty()) {
return correspondingPrefix + SerializationConstants.COLON;
}
@@ -274,34 +296,33 @@ private String getPrefixedNameInternal(String iriString) {
* @param prefix The associated prefix.
*/
private void addPrefixMapping(String namespaceURI, String prefix) {
- if (iriToPrefixMapping.containsKey(namespaceURI)) {
- if (iriToPrefixMapping.get(namespaceURI).equals(prefix)) {
+ if (this.prefixHandler.hasNamespace(namespaceURI)) {
+ if (this.prefixHandler.getPrefix(namespaceURI).equals(prefix)) {
return;
} else {
if (logger.isWarnEnabled()) {
logger.warn("Namespace URI '{}' is already mapped to prefix '{}'. Cannot map to new prefix '{}'. " +
"Existing mapping for this namespace will be retained.",
- namespaceURI, iriToPrefixMapping.get(namespaceURI), prefix);
+ namespaceURI, this.prefixHandler.getPrefix(namespaceURI), prefix);
}
return;
}
}
String effectivePrefix = prefix;
- if (prefixToIriMapping.containsKey(prefix)) {
- if (!prefixToIriMapping.get(prefix).equals(namespaceURI)) {
+ if (this.prefixHandler.hasPrefix(prefix)) {
+ if (! this.prefixHandler.getNamespace(prefix).equals(namespaceURI)) {
if (logger.isWarnEnabled()) {
logger.warn("Prefix '{}' is already mapped to namespace '{}'. Cannot map to new namespace '{}'. " +
"A new unique prefix will be generated for '{}'.",
- prefix, prefixToIriMapping.get(prefix), namespaceURI, namespaceURI);
+ prefix, this.prefixHandler.getNamespace(prefix), namespaceURI, namespaceURI);
}
effectivePrefix = generateUniquePrefix(prefix);
}
}
- iriToPrefixMapping.put(namespaceURI, effectivePrefix);
- prefixToIriMapping.put(effectivePrefix, namespaceURI);
+ this.prefixHandler.setPrefix(effectivePrefix, namespaceURI);
}
/**
@@ -314,7 +335,7 @@ private void addPrefixMapping(String namespaceURI, String prefix) {
private String generateUniquePrefix(String basePrefix) {
String candidate = basePrefix;
int i = 0;
- while (prefixToIriMapping.containsKey(candidate)) {
+ while (this.prefixHandler.hasPrefix(candidate)) {
candidate = basePrefix + (++i);
}
return candidate;
@@ -469,30 +490,6 @@ private boolean shouldWriteDatatype(Literal literal) {
&& datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.MINIMAL));
}
-
- /**
- * Extracts the namespace URI part from an IRI string.
- * This is a common heuristic for RDF IRIs.
- *
- * @param iriString The full IRI.
- * @return The namespace URI part.
- */
- private String getNamespace(String iriString) {
- int hashIdx = iriString.lastIndexOf(SerializationConstants.HASH);
- int slashIdx = iriString.lastIndexOf(SerializationConstants.SLASH);
-
- if (hashIdx > -1) {
- return iriString.substring(0, hashIdx + 1);
- } else if (slashIdx > -1 && slashIdx < iriString.length() - 1) {
- int dotIdx = iriString.lastIndexOf(SerializationConstants.POINT);
- if (dotIdx > slashIdx) {
- return iriString.substring(0, slashIdx + 1);
- }
- return iriString.substring(0, slashIdx + 1);
- }
- return iriString;
- }
-
/**
* Suggests a prefix for a given namespace URI.
* Attempts to derive a meaningful prefix or generates a unique one.
@@ -501,14 +498,6 @@ private String getNamespace(String iriString) {
* @return A suggested prefix, or null if suggestion is not possible.
*/
private String getSuggestedPrefix(String namespace) {
-
- if (namespace.equals(RDF.getVocabularyNamespace())) return RDF.getVocabularyPreferredPrefix();
- if (namespace.equals(RDFS.getVocabularyNamespace())) return RDFS.getVocabularyPreferredPrefix();
- if (namespace.equals(XSD.getVocabularyNamespace())) return XSD.getVocabularyPreferredPrefix();
- if (namespace.equals(OWL.getVocabularyNamespace())) return OWL.getVocabularyPreferredPrefix();
- if (namespace.equals(FOAF.getVocabularyNamespace())) return FOAF.getVocabularyPreferredPrefix();
-
-
String base = namespace;
if (base.endsWith(SerializationConstants.HASH) || base.endsWith(SerializationConstants.SLASH)) {
base = base.substring(0, base.length() - 1);
@@ -540,7 +529,7 @@ private String getSuggestedPrefix(String namespace) {
String candidate = base;
int i = 0;
- while (prefixToIriMapping.containsKey(candidate) && !prefixToIriMapping.get(candidate).equals(namespace)) {
+ while (this.prefixHandler.hasPrefix(candidate) && !this.prefixHandler.getPrefix(candidate).equals(namespace)) {
candidate = base + (++i);
}
return candidate;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
index 9c2f00231..64f9198f8 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
@@ -1,6 +1,7 @@
package fr.inria.corese.core.next.impl.io.serialization.rdfxml;
-import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serializer.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serializer.UsesPrefixOptions;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
@@ -18,7 +19,7 @@
* Use the {@link Builder} class to create instances of {@code RDFXMLSerializerOptions}.
* A predefined default configuration is available via {@link #defaultConfig()}.
*/
-public class RDFXMLSerializerOptions extends AbstractSerializerOptions implements PrettyPrintOptions {
+public class RDFXMLSerializerOptions extends AbstractSerializerOptions implements PrettyPrintOptions, UsesPrefixOptions {
/**
* Whether prefix declarations (e.g., `xmlns:prefix="uri"`) should be used for compact IRIs.
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
index e5ee9691d..8d692d5af 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
@@ -16,11 +16,9 @@
import fr.inria.corese.core.next.api.Statement;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
-import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
-import fr.inria.corese.core.next.api.io.serialization.PrettyPrintOptions;
+import fr.inria.corese.core.next.api.io.serializer.LineEndingOptions;
+import fr.inria.corese.core.next.api.io.serializer.PrettyPrintOptions;
import fr.inria.corese.core.next.impl.io.serialization.base.AbstractGraphSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
index eb98bc223..4de909266 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
@@ -6,10 +6,6 @@
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
-import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
-import fr.inria.corese.core.next.api.io.serialization.UsesPrefixOptions;
-import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java
index d3b200fef..8a001358c 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerOptions.java
@@ -1,11 +1,9 @@
package fr.inria.corese.core.next.impl.io.serialization.turtle;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serialization.LineEndingOptions;
+import fr.inria.corese.core.next.api.io.serializer.LineEndingOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.BlankNodeStyleEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Configuration for Turtle serialization format.
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java
index f196531b5..e3fa9c040 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java
@@ -3,8 +3,7 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
-import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
@@ -33,7 +32,7 @@ class JSONLDCircularTest {
private ValueFactory valueFactory;
- private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
+ private fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
private JSONLDOptions defaultConfig;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/nquads/NQuadsCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/nquads/NQuadsCircularTest.java
index 2ea8b638d..1bad1a5cc 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/nquads/NQuadsCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/nquads/NQuadsCircularTest.java
@@ -3,7 +3,7 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializerOptions;
@@ -32,7 +32,7 @@
class NQuadsCircularTest {
private ValueFactory valueFactory;
- private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
+ private fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
private NQuadsSerializerOptions defaultConfig;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/ntriples/NTriplesCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/ntriples/NTriplesCircularTest.java
index bbfc741be..155b601a7 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/ntriples/NTriplesCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/ntriples/NTriplesCircularTest.java
@@ -3,7 +3,7 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializerOptions;
@@ -30,7 +30,7 @@
class NTriplesCircularTest {
private ValueFactory valueFactory;
- private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
+ private fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
private NTriplesSerializerOptions defaultConfig;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java
index 28af64e60..491ca3502 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLCircularTest.java
@@ -3,7 +3,7 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOptions;
@@ -36,7 +36,7 @@
class RDFXMLCircularTest {
private ValueFactory valueFactory;
- private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
+ private fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
private RDFXMLSerializerOptions defaultConfig;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/trig/TriGCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/trig/TriGCircularTest.java
index 0fa9d4720..9cf5fdaa6 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/trig/TriGCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/trig/TriGCircularTest.java
@@ -15,7 +15,7 @@
import fr.inria.corese.core.next.api.ValueFactory;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializerOptions;
@@ -37,7 +37,7 @@
class TriGCircularTest {
private ValueFactory valueFactory;
- private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
+ private fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
private TriGSerializerOptions defaultConfig;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/turtle/TurtleCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/turtle/TurtleCircularTest.java
index 848c1336e..ab59f1c80 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/turtle/TurtleCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/turtle/TurtleCircularTest.java
@@ -15,7 +15,7 @@
import fr.inria.corese.core.next.api.ValueFactory;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializerOptions;
@@ -35,7 +35,7 @@
class TurtleCircularTest {
private ValueFactory valueFactory;
- private fr.inria.corese.core.next.api.io.serialization.SerializerFactory serializerFactory;
+ private fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
private ParserFactory parserFactory;
private TurtleSerializerOptions defaultConfig;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
index d2d041c09..807e199a9 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
@@ -2,12 +2,7 @@
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
-import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
-import fr.inria.corese.core.next.impl.exception.SerializationException;
-import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
-import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Serializer;
-import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10SerializerOptions;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.serialization.jsonld.JSONLDSerializer;
import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializer;
import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializerOptions;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
index 7233acf46..ce017b542 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
@@ -3,7 +3,7 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializerTest.java
index 0a758c136..a22938244 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/jsonld/JSONLDSerializerTest.java
@@ -2,7 +2,7 @@
import com.apicatalog.jsonld.json.JsonLdComparison;
import fr.inria.corese.core.next.api.*;
-import fr.inria.corese.core.next.api.io.serialization.RDFSerializer;
+import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
import fr.inria.corese.core.next.impl.temp.CoreseModel;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
index 6713b69e1..7eb22e8fe 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
@@ -2,6 +2,7 @@
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.Statement;
+import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.common.vocabulary.XSD;
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.TestStatementFactory;
@@ -13,6 +14,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.StringWriter;
import java.util.stream.Stream;
@@ -26,6 +29,8 @@
*/
class RDFXMLSerializerTest {
+ private static final Logger logger = LoggerFactory.getLogger(RDFXMLSerializerTest.class);
+
@Mock
private Model mockModel;
RDFXMLSerializerOptions mockConfig;
@@ -65,14 +70,13 @@ void shouldSerializeSimpleIriTriple() throws SerializationException {
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
-
RDFXMLSerializer serializer = new RDFXMLSerializer(mockModel, testConfig);
serializer.write(writer);
String expected = """
-
+
@@ -104,7 +108,7 @@ void shouldHandleBlankNodeSubject() throws SerializationException {
String expected = """
-
+
@@ -138,7 +142,7 @@ void shouldHandleBlankNodeObject() throws SerializationException {
String expected = """
-
+
@@ -170,7 +174,7 @@ void shouldSerializeLiteralWithStringDatatypeMinimalPolicy() throws Serializatio
String expected = """
-
+
John Doe
@@ -202,7 +206,7 @@ void shouldSerializeLiteralWithCustomDatatypeMinimalPolicy() throws Serializatio
String expected = """
-
+
123
@@ -232,7 +236,7 @@ void shouldSerializeLiteralWithLanguage() throws SerializationException {
String expected = """
-
+
The Book
@@ -276,7 +280,6 @@ void shouldRespectPrefixOrderingDefault() throws SerializationException {
assertTrue(actual.contains("xmlns:exorg=\"http://ex.org/\""));
assertTrue(actual.contains("xmlns:excom=\"http://ex.com/\""));
- assertTrue(actual.contains("xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""));
String desc1 = " \n \n ";
String desc2 = " \n \n ";
@@ -312,7 +315,7 @@ void shouldSortSubjectsAlphabetically() throws SerializationException {
String expected = """
-
+
@@ -346,7 +349,7 @@ void shouldEscapeXmlAttributeValues() throws SerializationException {
String expected = """
-
+
@@ -379,7 +382,7 @@ void shouldEscapeXmlContentValues() throws SerializationException {
String expected = """
-
+
Value with <tags> & entities
@@ -412,9 +415,9 @@ void shouldNotAutoDeclarePrefixesIfDisabled() throws SerializationException {
String expected = """
-
+
-
+
""";
@@ -484,7 +487,7 @@ void shouldNotGenerateStableBlankNodeIds() throws SerializationException {
String expected = """
-
+
@@ -511,7 +514,7 @@ void shouldHandleEmptyModel() throws SerializationException {
String expected = """
-
+
""";
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
index 2309c1da1..1a7976689 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
@@ -7,6 +7,7 @@
import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.TestStatementFactory;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
+import fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
import fr.inria.corese.core.next.impl.temp.CoreseModel;
import org.junit.jupiter.api.BeforeEach;
@@ -294,6 +295,8 @@ void testBlankNodeSerializarionWithoutId() {
Logger logger = LoggerFactory.getLogger(TurtleSerializerTest.class);
ValueFactory valueFactory;
+ fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
+ ParserFactory parserFactory;
TurtleSerializerOptions defaultConfig;
String EXAMPLE_NS = "http://example.org/";
String PREDICATE_KNOWS = EXAMPLE_NS + "knows";
From bdd4a4e150d6502735ccba82016bde5d2c02827c Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Mon, 15 Dec 2025 16:43:28 +0100
Subject: [PATCH 07/12] escaped URIs in XML
---
.../corese/core/next/api/IPrefixHandler.java | 7 ++
.../impl/common/prefix/PrefixHandler.java | 17 +++-
.../core/next/impl/common/util/IRIUtils.java | 43 +++++----
.../io/serialization/SerializerFactory.java | 6 +-
.../rdfxml/RDFXMLSerializer.java | 90 ++++++-------------
.../next/impl/common/util/IRIUtilsTest.java | 6 ++
.../io/parser/jsonld/JSONLDCircularTest.java | 1 +
.../serialization/SerializerFactoryTest.java | 9 +-
.../rdfxml/RDFXMLSerializerTest.java | 6 +-
.../turtle/TurtleSerializerTest.java | 3 +-
10 files changed, 100 insertions(+), 88 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java b/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java
index 29742fee9..e2555c2d5 100644
--- a/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java
+++ b/src/main/java/fr/inria/corese/core/next/api/IPrefixHandler.java
@@ -68,6 +68,13 @@ public interface IPrefixHandler {
*/
Map getPrefixMap();
+ /**
+ * Returns all namespaces mappings as an unmodifiable map.
+ *
+ * @return an unmodifiable map where keys are namespaces IRIs and values are prefixes
+ */
+ Map getNamespaceMap();
+
/**
* Returns all namespace objects as an immutable set.
* Each Namespace object contains both prefix and IRI.
diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java b/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
index 0403836a8..402457f60 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
@@ -90,10 +90,15 @@ public void setPrefix(String prefix, String namespace) {
}
String oldNamespace = prefixToNamespace.get(prefix);
- if (oldNamespace != null && !oldNamespace.equals(namespace)) {
+ if (oldNamespace != null && ! oldNamespace.equals(namespace)) {
namespaceToPrefix.remove(oldNamespace);
prefixToNamespace.remove(prefix);
}
+ String oldPrefix = namespaceToPrefix.get(namespace);
+ if(oldPrefix != null && ! oldPrefix.equals(prefix)) {
+ namespaceToPrefix.remove(namespace);
+ prefixToNamespace.remove(oldPrefix);
+ }
prefixToNamespace.put(prefix, namespace);
namespaceToPrefix.put(namespace, prefix);
@@ -227,6 +232,16 @@ public Map getPrefixMap() {
return Collections.unmodifiableMap(new HashMap<>(prefixToNamespace));
}
+ /**
+ * Returns all namespaces mappings as an unmodifiable map.
+ *
+ * @return an unmodifiable map where keys are namespaces IRIs and values are prefixes
+ */
+ @Override
+ public Map getNamespaceMap() {
+ return Collections.unmodifiableMap(new HashMap<>(namespaceToPrefix));
+ }
+
/**
* Returns all namespace objects as an immutable set.
* Each Namespace object contains both prefix and IRI.
diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java b/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
index 55a04a6c5..d5889fd09 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
@@ -1,5 +1,8 @@
package fr.inria.corese.core.next.impl.common.util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;
@@ -14,14 +17,21 @@
*/
public class IRIUtils {
- private static final Pattern IRI_PATTERN = Pattern.compile("^(?" +
- "(?[\\w\\-]+):(?\\/\\/)?" +
- "(?([\\w\\-_:@]+\\.)*[\\w\\-_:]*))" +
- "((?\\/([\\w\\-\\._\\:]+\\/)*)" +
- "(?[\\w\\-\\._\\:]+)?" +
- "(?\\?[\\w\\-_\\:\\?\\=]+)?" +
- "(?(\\#))?" +
- "(?([\\w\\-_]+))?)?$");
+ private static final Logger logger = LoggerFactory.getLogger(IRIUtils.class);
+
+ // Example 1 : http://webisa.webdatacommons.org/data/sparql?query=q#line1
+ private static final Pattern IRI_PATTERN = Pattern.compile("^(?" + // http://webisa.webdatacommons.org
+ "(?[\\w\\-]+):" + // http:
+ "(?\\/\\/)?" + // //
+ "(?([\\w\\[\\]\\-_:@]+\\.)*[\\w\\-_:]*)" + // webisa.webdatacommons.org
+ ")" +
+ "(?\\/([\\w\\-\\._\\:]+\\/)*)*" + // /data/
+ "(?[\\w&<>;\\-\\._\\:\\\"\\\']+)?" + // sparql
+ "(?\\?[\\w\\-\\\"\\\'_\\:\\?\\=]+)?" + // ?query=q
+ "(?\\#)?" + // #
+ "(?[\\w\\-_]+)?" + // line1
+ "$"
+ );
private static final Pattern STANDARD_IRI_PATTERN = Pattern.compile("^(([^:/?#\\s]+):)(\\/\\/([^/?#\\s]*))?([^?#\\s]*)(\\?([^#\\s]*))?(#(.*))?");
private static final int MAX_IRI_LENGTH = 2048;
private static final long REGEX_TIMEOUT_MS = 100;
@@ -40,11 +50,13 @@ private IRIUtils() {
* @return the guessed namespace of the IRI or an empty string if no match is found.
*/
public static String guessNamespace(String iri) {
+ logger.info("guessNamespace {}", iri);
if (isInvalidInput(iri)) {
return "";
}
try {
Matcher matcher = matchWithTimeout(IRI_PATTERN, iri);
+ logger.info("{} : {}", iri, matcher.matches());
if (matcher == null || !matcher.matches()) {
if (iri.endsWith("#")) {
return iri;
@@ -54,20 +66,21 @@ public static String guessNamespace(String iri) {
return iri;
}
} else if (matcher.matches()) {
+ // This is a blank node
if (matcher.group("protocol") != null && matcher.group("protocol").equals("_")) {
return "";
}
+
StringBuilder namespace = new StringBuilder();
- namespace.append(matcher.group("protocol")).append(":");
- if (matcher.group("dblSlashes") != null) {
- namespace.append(matcher.group("dblSlashes"));
- }
- namespace.append(matcher.group("domain"));
+ namespace.append(matcher.group("rootnamespace"));
if (matcher.group("path") != null) {
namespace.append(matcher.group("path"));
}
- if((matcher.group("fragment") != null || matcher.group("anchor") != null) && matcher.group("finalPath") != null) {
- namespace.append(matcher.group("finalPath")).append("#");
+ if(matcher.group("anchor") != null) {
+ if(matcher.group("finalPath") != null) {
+ namespace.append(matcher.group("finalPath"));
+ }
+ namespace.append(matcher.group("anchor"));
}
return namespace.toString();
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
index 3ac796b4d..a0183829d 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
@@ -5,6 +5,8 @@
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
+import fr.inria.corese.core.next.impl.exception.SerializationException;
+import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Canonicalizer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Serializer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10SerializerOptions;
@@ -14,7 +16,7 @@
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializer;
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOption;
+import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializer;
import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializer;
@@ -112,7 +114,7 @@ public SerializerFactory() {
tempDefaultRegistry.put(RDFFormat.TRIG, TriGSerializer::new);
tempRegistry.put(RDFFormat.RDFXML, (model, genericConfig) -> {
- if (genericConfig instanceof RDFXMLSerializerOption specificConfig) {
+ if (genericConfig instanceof RDFXMLSerializerOptions specificConfig) {
return new RDFXMLSerializer(model, specificConfig);
}
throw new SerializationException(
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
index 70c968d3a..6ecd81b5b 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
@@ -81,7 +81,9 @@ public RDFXMLSerializer(Model model, IOOptions config) {
this.prefixHandler = usesPrefixOptions.getPrefixHandler();
} else {
this.prefixHandler = new PrefixHandler(false);
+ // These namespaces are part of the RDF/XML standard
this.prefixHandler.setPrefix(RDF.getVocabularyPreferredPrefix(), RDF.getVocabularyNamespace());
+ this.prefixHandler.setPrefix(XSD.getVocabularyPreferredPrefix(), XSD.getVocabularyNamespace());
}
this.blankNodeIds = new HashMap<>();
}
@@ -180,12 +182,33 @@ private void writeRdfRootElement(Writer writer) throws IOException {
*/
private void writeNamespaceAttributes(Writer writer, Set actuallyUsedNamespaces) throws IOException {
logger.info("actually used Namespaces: {}", actuallyUsedNamespaces);
+ logger.info("Known prefixes: {}", this.prefixHandler.getPrefixMap());
+ logger.info("Known namespaces: {}", this.prefixHandler.getNamespaceMap());
ArrayList namespacelist = new ArrayList<>(actuallyUsedNamespaces);
+
+ if(this.config instanceof UsesPrefixOptions usesPrefixOptions
+ && usesPrefixOptions.autoDeclarePrefixes()) {
+ logger.info("{}", namespacelist);
+
+ namespacelist.forEach(namespace -> {
+ logger.info("{} is in PrefixHandler = {}", namespace, this.prefixHandler.hasNamespace(namespace));
+ if (! this.prefixHandler.hasNamespace(namespace)) {
+ String prefix = getSuggestedPrefix(namespace);
+ if (prefix != null) {
+ this.prefixHandler.setPrefix(prefix, namespace);
+ }
+ }
+ });
+ }
+
if (this.config instanceof PrettyPrintOptions prettyPrintOptions
&& prettyPrintOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
namespacelist.sort(
- (ns1, ns2) ->
- prefixHandler.getPrefix(ns1).compareTo(prefixHandler.getPrefix(ns2)));
+ (ns1, ns2) -> {
+ logger.info("{}: {} <> {}: {}", ns1, prefixHandler.getPrefix(ns1), ns2, prefixHandler.getPrefix(ns2));
+ return prefixHandler.getPrefix(ns1).compareTo(prefixHandler.getPrefix(ns2));
+ }
+ );
}
for(String namespace : namespacelist) {
@@ -220,31 +243,7 @@ private Set collectUsedNamespaces() {
.filter(Value::isIRI)
.map(v -> IRIUtils.guessNamespace(v.stringValue()))
.collect(Collectors.toSet());
- logger.info("{}", potentialNamespaces);
-
- // potential namespaces can contain different candidates that are based on each other. We keep the shortest
- Set copyPotentialNamespaces = Set.copyOf(potentialNamespaces);
- potentialNamespaces = potentialNamespaces
- .stream()
- .filter(potentialNamespace -> copyPotentialNamespaces
- .stream()
- .noneMatch(otherPotentialNamespace -> (! otherPotentialNamespace.equals(potentialNamespace)) && potentialNamespace.startsWith(otherPotentialNamespace)))
- .collect(Collectors.toSet());
- logger.info("{}", potentialNamespaces);
-
- potentialNamespaces.forEach(namespace -> {
- logger.info("{} is in PrefixHandler = {}", namespace, this.prefixHandler.hasNamespace(namespace));
- if (! this.prefixHandler.hasNamespace(namespace) &&
- // removing known namespaces from the list of potential namespaces
- this.prefixHandler.getNamespaces()
- .stream()
- .noneMatch(knownNamespace -> (knownNamespace.startsWith(namespace)))) {
- String prefix = getSuggestedPrefix(namespace);
- if (prefix != null) {
- addPrefixMapping(namespace, prefix);
- }
- }
- });
+ logger.info("Potential namespaces{}", potentialNamespaces);
return potentialNamespaces;
}
@@ -288,43 +287,6 @@ private String getPrefixedNameInternal(String iriString) {
return null;
}
- /**
- * Adds a prefix-namespace URI mapping to the internal mappings.
- * Handles potential conflicts to ensure uniqueness.
- *
- * @param namespaceURI The namespace URI.
- * @param prefix The associated prefix.
- */
- private void addPrefixMapping(String namespaceURI, String prefix) {
- if (this.prefixHandler.hasNamespace(namespaceURI)) {
- if (this.prefixHandler.getPrefix(namespaceURI).equals(prefix)) {
- return;
- } else {
-
- if (logger.isWarnEnabled()) {
- logger.warn("Namespace URI '{}' is already mapped to prefix '{}'. Cannot map to new prefix '{}'. " +
- "Existing mapping for this namespace will be retained.",
- namespaceURI, this.prefixHandler.getPrefix(namespaceURI), prefix);
- }
- return;
- }
- }
-
- String effectivePrefix = prefix;
- if (this.prefixHandler.hasPrefix(prefix)) {
- if (! this.prefixHandler.getNamespace(prefix).equals(namespaceURI)) {
- if (logger.isWarnEnabled()) {
- logger.warn("Prefix '{}' is already mapped to namespace '{}'. Cannot map to new namespace '{}'. " +
- "A new unique prefix will be generated for '{}'.",
- prefix, this.prefixHandler.getNamespace(prefix), namespaceURI, namespaceURI);
- }
- effectivePrefix = generateUniquePrefix(prefix);
- }
- }
-
- this.prefixHandler.setPrefix(effectivePrefix, namespaceURI);
- }
-
/**
* Generates a unique prefix based on a given base string, ensuring it's not already in use.
* This method appends numbers to the base prefix until a unique one is found.
diff --git a/src/test/java/fr/inria/corese/core/next/impl/common/util/IRIUtilsTest.java b/src/test/java/fr/inria/corese/core/next/impl/common/util/IRIUtilsTest.java
index 4336896b5..b1626962b 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/common/util/IRIUtilsTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/common/util/IRIUtilsTest.java
@@ -20,6 +20,8 @@ public class IRIUtilsTest {
private static final String uriToHTMLPageWithQueryAndFragment = "https://www.syuno-pit.biz/tezukayama-bandai-2.html?query=1#fragment";
private static final String uriToHTMLPageWithFragment = "https://www.syuno-pit.biz/tezukayama-bandai-2.html#fragment";
private static final String blankNode = "_:n2d65906b09534cabb44314ff2e2b248axb4";
+ private static final String uriWithUnexpectedCharactersObject = "http://example.org/obj"ect&apos";
+ private static final String uriWithUnexpectedCharactersSubject = "http://example.org/sub&ject";
// Array of strings that should be recognized as correct IRIs. Some of them taken from the official IRI documentation.
private static final String[] correctARIs = { uriSchema, uriWithFragment, uriWithQuery, uriWithPort, uriWithPortAndQuery, uriWithPortAndQueryAndFragment, uriWithPortAndFragment, uriToHTMLPage, uriToHTMLPageWithQuery, uriToHTMLPageWithQueryAndFragment, uriToHTMLPageWithFragment, "ftp://ftp.is.co.za/rfc/rfc1808.txt", "http://www.ietf.org/rfc/rfc2396.txt", "ldap://[2001:db8::7]/c=GB?objectClass?one", "mailto:John.Doe@example.com", "news:comp.infosystems.www.servers.unix", "tel:+1-816-555-1212", "telnet://192.0.2.16:80/", "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "http://foo.co.uk/", "http://regexr.com/foo.html?q=bar" };
@@ -40,6 +42,8 @@ public void guessNamespaceTest() {
assertEquals("https://www.syuno-pit.biz/tezukayama-bandai-2.html#", IRIUtils.guessNamespace(uriToHTMLPageWithFragment));
assertEquals("", IRIUtils.guessNamespace(blankNode));
assertEquals("http://www.w3.org/2001/XMLSchema#", IRIUtils.guessNamespace("http://www.w3.org/2001/XMLSchema#"));
+ assertEquals("http://example.org/", IRIUtils.guessNamespace(uriWithUnexpectedCharactersObject));
+ assertEquals("http://example.org/", IRIUtils.guessNamespace(uriWithUnexpectedCharactersSubject));
}
@Test
@@ -56,6 +60,8 @@ public void guessLocalNameTest() {
assertEquals("fragment", IRIUtils.guessLocalName(uriToHTMLPageWithQueryAndFragment));
assertEquals("fragment", IRIUtils.guessLocalName(uriToHTMLPageWithFragment));
assertEquals("", IRIUtils.guessLocalName(blankNode));
+ assertEquals("obj"ect&apos", IRIUtils.guessLocalName(uriWithUnexpectedCharactersObject));
+ assertEquals("sub&ject", IRIUtils.guessLocalName(uriWithUnexpectedCharactersSubject));
}
@Test
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java
index e3fa9c040..c79c85d3c 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/jsonld/JSONLDCircularTest.java
@@ -4,6 +4,7 @@
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.parser.RDFParser;
import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
+import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
index 807e199a9..196d32d63 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
@@ -2,14 +2,19 @@
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.base.io.RDFFormat;
+import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
+import fr.inria.corese.core.next.impl.exception.SerializationException;
+import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
+import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Serializer;
+import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10SerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.jsonld.JSONLDSerializer;
import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializer;
import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializer;
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOption;
+import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializer;
import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializer;
@@ -99,7 +104,7 @@ void createSerializer_shouldReturnTriGSerializer_forTriGFormat() {
@Test
@DisplayName("createSerializer should return XmlSerializer for RDFXML format")
void createSerializer_shouldReturnXmlSerializer_forRdfXmlFormat() {
- RDFXMLSerializerOption config = RDFXMLSerializerOption.defaultConfig();
+ RDFXMLSerializerOptions config = RDFXMLSerializerOptions.defaultConfig();
try (MockedConstruction mockedConstruction = mockConstruction(RDFXMLSerializer.class)) {
RDFSerializer serializer = factory.createSerializer(RDFFormat.RDFXML, mockModel, config);
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
index 7eb22e8fe..4a3cbe020 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
@@ -43,7 +43,7 @@ void setUp() {
closeable = MockitoAnnotations.openMocks(this);
writer = new StringWriter();
factory = new TestStatementFactory();
- mockConfig = RDFXMLSerializerOption.defaultConfig();
+ mockConfig = RDFXMLSerializerOptions.defaultConfig();
}
@AfterEach
@@ -201,12 +201,14 @@ void shouldSerializeLiteralWithCustomDatatypeMinimalPolicy() throws Serializatio
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
+ logger.info("AutoDeclarePrefix ? {}", testConfig.autoDeclarePrefixes());
+
RDFXMLSerializer serializer = new RDFXMLSerializer(mockModel, testConfig);
serializer.write(writer);
String expected = """
-
+
123
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
index 1a7976689..4a33b006e 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializerTest.java
@@ -5,6 +5,7 @@
import fr.inria.corese.core.next.impl.common.literal.XSD;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.exception.SerializationException;
+import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.TestStatementFactory;
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
import fr.inria.corese.core.next.impl.exception.SerializationException;
@@ -295,8 +296,6 @@ void testBlankNodeSerializarionWithoutId() {
Logger logger = LoggerFactory.getLogger(TurtleSerializerTest.class);
ValueFactory valueFactory;
- fr.inria.corese.core.next.api.io.serializer.SerializerFactory serializerFactory;
- ParserFactory parserFactory;
TurtleSerializerOptions defaultConfig;
String EXAMPLE_NS = "http://example.org/";
String PREDICATE_KNOWS = EXAMPLE_NS + "knows";
From eae9f86251fd6abd650bf568d269b1fa6eb2590f Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Mon, 15 Dec 2025 16:50:47 +0100
Subject: [PATCH 08/12] Fixing tests that removed #
---
.../impl/io/parser/rdfxml/RDFXMLUtilsTest.java | 2 +-
.../canonical/RDFC10SerializerTest.java | 18 +++++++++---------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLUtilsTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLUtilsTest.java
index 727d6209f..592ff3623 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLUtilsTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/parser/rdfxml/RDFXMLUtilsTest.java
@@ -75,7 +75,7 @@ public void testExtractSubjectWithID() {
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute(RDF.type.getNamespace(), "ID", "", "CDATA", "id123");
Resource subject = RDFXMLUtils.extractSubject(attrs, factory, "http://example.org/", null);
- assertEquals("http://example.org/id123", subject.stringValue());
+ assertEquals("http://example.org/#id123", subject.stringValue());
}
/**
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
index ce017b542..a258dc44e 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
@@ -297,11 +297,11 @@ void testSerializeFigure3() {
assertFalse(canonicalOutput.isEmpty(), "Canonical output should not be empty");
String actual = canonicalOutput.trim().replace("\r\n", "\n");
String expected = """
- _:c14n2 .
- _:c14n3 .
- _:c14n0 _:c14n1 .
- _:c14n2 _:c14n1 .
- _:c14n3 _:c14n0 .""";
+ _:c14n2 .
+ _:c14n3 .
+ _:c14n0 _:c14n1 .
+ _:c14n2 _:c14n1 .
+ _:c14n3 _:c14n0 .""";
assertEquals(expected, actual, "Canonical output should match expected format");
}
@@ -317,10 +317,10 @@ void testSerializeFigure2() {
String actual = canonicalOutput.trim().replace("\r\n", "\n");
String expected = """
- _:c14n0 .
- _:c14n1 .
- _:c14n0 .
- _:c14n1 .""";
+ _:c14n0 .
+ _:c14n1 .
+ _:c14n0 .
+ _:c14n1 .""";
assertEquals(expected, actual, "Canonical output should match RDFC-1.0 specification");
}
From d2950e91160262f23aa28b6c390d9d925e8846cc Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Mon, 15 Dec 2025 17:30:37 +0100
Subject: [PATCH 09/12] fix serializerFactory
---
.../core/next/impl/common/util/IRIUtils.java | 4 -
.../io/serialization/SerializerFactory.java | 66 ++--------------
.../base/AbstractGraphSerializer.java | 77 +++++++++++--------
.../rdfxml/RDFXMLSerializer.java | 21 +----
.../io/serialization/trig/TriGSerializer.java | 7 +-
.../turtle/TurtleSerializer.java | 9 ++-
.../serialization/SerializerFactoryTest.java | 46 ++++++++---
.../rdfxml/RDFXMLSerializerTest.java | 19 +++--
8 files changed, 116 insertions(+), 133 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java b/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
index d5889fd09..5afe6d323 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
@@ -17,8 +17,6 @@
*/
public class IRIUtils {
- private static final Logger logger = LoggerFactory.getLogger(IRIUtils.class);
-
// Example 1 : http://webisa.webdatacommons.org/data/sparql?query=q#line1
private static final Pattern IRI_PATTERN = Pattern.compile("^(?" + // http://webisa.webdatacommons.org
"(?[\\w\\-]+):" + // http:
@@ -50,13 +48,11 @@ private IRIUtils() {
* @return the guessed namespace of the IRI or an empty string if no match is found.
*/
public static String guessNamespace(String iri) {
- logger.info("guessNamespace {}", iri);
if (isInvalidInput(iri)) {
return "";
}
try {
Matcher matcher = matchWithTimeout(IRI_PATTERN, iri);
- logger.info("{} : {}", iri, matcher.matches());
if (matcher == null || !matcher.matches()) {
if (iri.endsWith("#")) {
return iri;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
index a0183829d..86cae25b1 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
@@ -65,76 +65,22 @@ public SerializerFactory() {
Map> tempRegistry = new HashMap<>();
Map> tempDefaultRegistry = new HashMap<>();
- tempRegistry.put(RDFFormat.TURTLE, (model, genericConfig) -> {
- if (genericConfig instanceof TurtleSerializerOptions specificConfig) {
- return new TurtleSerializer(model, specificConfig);
- }
- throw new SerializationException(
- "Invalid configuration type. Expected TurtleSerializerOptions, got: " +
- genericConfig.getClass().getSimpleName(),
- RDFFormat.TURTLE.getName()
- );
- });
+ tempRegistry.put(RDFFormat.TURTLE, (model, genericConfig) -> new TurtleSerializer(model, genericConfig));
tempDefaultRegistry.put(RDFFormat.TURTLE, TurtleSerializer::new);
- tempRegistry.put(RDFFormat.NTRIPLES, (model, genericConfig) -> {
- if (genericConfig instanceof NTriplesSerializerOptions specificConfig) {
- return new NTriplesSerializer(model, specificConfig);
- }
- throw new SerializationException(
- "Invalid configuration type. Expected NTriplesSerializerOptions, got: " +
- genericConfig.getClass().getSimpleName(),
- RDFFormat.NTRIPLES.getName()
- );
- });
+ tempRegistry.put(RDFFormat.NTRIPLES, (model, genericConfig) -> new NTriplesSerializer(model, genericConfig));
tempDefaultRegistry.put(RDFFormat.NTRIPLES, NTriplesSerializer::new);
- tempRegistry.put(RDFFormat.NQUADS, (model, genericConfig) -> {
- if (genericConfig instanceof NQuadsSerializerOptions specificConfig) {
- return new NQuadsSerializer(model, specificConfig);
- }
- throw new SerializationException(
- "Invalid configuration type. Expected NQuadsSerializerOptions, got: " +
- genericConfig.getClass().getSimpleName(),
- RDFFormat.NQUADS.getName()
- );
- });
+ tempRegistry.put(RDFFormat.NQUADS, (model, genericConfig) -> new NQuadsSerializer(model, genericConfig));
tempDefaultRegistry.put(RDFFormat.NQUADS, NQuadsSerializer::new);
- tempRegistry.put(RDFFormat.TRIG, (model, genericConfig) -> {
- if (genericConfig instanceof TriGSerializerOptions specificConfig) {
- return new TriGSerializer(model, specificConfig);
- }
- throw new SerializationException(
- "Invalid configuration type. Expected TriGSerializerOptions, got: " +
- genericConfig.getClass().getSimpleName(),
- RDFFormat.TRIG.getName()
- );
- });
+ tempRegistry.put(RDFFormat.TRIG, (model, genericConfig) -> new TriGSerializer(model, genericConfig));
tempDefaultRegistry.put(RDFFormat.TRIG, TriGSerializer::new);
- tempRegistry.put(RDFFormat.RDFXML, (model, genericConfig) -> {
- if (genericConfig instanceof RDFXMLSerializerOptions specificConfig) {
- return new RDFXMLSerializer(model, specificConfig);
- }
- throw new SerializationException(
- "Invalid configuration type. Expected RDFXMLSerializerOption, got: " +
- genericConfig.getClass().getSimpleName(),
- RDFFormat.RDFXML.getName()
- );
- });
+ tempRegistry.put(RDFFormat.RDFXML, (model, genericConfig) -> new RDFXMLSerializer(model, genericConfig));
tempDefaultRegistry.put(RDFFormat.RDFXML, RDFXMLSerializer::new);
- tempRegistry.put(RDFFormat.JSONLD, (model, genericConfig) -> {
- if (genericConfig instanceof JSONLDOptions specificConfig) {
- return new JSONLDSerializer(model, specificConfig);
- }
- throw new SerializationException(
- "Invalid configuration type. Expected JSONLDOptions, got: " +
- genericConfig.getClass().getSimpleName(),
- RDFFormat.JSONLD.getName()
- );
- });
+ tempRegistry.put(RDFFormat.JSONLD, (model, genericConfig) -> new JSONLDSerializer(model, genericConfig));
tempDefaultRegistry.put(RDFFormat.JSONLD, JSONLDSerializer::new);
tempRegistry.put(RDFFormat.RDFC_1_0, (model, genericConfig) -> {
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
index 66f1e60b3..6e247f9ca 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractGraphSerializer.java
@@ -2,9 +2,8 @@
import fr.inria.corese.core.next.api.*;
import fr.inria.corese.core.next.api.io.IOOptions;
-import fr.inria.corese.core.next.api.io.serializer.PrettyPrintOptions;
-import fr.inria.corese.core.next.api.io.serializer.UsesPrefixOptions;
-import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
+import fr.inria.corese.core.next.api.io.common.BaseIRIOptions;
+import fr.inria.corese.core.next.api.io.serializer.*;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.common.util.IRIUtils;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
@@ -44,7 +43,7 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
protected static final Logger logger = LoggerFactory.getLogger(AbstractGraphSerializer.class);
protected final Model model;
- protected AbstractSerializerOptions option;
+ protected IOOptions option;
protected PrefixHandler prefixHandler;
protected final Set consumedBlankNodes;
protected final Set currentlyWritingBlankNodes;
@@ -59,11 +58,7 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
protected AbstractGraphSerializer(Model model, IOOptions config) {
this.model = Objects.requireNonNull(model, "The model cannot be null");
Objects.requireNonNull(config, "The configuration cannot be null");
- if(config instanceof AbstractSerializerOptions abstractSerializerOptions) {
- this.option = abstractSerializerOptions;
- } else {
- throw new IllegalArgumentException("AbstractGraphSerializer expect option object to extend AbstractSerializerOptions. Inheritor class should have taken care of that.");
- }
+ this.option = config;
if(config instanceof UsesPrefixOptions usesPrefixOptions) {
this.prefixHandler = usesPrefixOptions.getPrefixHandler();
} else {
@@ -114,10 +109,12 @@ public void write(Writer writer) throws SerializationException {
* @throws IOException if an I/O error occurs.
*/
protected void writeHeader(Writer writer) throws IOException {
- if (option.getBaseIRI() != null) {
+ if (option instanceof BaseIRIOptions baseIRIOptions
+ && option instanceof LineEndingOptions lineEndingOptions
+ && baseIRIOptions.getBaseIRI() != null) {
writer.write(String.format("@base <%s> .%s",
- option.getBaseIRI(),
- option.getLineEnding()));
+ baseIRIOptions.getBaseIRI(),
+ lineEndingOptions.getLineEnding()));
}
Set actuallyUsedNamespaces = Set.of();
@@ -176,7 +173,9 @@ protected Set collectUsedNamespaces() {
*/
protected void writePrefixDeclarations(Writer writer, Set actuallyUsedNamespaces) throws IOException {
if(this.option instanceof UsesPrefixOptions prefixOptions
- && prefixOptions.usePrefixes()) {
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && this.option instanceof BaseIRIOptions baseIRIOptions
+ && prefixOptions.usePrefixes()) {
List prefixes = new ArrayList<>(actuallyUsedNamespaces.stream().map(namespace -> this.prefixHandler.getPrefix(namespace)).toList());
if (prefixOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
@@ -187,11 +186,11 @@ protected void writePrefixDeclarations(Writer writer, Set actuallyUsedNa
writer.write(String.format("@prefix %s: <%s> .%s",
prefix,
this.prefixHandler.getNamespace(prefix),
- option.getLineEnding()));
+ lineEndingOptions.getLineEnding()));
}
- if (!prefixes.isEmpty() || option.getBaseIRI() != null) {
- writer.write(option.getLineEnding());
+ if (!prefixes.isEmpty() || baseIRIOptions.getBaseIRI() != null) {
+ writer.write(lineEndingOptions.getLineEnding());
}
}
}
@@ -217,7 +216,9 @@ protected void writeSimpleStatements(Writer writer) throws IOException {
for (Statement stmt : model) {
if (!isConsumed(stmt.getSubject())) {
writeStatement(writer, stmt);
- writer.write(option.getLineEnding());
+ if(this.option instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
}
}
}
@@ -337,7 +338,7 @@ protected void writeValue(Writer writer, Value value) throws IOException {
* @throws IOException if an I/O error occurs.
*/
protected void writeIRI(Writer writer, IRI iri) throws IOException {
- if (option.isStrictMode() && option.validateURIs()) {
+ if (this.option instanceof AbstractSerializerOptions abstractSerializerOptions && abstractSerializerOptions.isStrictMode() && abstractSerializerOptions.validateURIs()) {
validateIRI(iri);
}
@@ -419,9 +420,10 @@ protected boolean shouldWriteDatatype(Literal literal) {
return false;
}
- return option.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.ALWAYS_TYPED ||
- (!datatype.equals(XSD.xsdString.getIRI()) &&
- option.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.MINIMAL);
+ return this.option instanceof DatatypePolicyOptions datatypePolicyOptions &&
+ (datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.ALWAYS_TYPED
+ || (!datatype.equals(XSD.xsdString.getIRI()) &&
+ datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.MINIMAL));
}
/**
@@ -450,8 +452,10 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
}
firstProperty = false;
- if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint()) {
- writer.write(option.getLineEnding() + propIndent);
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyPrintOptions.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + propIndent);
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -461,8 +465,11 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
writeValue(writer, stmt.getObject());
}
- if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint() && !properties.isEmpty() && !firstProperty) {
- writer.write(option.getLineEnding() + currentIndent);
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyPrintOptions.prettyPrint()
+ && !properties.isEmpty() && !firstProperty) {
+ writer.write(lineEndingOptions.getLineEnding() + currentIndent);
}
writer.write(SerializationConstants.BLANK_NODE_END);
@@ -501,8 +508,10 @@ protected void writeOptimizedStatements(Writer writer) throws IOException {
for (Map.Entry> predicateEntry : byPredicate.entrySet()) {
if (!firstPredicate) {
writer.write(SerializationConstants.SEMICOLON);
- if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint()) {
- writer.write(option.getLineEnding() + indent + prettyPrintOptions.getIndent());
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyPrintOptions.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + indent + prettyPrintOptions.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -516,8 +525,10 @@ protected void writeOptimizedStatements(Writer writer) throws IOException {
for (Statement stmt : predicateEntry.getValue()) {
if (!firstObject) {
writer.write(SerializationConstants.COMMA);
- if (this.option instanceof PrettyPrintOptions prettyPrintOptions && prettyPrintOptions.prettyPrint()) {
- writer.write(option.getLineEnding() + indent + prettyPrintOptions.getIndent() + prettyPrintOptions.getIndent());
+ if (this.option instanceof PrettyPrintOptions prettyPrintOptions
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyPrintOptions.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + indent + prettyPrintOptions.getIndent() + prettyPrintOptions.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -529,7 +540,9 @@ protected void writeOptimizedStatements(Writer writer) throws IOException {
}
writer.write(SerializationConstants.SPACE + SerializationConstants.POINT);
- writer.write(option.getLineEnding());
+ if(this.option instanceof LineEndingOptions lineEndingOptions) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
}
}
@@ -867,7 +880,9 @@ protected void validateValue(Value value) {
throw new SerializationException("Value cannot be null in {} format when strictMode is enabled.", getFormatName());
}
- if (option.isStrictMode() && value.isLiteral()) {
+ if (this.option instanceof AbstractSerializerOptions abstractSerializerOptions
+ && abstractSerializerOptions.isStrictMode()
+ && value.isLiteral()) {
validateLiteral((Literal) value);
}
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
index 6ecd81b5b..5c037295d 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
@@ -45,8 +45,6 @@
*/
public class RDFXMLSerializer implements RDFSerializer {
- private static final Logger logger = LoggerFactory.getLogger(RDFXMLSerializer.class);
-
private final Model model;
private final IOOptions config;
private final PrefixHandler prefixHandler;
@@ -181,17 +179,12 @@ private void writeRdfRootElement(Writer writer) throws IOException {
* @throws IOException if an I/O error occurs.
*/
private void writeNamespaceAttributes(Writer writer, Set actuallyUsedNamespaces) throws IOException {
- logger.info("actually used Namespaces: {}", actuallyUsedNamespaces);
- logger.info("Known prefixes: {}", this.prefixHandler.getPrefixMap());
- logger.info("Known namespaces: {}", this.prefixHandler.getNamespaceMap());
ArrayList namespacelist = new ArrayList<>(actuallyUsedNamespaces);
if(this.config instanceof UsesPrefixOptions usesPrefixOptions
&& usesPrefixOptions.autoDeclarePrefixes()) {
- logger.info("{}", namespacelist);
namespacelist.forEach(namespace -> {
- logger.info("{} is in PrefixHandler = {}", namespace, this.prefixHandler.hasNamespace(namespace));
if (! this.prefixHandler.hasNamespace(namespace)) {
String prefix = getSuggestedPrefix(namespace);
if (prefix != null) {
@@ -204,10 +197,8 @@ private void writeNamespaceAttributes(Writer writer, Set actuallyUsedNam
if (this.config instanceof PrettyPrintOptions prettyPrintOptions
&& prettyPrintOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
namespacelist.sort(
- (ns1, ns2) -> {
- logger.info("{}: {} <> {}: {}", ns1, prefixHandler.getPrefix(ns1), ns2, prefixHandler.getPrefix(ns2));
- return prefixHandler.getPrefix(ns1).compareTo(prefixHandler.getPrefix(ns2));
- }
+ (ns1, ns2) ->
+ prefixHandler.getPrefix(ns1).compareTo(prefixHandler.getPrefix(ns2))
);
}
@@ -243,7 +234,6 @@ private Set collectUsedNamespaces() {
.filter(Value::isIRI)
.map(v -> IRIUtils.guessNamespace(v.stringValue()))
.collect(Collectors.toSet());
- logger.info("Potential namespaces{}", potentialNamespaces);
return potentialNamespaces;
}
@@ -257,17 +247,13 @@ private Set collectUsedNamespaces() {
* @return The prefixed name (e.g., "foaf:name") or null if no suitable prefix is found.
*/
private String getPrefixedNameInternal(String iriString) {
- logger.info("getPrefixedNameInternal({})", iriString);
String longestMatchingNamespace = null;
String correspondingPrefix = null;
int longestMatchLength = -1;
- logger.info("{}", this.prefixHandler.getPrefixMap());
for (String namespace : this.prefixHandler.getNamespaces()) {
- logger.info("{} contains {} ? {}", iriString, namespace, iriString.startsWith(namespace));
if (iriString.startsWith(namespace)) {
String prefix = this.prefixHandler.getPrefix(namespace);
- logger.info("{} = {}", namespace, prefix);
if (namespace.length() > longestMatchLength) {
longestMatchLength = namespace.length();
longestMatchingNamespace = namespace;
@@ -278,7 +264,6 @@ private String getPrefixedNameInternal(String iriString) {
if (longestMatchingNamespace != null) {
String localName = iriString.substring(longestMatchingNamespace.length());
- logger.info("{} = {} : {}", iriString, longestMatchingNamespace, localName);
if (localName.isEmpty()) {
return correspondingPrefix + SerializationConstants.COLON;
}
@@ -368,7 +353,6 @@ private void writePropertyElement(Writer writer, IRI predicate, Value object, St
elementName = prefixedPredicateName;
} else {
elementName = predicateString;
- logger.warn("Predicate IRI '{}' cannot be expressed as a valid prefixed element name. Using full IRI as element name in RDF/XML.", predicateString);
}
writer.write(currentIndent);
@@ -481,7 +465,6 @@ private String getSuggestedPrefix(String namespace) {
base = "p";
}
} catch (java.net.URISyntaxException e) {
- logger.warn("Malformed URI encountered while suggesting prefix: {}", namespace, e);
base = "p";
}
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
index 8d692d5af..a3f7cfab9 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
@@ -19,6 +19,7 @@
import fr.inria.corese.core.next.api.io.serializer.LineEndingOptions;
import fr.inria.corese.core.next.api.io.serializer.PrettyPrintOptions;
import fr.inria.corese.core.next.impl.io.serialization.base.AbstractGraphSerializer;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.option.AbstractTFamilyOptions;
import fr.inria.corese.core.next.impl.io.serialization.util.SerializationConstants;
@@ -247,7 +248,11 @@ protected String escapeLiteralString(String value) {
sb.append(SerializationConstants.BACK_SLASH).append(SerializationConstants.BACK_SLASH);
break;
default:
- if (option.escapeUnicode() && (c <= 0x1F || c == 0x7F || (c >= 0x80 && c <= 0xFFFF))) {
+ if (this.option instanceof AbstractSerializerOptions abstractSerializerOptions
+ && abstractSerializerOptions.escapeUnicode()
+ && (c <= 0x1F
+ || c == 0x7F
+ || (c >= 0x80 && c <= 0xFFFF))) {
sb.append(String.format("\\u%04X", (int) c));
} else if (Character.isHighSurrogate(c)) {
int codePoint = value.codePointAt(i);
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
index 4de909266..14f5115ef 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
@@ -6,6 +6,7 @@
import fr.inria.corese.core.next.api.base.io.RDFFormat;
import fr.inria.corese.core.next.api.io.IOOptions;
+import fr.inria.corese.core.next.impl.io.serialization.option.AbstractSerializerOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -152,12 +153,16 @@ protected String escapeLiteralString(String value) {
if (Character.isISOControl(c) ||c == 0x7F) {
sb.append(String.format("\\u%04X", (int) c));
}
- else if (option.escapeUnicode() && c >= 0x80 && c <= 0xFFFF) {
+ else if (this.option instanceof AbstractSerializerOptions abstractSerializerOptions
+ && abstractSerializerOptions.escapeUnicode()
+ && c >= 0x80
+ && c <= 0xFFFF) {
sb.append(String.format("\\u%04X", (int) c));
} else if (Character.isHighSurrogate(c)) {
int codePoint = value.codePointAt(i);
if (Character.isValidCodePoint(codePoint)) {
- if (option.escapeUnicode()) {
+ if (this.option instanceof AbstractSerializerOptions abstractSerializerOptions
+ && abstractSerializerOptions.escapeUnicode()) {
sb.append(String.format("\\U%08X", codePoint));
} else {
sb.append(Character.toChars(codePoint));
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
index 196d32d63..d23d6165d 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactoryTest.java
@@ -141,16 +141,6 @@ void createSerializer_shouldReturnJSONLDSerializer_forJSONLDFormat() {
}
}
- @Test
- @DisplayName("createSerializer should throw SerializationException for wrong config type")
- void createSerializer_shouldThrowSerializationException_forWrongConfigType() {
- IOOptions wrongConfig = mock(IOOptions.class);
-
- assertThrows(SerializationException.class,
- () -> factory.createSerializer(RDFFormat.TURTLE, mockModel, wrongConfig),
- "Should throw SerializationException for wrong config type");
- }
-
@Test
@DisplayName("createSerializer should throw NullPointerException for a null format")
void createSerializer_shouldThrowNPE_forNullFormat() {
@@ -283,4 +273,40 @@ void createSerializerWithoutConfig_shouldThrowNPE_forNullModel() {
() -> factory.createSerializer(RDFFormat.TURTLE, null),
"Should throw NullPointerException for null Model");
}
+
+ @Test
+ @DisplayName("Should accept cross-use of config objects")
+ void configCrossUse() {
+ JSONLDOptions jsonldOptions = new JSONLDOptions.Builder().build();
+ NQuadsSerializerOptions nQuadsSerializerOptions = new NQuadsSerializerOptions.Builder().build();
+ NTriplesSerializerOptions nTriplesSerializerOptions = new NTriplesSerializerOptions.Builder().build();
+ RDFXMLSerializerOptions rdfxmlSerializerOptions = new RDFXMLSerializerOptions.Builder().build();
+ TriGSerializerOptions triGSerializerOptions = new TriGSerializerOptions.Builder().build();
+ TurtleSerializerOptions turtleSerializerOptions = new TurtleSerializerOptions.Builder().build();
+
+ assertDoesNotThrow(() -> {
+ // JSONLDOptions -- NQuads
+ factory.createSerializer(RDFFormat.JSONLD, mockModel, nQuadsSerializerOptions);
+ });
+ assertDoesNotThrow(() -> {
+ // NQuads -- NTriples
+ factory.createSerializer(RDFFormat.NQUADS, mockModel, nTriplesSerializerOptions);
+ });
+ assertDoesNotThrow(() -> {
+ // NTriples -- RDFXML
+ factory.createSerializer(RDFFormat.NTRIPLES, mockModel, rdfxmlSerializerOptions);
+ });
+ assertDoesNotThrow(() -> {
+ // RDFXML -- TriG
+ factory.createSerializer(RDFFormat.RDFXML, mockModel, triGSerializerOptions);
+ });
+ assertDoesNotThrow(() -> {
+ // TriG -- Turtle
+ factory.createSerializer(RDFFormat.TRIG, mockModel, turtleSerializerOptions);
+ });
+ assertDoesNotThrow(() -> {
+ // Turtle -- JSONLD
+ factory.createSerializer(RDFFormat.TURTLE, mockModel, jsonldOptions);
+ });
+ }
}
\ No newline at end of file
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
index 4a3cbe020..e05250020 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerTest.java
@@ -2,6 +2,7 @@
import fr.inria.corese.core.next.api.Model;
import fr.inria.corese.core.next.api.Statement;
+import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.common.vocabulary.XSD;
import fr.inria.corese.core.next.impl.exception.SerializationException;
@@ -20,8 +21,7 @@
import java.io.StringWriter;
import java.util.stream.Stream;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
/**
@@ -29,8 +29,6 @@
*/
class RDFXMLSerializerTest {
- private static final Logger logger = LoggerFactory.getLogger(RDFXMLSerializerTest.class);
-
@Mock
private Model mockModel;
RDFXMLSerializerOptions mockConfig;
@@ -201,8 +199,6 @@ void shouldSerializeLiteralWithCustomDatatypeMinimalPolicy() throws Serializatio
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
- logger.info("AutoDeclarePrefix ? {}", testConfig.autoDeclarePrefixes());
-
RDFXMLSerializer serializer = new RDFXMLSerializer(mockModel, testConfig);
serializer.write(writer);
@@ -522,4 +518,15 @@ void shouldHandleEmptyModel() throws SerializationException {
assertEquals(expected, writer.toString());
}
+
+ @Test
+ @DisplayName("Should accept any IOOptions object")
+ void shouldAcceptAnyOptionFile() {
+ assertDoesNotThrow(() -> {
+ IOOptions option = new IOOptions() {
+ };
+ when(mockModel.stream()).thenReturn(Stream.empty());
+ RDFXMLSerializer serializer = new RDFXMLSerializer(mockModel, option);
+ });
+ }
}
From 29b637982d25117f626152c29b88feeb9eb83b90 Mon Sep 17 00:00:00 2001
From: Pierre Maillot
Date: Tue, 16 Dec 2025 14:49:47 +0100
Subject: [PATCH 10/12] Adding comments
---
.../api/io/serializer/BlankNodeIdGenerationOptions.java | 3 +++
.../core/next/api/io/serializer/DatatypePolicyOptions.java | 3 +++
.../core/next/api/io/serializer/LineEndingOptions.java | 7 +++++++
.../core/next/api/io/serializer/PrettyPrintOptions.java | 3 +++
.../core/next/api/io/serializer/UsesPrefixOptions.java | 3 +++
.../corese/core/next/impl/common/prefix/PrefixHandler.java | 3 +++
.../io/serialization/option/AbstractSerializerOptions.java | 1 +
.../io/serialization/option/AbstractTFamilyOptions.java | 4 +++-
.../io/serialization/rdfxml/RDFXMLSerializerOptions.java | 4 ++++
9 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
index 91842391b..5fe2d6379 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
@@ -1,5 +1,8 @@
package fr.inria.corese.core.next.api.io.serializer;
+/**
+ * Interface for options that determine the generation of blank node Ids for serializers.
+ */
public interface BlankNodeIdGenerationOptions {
/**
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
index 0f55c34a2..b21dcaa48 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
@@ -2,6 +2,9 @@
import fr.inria.corese.core.next.impl.io.serialization.option.LiteralDatatypePolicyEnum;
+/**
+ * Interface for serializer options to determine the policy for the literal datatypes
+ */
public interface DatatypePolicyOptions {
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
index 64b226796..2b0478b2a 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
@@ -1,6 +1,13 @@
package fr.inria.corese.core.next.api.io.serializer;
+/**
+ * Interface to specify which line ending a serializer must use.
+ */
public interface LineEndingOptions {
+ /**
+ *
+ * @return the end line characters
+ */
String getLineEnding();
}
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
index 6ad5685af..ad371aae0 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
@@ -2,6 +2,9 @@
import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
+/**
+ * Interface for the options of serializer allowing for pretty printing.
+ */
public interface PrettyPrintOptions {
/**
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
index fd0bb51f9..5059bb46f 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
@@ -3,6 +3,9 @@
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
+/**
+ * Interface for the options of serializer that can declare prefixes
+ */
public interface UsesPrefixOptions {
/**
diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java b/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
index 402457f60..9e2722fcd 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/common/prefix/PrefixHandler.java
@@ -45,6 +45,9 @@ public PrefixHandler(boolean includeStandardVocabularies) {
}
}
+ /**
+ * Copy constructor
+ */
public PrefixHandler(PrefixHandler oHandler) {
this.prefixToNamespace = new ConcurrentHashMap<>(oHandler.prefixToNamespace);
this.namespaceToPrefix = new ConcurrentHashMap<>(oHandler.namespaceToPrefix);
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
index 3e137c881..9a971efa1 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractSerializerOptions.java
@@ -132,6 +132,7 @@ public String getBaseIRI() {
*
* @return {@code true} if stable blank node IDs are enabled, {@code false} otherwise.
*/
+ @Override
public boolean stableBlankNodeIds() {
return stableBlankNodeIds;
}
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
index c1ed6d9b1..8bf85d17e 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/option/AbstractTFamilyOptions.java
@@ -307,7 +307,9 @@ public abstract static class AbstractTFamilyBuilder
Date: Wed, 17 Dec 2025 13:16:20 +0100
Subject: [PATCH 11/12] Removed unused
---
.../core/next/impl/common/util/IRIUtils.java | 3 ---
.../io/serialization/SerializerFactory.java | 6 ------
.../serialization/rdfxml/RDFXMLSerializer.java | 18 ------------------
3 files changed, 27 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java b/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
index 5afe6d323..edf0c3c6c 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/common/util/IRIUtils.java
@@ -1,8 +1,5 @@
package fr.inria.corese.core.next.impl.common.util;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
index 86cae25b1..8693e1d5e 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/SerializerFactory.java
@@ -6,21 +6,15 @@
import fr.inria.corese.core.next.api.io.IOOptions;
import fr.inria.corese.core.next.api.io.serializer.RDFSerializer;
import fr.inria.corese.core.next.impl.exception.SerializationException;
-import fr.inria.corese.core.next.impl.io.common.JSONLDOptions;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Canonicalizer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10Serializer;
import fr.inria.corese.core.next.impl.io.serialization.canonical.RDFC10SerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.jsonld.JSONLDSerializer;
import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.nquads.NQuadsSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.ntriples.NTriplesSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.trig.TriGSerializerOptions;
import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializer;
-import fr.inria.corese.core.next.impl.io.serialization.turtle.TurtleSerializerOptions;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
import java.util.Collections;
diff --git a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
index 5c037295d..d70917a06 100644
--- a/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializer.java
@@ -13,8 +13,6 @@
import fr.inria.corese.core.next.impl.common.prefix.PrefixHandler;
import fr.inria.corese.core.next.impl.common.util.IRIUtils;
import fr.inria.corese.core.next.impl.common.vocabulary.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import fr.inria.corese.core.next.api.IRI;
import fr.inria.corese.core.next.api.Literal;
@@ -272,22 +270,6 @@ private String getPrefixedNameInternal(String iriString) {
return null;
}
- /**
- * Generates a unique prefix based on a given base string, ensuring it's not already in use.
- * This method appends numbers to the base prefix until a unique one is found.
- *
- * @param basePrefix The desired base prefix (e.g., "foaf").
- * @return A unique prefix (e.g., "foaf", "foaf1", "foaf2").
- */
- private String generateUniquePrefix(String basePrefix) {
- String candidate = basePrefix;
- int i = 0;
- while (this.prefixHandler.hasPrefix(candidate)) {
- candidate = basePrefix + (++i);
- }
- return candidate;
- }
-
/**
* Writes an `` element for a given subject.
* This element contains all properties (predicates and objects) for that subject.
From 69855ea86d3b741b8c8b76edcb801d641a7e808e Mon Sep 17 00:00:00 2001
From: "AD\\aabdoun"
Date: Wed, 17 Dec 2025 13:51:03 +0100
Subject: [PATCH 12/12] Imports are never used
---
.../fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java | 1 -
.../inria/corese/core/next/api/io/serializer/RDFSerializer.java | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java
index add748be1..9205cfd14 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java
@@ -1,6 +1,5 @@
package fr.inria.corese.core.next.api.io.common;
-import fr.inria.corese.core.next.api.io.IOOptions;
/**
* Options for RDF parsers and serializers that support a base IRI.
diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java
index 5e4868522..5fd4a2da4 100644
--- a/src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/RDFSerializer.java
@@ -37,7 +37,7 @@ public interface RDFSerializer {
*/
default String getFormatName() {
return getRDFFormat().getName();
- };
+ }
/**
* Gets the RDF format that this serializer generates.