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..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
@@ -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
@@ -60,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/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/BlankNodeIdGenerationOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
new file mode 100644
index 000000000..5fe2d6379
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/BlankNodeIdGenerationOptions.java
@@ -0,0 +1,14 @@
+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 {
+
+ /**
+ * 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/serializer/DatatypePolicyOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
new file mode 100644
index 000000000..b21dcaa48
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/DatatypePolicyOptions.java
@@ -0,0 +1,17 @@
+package fr.inria.corese.core.next.api.io.serializer;
+
+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 {
+
+
+ /**
+ * 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/serializer/LineEndingOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
new file mode 100644
index 000000000..2b0478b2a
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/LineEndingOptions.java
@@ -0,0 +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
new file mode 100644
index 000000000..ad371aae0
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/PrettyPrintOptions.java
@@ -0,0 +1,51 @@
+package fr.inria.corese.core.next.api.io.serializer;
+
+import fr.inria.corese.core.next.impl.io.serialization.option.PrefixOrderingEnum;
+
+/**
+ * Interface for the options of serializer allowing for pretty printing.
+ */
+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();
+
+ /**
+ * 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/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..5fd4a2da4 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;
@@ -37,7 +37,7 @@ public interface RDFSerializer {
*/
default String getFormatName() {
return getRDFFormat().getName();
- };
+ }
/**
* Gets the RDF format that this serializer generates.
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/serializer/UsesPrefixOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
new file mode 100644
index 000000000..5059bb46f
--- /dev/null
+++ b/src/main/java/fr/inria/corese/core/next/api/io/serializer/UsesPrefixOptions.java
@@ -0,0 +1,35 @@
+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;
+
+/**
+ * Interface for the options of serializer that can declare prefixes
+ */
+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.
+ */
+ PrefixOrderingEnum getPrefixOrdering();
+ /**
+ * Returns an unmodifiable map of custom URI prefixes.
+ *
+ * @return The {@link PrefixHandler} managing all prefix mappings.
+ */
+ PrefixHandler getPrefixHandler();
+}
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..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,15 @@ public PrefixHandler(boolean includeStandardVocabularies) {
}
}
+ /**
+ * Copy constructor
+ */
+ 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 +66,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());
}
/**
@@ -87,8 +93,14 @@ 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);
@@ -142,6 +154,11 @@ public boolean hasPrefix(String prefix) {
return prefixToNamespace.containsKey(prefix);
}
+ @Override
+ public boolean hasNamespace(String namespace) {
+ return namespaceToPrefix.containsKey(namespace);
+ }
+
/**
* Gets the default namespace
*
@@ -218,6 +235,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..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
@@ -14,14 +14,19 @@
*/
public class IRIUtils {
- private static final Pattern IRI_PATTERN = Pattern.compile("^(?" +
- "(?[\\w\\-]+):(?\\/\\/)?" +
- "(?([\\w\\-_:@]+\\.)*[\\w\\-_:]*))" +
- "((?\\/([\\w\\-\\._\\:]+\\/)*)" +
- "(?[\\w\\-\\._\\:]+)?" +
- "(?\\?[\\w\\-_\\:\\?\\=]+)?" +
- "(?(\\#))?" +
- "(?([\\w\\-_]+))?)?$");
+ // 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;
@@ -54,20 +59,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 b06573298..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
@@ -4,23 +4,17 @@
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.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.RDFXMLSerializerOption;
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;
@@ -31,7 +25,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 +38,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;
@@ -65,76 +59,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 RDFXMLSerializerOption 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 83c88aa40..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
@@ -1,8 +1,11 @@
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.RDFSerializer;
+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.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 fr.inria.corese.core.next.impl.exception.SerializationException;
import fr.inria.corese.core.next.impl.io.serialization.option.*;
@@ -28,8 +31,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,9 +43,8 @@ public abstract class AbstractGraphSerializer implements RDFSerializer {
protected static final Logger logger = LoggerFactory.getLogger(AbstractGraphSerializer.class);
protected final Model model;
- protected final AbstractSerializerOption option;
- protected final Map iriToPrefixMapping;
- protected final Map prefixToIriMapping;
+ protected IOOptions option;
+ protected PrefixHandler prefixHandler;
protected final Set consumedBlankNodes;
protected final Set currentlyWritingBlankNodes;
@@ -50,49 +52,20 @@ 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 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, AbstractSerializerOption 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");
+ this.option = config;
+ if(config instanceof UsesPrefixOptions usesPrefixOptions) {
+ this.prefixHandler = usesPrefixOptions.getPrefixHandler();
+ } else {
+ this.prefixHandler = new PrefixHandler(false);
+ }
this.consumedBlankNodes = new HashSet<>();
this.currentlyWritingBlankNodes = new HashSet<>();
- 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();
-
- for (String prefix : prefixHandler.getPrefixes()) {
- String namespace = prefixHandler.getNamespace(prefix);
- if (namespace != null) {
- addPrefixMapping(namespace, prefix);
- }
- }
- }
}
/**
@@ -136,27 +109,29 @@ 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()));
}
- if (option instanceof AbstractSerializerOption
- && getTFamilyOption().usePrefixes()
- && getTFamilyOption().autoDeclarePrefixes()) {
- collectUsedNamespaces();
+ Set actuallyUsedNamespaces = Set.of();
+ if (option instanceof UsesPrefixOptions prefixOptions
+ && prefixOptions.usePrefixes()
+ && prefixOptions.autoDeclarePrefixes()) {
+ 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(
@@ -167,21 +142,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;
}
/**
@@ -190,25 +171,38 @@ 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 {
- AbstractTFamilyOption tFamilyConfig = getTFamilyOption();
+ protected void writePrefixDeclarations(Writer writer, Set actuallyUsedNamespaces) throws IOException {
+ if(this.option instanceof UsesPrefixOptions prefixOptions
+ && 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());
- List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
+ if (prefixOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
+ Collections.sort(prefixes);
+ }
- if (tFamilyConfig.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
- Collections.sort(prefixes);
- }
+ for (String prefix : prefixes) {
+ writer.write(String.format("@prefix %s: <%s> .%s",
+ prefix,
+ this.prefixHandler.getNamespace(prefix),
+ lineEndingOptions.getLineEnding()));
+ }
- for (String prefix : prefixes) {
- writer.write(String.format("@prefix %s: <%s> .%s",
- prefix,
- prefixToIriMapping.get(prefix),
- option.getLineEnding()));
+ if (!prefixes.isEmpty() || baseIRIOptions.getBaseIRI() != null) {
+ writer.write(lineEndingOptions.getLineEnding());
+ }
}
+ }
- if (!prefixes.isEmpty() || option.getBaseIRI() != null) {
- writer.write(option.getLineEnding());
- }
+ /**
+ * 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());
}
/**
@@ -222,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());
+ }
}
}
}
@@ -236,9 +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 {
- 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 +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 {
- 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 +301,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();
@@ -340,12 +338,12 @@ 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);
}
String prefixed = null;
- if (option instanceof AbstractSerializerOption && getTFamilyOption().usePrefixes()) {
+ if (option instanceof UsesPrefixOptions prefixOptions && prefixOptions.usePrefixes()) {
prefixed = getPrefixedName(iri.stringValue());
}
@@ -369,8 +367,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("\"\"\""));
}
@@ -422,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));
}
/**
@@ -436,10 +435,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,8 +452,10 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
}
firstProperty = false;
- if (tFamilyConfig.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);
}
@@ -466,8 +465,11 @@ protected void writeInlineBlankNode(Writer writer, List properties) t
writeValue(writer, stmt.getObject());
}
- if (tFamilyConfig.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);
@@ -482,9 +484,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 +493,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 +508,10 @@ 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
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyPrintOptions.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + indent + prettyPrintOptions.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -523,8 +525,10 @@ 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
+ && this.option instanceof LineEndingOptions lineEndingOptions
+ && prettyPrintOptions.prettyPrint()) {
+ writer.write(lineEndingOptions.getLineEnding() + indent + prettyPrintOptions.getIndent() + prettyPrintOptions.getIndent());
} else {
writer.write(SerializationConstants.SPACE);
}
@@ -536,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());
+ }
}
}
@@ -638,19 +644,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();
@@ -752,17 +756,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);
@@ -770,31 +774,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);
}
/**
@@ -804,11 +784,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()) {
@@ -831,12 +809,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);
@@ -861,13 +833,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;
}
@@ -908,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/base/AbstractLineBasedSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/base/AbstractLineBasedSerializer.java
index 48081413f..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
@@ -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;
@@ -18,10 +18,9 @@
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.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 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/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/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 5de866837..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
@@ -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.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;
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/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/NTriplesSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/ntriples/NTriplesSerializer.java
index d4b1370e7..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
@@ -5,6 +5,11 @@
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.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;
@@ -33,7 +38,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 +49,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.
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/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 86%
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..9a971efa1 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,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.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;
@@ -15,7 +18,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, BlankNodeIdGenerationOptions, DatatypePolicyOptions {
/**
* The policy for how literal datatypes are printed.
@@ -72,7 +75,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 +122,7 @@ public boolean trailingDot() {
*
* @return The base IRI string, or {@code null} if no base IRI is specified.
*/
+ @Override
public String getBaseIRI() {
return baseIRI;
}
@@ -128,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;
}
@@ -137,6 +142,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 +175,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.
@@ -188,6 +194,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.
*
@@ -290,12 +321,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 89%
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..8bf85d17e 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,8 @@
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.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;
@@ -8,14 +11,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 +108,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 +138,7 @@ protected AbstractTFamilyOption(AbstractTFamilyBuilder> builder) {
*
* @return {@code true} if prefixes are used, {@code false} otherwise.
*/
+ @Override
public boolean usePrefixes() {
return usePrefixes;
}
@@ -144,6 +148,7 @@ public boolean usePrefixes() {
*
* @return {@code true} if auto-declaration is enabled, {@code false} otherwise.
*/
+ @Override
public boolean autoDeclarePrefixes() {
return autoDeclarePrefixes;
}
@@ -153,6 +158,7 @@ public boolean autoDeclarePrefixes() {
*
* @return The {@link PrefixOrderingEnum} for prefix ordering.
*/
+ @Override
public PrefixOrderingEnum getPrefixOrdering() {
return prefixOrdering;
}
@@ -162,6 +168,7 @@ public PrefixOrderingEnum getPrefixOrdering() {
*
* @return The {@link PrefixHandler} managing all prefix mappings.
*/
+ @Override
public PrefixHandler getPrefixHandler() {
return prefixHandler;
}
@@ -216,6 +223,7 @@ public boolean useMultilineLiterals() {
*
* @return {@code true} if pretty-printing is enabled, {@code false} otherwise.
*/
+ @Override
public boolean prettyPrint() {
return prettyPrint;
}
@@ -225,6 +233,7 @@ public boolean prettyPrint() {
*
* @return The indentation string.
*/
+ @Override
public String getIndent() {
return indent;
}
@@ -234,6 +243,7 @@ public String getIndent() {
*
* @return The maximum line length.
*/
+ @Override
public int getMaxLineLength() {
return maxLineLength;
}
@@ -252,6 +262,7 @@ public boolean groupBySubject() {
*
* @return {@code true} if subject sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortSubjects() {
return sortSubjects;
}
@@ -261,12 +272,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.
@@ -295,6 +307,36 @@ public abstract static class AbstractTFamilyBuilder iriToPrefixMapping;
- private final Map prefixToIriMapping;
+ private final IOOptions config;
+ private final PrefixHandler prefixHandler;
private final Map blankNodeIds;
private int blankNodeCounter = 0;
private List cachedStatements;
/**
* 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<>();
- 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 (config.usePrefixes()) {
- for (Map.Entry entry : config.getCustomPrefixes().entrySet()) {
- addPrefixMapping(entry.getValue(), entry.getKey());
- }
+ if(config instanceof UsesPrefixOptions usesPrefixOptions
+ && usesPrefixOptions.usePrefixes()) {
+ 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<>();
}
/**
@@ -132,7 +117,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 +130,44 @@ 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()) {
- 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(">");
- 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());
+ }
}
/**
@@ -175,19 +176,33 @@ 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 {
+ ArrayList namespacelist = new ArrayList<>(actuallyUsedNamespaces);
+
+ if(this.config instanceof UsesPrefixOptions usesPrefixOptions
+ && usesPrefixOptions.autoDeclarePrefixes()) {
+
+ namespacelist.forEach(namespace -> {
+ if (! this.prefixHandler.hasNamespace(namespace)) {
+ String prefix = getSuggestedPrefix(namespace);
+ if (prefix != null) {
+ this.prefixHandler.setPrefix(prefix, namespace);
+ }
+ }
+ });
}
- List prefixes = new ArrayList<>(prefixToIriMapping.keySet());
- if (config.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
- Collections.sort(prefixes);
+ if (this.config instanceof PrettyPrintOptions prettyPrintOptions
+ && prettyPrintOptions.getPrefixOrdering() == PrefixOrderingEnum.ALPHABETICAL) {
+ namespacelist.sort(
+ (ns1, ns2) ->
+ prefixHandler.getPrefix(ns1).compareTo(prefixHandler.getPrefix(ns2))
+ );
}
- 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)));
}
}
@@ -195,26 +210,30 @@ 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)) {
- String prefix = getSuggestedPrefix(namespace);
- if (prefix != null) {
- addPrefixMapping(namespace, prefix);
- }
- }
- });
+ return potentialNamespaces;
}
@@ -230,11 +249,9 @@ private String getPrefixedNameInternal(String iriString) {
String correspondingPrefix = null;
int longestMatchLength = -1;
- 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);
if (namespace.length() > longestMatchLength) {
longestMatchLength = namespace.length();
longestMatchingNamespace = namespace;
@@ -245,7 +262,6 @@ private String getPrefixedNameInternal(String iriString) {
if (longestMatchingNamespace != null) {
String localName = iriString.substring(longestMatchingNamespace.length());
-
if (localName.isEmpty()) {
return correspondingPrefix + SerializationConstants.COLON;
}
@@ -254,60 +270,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 (iriToPrefixMapping.containsKey(namespaceURI)) {
- if (iriToPrefixMapping.get(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);
- }
- return;
- }
- }
-
- String effectivePrefix = prefix;
- if (prefixToIriMapping.containsKey(prefix)) {
- if (!prefixToIriMapping.get(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);
- }
- effectivePrefix = generateUniquePrefix(prefix);
- }
- }
-
- iriToPrefixMapping.put(namespaceURI, effectivePrefix);
- prefixToIriMapping.put(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.
- *
- * @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 (prefixToIriMapping.containsKey(candidate)) {
- candidate = basePrefix + (++i);
- }
- return candidate;
- }
-
/**
* Writes an `` element for a given subject.
* This element contains all properties (predicates and objects) for that subject.
@@ -319,7 +281,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 +292,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 +312,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 +369,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 +388,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,33 +412,10 @@ private boolean shouldWriteDatatype(Literal literal) {
return false;
}
- return config.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.ALWAYS_TYPED ||
- (!datatype.equals(XSD.xsdString.getIRI()) &&
- config.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;
+ return config instanceof DatatypePolicyOptions datatypePolicyOptions
+ && (datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.ALWAYS_TYPED
+ || (!datatype.equals(XSD.xsdString.getIRI())
+ && datatypePolicyOptions.getLiteralDatatypePolicy() == LiteralDatatypePolicyEnum.MINIMAL));
}
/**
@@ -480,14 +426,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);
@@ -509,7 +447,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";
}
}
@@ -519,7 +456,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/RDFXMLSerializerOption.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/rdfxml/RDFXMLSerializerOptions.java
similarity index 92%
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..7876e181f 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,9 @@
package fr.inria.corese.core.next.impl.io.serialization.rdfxml;
+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.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 +13,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, UsesPrefixOptions {
/**
* Whether prefix declarations (e.g., `xmlns:prefix="uri"`) should be used for compact IRIs.
@@ -76,7 +78,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;
@@ -97,6 +99,7 @@ protected RDFXMLSerializerOption(Builder builder) {
*
* @return {@code true} if prefixes are used, {@code false} otherwise.
*/
+ @Override
public boolean usePrefixes() {
return usePrefixes;
}
@@ -106,6 +109,7 @@ public boolean usePrefixes() {
*
* @return {@code true} if auto-declaration is enabled, {@code false} otherwise.
*/
+ @Override
public boolean autoDeclarePrefixes() {
return autoDeclarePrefixes;
}
@@ -115,6 +119,7 @@ public boolean autoDeclarePrefixes() {
*
* @return The {@link PrefixOrderingEnum} for prefix ordering.
*/
+ @Override
public PrefixOrderingEnum getPrefixOrdering() {
return prefixOrdering;
}
@@ -124,26 +129,17 @@ public PrefixOrderingEnum getPrefixOrdering() {
*
* @return The {@link PrefixHandler} instance.
*/
+ @Override
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.
*
* @return {@code true} if pretty-printing is enabled, {@code false} otherwise.
*/
+ @Override
public boolean prettyPrint() {
return prettyPrint;
}
@@ -153,6 +149,7 @@ public boolean prettyPrint() {
*
* @return The indentation string.
*/
+ @Override
public String getIndent() {
return indent;
}
@@ -162,6 +159,7 @@ public String getIndent() {
*
* @return The maximum line length.
*/
+ @Override
public int getMaxLineLength() {
return maxLineLength;
}
@@ -171,6 +169,7 @@ public int getMaxLineLength() {
*
* @return {@code true} if subject sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortSubjects() {
return sortSubjects;
}
@@ -180,6 +179,7 @@ public boolean sortSubjects() {
*
* @return {@code true} if predicate sorting is enabled, {@code false} otherwise.
*/
+ @Override
public boolean sortPredicates() {
return sortPredicates;
}
@@ -194,11 +194,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 +364,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 +379,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/TriGSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializer.java
index 7177757b6..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
@@ -15,7 +15,12 @@
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.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;
/**
@@ -61,24 +66,9 @@ 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) {
+ public TriGSerializer(Model model, IOOptions config) {
super(model, config);
- 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.");
- }
- return (TriGSerializerOptions) option;
+ Objects.requireNonNull(config, "config cannot be null");
}
/**
@@ -90,11 +80,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 +98,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 +119,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 +136,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 +146,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 +161,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 +174,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());
}
}
@@ -251,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/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/TurtleSerializer.java b/src/main/java/fr/inria/corese/core/next/impl/io/serialization/turtle/TurtleSerializer.java
index 917c4f664..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
@@ -5,13 +5,15 @@
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.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;
/**
@@ -57,10 +59,11 @@ 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) {
+ public TurtleSerializer(Model model, IOOptions config) {
super(model, config);
- Objects.requireNonNull(config, "TurtleConfig cannot be null");
+ Objects.requireNonNull(config, "config cannot be null");
}
+
/**
* Retrieves the RDF format supported by this serializer, which is Turtle
*
@@ -81,7 +84,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);
@@ -150,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/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..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,17 +1,19 @@
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.api.io.IOOptions;
+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;
/**
* 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,16 +29,31 @@ 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.
*/
public Builder() {
+ super();
lineEnding(System.lineSeparator());
validateURIs(false);
useCollections(true);
blankNodeStyle(BlankNodeStyleEnum.ANONYMOUS);
+ }
+ /**
+ * Copy constructor for easy creation of option inheriting setting from others
+ */
+ public Builder(IOOptions otherOption) {
+ super(otherOption);
+ if(otherOption instanceof LineEndingOptions lineEndingOptions) {
+ lineEnding(lineEndingOptions.getLineEnding());
+ }
+ if(otherOption instanceof AbstractTFamilyOptions abstractTFamilyOptions) {
+ validateURIs(abstractTFamilyOptions.validateURIs());
+ useCollections(abstractTFamilyOptions.useCollections());
+ blankNodeStyle(abstractTFamilyOptions.getBlankNodeStyle());
+ }
}
/**
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 f196531b5..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
@@ -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.common.JSONLDOptions;
import fr.inria.corese.core.next.impl.io.parser.ParserFactory;
import fr.inria.corese.core.next.impl.io.serialization.SerializerFactory;
@@ -33,7 +33,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 997cc0a64..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,10 +3,10 @@
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.RDFXMLSerializerOption;
+import fr.inria.corese.core.next.impl.io.serialization.rdfxml.RDFXMLSerializerOptions;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
import fr.inria.corese.core.next.impl.temp.CoreseModel;
import org.junit.jupiter.api.BeforeEach;
@@ -36,9 +36,9 @@
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 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/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/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..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
@@ -3,7 +3,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.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;
@@ -14,7 +14,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;
@@ -104,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);
@@ -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/canonical/RDFC10SerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/canonical/RDFC10SerializerTest.java
index 7233acf46..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
@@ -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;
@@ -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");
}
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 777d0bf5a..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,8 @@
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;
import fr.inria.corese.core.next.impl.io.serialization.TestStatementFactory;
@@ -13,12 +15,13 @@
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;
-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;
/**
@@ -28,7 +31,7 @@ class RDFXMLSerializerTest {
@Mock
private Model mockModel;
- RDFXMLSerializerOption mockConfig;
+ RDFXMLSerializerOptions mockConfig;
private TestStatementFactory factory;
private StringWriter writer;
private AutoCloseable closeable;
@@ -38,7 +41,7 @@ void setUp() {
closeable = MockitoAnnotations.openMocks(this);
writer = new StringWriter();
factory = new TestStatementFactory();
- mockConfig = RDFXMLSerializerOption.defaultConfig();
+ mockConfig = RDFXMLSerializerOptions.defaultConfig();
}
@AfterEach
@@ -58,21 +61,20 @@ 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/")
.prefixOrdering(PrefixOrderingEnum.ALPHABETICAL)
.build();
-
RDFXMLSerializer serializer = new RDFXMLSerializer(mockModel, testConfig);
serializer.write(writer);
String expected = """
-
+
@@ -93,7 +95,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)
@@ -104,7 +106,7 @@ void shouldHandleBlankNodeSubject() throws SerializationException {
String expected = """
-
+
@@ -126,7 +128,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)
@@ -138,7 +140,7 @@ void shouldHandleBlankNodeObject() throws SerializationException {
String expected = """
-
+
@@ -159,7 +161,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)
@@ -170,7 +172,7 @@ void shouldSerializeLiteralWithStringDatatypeMinimalPolicy() throws Serializatio
String expected = """
-
+
John Doe
@@ -190,7 +192,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#")
@@ -202,7 +204,7 @@ void shouldSerializeLiteralWithCustomDatatypeMinimalPolicy() throws Serializatio
String expected = """
-
+
123
@@ -222,7 +224,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();
@@ -232,7 +234,7 @@ void shouldSerializeLiteralWithLanguage() throws SerializationException {
String expected = """
-
+
The Book
@@ -259,7 +261,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)
@@ -276,7 +278,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 ";
@@ -301,7 +302,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)
@@ -312,7 +313,7 @@ void shouldSortSubjectsAlphabetically() throws SerializationException {
String expected = """
-
+
@@ -337,7 +338,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();
@@ -346,7 +347,7 @@ void shouldEscapeXmlAttributeValues() throws SerializationException {
String expected = """
-
+
@@ -367,7 +368,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)
@@ -379,7 +380,7 @@ void shouldEscapeXmlContentValues() throws SerializationException {
String expected = """
-
+
Value with <tags> & entities
@@ -401,7 +402,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)
@@ -412,9 +413,9 @@ void shouldNotAutoDeclarePrefixesIfDisabled() throws SerializationException {
String expected = """
-
+
-
+
""";
@@ -433,7 +434,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 +472,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/")
@@ -484,7 +485,7 @@ void shouldNotGenerateStableBlankNodeIds() throws SerializationException {
String expected = """
-
+
@@ -502,7 +503,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();
@@ -511,10 +512,21 @@ void shouldHandleEmptyModel() throws SerializationException {
String expected = """
-
+
""";
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);
+ });
+ }
}
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();
diff --git a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerTest.java b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerTest.java
index 02e375c32..fa5f04a65 100644
--- a/src/test/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/impl/io/serialization/trig/TriGSerializerTest.java
@@ -68,10 +68,6 @@ void testBasicTriGSerialization() throws SerializationException {
String expected = """
@prefix ns: .
- @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..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,8 +5,10 @@
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;
import fr.inria.corese.core.next.impl.temp.CoreseAdaptedValueFactory;
import fr.inria.corese.core.next.impl.temp.CoreseModel;
import org.junit.jupiter.api.BeforeEach;
@@ -70,10 +72,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 +102,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 +115,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 +170,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 +204,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 +221,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 +385,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 +417,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 +525,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";