diff --git a/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/MigrateCommand.java b/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/MigrateCommand.java index 845c3ed..8a1e3cd 100644 --- a/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/MigrateCommand.java +++ b/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/MigrateCommand.java @@ -42,6 +42,7 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -498,7 +499,7 @@ public Integer call() { if (this.generateReport && !reportBuilder.isEmpty()) { final String reportContent = reportBuilder.toString(); if (this.reportFile != null) { - Files.writeString(this.reportFile.toPath(), reportContent); + Files.writeString(this.reportFile.toPath(), reportContent, StandardCharsets.UTF_8); } else { System.err.println(reportContent); } @@ -569,7 +570,7 @@ private MigrationResult processFile( } // Read input (strip UTF-8 BOM if present) - String content = Files.readString(inputFile.toPath()); + String content = Files.readString(inputFile.toPath(), StandardCharsets.UTF_8); if (content.startsWith("\uFEFF")) { content = content.substring(1); } @@ -674,9 +675,9 @@ private void writeOutput(@NotNull final File inputFile, @NotNull final String co if (this.output.isDirectory()) { final Path outPath = this.output.toPath().resolve(inputFile.getName()); - Files.writeString(outPath, content); + Files.writeString(outPath, content, StandardCharsets.UTF_8); } else if (this.inputFiles.size() == 1) { - Files.writeString(this.output.toPath(), content); + Files.writeString(this.output.toPath(), content, StandardCharsets.UTF_8); } else { throw new IllegalArgumentException( "Output must be a directory when multiple input files are specified"); @@ -689,7 +690,7 @@ private void writeOutput(@NotNull final File inputFile, @NotNull final String co final Path tempPath = Files.createTempFile( inputFile.toPath().getParent(), "migrate_", ".tmp"); try { - Files.writeString(tempPath, content); + Files.writeString(tempPath, content, StandardCharsets.UTF_8); if (this.backup) { final String timestamp = ZonedDateTime.now(ZoneOffset.UTC) .format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'")); diff --git a/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/ValidateCommand.java b/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/ValidateCommand.java index 0dc9442..ba9788a 100644 --- a/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/ValidateCommand.java +++ b/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/command/ValidateCommand.java @@ -36,6 +36,7 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; import java.util.concurrent.Callable; @@ -328,7 +329,7 @@ private ValidationResult validateFile( if (fileSize > 100 * 1024 * 1024) { throw new IOException("File exceeds maximum size (100MB): " + file); } - String content = Files.readString(file.toPath()); + String content = Files.readString(file.toPath(), StandardCharsets.UTF_8); if (content.startsWith("\uFEFF")) { content = content.substring(1); } diff --git a/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/format/YamlSnakeYamlFormatHandler.java b/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/format/YamlSnakeYamlFormatHandler.java index 9fe7585..f55d677 100644 --- a/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/format/YamlSnakeYamlFormatHandler.java +++ b/aether-datafixers-cli/src/main/java/de/splatgames/aether/datafixers/cli/format/YamlSnakeYamlFormatHandler.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.error.YAMLException; /** * Format handler for YAML using the SnakeYAML library. @@ -174,7 +175,7 @@ public Object parse(@NotNull final String content) { throw new FormatParseException("YAML parsed to null"); } return result; - } catch (final Exception e) { + } catch (final YAMLException | ClassCastException e) { throw new FormatParseException("Failed to parse YAML: " + e.getMessage(), e); } } diff --git a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/json/gson/GsonOps.java b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/json/gson/GsonOps.java index cc71911..02a4ad6 100644 --- a/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/json/gson/GsonOps.java +++ b/aether-datafixers-codec/src/main/java/de/splatgames/aether/datafixers/codec/json/gson/GsonOps.java @@ -784,7 +784,7 @@ public DataResult>> getMapEntries( return DataResult.success( object.entrySet().stream() .map(entry -> Pair.of( - (JsonElement) new JsonPrimitive(entry.getKey()), + new JsonPrimitive(entry.getKey()), entry.getValue() )) ); diff --git a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/DataFixerBuilder.java b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/DataFixerBuilder.java index b31bd16..2c06a23 100644 --- a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/DataFixerBuilder.java +++ b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/DataFixerBuilder.java @@ -155,11 +155,7 @@ public void registerAll(@NotNull final TypeReference type, @NotNull final Iterab public DataFixerBuilder addFix(@NotNull final TypeReference type, @NotNull final DataFix fix) { Preconditions.checkNotNull(type, "type must not be null"); Preconditions.checkNotNull(fix, "fix must not be null"); - Preconditions.checkArgument( - fix.fromVersion().compareTo(fix.toVersion()) <= 0, - "fix.fromVersion must be <= fix.toVersion" - ); - + // Version ordering validation is performed by DataFixRegistry.register() this.registry.register(type, fix); return this; } diff --git a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/SimpleSystemDataFixerContext.java b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/SimpleSystemDataFixerContext.java index 2ceda89..29bda42 100644 --- a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/SimpleSystemDataFixerContext.java +++ b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/SimpleSystemDataFixerContext.java @@ -63,11 +63,26 @@ private SimpleSystemDataFixerContext() { @Override public void info(@NotNull final String message, @Nullable final Object... args) { - System.out.printf("[INFO] " + message + "%n", args); + System.out.println("[INFO] " + formatMessage(message, args)); } @Override public void warn(@NotNull final String message, @Nullable final Object... args) { - System.out.printf("[WARN] " + message + "%n", args); + System.err.println("[WARN] " + formatMessage(message, args)); + } + + private static String formatMessage(final String message, final Object[] args) { + if (args == null || args.length == 0) { + return message; + } + final StringBuilder result = new StringBuilder(message); + for (final Object arg : args) { + final int idx = result.indexOf("{}"); + if (idx < 0) { + break; + } + result.replace(idx, idx + 2, String.valueOf(arg)); + } + return result.toString(); } } diff --git a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/Slf4jDataFixerContext.java b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/Slf4jDataFixerContext.java index dc38556..96585b9 100644 --- a/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/Slf4jDataFixerContext.java +++ b/aether-datafixers-core/src/main/java/de/splatgames/aether/datafixers/core/fix/Slf4jDataFixerContext.java @@ -112,17 +112,15 @@ public Slf4jDataFixerContext(@NotNull final Logger logger) { @Override public void info(@NotNull final String message, @Nullable final Object... args) { Preconditions.checkNotNull(message, "message must not be null"); - if (this.logger.isInfoEnabled()) { - this.logger.info(formatMessage(message, args)); - } + // Delegate directly to SLF4J which handles {} placeholder formatting lazily + this.logger.info(message, args); } @Override public void warn(@NotNull final String message, @Nullable final Object... args) { Preconditions.checkNotNull(message, "message must not be null"); - if (this.logger.isWarnEnabled()) { - this.logger.warn(formatMessage(message, args)); - } + // Delegate directly to SLF4J which handles {} placeholder formatting lazily + this.logger.warn(message, args); } /** diff --git a/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/AetherDataFixersProperties.java b/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/AetherDataFixersProperties.java index c609e00..8c6a797 100644 --- a/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/AetherDataFixersProperties.java +++ b/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/AetherDataFixersProperties.java @@ -522,6 +522,7 @@ public String getDomainTag() { * @throws NullPointerException if domainTag is {@code null} */ public void setDomainTag(@NotNull final String domainTag) { + Preconditions.checkArgument(!domainTag.isEmpty(), "domainTag must not be empty"); this.domainTag = domainTag; } } diff --git a/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/autoconfigure/DataFixerAutoConfiguration.java b/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/autoconfigure/DataFixerAutoConfiguration.java index ffa37f6..416deea 100644 --- a/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/autoconfigure/DataFixerAutoConfiguration.java +++ b/aether-datafixers-spring-boot-starter/src/main/java/de/splatgames/aether/datafixers/spring/autoconfigure/DataFixerAutoConfiguration.java @@ -353,7 +353,7 @@ private static AetherDataFixer createFixer( */ @SuppressFBWarnings( value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", - justification = "Null check for getCurrentVersion() is performed before access on line 363." + justification = "Null check for Field.get() result is performed before access via isAssignableFrom check." ) @NotNull private static DataVersion resolveVersion( diff --git a/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestDataBuilder.java b/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestDataBuilder.java index 897056e..e29bf68 100644 --- a/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestDataBuilder.java +++ b/aether-datafixers-testkit/src/main/java/de/splatgames/aether/datafixers/testkit/TestDataBuilder.java @@ -29,6 +29,7 @@ import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; import java.util.stream.Stream; @@ -288,7 +289,7 @@ public TestDataBuilder put(@NotNull final String key, final short value) { public TestDataBuilder put(@NotNull final String key, @NotNull final Dynamic value) { Preconditions.checkNotNull(key, "key must not be null"); Preconditions.checkNotNull(value, "value must not be null"); - Preconditions.checkArgument(this.ops == value.ops(), + Preconditions.checkArgument(Objects.equals(this.ops, value.ops()), "Dynamic uses different DynamicOps"); this.ensureObjectMode(); this.fields.put(key, value);