diff --git a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/gson/GsonOps.java b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/gson/GsonOps.java deleted file mode 100644 index 55df6ee..0000000 --- a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/gson/GsonOps.java +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Copyright (c) 2025 Splatgames.de Software and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package de.splatgames.aether.datafixers.codec.gson; - -import com.google.common.base.Preconditions; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import de.splatgames.aether.datafixers.api.dynamic.DynamicOps; -import de.splatgames.aether.datafixers.api.result.DataResult; -import de.splatgames.aether.datafixers.api.util.Pair; -import org.jetbrains.annotations.NotNull; -import org.jspecify.annotations.Nullable; - -import java.util.stream.Stream; - -/** - * Backwards-compatibility wrapper for {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps}. - * - *

This class provides API compatibility for code written against the pre-0.4.0 package structure. - * It delegates all operations to the new {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} - * implementation in the reorganized package hierarchy.

- * - *

Migration Guide

- *

To migrate to the new API, update your imports:

- *
{@code
- * // Old import (deprecated)
- * import de.splatgames.aether.datafixers.codec.gson.GsonOps;
- *
- * // New import (recommended)
- * import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;
- * }
- * - *

Removal Timeline

- *

This class is scheduled for removal in version 1.0.0. All functionality remains - * fully operational until removal, but users should migrate to the new package structure - * at their earliest convenience.

- * - *

Delegation Pattern

- *

This wrapper implements the delegation pattern, forwarding all method calls to the - * underlying {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} instance. - * This ensures identical behavior between the deprecated and new implementations.

- * - *

Thread Safety

- *

This class is thread-safe. The singleton {@link #INSTANCE} can be safely shared - * across multiple threads, as the underlying implementation is also thread-safe.

- * - * @author Erik Pförtner - * @see de.splatgames.aether.datafixers.codec.json.gson.GsonOps - * @see DynamicOps - * @since 0.1.0 - * @deprecated Since 0.4.0. Use {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} - * from the {@code codec.json.gson} package instead. This class will be removed - * in version 1.0.0 as part of the package reorganization. - */ -@Deprecated(forRemoval = true, since = "0.4.0") -public class GsonOps implements DynamicOps { - - /** - * The singleton instance of the deprecated {@code GsonOps} wrapper. - * - *

This instance wraps {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#INSTANCE} - * and provides full backwards compatibility. It is thread-safe and can be shared across - * the entire application.

- * - *

Migration

- *

Replace usages with:

- *
{@code
-     * // Old usage (deprecated)
-     * GsonOps.INSTANCE
-     *
-     * // New usage (recommended)
-     * de.splatgames.aether.datafixers.codec.json.gson.GsonOps.INSTANCE
-     * }
- * - * @deprecated Use {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#INSTANCE} instead. - */ - @Deprecated(forRemoval = true, since = "0.4.0") - public static final GsonOps INSTANCE = new GsonOps(de.splatgames.aether.datafixers.codec.json.gson.GsonOps.INSTANCE); - - /** - * The underlying {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} instance - * to which all operations are delegated. - * - *

This field holds the actual implementation that performs all DynamicOps operations. - * The wrapper simply forwards all method calls to this instance, ensuring behavioral - * equivalence between the deprecated and new implementations.

- */ - private final de.splatgames.aether.datafixers.codec.json.gson.GsonOps baseOps; - - /** - * Creates a new deprecated {@code GsonOps} wrapper delegating to the specified base implementation. - * - *

This constructor allows wrapping any {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} - * instance, though typically the singleton {@link #INSTANCE} should be used instead.

- * - *

Usage

- *
{@code
-     * // Typically use the singleton instead
-     * GsonOps ops = GsonOps.INSTANCE;
-     *
-     * // Or wrap a custom instance if needed
-     * GsonOps customOps = new GsonOps(
-     *     de.splatgames.aether.datafixers.codec.json.gson.GsonOps.INSTANCE
-     * );
-     * }
- * - * @param baseOps the base {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} - * instance to delegate all operations to; must not be {@code null} - * @deprecated Use {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} directly instead. - */ - @Deprecated(forRemoval = true, since = "0.4.0") - private GsonOps(@NotNull final de.splatgames.aether.datafixers.codec.json.gson.GsonOps baseOps) { - Preconditions.checkNotNull(baseOps, "baseOps must not be null"); - this.baseOps = baseOps; - } - - // ==================== Empty/Null Values ==================== - - /** - * {@inheritDoc} - * - *

Returns the canonical empty/null representation for Gson JSON data, - * which is {@link JsonNull#INSTANCE}. This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#empty()} method.

- * - * @return {@link JsonNull#INSTANCE} representing the absence of a value - */ - @NotNull - @Override - public JsonElement empty() { - return this.baseOps.empty(); - } - - /** - * {@inheritDoc} - * - *

Returns an empty JSON object ({@code {}}). This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#emptyMap()} method.

- * - * @return a new empty {@link JsonObject} instance - */ - @NotNull - @Override - public JsonElement emptyMap() { - return this.baseOps.emptyMap(); - } - - /** - * {@inheritDoc} - * - *

Returns an empty JSON array ({@code []}). This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#emptyList()} method.

- * - * @return a new empty {@link JsonArray} instance - */ - @NotNull - @Override - public JsonElement emptyList() { - return this.baseOps.emptyList(); - } - - // ==================== Type Checking ==================== - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON element is a map/object structure. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#isMap(JsonElement)} method.

- * - * @param value the JSON element to check; must not be {@code null} - * @return {@code true} if the value is a {@link JsonObject}, {@code false} otherwise - */ - @Override - public boolean isMap(@NotNull final JsonElement value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isMap(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON element is a list/array structure. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#isList(JsonElement)} method.

- * - * @param value the JSON element to check; must not be {@code null} - * @return {@code true} if the value is a {@link JsonArray}, {@code false} otherwise - */ - @Override - public boolean isList(@NotNull final JsonElement value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isList(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON element is a string primitive. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#isString(JsonElement)} method.

- * - * @param value the JSON element to check; must not be {@code null} - * @return {@code true} if the value is a {@link JsonPrimitive} containing a string, - * {@code false} otherwise - */ - @Override - public boolean isString(@NotNull final JsonElement value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isString(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON element is a numeric primitive. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#isNumber(JsonElement)} method.

- * - * @param value the JSON element to check; must not be {@code null} - * @return {@code true} if the value is a {@link JsonPrimitive} containing a number, - * {@code false} otherwise - */ - @Override - public boolean isNumber(@NotNull final JsonElement value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isNumber(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON element is a boolean primitive. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#isBoolean(JsonElement)} method.

- * - * @param value the JSON element to check; must not be {@code null} - * @return {@code true} if the value is a {@link JsonPrimitive} containing a boolean, - * {@code false} otherwise - */ - @Override - public boolean isBoolean(@NotNull final JsonElement value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isBoolean(value); - } - - // ==================== Primitive Creation ==================== - - /** - * {@inheritDoc} - * - *

Creates a JSON string primitive from the given string value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createString(String)} method.

- * - * @param value the string value to wrap; must not be {@code null} - * @return a new {@link JsonPrimitive} containing the string - */ - @NotNull - @Override - public JsonElement createString(@NotNull final String value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.createString(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given integer value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createInt(int)} method.

- * - * @param value the integer value to wrap - * @return a new {@link JsonPrimitive} containing the integer - */ - @NotNull - @Override - public JsonElement createInt(final int value) { - return this.baseOps.createInt(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given long value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createLong(long)} method.

- * - * @param value the long value to wrap - * @return a new {@link JsonPrimitive} containing the long - */ - @NotNull - @Override - public JsonElement createLong(final long value) { - return this.baseOps.createLong(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given float value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createFloat(float)} method.

- * - * @param value the float value to wrap - * @return a new {@link JsonPrimitive} containing the float - */ - @NotNull - @Override - public JsonElement createFloat(final float value) { - return this.baseOps.createFloat(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given double value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createDouble(double)} method.

- * - * @param value the double value to wrap - * @return a new {@link JsonPrimitive} containing the double - */ - @NotNull - @Override - public JsonElement createDouble(final double value) { - return this.baseOps.createDouble(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given byte value. - * Since JSON has no distinct byte type, the value is stored as a number. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createByte(byte)} method.

- * - * @param value the byte value to wrap - * @return a new {@link JsonPrimitive} containing the byte as a number - */ - @NotNull - @Override - public JsonElement createByte(final byte value) { - return this.baseOps.createByte(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given short value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createShort(short)} method.

- * - * @param value the short value to wrap - * @return a new {@link JsonPrimitive} containing the short - */ - @NotNull - @Override - public JsonElement createShort(final short value) { - return this.baseOps.createShort(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON boolean primitive from the given boolean value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createBoolean(boolean)} method.

- * - * @param value the boolean value to wrap - * @return a new {@link JsonPrimitive} containing the boolean - */ - @NotNull - @Override - public JsonElement createBoolean(final boolean value) { - return this.baseOps.createBoolean(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric primitive from the given {@link Number} value. - * The specific numeric type is preserved in the underlying JSON representation. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createNumeric(Number)} method.

- * - * @param value the number value to wrap; must not be {@code null} - * @return a new {@link JsonPrimitive} containing the number - */ - @NotNull - @Override - public JsonElement createNumeric(@NotNull final Number value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.createNumeric(value); - } - - // ==================== Primitive Reading ==================== - - /** - * {@inheritDoc} - * - *

Extracts the string value from a JSON element. The element must be a - * {@link JsonPrimitive} containing a string value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#getStringValue(JsonElement)} method.

- * - * @param input the JSON element to extract the string from; must not be {@code null} - * @return a {@link DataResult} containing the string value on success, - * or an error if the element is not a string primitive - */ - @NotNull - @Override - public DataResult getStringValue(@NotNull final JsonElement input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getStringValue(input); - } - - /** - * {@inheritDoc} - * - *

Extracts the numeric value from a JSON element. The element must be a - * {@link JsonPrimitive} containing a numeric value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#getNumberValue(JsonElement)} method.

- * - * @param input the JSON element to extract the number from; must not be {@code null} - * @return a {@link DataResult} containing the {@link Number} value on success, - * or an error if the element is not a numeric primitive - */ - @NotNull - @Override - public DataResult getNumberValue(@NotNull final JsonElement input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getNumberValue(input); - } - - /** - * {@inheritDoc} - * - *

Extracts the boolean value from a JSON element. The element must be a - * {@link JsonPrimitive} containing a boolean value. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#getBooleanValue(JsonElement)} method.

- * - * @param input the JSON element to extract the boolean from; must not be {@code null} - * @return a {@link DataResult} containing the boolean value on success, - * or an error if the element is not a boolean primitive - */ - @NotNull - @Override - public DataResult getBooleanValue(@NotNull final JsonElement input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getBooleanValue(input); - } - - // ==================== List Operations ==================== - - /** - * {@inheritDoc} - * - *

Creates a JSON array from a stream of JSON elements. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createList(Stream)} method.

- * - * @param values the stream of JSON elements to include in the array; must not be {@code null} - * @return a new {@link JsonArray} containing all elements from the stream - */ - @NotNull - @Override - public JsonElement createList(@NotNull final Stream values) { - Preconditions.checkNotNull(values, "values must not be null"); - return this.baseOps.createList(values); - } - - /** - * {@inheritDoc} - * - *

Extracts the elements of a JSON array as a stream. The input must be a - * {@link JsonArray}. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#getList(JsonElement)} method.

- * - * @param input the JSON element to extract list elements from; must not be {@code null} - * @return a {@link DataResult} containing a stream of the array elements on success, - * or an error if the input is not a JSON array - */ - @NotNull - @Override - public DataResult> getList(@NotNull final JsonElement input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getList(input); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON array by appending a value to an existing array. - * The original array is not modified; a deep copy is created. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#mergeToList(JsonElement, JsonElement)} method.

- * - * @param list the existing JSON array to append to; must not be {@code null} - * @param value the JSON element to append; must not be {@code null} - * @return a {@link DataResult} containing the new array with the appended value on success, - * or an error if the list is not a JSON array - */ - @NotNull - @Override - public DataResult mergeToList(@NotNull final JsonElement list, @NotNull final JsonElement value) { - Preconditions.checkNotNull(list, "list must not be null"); - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.mergeToList(list, value); - } - - // ==================== Map Operations ==================== - - /** - * {@inheritDoc} - * - *

Retrieves the value associated with a key from a JSON object. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#get(JsonElement, String)} method.

- * - * @param value the JSON object to retrieve from; must not be {@code null} - * @param key the key to look up; must not be {@code null} - * @return the JSON element associated with the key, or {@code null} if not present - * or if the input is not a JSON object - */ - @Override - public @Nullable JsonElement get(@NotNull final JsonElement value, @NotNull final String key) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.get(value, key); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object with a field set to the specified value. - * If the input is a JSON object, a deep copy is created with the field updated. - * If the input is not a JSON object, a new object is created containing only the specified field. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#set(JsonElement, String, JsonElement)} method.

- * - * @param value the JSON element to modify; must not be {@code null} - * @param key the key for the field to set; must not be {@code null} - * @param newValue the value to associate with the key; must not be {@code null} - * @return a new {@link JsonObject} with the field set to the specified value - */ - @NotNull - @Override - public JsonElement set(@NotNull final JsonElement value, @NotNull final String key, @NotNull final JsonElement newValue) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - Preconditions.checkNotNull(newValue, "newValue must not be null"); - return this.baseOps.set(value, key, newValue); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object with a field removed. - * A deep copy of the input object is created without the specified field. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#remove(JsonElement, String)} method.

- * - * @param value the JSON object to modify; must not be {@code null} - * @param key the key of the field to remove; must not be {@code null} - * @return a new {@link JsonObject} without the specified field - */ - @NotNull - @Override - public JsonElement remove(@NotNull final JsonElement value, @NotNull final String key) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.remove(value, key); - } - - /** - * {@inheritDoc} - * - *

Checks whether a JSON object contains a field with the specified key. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#has(JsonElement, String)} method.

- * - * @param value the JSON element to check; must not be {@code null} - * @param key the key to look for; must not be {@code null} - * @return {@code true} if the value is a {@link JsonObject} and contains the specified key, - * {@code false} otherwise - */ - @Override - public boolean has(@NotNull final JsonElement value, @NotNull final String key) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.has(value, key); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON object from a stream of key-value pairs. - * Keys must be JSON string primitives; non-string keys are skipped. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#createMap(Stream)} method.

- * - * @param entries the stream of key-value pairs; must not be {@code null} - * @return a new {@link JsonObject} containing all valid entries from the stream - */ - @NotNull - @Override - public JsonElement createMap(@NotNull final Stream> entries) { - Preconditions.checkNotNull(entries, "entries must not be null"); - return this.baseOps.createMap(entries); - } - - /** - * {@inheritDoc} - * - *

Extracts the entries of a JSON object as a stream of key-value pairs. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#getMapEntries(JsonElement)} method.

- * - * @param input the JSON element to extract entries from; must not be {@code null} - * @return a {@link DataResult} containing a stream of key-value pairs on success, - * or an error if the input is not a JSON object - */ - @NotNull - @Override - public DataResult>> getMapEntries(@NotNull final JsonElement input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getMapEntries(input); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object by adding a key-value pair to an existing map. - * A deep copy of the input map is created with the new entry added. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#mergeToMap(JsonElement, JsonElement, JsonElement)} method.

- * - * @param map the existing JSON object; must not be {@code null} - * @param key the key for the new entry (must be a JSON string); must not be {@code null} - * @param value the value for the new entry; must not be {@code null} - * @return a {@link DataResult} containing the new object with the added entry on success, - * or an error if the map is not a JSON object or the key is not a string - */ - @NotNull - @Override - public DataResult mergeToMap(@NotNull final JsonElement map, @NotNull final JsonElement key, @NotNull final JsonElement value) { - Preconditions.checkNotNull(map, "map must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.mergeToMap(map, key, value); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object by merging two maps together. - * A deep copy of the first map is created, and all entries from the second map are added. - * Entries in the second map override entries with the same key in the first map. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#mergeToMap(JsonElement, JsonElement)} method.

- * - * @param map the base JSON object; must not be {@code null} - * @param other the JSON object to merge from; must not be {@code null} - * @return a {@link DataResult} containing the merged object on success, - * or an error if either argument is not a JSON object - */ - @NotNull - @Override - public DataResult mergeToMap(@NotNull final JsonElement map, @NotNull final JsonElement other) { - Preconditions.checkNotNull(map, "map must not be null"); - Preconditions.checkNotNull(other, "other must not be null"); - return this.baseOps.mergeToMap(map, other); - } - - // ==================== Conversion ==================== - - /** - * {@inheritDoc} - * - *

Converts data from another {@link DynamicOps} format to Gson's {@link JsonElement}. - * Recursively converts primitives, lists, and maps to their Gson equivalents. - * This delegates to the underlying - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps#convertTo(DynamicOps, Object)} method.

- * - * @param the type parameter of the target format - * @param ops the target {@link DynamicOps} implementation; must not be {@code null} - * @param input the data to convert in the source format; must not be {@code null} - * @return the converted data as a Gson {@link JsonElement} - */ - @NotNull - @Override - public JsonElement convertTo(@NotNull final DynamicOps ops, @NotNull final U input) { - Preconditions.checkNotNull(ops, "ops must not be null"); - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.convertTo(ops, input); - } - - /** - * Returns a string representation of this deprecated wrapper. - * - *

The returned string clearly indicates that this is a deprecated wrapper - * class and suggests using the new implementation instead.

- * - * @return a descriptive string indicating deprecated status and the recommended alternative - */ - @Override - public String toString() { - return "GsonOps (deprecated, use de.splatgames.aether.datafixers.codec.json.gson.GsonOps)"; - } -} diff --git a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/gson/package-info.java b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/gson/package-info.java deleted file mode 100644 index c937d27..0000000 --- a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/gson/package-info.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2025 Splatgames.de Software and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * DEPRECATED: Legacy package for Gson-based {@link de.splatgames.aether.datafixers.api.dynamic.DynamicOps} - * implementation. This package is retained only for backwards compatibility and will be removed in version 1.0.0. - * - *

This package contains the original {@link de.splatgames.aether.datafixers.codec.gson.GsonOps} class - * from the pre-0.4.0 package structure. All classes in this package are deprecated and delegate to their - * replacements in the reorganized {@link de.splatgames.aether.datafixers.codec.json.gson} package.

- * - *

Migration Guide

- *

To migrate from this deprecated package to the new package structure:

- * - *

Import Changes

- *
{@code
- * // Old import (deprecated, will be removed in 1.0.0)
- * import de.splatgames.aether.datafixers.codec.gson.GsonOps;
- *
- * // New import (recommended)
- * import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;
- * }
- * - *

Code Changes

- *

No code changes are required beyond updating imports. The API is identical:

- *
{@code
- * // This code works with both old and new imports
- * GsonOps ops = GsonOps.INSTANCE;
- * Dynamic dynamic = new Dynamic<>(ops, jsonElement);
- * }
- * - *

Deprecation Timeline

- * - * - * - * - * - * - *
Deprecation and Removal Schedule
VersionStatusAction Required
0.4.0DeprecatedUpdate imports to new package; old code continues to work
0.5.0DeprecatedWarnings during compilation; functionality unchanged
1.0.0RemovedPackage deleted; migration required before upgrade
- * - *

Why This Change?

- *

The package reorganization in version 0.4.0 introduced a cleaner, more scalable structure:

- *
    - *
  • Format-Based Organization: All JSON implementations are now grouped under - * {@code codec.json.*}, YAML under {@code codec.yaml.*}, etc.
  • - *
  • Library-Based Subpackages: Each format has subpackages for different - * libraries (e.g., {@code json.gson}, {@code json.jackson})
  • - *
  • Consistent Naming: The new structure makes it easier to find and choose - * the right implementation for your needs
  • - *
- * - *

New Package Structure

- *
- * de.splatgames.aether.datafixers.codec
- * ├── json
- * │   ├── gson/GsonOps.java         (new location)
- * │   └── jackson/JacksonJsonOps.java
- * ├── yaml
- * │   ├── jackson/JacksonYamlOps.java
- * │   └── snakeyaml/SnakeYamlOps.java
- * ├── toml
- * │   └── jackson/JacksonTomlOps.java
- * └── xml
- *     └── jackson/JacksonXmlOps.java
- * 
- * - *

Delegation Pattern

- *

The deprecated {@link de.splatgames.aether.datafixers.codec.gson.GsonOps} class uses the - * delegation pattern to forward all method calls to the new - * {@link de.splatgames.aether.datafixers.codec.json.gson.GsonOps} implementation. This ensures:

- *
    - *
  • Identical behavior between deprecated and new implementations
  • - *
  • Bug fixes applied to the new implementation automatically benefit deprecated users
  • - *
  • No performance overhead beyond a single method delegation
  • - *
- * - *

Thread Safety

- *

All classes in this deprecated package maintain the same thread-safety guarantees as their - * replacements. The singleton {@link de.splatgames.aether.datafixers.codec.gson.GsonOps#INSTANCE} - * can be safely shared across multiple threads.

- * - * @author Erik Pförtner - * @see de.splatgames.aether.datafixers.codec.json.gson.GsonOps - * @see de.splatgames.aether.datafixers.codec.json - * @see de.splatgames.aether.datafixers.api.dynamic.DynamicOps - * @since 0.1.0 - * @deprecated Since 0.4.0. Use classes from {@link de.splatgames.aether.datafixers.codec.json.gson} - * instead. This package will be removed in version 1.0.0. - */ -@Deprecated(since = "0.4.0", forRemoval = true) -package de.splatgames.aether.datafixers.codec.gson; diff --git a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/jackson/JacksonOps.java b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/jackson/JacksonOps.java deleted file mode 100644 index 886fdaf..0000000 --- a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/jackson/JacksonOps.java +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (c) 2025 Splatgames.de Software and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package de.splatgames.aether.datafixers.codec.jackson; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.base.Preconditions; -import de.splatgames.aether.datafixers.api.dynamic.DynamicOps; -import de.splatgames.aether.datafixers.api.result.DataResult; -import de.splatgames.aether.datafixers.api.util.Pair; -import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.stream.Stream; - -/** - * Backwards-compatibility wrapper for {@link JacksonJsonOps}. - * - *

This class provides API compatibility for code written against the pre-0.4.0 package structure. - * It delegates all operations to the new {@link JacksonJsonOps} implementation in the reorganized - * package hierarchy.

- * - *

Migration Guide

- *

To migrate to the new API, update your imports and class references:

- *
{@code
- * // Old import (deprecated)
- * import de.splatgames.aether.datafixers.codec.jackson.JacksonOps;
- *
- * // New import (recommended)
- * import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;
- *
- * // Old usage (deprecated)
- * JacksonOps ops = JacksonOps.INSTANCE;
- * JacksonOps customOps = new JacksonOps(customMapper);
- *
- * // New usage (recommended)
- * JacksonJsonOps ops = JacksonJsonOps.INSTANCE;
- * JacksonJsonOps customOps = new JacksonJsonOps(customMapper);
- * }
- * - *

Removal Timeline

- *

This class is scheduled for removal in version 1.0.0. All functionality remains - * fully operational until removal, but users should migrate to the new package structure - * and class name at their earliest convenience.

- * - *

Delegation Pattern

- *

This wrapper implements the delegation pattern, forwarding all method calls to the - * underlying {@link JacksonJsonOps} instance. This ensures identical behavior between - * the deprecated and new implementations.

- * - *

Thread Safety

- *

This class is thread-safe. The singleton {@link #INSTANCE} can be safely shared - * across multiple threads, as the underlying implementation is also thread-safe. - * Custom instances created with a custom {@link ObjectMapper} are thread-safe if - * the provided mapper is thread-safe.

- * - * @author Erik Pförtner - * @see JacksonJsonOps - * @see DynamicOps - * @since 0.1.0 - * @deprecated Since 0.4.0. Use {@link JacksonJsonOps} from the {@code codec.json.jackson} - * package instead. This class will be removed in version 1.0.0 as part of - * the package reorganization. - */ -@Deprecated(forRemoval = true, since = "0.4.0") -public class JacksonOps implements DynamicOps { - - /** - * The singleton instance of the deprecated {@code JacksonOps} wrapper. - * - *

This instance wraps {@link JacksonJsonOps#INSTANCE} and provides full backwards - * compatibility. It uses a default {@link ObjectMapper} with standard configuration. - * The instance is thread-safe and can be shared across the entire application.

- * - *

Migration

- *

Replace usages with:

- *
{@code
-     * // Old usage (deprecated)
-     * JacksonOps.INSTANCE
-     *
-     * // New usage (recommended)
-     * JacksonJsonOps.INSTANCE
-     * }
- * - * @deprecated Use {@link JacksonJsonOps#INSTANCE} instead. - */ - @Deprecated(forRemoval = true, since = "0.4.0") - public static final JacksonOps INSTANCE = new JacksonOps(JacksonJsonOps.INSTANCE); - - /** - * The underlying {@link JacksonJsonOps} instance to which all operations are delegated. - * - *

This field holds the actual implementation that performs all DynamicOps operations. - * The wrapper simply forwards all method calls to this instance, ensuring behavioral - * equivalence between the deprecated and new implementations.

- */ - private final JacksonJsonOps baseOps; - - /** - * Creates a new deprecated {@code JacksonOps} wrapper delegating to the specified base implementation. - * - *

This constructor allows wrapping any {@link JacksonJsonOps} instance, enabling use - * of custom configurations while maintaining backwards compatibility.

- * - *

Usage

- *
{@code
-     * // Typically use the singleton instead
-     * JacksonOps ops = JacksonOps.INSTANCE;
-     *
-     * // Or wrap a custom JacksonJsonOps instance
-     * JacksonJsonOps customJsonOps = new JacksonJsonOps(customMapper);
-     * JacksonOps customOps = new JacksonOps(customJsonOps);
-     * }
- * - * @param baseOps the base {@link JacksonJsonOps} instance to delegate all operations to; - * must not be {@code null} - * @deprecated Use {@link JacksonJsonOps} directly instead. - */ - @Deprecated(forRemoval = true, since = "0.4.0") - private JacksonOps(@NotNull final JacksonJsonOps baseOps) { - Preconditions.checkNotNull(baseOps, "baseOps must not be null"); - this.baseOps = baseOps; - } - - /** - * Creates a new deprecated {@code JacksonOps} with the specified {@link ObjectMapper}. - * - *

This constructor provides backwards compatibility for code that creates custom - * {@code JacksonOps} instances with a specific mapper configuration.

- * - *

Usage

- *
{@code
-     * // Old usage (deprecated)
-     * ObjectMapper customMapper = new ObjectMapper()
-     *     .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-     * JacksonOps customOps = new JacksonOps(customMapper);
-     *
-     * // New usage (recommended)
-     * JacksonJsonOps customOps = new JacksonJsonOps(customMapper);
-     * }
- * - * @param mapper the {@link ObjectMapper} to use for JSON operations; must not be {@code null} - * @deprecated Use {@link JacksonJsonOps#JacksonJsonOps(ObjectMapper)} instead. - */ - @Deprecated(forRemoval = true, since = "0.4.0") - public JacksonOps(@NotNull final ObjectMapper mapper) { - Preconditions.checkNotNull(mapper, "mapper must not be null"); - this.baseOps = new JacksonJsonOps(mapper); - } - - /** - * Returns the {@link ObjectMapper} used by this instance. - * - *

This method provides access to the underlying Jackson mapper, which can be - * useful for advanced configuration or direct JSON serialization/deserialization.

- * - *

Migration

- *
{@code
-     * // Old usage (deprecated)
-     * ObjectMapper mapper = jacksonOps.mapper();
-     *
-     * // New usage (recommended)
-     * ObjectMapper mapper = jacksonJsonOps.mapper();
-     * }
- * - * @return the {@link ObjectMapper} used by the underlying {@link JacksonJsonOps} instance - * @deprecated Use {@link JacksonJsonOps#mapper()} instead. - */ - @Deprecated(forRemoval = true, since = "0.4.0") - public ObjectMapper mapper() { - return this.baseOps.mapper(); - } - - // ==================== Empty/Null Values ==================== - - /** - * {@inheritDoc} - * - *

Returns the canonical empty/null representation for Jackson JSON data, - * which is {@link NullNode#getInstance()}. This delegates to the underlying - * {@link JacksonJsonOps#empty()} method.

- * - * @return {@link NullNode#getInstance()} representing the absence of a value - */ - @NotNull - @Override - public JsonNode empty() { - return this.baseOps.empty(); - } - - /** - * {@inheritDoc} - * - *

Returns an empty JSON object ({@code {}}). This delegates to the underlying - * {@link JacksonJsonOps#emptyMap()} method.

- * - * @return a new empty {@link ObjectNode} instance - */ - @NotNull - @Override - public JsonNode emptyMap() { - return this.baseOps.emptyMap(); - } - - /** - * {@inheritDoc} - * - *

Returns an empty JSON array ({@code []}). This delegates to the underlying - * {@link JacksonJsonOps#emptyList()} method.

- * - * @return a new empty {@link ArrayNode} instance - */ - @NotNull - @Override - public JsonNode emptyList() { - return this.baseOps.emptyList(); - } - - // ==================== Type Checking ==================== - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON node is a map/object structure. - * This delegates to the underlying {@link JacksonJsonOps#isMap(JsonNode)} method.

- * - * @param value the JSON node to check; must not be {@code null} - * @return {@code true} if the value is an {@link ObjectNode}, {@code false} otherwise - */ - @Override - public boolean isMap(@NotNull final JsonNode value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isMap(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON node is a list/array structure. - * This delegates to the underlying {@link JacksonJsonOps#isList(JsonNode)} method.

- * - * @param value the JSON node to check; must not be {@code null} - * @return {@code true} if the value is an {@link ArrayNode}, {@code false} otherwise - */ - @Override - public boolean isList(@NotNull final JsonNode value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isList(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON node is a text/string node. - * This delegates to the underlying {@link JacksonJsonOps#isString(JsonNode)} method.

- * - * @param value the JSON node to check; must not be {@code null} - * @return {@code true} if the value is a text node, {@code false} otherwise - */ - @Override - public boolean isString(@NotNull final JsonNode value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isString(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON node is a numeric node. - * This delegates to the underlying {@link JacksonJsonOps#isNumber(JsonNode)} method.

- * - * @param value the JSON node to check; must not be {@code null} - * @return {@code true} if the value is a numeric node, {@code false} otherwise - */ - @Override - public boolean isNumber(@NotNull final JsonNode value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isNumber(value); - } - - /** - * {@inheritDoc} - * - *

Checks whether the given JSON node is a boolean node. - * This delegates to the underlying {@link JacksonJsonOps#isBoolean(JsonNode)} method.

- * - * @param value the JSON node to check; must not be {@code null} - * @return {@code true} if the value is a boolean node, {@code false} otherwise - */ - @Override - public boolean isBoolean(@NotNull final JsonNode value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.isBoolean(value); - } - - // ==================== Primitive Creation ==================== - - /** - * {@inheritDoc} - * - *

Creates a JSON text node from the given string value. - * This delegates to the underlying {@link JacksonJsonOps#createString(String)} method.

- * - * @param value the string value to wrap; must not be {@code null} - * @return a new text node containing the string - */ - @NotNull - @Override - public JsonNode createString(@NotNull final String value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.createString(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given integer value. - * This delegates to the underlying {@link JacksonJsonOps#createInt(int)} method.

- * - * @param value the integer value to wrap - * @return a new int node containing the integer - */ - @NotNull - @Override - public JsonNode createInt(final int value) { - return this.baseOps.createInt(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given long value. - * This delegates to the underlying {@link JacksonJsonOps#createLong(long)} method.

- * - * @param value the long value to wrap - * @return a new long node containing the long - */ - @NotNull - @Override - public JsonNode createLong(final long value) { - return this.baseOps.createLong(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given float value. - * This delegates to the underlying {@link JacksonJsonOps#createFloat(float)} method.

- * - * @param value the float value to wrap - * @return a new float node containing the float - */ - @NotNull - @Override - public JsonNode createFloat(final float value) { - return this.baseOps.createFloat(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given double value. - * This delegates to the underlying {@link JacksonJsonOps#createDouble(double)} method.

- * - * @param value the double value to wrap - * @return a new double node containing the double - */ - @NotNull - @Override - public JsonNode createDouble(final double value) { - return this.baseOps.createDouble(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given byte value. - * Since JSON has no distinct byte type, the value is stored as a short node. - * This delegates to the underlying {@link JacksonJsonOps#createByte(byte)} method.

- * - * @param value the byte value to wrap - * @return a new short node containing the byte value - */ - @NotNull - @Override - public JsonNode createByte(final byte value) { - return this.baseOps.createByte(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given short value. - * This delegates to the underlying {@link JacksonJsonOps#createShort(short)} method.

- * - * @param value the short value to wrap - * @return a new short node containing the short - */ - @NotNull - @Override - public JsonNode createShort(final short value) { - return this.baseOps.createShort(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON boolean node from the given boolean value. - * This delegates to the underlying {@link JacksonJsonOps#createBoolean(boolean)} method.

- * - * @param value the boolean value to wrap - * @return a new boolean node containing the boolean - */ - @NotNull - @Override - public JsonNode createBoolean(final boolean value) { - return this.baseOps.createBoolean(value); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON numeric node from the given {@link Number} value. - * The specific numeric type is preserved in the underlying JSON representation. - * This delegates to the underlying {@link JacksonJsonOps#createNumeric(Number)} method.

- * - * @param value the number value to wrap; must not be {@code null} - * @return a new numeric node containing the number - */ - @NotNull - @Override - public JsonNode createNumeric(@NotNull final Number value) { - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.createNumeric(value); - } - - // ==================== Primitive Reading ==================== - - /** - * {@inheritDoc} - * - *

Extracts the string value from a JSON node. The node must be a text node. - * This delegates to the underlying {@link JacksonJsonOps#getStringValue(JsonNode)} method.

- * - * @param input the JSON node to extract the string from; must not be {@code null} - * @return a {@link DataResult} containing the string value on success, - * or an error if the node is not a text node - */ - @NotNull - @Override - public DataResult getStringValue(@NotNull final JsonNode input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getStringValue(input); - } - - /** - * {@inheritDoc} - * - *

Extracts the numeric value from a JSON node. The node must be a numeric node. - * This delegates to the underlying {@link JacksonJsonOps#getNumberValue(JsonNode)} method.

- * - * @param input the JSON node to extract the number from; must not be {@code null} - * @return a {@link DataResult} containing the {@link Number} value on success, - * or an error if the node is not a numeric node - */ - @NotNull - @Override - public DataResult getNumberValue(@NotNull final JsonNode input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getNumberValue(input); - } - - /** - * {@inheritDoc} - * - *

Extracts the boolean value from a JSON node. The node must be a boolean node. - * This delegates to the underlying {@link JacksonJsonOps#getBooleanValue(JsonNode)} method.

- * - * @param input the JSON node to extract the boolean from; must not be {@code null} - * @return a {@link DataResult} containing the boolean value on success, - * or an error if the node is not a boolean node - */ - @NotNull - @Override - public DataResult getBooleanValue(@NotNull final JsonNode input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getBooleanValue(input); - } - - // ==================== List Operations ==================== - - /** - * {@inheritDoc} - * - *

Creates a JSON array node from a stream of JSON nodes. - * This delegates to the underlying {@link JacksonJsonOps#createList(Stream)} method.

- * - * @param values the stream of JSON nodes to include in the array; must not be {@code null} - * @return a new {@link ArrayNode} containing all elements from the stream - */ - @NotNull - @Override - public JsonNode createList(@NotNull final Stream values) { - Preconditions.checkNotNull(values, "values must not be null"); - return this.baseOps.createList(values); - } - - /** - * {@inheritDoc} - * - *

Extracts the elements of a JSON array as a stream. The input must be an - * {@link ArrayNode}. This delegates to the underlying - * {@link JacksonJsonOps#getList(JsonNode)} method.

- * - * @param input the JSON node to extract list elements from; must not be {@code null} - * @return a {@link DataResult} containing a stream of the array elements on success, - * or an error if the input is not an array node - */ - @NotNull - @Override - public DataResult> getList(@NotNull final JsonNode input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getList(input); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON array by appending a value to an existing array. - * The original array is not modified; a deep copy is created. - * This delegates to the underlying - * {@link JacksonJsonOps#mergeToList(JsonNode, JsonNode)} method.

- * - * @param list the existing JSON array to append to; must not be {@code null} - * @param value the JSON node to append; must not be {@code null} - * @return a {@link DataResult} containing the new array with the appended value on success, - * or an error if the list is not an array node - */ - @NotNull - @Override - public DataResult mergeToList(@NotNull final JsonNode list, @NotNull final JsonNode value) { - Preconditions.checkNotNull(list, "list must not be null"); - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.mergeToList(list, value); - } - - // ==================== Map Operations ==================== - - /** - * {@inheritDoc} - * - *

Retrieves the value associated with a key from a JSON object. - * This delegates to the underlying {@link JacksonJsonOps#get(JsonNode, String)} method.

- * - * @param value the JSON object to retrieve from; must not be {@code null} - * @param key the key to look up; must not be {@code null} - * @return the JSON node associated with the key, or {@code null} if not present - * or if the input is not an object node - */ - @Override - public @Nullable JsonNode get(@NotNull final JsonNode value, @NotNull final String key) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.get(value, key); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object with a field set to the specified value. - * If the input is an object node, a deep copy is created with the field updated. - * If the input is not an object node, a new object is created containing only the specified field. - * This delegates to the underlying - * {@link JacksonJsonOps#set(JsonNode, String, JsonNode)} method.

- * - * @param value the JSON node to modify; must not be {@code null} - * @param key the key for the field to set; must not be {@code null} - * @param newValue the value to associate with the key; must not be {@code null} - * @return a new {@link ObjectNode} with the field set to the specified value - */ - @NotNull - @Override - public JsonNode set(@NotNull final JsonNode value, @NotNull final String key, @NotNull final JsonNode newValue) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.set(value, key, newValue); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object with a field removed. - * A deep copy of the input object is created without the specified field. - * This delegates to the underlying - * {@link JacksonJsonOps#remove(JsonNode, String)} method.

- * - * @param value the JSON object to modify; must not be {@code null} - * @param key the key of the field to remove; must not be {@code null} - * @return a new {@link ObjectNode} without the specified field - */ - @NotNull - @Override - public JsonNode remove(@NotNull final JsonNode value, @NotNull final String key) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.remove(value, key); - } - - /** - * {@inheritDoc} - * - *

Checks whether a JSON object contains a field with the specified key. - * This delegates to the underlying - * {@link JacksonJsonOps#has(JsonNode, String)} method.

- * - * @param value the JSON node to check; must not be {@code null} - * @param key the key to look for; must not be {@code null} - * @return {@code true} if the value is an {@link ObjectNode} and contains the specified key, - * {@code false} otherwise - */ - @Override - public boolean has(@NotNull final JsonNode value, @NotNull final String key) { - Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - return this.baseOps.has(value, key); - } - - /** - * {@inheritDoc} - * - *

Creates a JSON object from a stream of key-value pairs. - * Keys must be text nodes; non-text keys are skipped. - * This delegates to the underlying {@link JacksonJsonOps#createMap(Stream)} method.

- * - * @param entries the stream of key-value pairs; must not be {@code null} - * @return a new {@link ObjectNode} containing all valid entries from the stream - */ - @NotNull - @Override - public JsonNode createMap(@NotNull final Stream> entries) { - Preconditions.checkNotNull(entries, "entries must not be null"); - return this.baseOps.createMap(entries); - } - - /** - * {@inheritDoc} - * - *

Extracts the entries of a JSON object as a stream of key-value pairs. - * This delegates to the underlying - * {@link JacksonJsonOps#getMapEntries(JsonNode)} method.

- * - * @param input the JSON node to extract entries from; must not be {@code null} - * @return a {@link DataResult} containing a stream of key-value pairs on success, - * or an error if the input is not an object node - */ - @NotNull - @Override - public DataResult>> getMapEntries(@NotNull final JsonNode input) { - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.getMapEntries(input); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object by adding a key-value pair to an existing map. - * A deep copy of the input map is created with the new entry added. - * This delegates to the underlying - * {@link JacksonJsonOps#mergeToMap(JsonNode, JsonNode, JsonNode)} method.

- * - * @param map the existing JSON object; must not be {@code null} - * @param key the key for the new entry (must be a text node); must not be {@code null} - * @param value the value for the new entry; must not be {@code null} - * @return a {@link DataResult} containing the new object with the added entry on success, - * or an error if the map is not an object node or the key is not a text node - */ - @NotNull - @Override - public DataResult mergeToMap(@NotNull final JsonNode map, @NotNull final JsonNode key, @NotNull final JsonNode value) { - Preconditions.checkNotNull(map, "map must not be null"); - Preconditions.checkNotNull(key, "key must not be null"); - Preconditions.checkNotNull(value, "value must not be null"); - return this.baseOps.mergeToMap(map, key, value); - } - - /** - * {@inheritDoc} - * - *

Creates a new JSON object by merging two maps together. - * A deep copy of the first map is created, and all entries from the second map are added. - * Entries in the second map override entries with the same key in the first map. - * This delegates to the underlying - * {@link JacksonJsonOps#mergeToMap(JsonNode, JsonNode)} method.

- * - * @param map the base JSON object; must not be {@code null} - * @param other the JSON object to merge from; must not be {@code null} - * @return a {@link DataResult} containing the merged object on success, - * or an error if either argument is not an object node - */ - @NotNull - @Override - public DataResult mergeToMap(@NotNull final JsonNode map, @NotNull final JsonNode other) { - Preconditions.checkNotNull(map, "map must not be null"); - Preconditions.checkNotNull(other, "other must not be null"); - return this.baseOps.mergeToMap(map, other); - } - - // ==================== Conversion ==================== - - /** - * {@inheritDoc} - * - *

Converts data from another {@link DynamicOps} format to Jackson's {@link JsonNode}. - * Recursively converts primitives, lists, and maps to their Jackson equivalents. - * This delegates to the underlying - * {@link JacksonJsonOps#convertTo(DynamicOps, Object)} method.

- * - * @param the type parameter of the target format - * @param ops the target {@link DynamicOps} implementation; must not be {@code null} - * @param input the data to convert in the source format; must not be {@code null} - * @return the converted data as a Jackson {@link JsonNode} - */ - @NotNull - @Override - public JsonNode convertTo(@NotNull final DynamicOps ops, @NotNull final U input) { - Preconditions.checkNotNull(ops, "ops must not be null"); - Preconditions.checkNotNull(input, "input must not be null"); - return this.baseOps.convertTo(ops, input); - } - - /** - * Returns a string representation of this deprecated wrapper. - * - *

The returned string clearly indicates that this is a deprecated wrapper - * class and suggests using the new implementation instead.

- * - * @return a descriptive string indicating deprecated status and the recommended alternative - */ - @Override - public String toString() { - return "JacksonOps (deprecated, use JacksonJsonOps)"; - } -} diff --git a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/jackson/package-info.java b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/jackson/package-info.java deleted file mode 100644 index 73a5b8f..0000000 --- a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/jackson/package-info.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2025 Splatgames.de Software and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * DEPRECATED: Legacy package for Jackson-based {@link de.splatgames.aether.datafixers.api.dynamic.DynamicOps} - * implementation. This package is retained only for backwards compatibility and will be removed in version 1.0.0. - * - *

This package contains the original {@link de.splatgames.aether.datafixers.codec.jackson.JacksonOps} class - * from the pre-0.4.0 package structure. All classes in this package are deprecated and delegate to their - * replacements in the reorganized {@link de.splatgames.aether.datafixers.codec.json.jackson} package.

- * - *

Migration Guide

- *

To migrate from this deprecated package to the new package structure:

- * - *

Import Changes

- *
{@code
- * // Old imports (deprecated, will be removed in 1.0.0)
- * import de.splatgames.aether.datafixers.codec.jackson.JacksonOps;
- *
- * // New imports (recommended)
- * import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;
- * }
- * - *

Code Changes

- *

The class has been renamed from {@code JacksonOps} to {@code JacksonJsonOps} for clarity:

- *
{@code
- * // Old code (deprecated)
- * JacksonOps ops = JacksonOps.INSTANCE;
- * JacksonOps customOps = new JacksonOps(customMapper);
- * Dynamic dynamic = new Dynamic<>(ops, jsonNode);
- *
- * // New code (recommended)
- * JacksonJsonOps ops = JacksonJsonOps.INSTANCE;
- * JacksonJsonOps customOps = new JacksonJsonOps(customMapper);
- * Dynamic dynamic = new Dynamic<>(ops, jsonNode);
- * }
- * - *

Deprecation Timeline

- * - * - * - * - * - * - *
Deprecation and Removal Schedule
VersionStatusAction Required
0.4.0DeprecatedUpdate imports and class names; old code continues to work
0.5.0DeprecatedWarnings during compilation; functionality unchanged
1.0.0RemovedPackage deleted; migration required before upgrade
- * - *

Why This Change?

- *

The package reorganization in version 0.4.0 introduced a cleaner, more scalable structure:

- *
    - *
  • Format-Based Organization: All JSON implementations are now grouped under - * {@code codec.json.*}, YAML under {@code codec.yaml.*}, etc.
  • - *
  • Library-Based Subpackages: Each format has subpackages for different - * libraries (e.g., {@code json.gson}, {@code json.jackson})
  • - *
  • Disambiguated Naming: {@code JacksonOps} is now {@code JacksonJsonOps} to - * distinguish it from {@code JacksonYamlOps}, {@code JacksonTomlOps}, and {@code JacksonXmlOps}
  • - *
- * - *

New Package Structure

- *
- * de.splatgames.aether.datafixers.codec
- * ├── json
- * │   ├── gson/GsonOps.java
- * │   └── jackson/JacksonJsonOps.java   (renamed from JacksonOps)
- * ├── yaml
- * │   ├── jackson/JacksonYamlOps.java   (new)
- * │   └── snakeyaml/SnakeYamlOps.java   (new)
- * ├── toml
- * │   └── jackson/JacksonTomlOps.java   (new)
- * └── xml
- *     └── jackson/JacksonXmlOps.java    (new)
- * 
- * - *

Class Mapping

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Old to New Class Mapping
Old Class (Deprecated)New Class (Recommended)
{@link de.splatgames.aether.datafixers.codec.jackson.JacksonOps}{@link de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps}
{@code JacksonOps.INSTANCE}{@link de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps#INSTANCE}
{@code new JacksonOps(mapper)}{@code new JacksonJsonOps(mapper)}
- * - *

Delegation Pattern

- *

The deprecated {@link de.splatgames.aether.datafixers.codec.jackson.JacksonOps} class uses the - * delegation pattern to forward all method calls to the new - * {@link de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps} implementation. This ensures:

- *
    - *
  • Identical behavior between deprecated and new implementations
  • - *
  • Bug fixes applied to the new implementation automatically benefit deprecated users
  • - *
  • No performance overhead beyond a single method delegation
  • - *
- * - *

Thread Safety

- *

All classes in this deprecated package maintain the same thread-safety guarantees as their - * replacements. The singleton {@link de.splatgames.aether.datafixers.codec.jackson.JacksonOps#INSTANCE} - * can be safely shared across multiple threads. Custom instances created with a custom - * {@link com.fasterxml.jackson.databind.ObjectMapper} are thread-safe if the provided mapper is thread-safe.

- * - * @author Erik Pförtner - * @see de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps - * @see de.splatgames.aether.datafixers.codec.json - * @see de.splatgames.aether.datafixers.api.dynamic.DynamicOps - * @since 0.1.0 - * @deprecated Since 0.4.0. Use classes from {@link de.splatgames.aether.datafixers.codec.json.jackson} - * instead. This package will be removed in version 1.0.0. - */ -@Deprecated(since = "0.4.0", forRemoval = true) -package de.splatgames.aether.datafixers.codec.jackson; diff --git a/aether-datafixers-testkit/pom.xml b/aether-datafixers-testkit/pom.xml index 08c93df..dde9eb2 100644 --- a/aether-datafixers-testkit/pom.xml +++ b/aether-datafixers-testkit/pom.xml @@ -54,7 +54,7 @@ gson - + com.fasterxml.jackson.core jackson-databind diff --git a/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestData.java b/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestData.java index f67c78b..e5acf4c 100644 --- a/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestData.java +++ b/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestData.java @@ -139,21 +139,6 @@ public static TestDataBuilder gson() { return new TestDataBuilder<>(GsonOps.INSTANCE); } - /** - * Creates a builder using {@link JacksonJsonOps}. - * - *

Use this when testing with Jackson's JSON representation.

- * - * @return a new {@link TestDataBuilder} for Jackson JSON - * @deprecated Since 0.5.0. Use {@link #jacksonJson()} instead for explicit format naming. - * This method will be removed in version 1.0.0. - */ - @Deprecated(forRemoval = true, since = "0.5.0") - @NotNull - public static TestDataBuilder jackson() { - return jacksonJson(); - } - /** * Creates a builder using {@link JacksonJsonOps}. * diff --git a/aether-datafixers-testkit/src/test/java/de/splatgames/aether/datafixers/testkit/TestDataTest.java b/aether-datafixers-testkit/src/test/java/de/splatgames/aether/datafixers/testkit/TestDataTest.java index 7f03785..04dd795 100644 --- a/aether-datafixers-testkit/src/test/java/de/splatgames/aether/datafixers/testkit/TestDataTest.java +++ b/aether-datafixers-testkit/src/test/java/de/splatgames/aether/datafixers/testkit/TestDataTest.java @@ -264,17 +264,6 @@ void jacksonJsonCreatesJacksonJsonBuilder() { assertThat(dynamic.ops()).isSameAs(JacksonJsonOps.INSTANCE); } - @Test - @DisplayName("jackson() creates Jackson JSON builder (deprecated)") - @SuppressWarnings("deprecation") - void jacksonCreatesJacksonJsonBuilder() { - final Dynamic dynamic = TestData.jackson().object() - .put("key", "value") - .build(); - - assertThat(dynamic.get("key").asString().result()).hasValue("value"); - } - @Test @DisplayName("snakeYaml() creates SnakeYAML builder") void snakeYamlCreatesSnakeYamlBuilder() { diff --git a/docs/appendix/glossary.md b/docs/appendix/glossary.md index 5bb793f..2f2af82 100644 --- a/docs/appendix/glossary.md +++ b/docs/appendix/glossary.md @@ -140,7 +140,7 @@ Terminology used in Aether Datafixers. : Test harness for validating Schema configurations. **TestData** -: Entry point for fluent test data builders (TestData.gson(), TestData.jackson()). +: Entry point for fluent test data builders (TestData.gson(), TestData.jacksonJson()). **TestDataBuilder** : Fluent builder for creating Dynamic objects with fields. diff --git a/docs/testkit/test-data-builders.md b/docs/testkit/test-data-builders.md index 157dba9..283e849 100644 --- a/docs/testkit/test-data-builders.md +++ b/docs/testkit/test-data-builders.md @@ -31,8 +31,6 @@ TestData.jacksonXml()... TestData.using(myCustomOps)... ``` -> **Deprecation Notice:** `TestData.jackson()` is deprecated since 0.5.0 and will be removed in 1.0.0. Use `TestData.jacksonJson()` instead for explicit format naming. - ## Creating Primitives ```java