[*] Remove config entry sealing

This commit is contained in:
2025-06-10 00:46:03 +02:00
parent a6900e673a
commit 2096ae540c
28 changed files with 201 additions and 163 deletions

View File

@@ -1,6 +1,7 @@
package de.siphalor.tweed5.weaver.pojo.api.entry;
import de.siphalor.tweed5.construct.api.TweedConstructFactory;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.CollectionConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
@@ -17,9 +18,9 @@ public interface WeavableCollectionConfigEntry<E, T extends Collection<E>> exten
@SuppressWarnings("rawtypes")
TweedConstructFactory<WeavableCollectionConfigEntry> FACTORY =
TweedConstructFactory.builder(WeavableCollectionConfigEntry.class)
.typedArg(ConfigContainer.class)
.typedArg(Class.class) // value class
.typedArg(IntFunction.class) // value class constructor with capacity
.namedArg("elementEntry", ConfigEntry.class)
.build();
void elementEntry(ConfigEntry<E> elementEntry);
}

View File

@@ -1,6 +1,7 @@
package de.siphalor.tweed5.weaver.pojo.api.entry;
import de.siphalor.tweed5.construct.api.TweedConstructFactory;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import lombok.RequiredArgsConstructor;
@@ -8,6 +9,8 @@ import lombok.Value;
import org.jspecify.annotations.Nullable;
import java.lang.invoke.MethodHandle;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
/**
@@ -19,12 +22,12 @@ public interface WeavableCompoundConfigEntry<T> extends CompoundConfigEntry<T> {
@SuppressWarnings("rawtypes")
TweedConstructFactory<WeavableCompoundConfigEntry> FACTORY =
TweedConstructFactory.builder(WeavableCompoundConfigEntry.class)
.typedArg(ConfigContainer.class)
.typedArg(Class.class) // the value class
.typedArg(Supplier.class) // constructor for the value class
.namedArg("subEntries", List.class) // List of SubEntry's
.build();
void registerSubEntry(SubEntry subEntry);
@Value
@RequiredArgsConstructor
class SubEntry {

View File

@@ -1,5 +1,6 @@
package de.siphalor.tweed5.weaver.pojo.api.weaving;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.extension.RegisteredExtensionData;
import de.siphalor.tweed5.typeutils.api.type.ActualType;
@@ -44,22 +45,21 @@ public class CollectionPojoWeaver implements TweedPojoWeaver {
IntFunction<Collection<Object>> constructor = getCollectionConstructor(valueType);
WeavableCollectionConfigEntry configEntry = WeavableCollectionConfigEntry.FACTORY
.construct(Objects.requireNonNull(weavingConfig.collectionEntryClass()))
.typedArg(valueType.declaredType())
.typedArg(IntFunction.class, constructor)
.finish();
configEntry.elementEntry(context.weaveEntry(
ConfigEntry<?> elementEntry = context.weaveEntry(
collectionTypeParams.get(0),
context.subContextBuilder("element")
.annotations(collectionTypeParams.get(0))
.extensionsData(newExtensionsData)
.build()
));
configEntry.seal(context.configContainer());
);
return configEntry;
return WeavableCollectionConfigEntry.FACTORY
.construct(Objects.requireNonNull(weavingConfig.collectionEntryClass()))
.typedArg(ConfigContainer.class, context.configContainer())
.typedArg(valueType.declaredType())
.typedArg(IntFunction.class, constructor)
.namedArg("elementEntry", elementEntry)
.finish();
} catch (Exception e) {
throw new PojoWeavingException("Exception occurred trying to weave collection for class " + valueType, e);
}

View File

@@ -1,5 +1,6 @@
package de.siphalor.tweed5.weaver.pojo.api.weaving;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.extension.RegisteredExtensionData;
import de.siphalor.tweed5.namingformat.api.NamingFormat;
@@ -20,8 +21,10 @@ import org.jspecify.annotations.Nullable;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* A weaver that weaves classes with the {@link CompoundWeaving} annotation as compound entries.
@@ -54,18 +57,12 @@ public class CompoundPojoWeaver implements TweedPojoWeaver {
PojoClassIntrospector introspector = PojoClassIntrospector.forClass(valueType.declaredType());
WeavableCompoundConfigEntry<T> compoundEntry = instantiateCompoundEntry(introspector, weavingConfig);
List<WeavableCompoundConfigEntry.SubEntry> subEntries = introspector.properties().values().stream()
.filter(this::shouldIncludeCompoundPropertyInWeaving)
.map(property -> weaveCompoundSubEntry(property, newExtensionsData, context))
.collect(Collectors.toList());
Map<String, PojoClassIntrospector.Property> properties = introspector.properties();
properties.forEach((name, property) -> {
if (shouldIncludeCompoundPropertyInWeaving(property)) {
compoundEntry.registerSubEntry(weaveCompoundSubEntry(property, newExtensionsData, context));
}
});
compoundEntry.seal(context.configContainer());
return compoundEntry;
return instantiateCompoundEntry(introspector, weavingConfig, subEntries, context);
} catch (Exception e) {
throw new PojoWeavingException("Exception occurred trying to weave compound for class " + valueType, e);
}
@@ -109,7 +106,9 @@ public class CompoundPojoWeaver implements TweedPojoWeaver {
@SuppressWarnings("unchecked")
private <C> WeavableCompoundConfigEntry<C> instantiateCompoundEntry(
PojoClassIntrospector classIntrospector,
CompoundWeavingConfig weavingConfig
CompoundWeavingConfig weavingConfig,
List<WeavableCompoundConfigEntry.SubEntry> subEntries,
WeavingContext weavingContext
) {
MethodHandle valueConstructorHandle = classIntrospector.noArgsConstructor();
if (valueConstructorHandle == null) {
@@ -131,8 +130,10 @@ public class CompoundPojoWeaver implements TweedPojoWeaver {
: StaticPojoCompoundConfigEntry.class
);
return WeavableCompoundConfigEntry.FACTORY.construct(weavableEntryClass)
.typedArg(ConfigContainer.class, weavingContext.configContainer())
.typedArg(classIntrospector.type())
.typedArg(Supplier.class, valueConstructor)
.namedArg("subEntries", subEntries)
.finish();
}

View File

@@ -12,8 +12,6 @@ public class TrivialPojoWeaver implements TweedPojoWeaver {
@Override
public <T> ConfigEntry<T> weaveEntry(ActualType<T> valueType, WeavingContext context) {
SimpleConfigEntryImpl<T> entry = new SimpleConfigEntryImpl<>(valueType.declaredType());
entry.seal(context.configContainer());
return entry;
return new SimpleConfigEntryImpl<>(context.configContainer(), valueType.declaredType());
}
}

View File

@@ -8,8 +8,7 @@ import org.jspecify.annotations.Nullable;
public interface TweedPojoWeavingFunction {
/**
* Weaves a {@link ConfigEntry} for the given value class and context.
* The returned config entry must be sealed.
* @return The resulting, sealed config entry or {@code null}, if the weaving function is not applicable to the given parameters.
* @return The resulting config entry or {@code null}, if the weaving function is not applicable to the given parameters.
*/
<T> @Nullable ConfigEntry<T> weaveEntry(ActualType<T> valueType, WeavingContext context);
@@ -19,7 +18,7 @@ public interface TweedPojoWeavingFunction {
* {@inheritDoc}
* <br />
* The function must ensure that the resulting entry is not null, e.g., by trowing a {@link RuntimeException}.
* @return The resulting, sealed config entry.
* @return The resulting config entry.
* @throws RuntimeException when a valid config entry could not be resolved.
*/
@Override

View File

@@ -1,5 +1,7 @@
package de.siphalor.tweed5.weaver.pojo.impl.entry;
import de.siphalor.tweed5.construct.api.ConstructParameter;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.BaseConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntryValueVisitor;
@@ -19,15 +21,16 @@ import java.util.function.IntFunction;
@ToString(callSuper = true)
public class CollectionConfigEntryImpl<E, T extends Collection<E>> extends BaseConfigEntry<T> implements WeavableCollectionConfigEntry<E, T> {
private final IntFunction<T> constructor;
private @Nullable ConfigEntry<E> elementEntry;
private final @Nullable ConfigEntry<E> elementEntry;
public CollectionConfigEntryImpl(@NotNull Class<T> valueClass, IntFunction<T> constructor) {
super(valueClass);
public CollectionConfigEntryImpl(
ConfigContainer<?> configContainer,
Class<T> valueClass,
IntFunction<T> constructor,
@ConstructParameter(name = "elementEntry") ConfigEntry<E> elementEntry
) {
super(configContainer, valueClass);
this.constructor = constructor;
}
@Override
public void elementEntry(ConfigEntry<E> elementEntry) {
this.elementEntry = elementEntry;
}

View File

@@ -1,5 +1,7 @@
package de.siphalor.tweed5.weaver.pojo.impl.entry;
import de.siphalor.tweed5.construct.api.ConstructParameter;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.BaseConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntryValueVisitor;
@@ -8,22 +10,32 @@ import de.siphalor.tweed5.weaver.pojo.api.entry.WeavableCompoundConfigEntry;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class StaticPojoCompoundConfigEntry<T> extends BaseConfigEntry<T> implements WeavableCompoundConfigEntry<T> {
private final Supplier<T> noArgsConstructor;
private final Map<String, SubEntry> subEntries = new LinkedHashMap<>();
private final Map<String, ConfigEntry<?>> subConfigEntries = new LinkedHashMap<>();
private final Map<String, SubEntry> subEntries;
private final Map<String, ConfigEntry<?>> subConfigEntries;
public StaticPojoCompoundConfigEntry(Class<T> valueClass, Supplier<T> noArgsConstructor) {
super(valueClass);
public StaticPojoCompoundConfigEntry(
ConfigContainer<?> configContainer,
Class<T> valueClass,
Supplier<T> noArgsConstructor,
@ConstructParameter(name = "subEntries") List<SubEntry> subEntries
) {
super(configContainer, valueClass);
this.noArgsConstructor = noArgsConstructor;
this.subEntries = new LinkedHashMap<>(subEntries.size(), 1);
this.subConfigEntries = new LinkedHashMap<>(subEntries.size(), 1);
for (SubEntry subEntry : subEntries) {
this.subEntries.put(subEntry.name(), subEntry);
this.subConfigEntries.put(subEntry.name(), subEntry.configEntry());
}
}
public void registerSubEntry(SubEntry subEntry) {
requireUnsealed();
subEntries.put(subEntry.name(), subEntry);
subConfigEntries.put(subEntry.name(), subEntry.configEntry());
}

View File

@@ -82,7 +82,7 @@ public class TweedPojoWeaverBootstrapper<T> {
WeavingContext weavingContext = createWeavingContext();
ConfigEntry<T> rootEntry = this.weaveEntry(ActualType.ofClass(pojoClass), weavingContext);
configContainer.attachAndSealTree(rootEntry);
configContainer.attachTree(rootEntry);
return configContainer;
}
@@ -140,9 +140,6 @@ public class TweedPojoWeaverBootstrapper<T> {
for (TweedPojoWeaver weaver : weavers) {
ConfigEntry<U> configEntry = weaver.weaveEntry(dataClass, context);
if (configEntry != null) {
if (!configEntry.sealed()) {
configEntry.seal(configContainer);
}
applyPostProcessors(configEntry, context);
return configEntry;
}

View File

@@ -42,7 +42,7 @@ class CompoundPojoWeaverTest {
if (entry != null) {
return entry;
} else {
return new SimpleConfigEntryImpl<>(valueType.declaredType());
return new SimpleConfigEntryImpl<>(context.configContainer(), valueType.declaredType());
}
}
}, mock(ConfigContainer.class))

View File

@@ -36,8 +36,6 @@ class TweedPojoWeaverBootstrapperTest {
.hasSize(5)
));
configContainer.initialize();
assertThat(configContainer.extensions())
.satisfiesOnlyOnce(extension -> assertThat(extension).isInstanceOf(DummyExtension.class))
.hasSize(1);