[attributes] Introduce attributes extensions
This commit is contained in:
11
tweed5-weaver-pojo-attributes-extension/build.gradle.kts
Normal file
11
tweed5-weaver-pojo-attributes-extension/build.gradle.kts
Normal file
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id("de.siphalor.tweed5.base-module")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":tweed5-weaver-pojo"))
|
||||
api(project(":tweed5-attributes-extension"))
|
||||
|
||||
testImplementation(project(":tweed5-default-extensions"))
|
||||
testImplementation(project(":tweed5-serde-hjson"))
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package de.siphalor.tweed5.weaver.pojoext.attributes.api;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE})
|
||||
@Repeatable(Attributes.class)
|
||||
public @interface Attribute {
|
||||
String key();
|
||||
String[] values();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package de.siphalor.tweed5.weaver.pojoext.attributes.api;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE})
|
||||
@Repeatable(AttributeDefaults.class)
|
||||
public @interface AttributeDefault {
|
||||
String key();
|
||||
String[] defaultValue();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package de.siphalor.tweed5.weaver.pojoext.attributes.api;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE})
|
||||
public @interface AttributeDefaults {
|
||||
AttributeDefault[] value();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package de.siphalor.tweed5.weaver.pojoext.attributes.api;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE})
|
||||
public @interface Attributes {
|
||||
Attribute[] value();
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package de.siphalor.tweed5.weaver.pojoext.attributes.api;
|
||||
|
||||
import de.siphalor.tweed5.attributesextension.api.AttributesExtension;
|
||||
import de.siphalor.tweed5.core.api.container.ConfigContainer;
|
||||
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
|
||||
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 lombok.var;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class AttributesPojoWeavingProcessor implements TweedPojoWeavingExtension {
|
||||
AttributesExtension attributesExtension;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public AttributesPojoWeavingProcessor(ConfigContainer<?> configContainer) {
|
||||
attributesExtension = configContainer.extension(AttributesExtension.class)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"You must register a " + AttributesExtension.class.getSimpleName()
|
||||
+ " to use the " + getClass().getSimpleName()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(SetupContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void afterWeaveEntry(ActualType<T> valueType, ConfigEntry<T> configEntry, WeavingContext context) {
|
||||
var attributeAnnotations = context.annotations().getAnnotationsByType(Attribute.class);
|
||||
var attributes = collectAttributesFromAnnotations(attributeAnnotations, Attribute::key, Attribute::values);
|
||||
attributes.forEach((key, values) -> attributesExtension.setAttribute(configEntry, key, values));
|
||||
|
||||
var attributeDefaultAnnotations = context.annotations().getAnnotationsByType(AttributeDefault.class);
|
||||
var attributeDefaults = collectAttributesFromAnnotations(
|
||||
attributeDefaultAnnotations,
|
||||
AttributeDefault::key,
|
||||
AttributeDefault::defaultValue
|
||||
);
|
||||
attributeDefaults.forEach((key, values) -> attributesExtension.setAttributeDefault(configEntry, key, values));
|
||||
}
|
||||
|
||||
private <T> Map<String, List<String>> collectAttributesFromAnnotations(
|
||||
T[] annotations,
|
||||
Function<T, String> keyGetter,
|
||||
Function<T, String[]> valueGetter
|
||||
) {
|
||||
if (annotations.length == 0) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, List<String>> attributes;
|
||||
if (annotations.length == 1) {
|
||||
return Collections.singletonMap(
|
||||
keyGetter.apply(annotations[0]),
|
||||
Arrays.asList(valueGetter.apply(annotations[0]))
|
||||
);
|
||||
} else if (annotations.length <= 12) {
|
||||
attributes = new TreeMap<>();
|
||||
} else {
|
||||
attributes = new HashMap<>();
|
||||
}
|
||||
|
||||
for (T annotation : annotations) {
|
||||
attributes.computeIfAbsent(keyGetter.apply(annotation), k -> new ArrayList<>())
|
||||
.addAll(Arrays.asList(valueGetter.apply(annotation)));
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
@NullMarked
|
||||
package de.siphalor.tweed5.weaver.pojoext.attributes.api;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
Reference in New Issue
Block a user