[*] Rework registration of TweedExtensions

This commit is contained in:
2025-04-25 15:33:55 +02:00
parent c97f711c0b
commit 59f882bd12
27 changed files with 639 additions and 257 deletions

View File

@@ -3,11 +3,14 @@ package de.siphalor.tweed5.data.extension.api;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.extension.TweedExtension;
import de.siphalor.tweed5.data.extension.api.extension.ReadWriteContextExtensionsData;
import de.siphalor.tweed5.data.extension.impl.ReadWriteExtensionImpl;
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import org.jspecify.annotations.Nullable;
public interface ReadWriteExtension extends TweedExtension {
Class<? extends ReadWriteExtension> DEFAULT = ReadWriteExtensionImpl.class;
void setEntryReaderWriterDefinition(ConfigEntry<?> entry, EntryReaderWriterDefinition readerWriterDefinition);
ReadWriteContextExtensionsData createReadWriteContextExtensionsData();

View File

@@ -1,6 +1,7 @@
package de.siphalor.tweed5.data.extension.impl;
import com.google.auto.service.AutoService;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.extension.EntryExtensionsData;
import de.siphalor.tweed5.core.api.extension.RegisteredExtensionData;
@@ -24,7 +25,6 @@ import lombok.Setter;
import lombok.Value;
import lombok.val;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import java.lang.invoke.MethodHandle;
@@ -33,16 +33,27 @@ import java.util.HashMap;
import java.util.Map;
@AutoService(ReadWriteExtension.class)
@NullUnmarked
public class ReadWriteExtensionImpl implements ReadWriteExtension {
private final ConfigContainer<?> configContainer;
private final RegisteredExtensionData<EntryExtensionsData, EntryReaderWriterDefinition>
readerWriterDefinitionExtension;
private final RegisteredExtensionData<EntryExtensionsData, ReadWriteEntryDataExtension> readWriteEntryDataExtension;
private DefaultMiddlewareContainer<TweedEntryReader<?, ?>>
entryReaderMiddlewareContainer
= new DefaultMiddlewareContainer<>();
private DefaultMiddlewareContainer<TweedEntryWriter<?, ?>>
entryWriterMiddlewareContainer
= new DefaultMiddlewareContainer<>();
private final Map<Class<?>, RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?>>
readWriteContextExtensionsDataClasses
= new HashMap<>();
private @Nullable PatchworkClass<@NonNull ReadWriteContextExtensionsData> readWriteContextExtensionsDataPatchwork;
private RegisteredExtensionData<EntryExtensionsData, EntryReaderWriterDefinition> readerWriterDefinitionExtension;
private RegisteredExtensionData<EntryExtensionsData, ReadWriteEntryDataExtension> readWriteEntryDataExtension;
private DefaultMiddlewareContainer<TweedEntryReader<?, ?>> entryReaderMiddlewareContainer;
private DefaultMiddlewareContainer<TweedEntryWriter<?, ?>> entryWriterMiddlewareContainer;
private Map<Class<?>, RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?>>
readWriteContextExtensionsDataClasses;
private PatchworkClass<@NonNull ReadWriteContextExtensionsData> readWriteContextExtensionsDataPatchwork;
public ReadWriteExtensionImpl(ConfigContainer<?> configContainer, TweedExtensionSetupContext context) {
this.configContainer = configContainer;
this.readerWriterDefinitionExtension = context.registerEntryExtensionData(EntryReaderWriterDefinition.class);
this.readWriteEntryDataExtension = context.registerEntryExtensionData(ReadWriteEntryDataExtension.class);
}
@Override
public String getId() {
@@ -50,13 +61,8 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
@Override
public void setup(TweedExtensionSetupContext context) {
readerWriterDefinitionExtension = context.registerEntryExtensionData(EntryReaderWriterDefinition.class);
readWriteEntryDataExtension = context.registerEntryExtensionData(ReadWriteEntryDataExtension.class);
Collection<TweedExtension> extensions = context.configContainer().extensions();
readWriteContextExtensionsDataClasses = new HashMap<>(extensions.size());
public void extensionsFinalized() {
Collection<TweedExtension> extensions = configContainer.extensions();
ReadWriteExtensionSetupContext setupContext = new ReadWriteExtensionSetupContext() {
@Override
@@ -154,6 +160,7 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
@Override
public ReadWriteContextExtensionsData createReadWriteContextExtensionsData() {
try {
assert readWriteContextExtensionsDataPatchwork != null;
return (ReadWriteContextExtensionsData) readWriteContextExtensionsDataPatchwork.constructor().invoke();
} catch (Throwable e) {
throw new IllegalStateException("Failed to instantiate read write context extensions' data", e);
@@ -161,7 +168,7 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
@Override
public <T> T read(
public <T extends @Nullable Object> T read(
@NonNull TweedDataReader reader,
@NonNull ConfigEntry<T> entry,
@NonNull ReadWriteContextExtensionsData contextExtensionsData
@@ -174,7 +181,7 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
@Override
public <T> void write(
public <T extends @Nullable Object> void write(
@NonNull TweedDataVisitor writer,
@Nullable T value,
@NonNull ConfigEntry<T> entry,

View File

@@ -27,21 +27,19 @@ import java.io.Writer;
import java.util.*;
import java.util.function.Function;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ReadWriteExtensionImplTest {
private StringWriter stringWriter;
private final StringWriter stringWriter = new StringWriter();
private final ConfigContainer<Map<String, Object>> configContainer = new DefaultConfigContainer<>();
private StaticMapCompoundConfigEntryImpl<Map<String, Object>> rootEntry;
private ReadWriteExtension readWriteExtension;
@SuppressWarnings("unchecked")
@BeforeEach
void setUp() {
ConfigContainer<Map<String, Object>> configContainer = new DefaultConfigContainer<>();
readWriteExtension = new ReadWriteExtensionImpl();
configContainer.registerExtension(readWriteExtension);
configContainer.registerExtension(ReadWriteExtension.DEFAULT);
configContainer.finishExtensionSetup();
rootEntry = new StaticMapCompoundConfigEntryImpl<>(((Class<Map<String, Object>>) (Class<?>) Map.class), LinkedHashMap::new);
@@ -73,6 +71,7 @@ class ReadWriteExtensionImplTest {
value.put("int", 123);
value.put("list", Arrays.asList(true, false, true));
ReadWriteExtension readWriteExtension = configContainer.extension(ReadWriteExtension.class).orElseThrow();
assertDoesNotThrow(() -> readWriteExtension.write(
setupWriter(writer -> new HjsonWriter(writer, new HjsonWriter.Options())),
value,
@@ -80,13 +79,33 @@ class ReadWriteExtensionImplTest {
readWriteExtension.createReadWriteContextExtensionsData()
));
assertEquals("{\n\tint: 123\n\tlist: [\n\t\ttrue\n\t\tfalse\n\t\ttrue\n\t]\n}\n", stringWriter.toString());
assertThat(stringWriter.toString()).isEqualTo("""
{
\tint: 123
\tlist: [
\t\ttrue
\t\tfalse
\t\ttrue
\t]
}
"""
);
}
@Test
void read() {
ReadWriteExtension readWriteExtension = configContainer.extension(ReadWriteExtension.class).orElseThrow();
Map<String, Object> result = assertDoesNotThrow(() -> readWriteExtension.read(
new HjsonReader(new HjsonLexer(new StringReader("{\n\tint: 123\n\tlist: [\n\t\ttrue\n\t\tfalse\n\t\ttrue\n\t]\n}\n"))),
new HjsonReader(new HjsonLexer(new StringReader("""
{
\tint: 123
\tlist: [
\t\ttrue
\t\tfalse
\t\ttrue
\t]
}
"""))),
rootEntry,
readWriteExtension.createReadWriteContextExtensionsData()
));
@@ -97,7 +116,6 @@ class ReadWriteExtensionImplTest {
}
private TweedDataVisitor setupWriter(Function<Writer, TweedDataVisitor> writerFactory) {
stringWriter = new StringWriter();
return writerFactory.apply(stringWriter);
}