[weaver-pojo] Introduce pojo weaver post processors

This commit is contained in:
2024-12-09 23:35:26 +01:00
parent aaf05d1a33
commit f10a23a0f5
27 changed files with 1078 additions and 97 deletions

View File

@@ -7,6 +7,8 @@ import de.siphalor.tweed5.dataapi.api.TweedDataReader;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
public interface ReadWriteExtension extends TweedExtension {
void setEntryReaderWriterDefinition(ConfigEntry<?> entry, EntryReaderWriterDefinition readerWriterDefinition);
ReadWriteContextExtensionsData createReadWriteContextExtensionsData();
<T> T read(TweedDataReader reader, ConfigEntry<T> entry, ReadWriteContextExtensionsData contextExtensionsData) throws TweedEntryReadException;

View File

@@ -1,6 +1,5 @@
package de.siphalor.tweed5.data.extension.api;
import de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriter;
import lombok.RequiredArgsConstructor;
/**
@@ -13,14 +12,11 @@ public interface TweedReaderWriterProvider {
/**
* The context where reader and writer factories may be registered.<br />
* The reader and writer ids must be globally unique. It is therefore recommended to scope custom reader and writer ids in your own namespace (e.g. "de.siphalor.custom.blub")
* Ids may consist of alphanumeric characters and dots.
*/
interface ProviderContext {
void registerReaderFactory(String id, ReaderWriterFactory<? extends TweedEntryReader<?, ?>> readerFactory);
void registerWriterFactory(String id, ReaderWriterFactory<? extends TweedEntryWriter<?, ?>> writerFactory);
default void registerReaderWriterFactory(String id, ReaderWriterFactory<? extends TweedEntryReaderWriter<?, ?>> readerWriterFactory) {
registerReaderFactory(id, readerWriterFactory);
registerWriterFactory(id, readerWriterFactory);
}
void registerReaderFactory(String id, ReaderWriterFactory<TweedEntryReader<?, ?>> readerFactory);
void registerWriterFactory(String id, ReaderWriterFactory<TweedEntryWriter<?, ?>> writerFactory);
}
/**

View File

@@ -3,6 +3,8 @@ package de.siphalor.tweed5.data.extension.api.readwrite;
import de.siphalor.tweed5.core.api.entry.CoherentCollectionConfigEntry;
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.data.extension.api.TweedEntryReader;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@@ -43,8 +45,12 @@ public class TweedEntryReaderWriters {
return TweedEntryReaderWriterImpls.STRING_READER_WRITER;
}
public static <T, C extends ConfigEntry<T>> TweedEntryReaderWriter<T, C> nullableReaderWriter(TweedEntryReaderWriter<T, C> delegate) {
return new TweedEntryReaderWriterImpls.NullableReaderWriter<>(delegate);
public static <T, C extends ConfigEntry<T>> TweedEntryReader<T, C> nullableReader(TweedEntryReader<T, C> delegate) {
return new TweedEntryReaderWriterImpls.NullableReader<>(delegate);
}
public static <T, C extends ConfigEntry<T>> TweedEntryWriter<T, C> nullableWriter(TweedEntryWriter<T, C> delegate) {
return new TweedEntryReaderWriterImpls.NullableWriter<>(delegate);
}
public static <T, C extends Collection<T>> TweedEntryReaderWriter<C, CoherentCollectionConfigEntry<T, C>> coherentCollectionReaderWriter() {

View File

@@ -1,6 +1,8 @@
package de.siphalor.tweed5.data.extension.impl;
import com.google.auto.service.AutoService;
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 static de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriters.*;
@@ -9,22 +11,48 @@ import static de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWr
public class DefaultTweedEntryReaderWriterImplsProvider implements TweedReaderWriterProvider {
@Override
public void provideReaderWriters(ProviderContext context) {
context.registerReaderWriterFactory("boolean", new StaticReaderWriterFactory<>(booleanReaderWriter()));
context.registerReaderWriterFactory("byte", new StaticReaderWriterFactory<>(byteReaderWriter()));
context.registerReaderWriterFactory("short", new StaticReaderWriterFactory<>(shortReaderWriter()));
context.registerReaderWriterFactory("int", new StaticReaderWriterFactory<>(intReaderWriter()));
context.registerReaderWriterFactory("long", new StaticReaderWriterFactory<>(longReaderWriter()));
context.registerReaderWriterFactory("float", new StaticReaderWriterFactory<>(floatReaderWriter()));
context.registerReaderWriterFactory("double", new StaticReaderWriterFactory<>(doubleReaderWriter()));
context.registerReaderWriterFactory("string", new StaticReaderWriterFactory<>(stringReaderWriter()));
context.registerReaderWriterFactory("coherent_collection", new StaticReaderWriterFactory<>(coherentCollectionReaderWriter()));
context.registerReaderWriterFactory("compound", new StaticReaderWriterFactory<>(compoundReaderWriter()));
StaticReaderWriterFactory<TweedEntryReader<?, ?>> booleanReaderFactory = new StaticReaderWriterFactory<>(booleanReaderWriter());
StaticReaderWriterFactory<TweedEntryWriter<?, ?>> booleanWriterFactory = new StaticReaderWriterFactory<>(booleanReaderWriter());
context.registerReaderFactory("tweed5.bool", booleanReaderFactory);
context.registerReaderFactory("tweed5.boolean", booleanReaderFactory);
context.registerWriterFactory("tweed5.bool", booleanWriterFactory);
context.registerWriterFactory("tweed5.boolean", booleanWriterFactory);
context.registerReaderFactory("tweed5.byte", new StaticReaderWriterFactory<>(byteReaderWriter()));
context.registerWriterFactory("tweed5.byte", new StaticReaderWriterFactory<>(byteReaderWriter()));
context.registerReaderFactory("tweed5.short", new StaticReaderWriterFactory<>(shortReaderWriter()));
context.registerWriterFactory("tweed5.short", new StaticReaderWriterFactory<>(shortReaderWriter()));
StaticReaderWriterFactory<TweedEntryReader<?, ?>> integerReaderFactory =
new StaticReaderWriterFactory<>(intReaderWriter());
StaticReaderWriterFactory<TweedEntryWriter<?, ?>> integerWriterFactory =
new StaticReaderWriterFactory<>(intReaderWriter());
context.registerReaderFactory("tweed5.int", integerReaderFactory);
context.registerReaderFactory("tweed5.integer", integerReaderFactory);
context.registerWriterFactory("tweed5.int", integerWriterFactory);
context.registerWriterFactory("tweed5.integer", integerWriterFactory);
context.registerReaderFactory("tweed5.long", new StaticReaderWriterFactory<>(longReaderWriter()));
context.registerWriterFactory("tweed5.long", new StaticReaderWriterFactory<>(longReaderWriter()));
context.registerReaderFactory("tweed5.float", new StaticReaderWriterFactory<>(floatReaderWriter()));
context.registerWriterFactory("tweed5.float", new StaticReaderWriterFactory<>(floatReaderWriter()));
context.registerReaderFactory("tweed5.double", new StaticReaderWriterFactory<>(doubleReaderWriter()));
context.registerWriterFactory("tweed5.double", new StaticReaderWriterFactory<>(doubleReaderWriter()));
context.registerReaderFactory("tweed5.string", new StaticReaderWriterFactory<>(stringReaderWriter()));
context.registerWriterFactory("tweed5.string", new StaticReaderWriterFactory<>(stringReaderWriter()));
context.registerReaderFactory("tweed5.collection.coherent", new StaticReaderWriterFactory<>(coherentCollectionReaderWriter()));
context.registerWriterFactory("tweed5.collection.coherent", new StaticReaderWriterFactory<>(coherentCollectionReaderWriter()));
context.registerReaderFactory("tweed5.compound", new StaticReaderWriterFactory<>(compoundReaderWriter()));
context.registerWriterFactory("tweed5.compound", new StaticReaderWriterFactory<>(compoundReaderWriter()));
context.registerReaderWriterFactory("nullable", delegateReaderWriters -> {
if (delegateReaderWriters.length != 1) {
throw new IllegalArgumentException("Nullable reader writer requires a single delegate argument, got " + delegateReaderWriters.length);
context.registerReaderFactory("tweed5.nullable", delegateReaders -> {
if (delegateReaders.length != 1) {
throw new IllegalArgumentException("Nullable reader requires a single delegate argument, got " + delegateReaders.length);
}
return nullableReaderWriter(delegateReaderWriters[0]);
return nullableReader(delegateReaders[0]);
});
context.registerWriterFactory("tweed5.nullable", delegateWriters -> {
if (delegateWriters.length != 1) {
throw new IllegalArgumentException("Nullable writer requires a single delegate argument, got " + delegateWriters.length);
}
return nullableWriter(delegateWriters[0]);
});
}
}

View File

@@ -31,6 +31,7 @@ import java.util.Map;
@AutoService(ReadWriteExtension.class)
public class ReadWriteExtensionImpl implements ReadWriteExtension {
private RegisteredExtensionData<EntryExtensionsData, EntryReaderWriterDefinition> readerWriterDefinitionExtension;
private RegisteredExtensionData<EntryExtensionsData, ReadWriteEntryDataExtension> readWriteEntryDataExtension;
private DefaultMiddlewareContainer<TweedEntryReader<?, ?>> entryReaderMiddlewareContainer;
private DefaultMiddlewareContainer<TweedEntryWriter<?, ?>> entryWriterMiddlewareContainer;
@@ -44,8 +45,8 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
@Override
public void setup(TweedExtensionSetupContext context) {
readerWriterDefinitionExtension = context.registerEntryExtensionData(EntryReaderWriterDefinition.class);
readWriteEntryDataExtension = context.registerEntryExtensionData(ReadWriteEntryDataExtension.class);
context.registerEntryExtensionData(EntryReaderWriterDefinition.class);
Collection<TweedExtension> extensions = context.configContainer().extensions();
@@ -120,6 +121,11 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
));
}
@Override
public void setEntryReaderWriterDefinition(ConfigEntry<?> entry, EntryReaderWriterDefinition readerWriterDefinition) {
readerWriterDefinitionExtension.set(entry.extensionsData(), readerWriterDefinition);
}
@Override
public ReadWriteContextExtensionsData createReadWriteContextExtensionsData() {
try {

View File

@@ -32,16 +32,22 @@ public class TweedEntryReaderWriterImpls {
public static final TweedEntryReaderWriter<Object, ConfigEntry<Object>> NOOP_READER_WRITER = new NoopReaderWriter();
@RequiredArgsConstructor
public static class NullableReaderWriter<T, C extends ConfigEntry<T>> implements TweedEntryReaderWriter<T, C> {
private final TweedEntryReaderWriter<T, C> delegate;
public static class NullableReader<T, C extends ConfigEntry<T>> implements TweedEntryReader<T, C> {
private final TweedEntryReader<T, C> delegate;
@Override
public T read(TweedDataReader reader, C entry, TweedReadContext context) throws TweedEntryReadException, TweedDataReadException {
if (reader.peekToken().isNull()) {
reader.readToken();
return null;
}
return delegate.read(reader, entry, context);
}
}
@RequiredArgsConstructor
public static class NullableWriter<T, C extends ConfigEntry<T>> implements TweedEntryWriter<T, C> {
private final TweedEntryWriter<T, C> delegate;
@Override
public void write(TweedDataVisitor writer, T value, C entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException {
@@ -137,9 +143,10 @@ public class TweedEntryReaderWriterImpls {
//noinspection unchecked
ConfigEntry<Object> subEntry = (ConfigEntry<Object>) compoundEntries.get(key);
TweedEntryReader<Object, ConfigEntry<Object>> subEntryReaderChain = ReadWriteExtensionImpl.getReaderChain(subEntry);
Object subEntryValue = subEntryReaderChain.read(reader, subEntry, context);
entry.set(compoundValue, key, subEntryValue);
if (subEntryReaderChain != null) {
Object subEntryValue = subEntryReaderChain.read(reader, subEntry, context);
entry.set(compoundValue, key, subEntryValue);
}
} else {
throw new TweedEntryReadException("Unexpected token " + token + ": Expected map key or map end");
}
@@ -159,10 +166,12 @@ public class TweedEntryReaderWriterImpls {
String key = e.getKey();
ConfigEntry<Object> subEntry = e.getValue();
writer.visitMapEntryKey(key);
TweedEntryWriter<Object, ConfigEntry<Object>> subEntryWriterChain = ReadWriteExtensionImpl.getWriterChain(subEntry);
subEntryWriterChain.write(writer, entry.get(value, key), subEntry, context);
if (subEntryWriterChain != null) {
writer.visitMapEntryKey(key);
subEntryWriterChain.write(writer, entry.get(value, key), subEntry, context);
}
}
writer.visitMapEnd();