[serde-*] Make data readers and writers AutoCloseable

This commit is contained in:
2025-08-03 20:36:28 +02:00
parent 1fc418970f
commit 7ce3aaac06
16 changed files with 117 additions and 63 deletions

View File

@@ -12,7 +12,7 @@ public interface JsonReaderTest {
@Test @Test
@SneakyThrows @SneakyThrows
default void complexJsonReadTest() { default void complexJsonReadTest() {
var reader = createJsonReader(""" String text = """
{ {
"first": [ "first": [
[ 1 ] [ 1 ]
@@ -21,8 +21,9 @@ public interface JsonReaderTest {
"test": "Hello World!" "test": "Hello World!"
} }
} }
"""); """;
try (var reader = createJsonReader(text)) {
var token = reader.peekToken(); var token = reader.peekToken();
assertThat(token.isMapStart()).isTrue(); assertThat(token.isMapStart()).isTrue();
token = reader.readToken(); token = reader.readToken();
@@ -70,4 +71,5 @@ public interface JsonReaderTest {
token = reader.readToken(); token = reader.readToken();
assertThat(token.isMapEnd()).isTrue(); assertThat(token.isMapEnd()).isTrue();
} }
}
} }

View File

@@ -16,10 +16,7 @@ import de.siphalor.tweed5.data.extension.api.TweedReadContext;
import de.siphalor.tweed5.data.extension.api.extension.ReadWriteExtensionSetupContext; import de.siphalor.tweed5.data.extension.api.extension.ReadWriteExtensionSetupContext;
import de.siphalor.tweed5.data.extension.api.extension.ReadWriteRelatedExtension; import de.siphalor.tweed5.data.extension.api.extension.ReadWriteRelatedExtension;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls; import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import de.siphalor.tweed5.dataapi.api.DelegatingTweedDataVisitor; import de.siphalor.tweed5.dataapi.api.*;
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
import de.siphalor.tweed5.dataapi.api.TweedDataUnsupportedValueException;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
import de.siphalor.tweed5.patchwork.api.Patchwork; import de.siphalor.tweed5.patchwork.api.Patchwork;
import de.siphalor.tweed5.patchwork.api.PatchworkPartAccess; import de.siphalor.tweed5.patchwork.api.PatchworkPartAccess;
@@ -285,7 +282,7 @@ public class AttributesReadWriteFilterExtensionImpl
return true; return true;
} }
private static class MapEntryKeyDeferringWriter extends DelegatingTweedDataVisitor { private static class MapEntryKeyDeferringWriter extends DelegatingTweedDataWriter {
private final Deque<Boolean> mapContext = new ArrayDeque<>(); private final Deque<Boolean> mapContext = new ArrayDeque<>();
private final Deque<TweedDataDecoration> preDecorationQueue = new ArrayDeque<>(); private final Deque<TweedDataDecoration> preDecorationQueue = new ArrayDeque<>();
private final Deque<TweedDataDecoration> postDecorationQueue = new ArrayDeque<>(); private final Deque<TweedDataDecoration> postDecorationQueue = new ArrayDeque<>();

View File

@@ -3,8 +3,9 @@ package de.siphalor.tweed5.defaultextensions.comment.impl;
import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.middleware.Middleware; import de.siphalor.tweed5.core.api.middleware.Middleware;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter; import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.dataapi.api.DelegatingTweedDataVisitor; import de.siphalor.tweed5.dataapi.api.DelegatingTweedDataWriter;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor; import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.TweedDataWriter;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
import de.siphalor.tweed5.patchwork.api.PatchworkPartAccess; import de.siphalor.tweed5.patchwork.api.PatchworkPartAccess;
@@ -48,7 +49,7 @@ class TweedEntryWriterCommentMiddleware implements Middleware<TweedEntryWriter<?
}; };
} }
private static class MapEntryKeyDeferringWriter extends DelegatingTweedDataVisitor { private static class MapEntryKeyDeferringWriter extends DelegatingTweedDataWriter {
private final Deque<TweedDataDecoration> decorationQueue = new ArrayDeque<>(); private final Deque<TweedDataDecoration> decorationQueue = new ArrayDeque<>();
private @Nullable String mapEntryKey; private @Nullable String mapEntryKey;

View File

@@ -36,4 +36,9 @@ public class PathTrackingDataReader implements TweedDataReader {
} }
return token; return token;
} }
@Override
public void close() throws Exception {
delegate.close();
}
} }

View File

@@ -6,6 +6,7 @@ import de.siphalor.tweed5.core.api.middleware.Middleware;
import de.siphalor.tweed5.data.extension.api.*; import de.siphalor.tweed5.data.extension.api.*;
import de.siphalor.tweed5.data.extension.api.extension.ReadWriteExtensionSetupContext; import de.siphalor.tweed5.data.extension.api.extension.ReadWriteExtensionSetupContext;
import de.siphalor.tweed5.data.extension.api.extension.ReadWriteRelatedExtension; import de.siphalor.tweed5.data.extension.api.extension.ReadWriteRelatedExtension;
import de.siphalor.tweed5.dataapi.api.DelegatingTweedDataWriter;
import de.siphalor.tweed5.dataapi.api.TweedDataReader; import de.siphalor.tweed5.dataapi.api.TweedDataReader;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor; import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.defaultextensions.pather.api.PathTracking; import de.siphalor.tweed5.defaultextensions.pather.api.PathTracking;

View File

@@ -8,7 +8,7 @@ import org.jspecify.annotations.Nullable;
@Getter @Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED) @RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class DelegatingTweedDataVisitor implements TweedDataVisitor { public class DelegatingTweedDataWriter implements TweedDataWriter {
protected final TweedDataVisitor delegate; protected final TweedDataVisitor delegate;
@Override @Override
@@ -115,4 +115,11 @@ public class DelegatingTweedDataVisitor implements TweedDataVisitor {
public void visitDecoration(TweedDataDecoration decoration) { public void visitDecoration(TweedDataDecoration decoration) {
delegate.visitDecoration(decoration); delegate.visitDecoration(decoration);
} }
@Override
public void close() throws Exception {
if (delegate instanceof AutoCloseable) {
((AutoCloseable) delegate).close();
}
}
} }

View File

@@ -1,6 +1,6 @@
package de.siphalor.tweed5.dataapi.api; package de.siphalor.tweed5.dataapi.api;
public interface TweedDataReader { public interface TweedDataReader extends AutoCloseable {
TweedDataToken peekToken() throws TweedDataReadException; TweedDataToken peekToken() throws TweedDataReadException;
TweedDataToken readToken() throws TweedDataReadException; TweedDataToken readToken() throws TweedDataReadException;
} }

View File

@@ -0,0 +1,4 @@
package de.siphalor.tweed5.dataapi.api;
public interface TweedDataWriter extends TweedDataVisitor, AutoCloseable {
}

View File

@@ -1,8 +1,8 @@
package de.siphalor.tweed5.data.extension.api; package de.siphalor.tweed5.data.extension.api;
import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor; import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
@FunctionalInterface @FunctionalInterface

View File

@@ -266,6 +266,11 @@ public class GsonReader implements TweedDataReader {
}; };
} }
@Override
public void close() throws Exception {
reader.close();
}
private enum Context { private enum Context {
VALUE, VALUE,
LIST, LIST,

View File

@@ -3,6 +3,7 @@ package de.siphaolor.tweed5.data.gson;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor; import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException; import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.dataapi.api.TweedDataWriter;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
@@ -11,7 +12,7 @@ import java.io.IOException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
public class GsonWriter implements TweedDataVisitor { public class GsonWriter implements TweedDataWriter {
private final JsonWriter writer; private final JsonWriter writer;
private final Deque<Context> contextStack = new ArrayDeque<>(); private final Deque<Context> contextStack = new ArrayDeque<>();
@@ -181,6 +182,11 @@ public class GsonWriter implements TweedDataVisitor {
} }
} }
@Override
public void close() throws Exception {
writer.close();
}
private void afterValueWritten() { private void afterValueWritten() {
if (peekContext() == Context.VALUE) { if (peekContext() == Context.VALUE) {
contextStack.pop(); contextStack.pop();

View File

@@ -11,7 +11,7 @@ import java.util.PrimitiveIterator;
@ApiStatus.Internal @ApiStatus.Internal
@RequiredArgsConstructor @RequiredArgsConstructor
public class HjsonLexer { public class HjsonLexer implements AutoCloseable {
private static final int EMPTY_CODEPOINT = -2; private static final int EMPTY_CODEPOINT = -2;
private final Reader reader; private final Reader reader;
@@ -482,4 +482,9 @@ public class HjsonLexer {
throw TweedDataReadException.builder().message("Failed to read character from input at " + currentPos).cause(e).build(); throw TweedDataReadException.builder().message("Failed to read character from input at " + currentPos).cause(e).build();
} }
} }
@Override
public void close() throws Exception {
reader.close();
}
} }

View File

@@ -630,6 +630,11 @@ public class HjsonReader implements TweedDataReader {
return contexts.peek(); return contexts.peek();
} }
@Override
public void close() throws Exception {
lexer.close();
}
private enum Context { private enum Context {
VALUE, VALUE,
LIST, LIST,

View File

@@ -1,7 +1,7 @@
package de.siphalor.tweed5.data.hjson; package de.siphalor.tweed5.data.hjson;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException; import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor; import de.siphalor.tweed5.dataapi.api.TweedDataWriter;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
import lombok.Data; import lombok.Data;
@@ -12,7 +12,7 @@ import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class HjsonWriter implements TweedDataVisitor { public class HjsonWriter implements TweedDataWriter {
private static final int PREFILL_INDENT = 10; private static final int PREFILL_INDENT = 10;
private static final Pattern LINE_FEED_PATTERN = Pattern.compile("\\n|\\r\\n"); private static final Pattern LINE_FEED_PATTERN = Pattern.compile("\\n|\\r\\n");
private static final Pattern NUMBER_PATTERN = Pattern.compile("^-?\\d+(?:\\.\\d*)?(?:[eE][+-]?\\d+)?$"); private static final Pattern NUMBER_PATTERN = Pattern.compile("^-?\\d+(?:\\.\\d*)?(?:[eE][+-]?\\d+)?$");
@@ -580,6 +580,11 @@ public class HjsonWriter implements TweedDataVisitor {
return new TweedDataWriteException("Writing Hjson failed", e); return new TweedDataWriteException("Writing Hjson failed", e);
} }
@Override
public void close() throws Exception {
writer.close();
}
private enum Context { private enum Context {
ROOT, ROOT,
LIST, LIST,

View File

@@ -256,6 +256,11 @@ public class JacksonReader implements TweedDataReader {
}; };
} }
@Override
public void close() throws Exception {
parser.close();
}
private enum Context { private enum Context {
VALUE, VALUE,
LIST, LIST,

View File

@@ -3,6 +3,7 @@ package de.siphalor.tweed5.data.jackson;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor; import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException; import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.dataapi.api.TweedDataWriter;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration;
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration; import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
@@ -11,7 +12,7 @@ import java.io.IOException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
public class JacksonWriter implements TweedDataVisitor { public class JacksonWriter implements TweedDataWriter {
private final JsonGenerator generator; private final JsonGenerator generator;
private final CommentWriteMode commentWriteMode; private final CommentWriteMode commentWriteMode;
@@ -198,6 +199,11 @@ public class JacksonWriter implements TweedDataVisitor {
} }
} }
@Override
public void close() throws Exception {
generator.close();
}
private void afterValueVisited() { private void afterValueVisited() {
if (contextStack.peek() == Context.VALUE) { if (contextStack.peek() == Context.VALUE) {
contextStack.pop(); contextStack.pop();