From 0fb33942403c8cdb0d0834d795dee7ab3bbe69a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Erik=20Pf=C3=B6rtner?= Null handling: The inner codec must never decode to {@code null}.
+ * If the inner codec successfully decodes but produces a null value, this codec
+ * returns a {@link DataResult} error. To handle absent values, the inner codec
+ * should fail (returning an error), which this codec maps to {@code Optional.empty()}. Cross-format edge cases: Converting between different format representations
+ * may lose information or fail for format-specific features: For maximum compatibility, use data shapes that are valid across all target formats:
+ * string/number/boolean primitives, homogeneous arrays, and non-null values. Implementations should be thread-safe for concurrent access. Implementations must be thread-safe for concurrent reads after
+ * {@code freeze()} has been called. Registration methods are not required to be
+ * thread-safe and should only be called during single-threaded initialization. Security note: Full stack traces may expose internal implementation
+ * details, file paths, and class names. Do not expose verbose output to untrusted
+ * users if the CLI is wrapped in a service or web interface. Default value: {@code false} CLI usage: {@code -v} or {@code --verbose}
+ *
+ * Thread Safety
- *
Important: The {@code DynamicOps
XML has no native array type. Arrays are typically represented as repeated elements * with the same name or wrapped in a container element. The {@link XmlMapper}'s diff --git a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/yaml/snakeyaml/SnakeYamlOps.java b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/yaml/snakeyaml/SnakeYamlOps.java index 422a511..72c97d4 100644 --- a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/yaml/snakeyaml/SnakeYamlOps.java +++ b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/yaml/snakeyaml/SnakeYamlOps.java @@ -1244,6 +1244,16 @@ public Object convertTo(@NotNull final DynamicOps sourceOps, * are immutable in Java) * * + *
Performance Note: Unlike Jackson-based implementations which delegate to + * the optimized {@code JsonNode.deepCopy()}, this method performs a manual recursive + * copy using Java reflection-free iteration. For very large data structures, this may + * be measurably slower. Consider using Jackson-based implementations + * ({@link de.splatgames.aether.datafixers.codec.yaml.jackson.JacksonYamlOps}) for + * performance-sensitive use cases.
+ * + *Performance Note
*Deep copying has O(n) time and space complexity where n is the total number of * elements in the structure. For large data structures, this can be significant. diff --git a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/schema/SimpleSchemaRegistry.java b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/schema/SimpleSchemaRegistry.java index b992d62..5d08e6a 100644 --- a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/schema/SimpleSchemaRegistry.java +++ b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/schema/SimpleSchemaRegistry.java @@ -61,8 +61,9 @@ * } * *
This implementation is not thread-safe. For concurrent access, external - * synchronization is required.
+ *Thread-safe for concurrent reads after {@link #freeze()} is called. + * Registration methods ({@link #register}) are not thread-safe and should + * only be called during single-threaded initialization.
* * @author Erik Pförtner * @see SchemaRegistry diff --git a/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/analysis/MigrationAnalyzer.java b/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/analysis/MigrationAnalyzer.java index 1b1ba0d..16601c8 100644 --- a/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/analysis/MigrationAnalyzer.java +++ b/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/analysis/MigrationAnalyzer.java @@ -451,9 +451,13 @@ private void analyzeStepCoverage( * but no DataFix is registered to handle the type at this version, * a coverage gap is recorded. * - *Note: This implementation checks for the presence of any fix - * for the type. A more sophisticated implementation could verify that - * the fix actually handles all specific field changes.
+ *Known Limitation: This implementation only checks whether any fix + * exists for the type at this version. It does not verify that the fix handles + * all specific field changes (e.g., a fix may handle field 'armor' but not 'health'). + * This can produce false negatives where a gap exists at the field level but is not + * reported because a type-level fix is present. Verifying field-level coverage would + * require metadata in {@link DataFix} about which fields it modifies, which is not + * currently part of the API.
* * @param type the type being analyzed, must not be {@code null} * @param sourceSchema the source schema, must not be {@code null} diff --git a/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/introspection/TypeIntrospector.java b/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/introspection/TypeIntrospector.java index 8a44481..e3cbed4 100644 --- a/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/introspection/TypeIntrospector.java +++ b/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/introspection/TypeIntrospector.java @@ -128,6 +128,12 @@ public static TypeStructure introspect(@NotNull final Type> type) { *Recursive behavior: Fields are extracted recursively from nested types. + * The result includes both parent fields and their nested children using dot-notation + * paths. For example, a type with field "player" containing nested field "position" + * with sub-field "x" produces entries: {@code ["player", "player.position", + * "player.position.x"]}.
+ * * @param type the type to extract fields from, must not be {@code null} * @return a list of fields found in the type, never {@code null} * @throws NullPointerException if {@code type} is {@code null} diff --git a/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/validation/ValidationResult.java b/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/validation/ValidationResult.java index f6609c5..1396726 100644 --- a/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/validation/ValidationResult.java +++ b/aether-datafixers-schema-tools/src/main/java/de/splatgames/aether/datafixers/schematools/validation/ValidationResult.java @@ -121,6 +121,18 @@ private ValidationResult(@NotNull final List