[weaver-pojo*] Refactor POJO weaver extensibility

This commit is contained in:
2025-06-21 15:27:15 +02:00
parent 95b2cbc7dd
commit dc318722d3
26 changed files with 414 additions and 203 deletions

View File

@@ -1,13 +1,15 @@
package de.siphalor.tweed5.weaver.pojoext.serde.api;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.data.extension.api.ReadWriteExtension;
import de.siphalor.tweed5.data.extension.api.TweedEntryReader;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.data.extension.api.TweedReaderWriterProvider;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import de.siphalor.tweed5.typeutils.api.type.ActualType;
import de.siphalor.tweed5.weaver.pojo.api.weaving.TweedPojoWeavingExtension;
import de.siphalor.tweed5.weaver.pojo.api.weaving.WeavingContext;
import de.siphalor.tweed5.weaver.pojo.api.weaving.postprocess.TweedPojoWeavingPostProcessor;
import de.siphalor.tweed5.weaver.pojoext.serde.impl.SerdePojoReaderWriterSpec;
import lombok.extern.apachecommons.CommonsLog;
import org.jspecify.annotations.Nullable;
@@ -18,11 +20,21 @@ import java.lang.reflect.InvocationTargetException;
import java.util.*;
@CommonsLog
public class ReadWritePojoPostProcessor implements TweedPojoWeavingPostProcessor {
public class ReadWritePojoWeavingProcessor implements TweedPojoWeavingExtension {
private final Map<String, TweedReaderWriterProvider.ReaderWriterFactory<TweedEntryReader<?, ?>>> readerFactories = new HashMap<>();
private final Map<String, TweedReaderWriterProvider.ReaderWriterFactory<TweedEntryWriter<?, ?>>> writerFactories = new HashMap<>();
private final ReadWriteExtension readWriteExtension;
public ReadWritePojoPostProcessor() {
public ReadWritePojoWeavingProcessor(ConfigContainer<?> configContainer) {
this.readWriteExtension = configContainer.extension(ReadWriteExtension.class)
.orElseThrow(() -> new IllegalStateException(
"You must register a " + ReadWriteExtension.class.getSimpleName()
+ " to use the " + getClass().getSimpleName()
));
}
@Override
public void setup(SetupContext context) {
loadProviders();
}
@@ -63,18 +75,12 @@ public class ReadWritePojoPostProcessor implements TweedPojoWeavingPostProcessor
}
@Override
public void apply(ConfigEntry<?> configEntry, WeavingContext context) {
public <T> void afterWeaveEntry(ActualType<T> valueType, ConfigEntry<T> configEntry, WeavingContext context) {
EntryReadWriteConfig entryConfig = context.annotations().getAnnotation(EntryReadWriteConfig.class);
if (entryConfig == null) {
return;
}
ReadWriteExtension readWriteExtension = context.configContainer().extension(ReadWriteExtension.class).orElse(null);
if (readWriteExtension == null && log.isErrorEnabled()) {
log.error("You must not use " + getClass().getName() + " without the " + ReadWriteExtension.class.getName());
return;
}
//noinspection rawtypes,unchecked
readWriteExtension.setEntryReaderWriter(
(ConfigEntry) configEntry,

View File

@@ -1,4 +1,4 @@
package de.siphalor.tweed5.weaver.pojoext.serde;
package de.siphalor.tweed5.weaver.pojoext.serde.api;
import com.google.auto.service.AutoService;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
@@ -10,11 +10,12 @@ import de.siphalor.tweed5.data.hjson.HjsonWriter;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.weaver.pojo.api.annotation.CompoundWeaving;
import de.siphalor.tweed5.weaver.pojo.api.annotation.DefaultWeavingExtensions;
import de.siphalor.tweed5.weaver.pojo.api.annotation.PojoWeaving;
import de.siphalor.tweed5.weaver.pojo.api.annotation.PojoWeavingExtension;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojoext.serde.api.EntryReadWriteConfig;
import de.siphalor.tweed5.weaver.pojoext.serde.api.ReadWritePojoPostProcessor;
import lombok.*;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import java.io.StringReader;
@@ -22,12 +23,13 @@ import java.io.StringWriter;
import static org.assertj.core.api.Assertions.assertThat;
class WeaverPojoSerdeExtensionTest {
class ReadWritePojoWeavingProcessorTest {
@Test
@SneakyThrows
void testAnnotated() {
TweedPojoWeaverBootstrapper<AnnotatedConfig> weaverBootstrapper = TweedPojoWeaverBootstrapper.create(AnnotatedConfig.class);
TweedPojoWeaverBootstrapper<AnnotatedConfig> weaverBootstrapper = TweedPojoWeaverBootstrapper.create(
AnnotatedConfig.class);
ConfigContainer<AnnotatedConfig> configContainer = weaverBootstrapper.weave();
configContainer.initialize();
@@ -38,12 +40,27 @@ class WeaverPojoSerdeExtensionTest {
StringWriter stringWriter = new StringWriter();
HjsonWriter hjsonWriter = new HjsonWriter(stringWriter, new HjsonWriter.Options());
readWriteExtension.write(hjsonWriter, config, configContainer.rootEntry(), readWriteExtension.createReadWriteContextExtensionsData());
readWriteExtension.write(
hjsonWriter,
config,
configContainer.rootEntry(),
readWriteExtension.createReadWriteContextExtensionsData()
);
assertThat(stringWriter).hasToString("{\n\tanInt: 123\n\ttext: test\n\ttest: my cool custom writer\n}\n");
assertThat(stringWriter).hasToString("""
{
\tanInt: 123
\ttext: test
\ttest: my cool custom writer
}
""");
HjsonReader reader = new HjsonReader(new HjsonLexer(new StringReader(
"{\n\tanInt: 987\n\ttext: abdef\n\ttest: { inner: 29 }\n}"
HjsonReader reader = new HjsonReader(new HjsonLexer(new StringReader("""
{
\tanInt: 987
\ttext: abdef
\ttest: { inner: 29 }
}"""
)));
assertThat(readWriteExtension.read(
reader,
@@ -59,10 +76,10 @@ class WeaverPojoSerdeExtensionTest {
context.registerWriterFactory("tweed5.test.dummy", delegates -> new TweedEntryWriter<Object, @NonNull ConfigEntry<Object>>() {
@Override
public void write(
@NonNull TweedDataVisitor writer,
Object value,
TweedDataVisitor writer,
@Nullable Object value,
ConfigEntry<Object> entry,
@NonNull TweedWriteContext context
TweedWriteContext context
) throws TweedDataWriteException {
writer.visitString("my cool custom writer");
}
@@ -70,9 +87,12 @@ class WeaverPojoSerdeExtensionTest {
}
}
@PojoWeaving(extensions = ReadWriteExtension.class, postProcessors = ReadWritePojoPostProcessor.class)
@PojoWeaving(extensions = ReadWriteExtension.class)
@DefaultWeavingExtensions
@PojoWeavingExtension(de.siphalor.tweed5.weaver.pojoext.serde.api.ReadWritePojoWeavingProcessor.class)
@CompoundWeaving
@EntryReadWriteConfig("tweed5.compound")
// lombok
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode

View File

@@ -1,6 +1,7 @@
package de.siphalor.tweed5.weaver.pojoext.serde.impl;
import lombok.SneakyThrows;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
@@ -52,7 +53,7 @@ class SerdePojoReaderWriterSpecTest {
"abc..def;5;.",
})
@SneakyThrows
void parseError(String input, int index, String codePoint) {
void parseError(String input, int index, @Nullable String codePoint) {
assertThatThrownBy(() -> SerdePojoReaderWriterSpec.parse(input))
.asInstanceOf(type(SerdePojoReaderWriterSpec.ParseException.class))
.isInstanceOf(SerdePojoReaderWriterSpec.ParseException.class)
@@ -62,4 +63,4 @@ class SerdePojoReaderWriterSpecTest {
.isEqualTo(codePoint == null ? -1 : codePoint.codePointAt(0))
);
}
}
}