[serde-*] Make data readers and writers AutoCloseable
This commit is contained in:
@@ -12,7 +12,7 @@ public interface JsonReaderTest {
|
||||
@Test
|
||||
@SneakyThrows
|
||||
default void complexJsonReadTest() {
|
||||
var reader = createJsonReader("""
|
||||
String text = """
|
||||
{
|
||||
"first": [
|
||||
[ 1 ]
|
||||
@@ -21,53 +21,55 @@ public interface JsonReaderTest {
|
||||
"test": "Hello World!"
|
||||
}
|
||||
}
|
||||
""");
|
||||
""";
|
||||
|
||||
var token = reader.peekToken();
|
||||
assertThat(token.isMapStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryKey()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("first");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.isListStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isFalse();
|
||||
assertThat(token.isListValue()).isTrue();
|
||||
assertThat(token.isListStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isListValue()).isTrue();
|
||||
assertThat(token.canReadAsInt()).isTrue();
|
||||
assertThat(token.readAsInt()).isEqualTo(1);
|
||||
token = reader.readToken();
|
||||
assertThat(token.isListValue()).isTrue();
|
||||
assertThat(token.isListEnd()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isListValue()).isFalse();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.isListEnd()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryKey()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("second");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.isMapStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isFalse();
|
||||
assertThat(token.isMapEntryKey()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("test");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("Hello World!");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEnd()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEnd()).isTrue();
|
||||
try (var reader = createJsonReader(text)) {
|
||||
var token = reader.peekToken();
|
||||
assertThat(token.isMapStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryKey()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("first");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.isListStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isFalse();
|
||||
assertThat(token.isListValue()).isTrue();
|
||||
assertThat(token.isListStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isListValue()).isTrue();
|
||||
assertThat(token.canReadAsInt()).isTrue();
|
||||
assertThat(token.readAsInt()).isEqualTo(1);
|
||||
token = reader.readToken();
|
||||
assertThat(token.isListValue()).isTrue();
|
||||
assertThat(token.isListEnd()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isListValue()).isFalse();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.isListEnd()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryKey()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("second");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.isMapStart()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isFalse();
|
||||
assertThat(token.isMapEntryKey()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("test");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEntryValue()).isTrue();
|
||||
assertThat(token.canReadAsString()).isTrue();
|
||||
assertThat(token.readAsString()).isEqualTo("Hello World!");
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEnd()).isTrue();
|
||||
token = reader.readToken();
|
||||
assertThat(token.isMapEnd()).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.ReadWriteRelatedExtension;
|
||||
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
|
||||
import de.siphalor.tweed5.dataapi.api.DelegatingTweedDataVisitor;
|
||||
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.*;
|
||||
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
|
||||
import de.siphalor.tweed5.patchwork.api.Patchwork;
|
||||
import de.siphalor.tweed5.patchwork.api.PatchworkPartAccess;
|
||||
@@ -285,7 +282,7 @@ public class AttributesReadWriteFilterExtensionImpl
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class MapEntryKeyDeferringWriter extends DelegatingTweedDataVisitor {
|
||||
private static class MapEntryKeyDeferringWriter extends DelegatingTweedDataWriter {
|
||||
private final Deque<Boolean> mapContext = new ArrayDeque<>();
|
||||
private final Deque<TweedDataDecoration> preDecorationQueue = new ArrayDeque<>();
|
||||
private final Deque<TweedDataDecoration> postDecorationQueue = new ArrayDeque<>();
|
||||
|
||||
@@ -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.middleware.Middleware;
|
||||
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.TweedDataWriter;
|
||||
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataCommentDecoration;
|
||||
import de.siphalor.tweed5.dataapi.api.decoration.TweedDataDecoration;
|
||||
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 @Nullable String mapEntryKey;
|
||||
|
||||
|
||||
@@ -36,4 +36,9 @@ public class PathTrackingDataReader implements TweedDataReader {
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
delegate.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.extension.ReadWriteExtensionSetupContext;
|
||||
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.TweedDataVisitor;
|
||||
import de.siphalor.tweed5.defaultextensions.pather.api.PathTracking;
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.jspecify.annotations.Nullable;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class DelegatingTweedDataVisitor implements TweedDataVisitor {
|
||||
public class DelegatingTweedDataWriter implements TweedDataWriter {
|
||||
protected final TweedDataVisitor delegate;
|
||||
|
||||
@Override
|
||||
@@ -115,4 +115,11 @@ public class DelegatingTweedDataVisitor implements TweedDataVisitor {
|
||||
public void visitDecoration(TweedDataDecoration decoration) {
|
||||
delegate.visitDecoration(decoration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
if (delegate instanceof AutoCloseable) {
|
||||
((AutoCloseable) delegate).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.siphalor.tweed5.dataapi.api;
|
||||
|
||||
public interface TweedDataReader {
|
||||
public interface TweedDataReader extends AutoCloseable {
|
||||
TweedDataToken peekToken() throws TweedDataReadException;
|
||||
TweedDataToken readToken() throws TweedDataReadException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package de.siphalor.tweed5.dataapi.api;
|
||||
|
||||
public interface TweedDataWriter extends TweedDataVisitor, AutoCloseable {
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.siphalor.tweed5.data.extension.api;
|
||||
|
||||
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.TweedDataWriteException;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@FunctionalInterface
|
||||
|
||||
@@ -266,6 +266,11 @@ public class GsonReader implements TweedDataReader {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
reader.close();
|
||||
}
|
||||
|
||||
private enum Context {
|
||||
VALUE,
|
||||
LIST,
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.siphaolor.tweed5.data.gson;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
|
||||
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.TweedDataDecoration;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -11,7 +12,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class GsonWriter implements TweedDataVisitor {
|
||||
public class GsonWriter implements TweedDataWriter {
|
||||
private final JsonWriter writer;
|
||||
|
||||
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() {
|
||||
if (peekContext() == Context.VALUE) {
|
||||
contextStack.pop();
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.PrimitiveIterator;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@RequiredArgsConstructor
|
||||
public class HjsonLexer {
|
||||
public class HjsonLexer implements AutoCloseable {
|
||||
private static final int EMPTY_CODEPOINT = -2;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,6 +630,11 @@ public class HjsonReader implements TweedDataReader {
|
||||
return contexts.peek();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
lexer.close();
|
||||
}
|
||||
|
||||
private enum Context {
|
||||
VALUE,
|
||||
LIST,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package de.siphalor.tweed5.data.hjson;
|
||||
|
||||
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.TweedDataDecoration;
|
||||
import lombok.Data;
|
||||
@@ -12,7 +12,7 @@ import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
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 Pattern LINE_FEED_PATTERN = Pattern.compile("\\n|\\r\\n");
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
private enum Context {
|
||||
ROOT,
|
||||
LIST,
|
||||
|
||||
@@ -256,6 +256,11 @@ public class JacksonReader implements TweedDataReader {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
parser.close();
|
||||
}
|
||||
|
||||
private enum Context {
|
||||
VALUE,
|
||||
LIST,
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.siphalor.tweed5.data.jackson;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
|
||||
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.TweedDataDecoration;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -11,7 +12,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class JacksonWriter implements TweedDataVisitor {
|
||||
public class JacksonWriter implements TweedDataWriter {
|
||||
private final JsonGenerator generator;
|
||||
private final CommentWriteMode commentWriteMode;
|
||||
|
||||
@@ -198,6 +199,11 @@ public class JacksonWriter implements TweedDataVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
generator.close();
|
||||
}
|
||||
|
||||
private void afterValueVisited() {
|
||||
if (contextStack.peek() == Context.VALUE) {
|
||||
contextStack.pop();
|
||||
|
||||
Reference in New Issue
Block a user