forked from public-mirrors/ConfigLib
Rename TypeComponent to ConfigurationElement and refactor it
This commit also introduces the term "configuration element" to refer to either a class field or record component of a configuration type.dev
parent
bb58025239
commit
eaccf30d5e
@ -0,0 +1,77 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
|
||||
/**
|
||||
* Represents an element of a serializable configuration type. The element can either be a
|
||||
* {@link Field} for configuration classes or a {@link RecordComponent} for records.
|
||||
*
|
||||
* @param <T> the type of the element
|
||||
*/
|
||||
public sealed interface ConfigurationElement<T extends AnnotatedElement>
|
||||
permits
|
||||
ConfigurationElements.FieldElement,
|
||||
ConfigurationElements.RecordComponentElement {
|
||||
/**
|
||||
* Returns the element itself.
|
||||
*
|
||||
* @return the element
|
||||
*/
|
||||
T element();
|
||||
|
||||
/**
|
||||
* Returns the name of the element.
|
||||
*
|
||||
* @return name of the element
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Returns the type of the element.
|
||||
*
|
||||
* @return type of the element
|
||||
*/
|
||||
Class<?> type();
|
||||
|
||||
/**
|
||||
* Returns the annotated type of the element.
|
||||
*
|
||||
* @return annotated type of element
|
||||
*/
|
||||
AnnotatedType annotatedType();
|
||||
|
||||
/**
|
||||
* Given an instance of the configuration type which defines this element, returns the value
|
||||
* the element is holding.
|
||||
*
|
||||
* @param elementHolder an instance of the configuration type that defines this element
|
||||
* @return value the element is holding
|
||||
* @throws IllegalArgumentException if {@code elementHolder} is not an instance of the
|
||||
* configuration type which defines this element
|
||||
*/
|
||||
Object value(Object elementHolder);
|
||||
|
||||
/**
|
||||
* Returns the configuration type that defines this element.
|
||||
*
|
||||
* @return the configuration type that defines this element
|
||||
*/
|
||||
Class<?> declaringType();
|
||||
|
||||
/**
|
||||
* Returns the annotation of the given type or null if the element is not annotated
|
||||
* with such an annotation.
|
||||
*
|
||||
* @param annotationType the type of annotation
|
||||
* @param <A> the type of annotation
|
||||
* @return the annotation or null
|
||||
* @throws NullPointerException if {@code annotationType} is null
|
||||
*/
|
||||
default <A extends Annotation> A annotation(Class<A> annotationType) {
|
||||
return element().getAnnotation(annotationType);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
|
||||
final class ConfigurationElements {
|
||||
private ConfigurationElements() {}
|
||||
|
||||
record FieldElement(Field element) implements ConfigurationElement<Field> {
|
||||
@Override
|
||||
public String name() {
|
||||
return element.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> type() {
|
||||
return element.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedType annotatedType() {
|
||||
return element.getAnnotatedType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object value(Object elementHolder) {
|
||||
return Reflect.getValue(element, elementHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> declaringType() {
|
||||
return element.getDeclaringClass();
|
||||
}
|
||||
}
|
||||
|
||||
record RecordComponentElement(RecordComponent element)
|
||||
implements ConfigurationElement<RecordComponent> {
|
||||
@Override
|
||||
public String name() {
|
||||
return element.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> type() {
|
||||
return element.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedType annotatedType() {
|
||||
return element.getAnnotatedType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object value(Object elementHolder) {
|
||||
return Reflect.getValue(element, elementHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> declaringType() {
|
||||
return element.getDeclaringRecord();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import static de.exlll.configlib.Validator.requireNonNull;
|
||||
|
||||
/**
|
||||
* Represents a component of a serializable type which can either be a {@link Field} for
|
||||
* configurations or a {@link RecordComponent} for records.
|
||||
*
|
||||
* @param <T> the type of the component
|
||||
*/
|
||||
sealed interface TypeComponent<T extends AnnotatedElement> {
|
||||
/**
|
||||
* Returns the component itself.
|
||||
*
|
||||
* @return the component
|
||||
*/
|
||||
T component();
|
||||
|
||||
/**
|
||||
* Returns the name of the component.
|
||||
*
|
||||
* @return name of the component
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Returns the type of the component.
|
||||
*
|
||||
* @return type of the component
|
||||
*/
|
||||
Class<?> type();
|
||||
|
||||
/**
|
||||
* Returns the annotated type of the component.
|
||||
*
|
||||
* @return annotated type of component
|
||||
*/
|
||||
AnnotatedType annotatedType();
|
||||
|
||||
/**
|
||||
* Returns the value the component is holding.
|
||||
*
|
||||
* @param componentHolder the holder to which this component belongs
|
||||
* @return value the component is holding
|
||||
* @throws IllegalArgumentException if {@code componentHolder} is not an instance of the type to
|
||||
* which this component belongs
|
||||
*/
|
||||
Object value(Object componentHolder);
|
||||
|
||||
/**
|
||||
* Returns the type that declares this component.
|
||||
*
|
||||
* @return the declaring type
|
||||
*/
|
||||
Class<?> declaringType();
|
||||
|
||||
/**
|
||||
* Returns the annotation of the given type or null if the component is not annotated
|
||||
* with such an annotation.
|
||||
*
|
||||
* @param annotationType the type of annotation
|
||||
* @param <A> the type of annotation
|
||||
* @return the annotation or null
|
||||
* @throws NullPointerException if {@code annotationType} is null
|
||||
*/
|
||||
default <A extends Annotation> A annotation(Class<A> annotationType) {
|
||||
return component().getAnnotation(annotationType);
|
||||
}
|
||||
|
||||
record ConfigurationField(Field component) implements TypeComponent<Field> {
|
||||
public ConfigurationField(Field component) {
|
||||
this.component = requireNonNull(component, "component");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return component.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> type() {
|
||||
return component.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedType annotatedType() {
|
||||
return component.getAnnotatedType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object value(Object componentHolder) {
|
||||
return Reflect.getValue(component, componentHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> declaringType() {
|
||||
return component.getDeclaringClass();
|
||||
}
|
||||
}
|
||||
|
||||
record ConfigurationRecordComponent(RecordComponent component)
|
||||
implements TypeComponent<RecordComponent> {
|
||||
public ConfigurationRecordComponent(RecordComponent component) {
|
||||
this.component = requireNonNull(component, "component");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return component.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedType annotatedType() {
|
||||
return component.getAnnotatedType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> type() {
|
||||
return component.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object value(Object componentHolder) {
|
||||
return Reflect.getValue(component, componentHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> declaringType() {
|
||||
return component.getDeclaringRecord();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import de.exlll.configlib.ConfigurationElements.FieldElement;
|
||||
import de.exlll.configlib.ConfigurationElements.RecordComponentElement;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
class ConfigurationElementsTest {
|
||||
|
||||
static final class FieldElementTest {
|
||||
private static final Field FIELD = C.class.getDeclaredFields()[0];
|
||||
private static final FieldElement ELEMENT = new FieldElement(FIELD);
|
||||
|
||||
static final class C {
|
||||
@Comment("")
|
||||
List<String> field = List.of("20");
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementName() {
|
||||
assertThat(ELEMENT.name(), is("field"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementType() {
|
||||
assertThat(ELEMENT.type(), equalTo(List.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementAnnotatedType() {
|
||||
assertThat(ELEMENT.annotatedType(), is(FIELD.getAnnotatedType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementValue() {
|
||||
assertThat(ELEMENT.value(new C()), is(List.of("20")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void declaringType() {
|
||||
assertThat(ELEMENT.declaringType(), equalTo(C.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotation() {
|
||||
assertThat(ELEMENT.annotation(Comment.class), notNullValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final class RecordComponentElementTest {
|
||||
private static final RecordComponent RECORD_COMPONENT = R.class.getRecordComponents()[0];
|
||||
private static final RecordComponentElement ELEMENT =
|
||||
new RecordComponentElement(RECORD_COMPONENT);
|
||||
|
||||
record R(@Comment("") Set<Integer> comp) {}
|
||||
|
||||
@Test
|
||||
void elementName() {
|
||||
assertThat(ELEMENT.name(), is("comp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementType() {
|
||||
assertThat(ELEMENT.type(), equalTo(Set.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementAnnotatedType() {
|
||||
assertThat(ELEMENT.annotatedType(), is(RECORD_COMPONENT.getAnnotatedType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void elementValue() {
|
||||
assertThat(ELEMENT.value(new R(Set.of(1))), is(Set.of(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void declaringType() {
|
||||
assertThat(ELEMENT.declaringType(), equalTo(R.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotation() {
|
||||
assertThat(ELEMENT.annotation(Comment.class), notNullValue());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import de.exlll.configlib.TypeComponent.ConfigurationField;
|
||||
import de.exlll.configlib.TypeComponent.ConfigurationRecordComponent;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
class TypeComponentTest {
|
||||
|
||||
static final class ConfigurationFieldTest {
|
||||
private static final Field FIELD = TestUtils.getField(C.class, "field");
|
||||
private static final ConfigurationField COMPONENT = new ConfigurationField(FIELD);
|
||||
|
||||
static final class C {
|
||||
@Comment("")
|
||||
List<String> field = List.of("20");
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentName() {
|
||||
assertThat(COMPONENT.name(), is("field"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentType() {
|
||||
assertThat(COMPONENT.type(), equalTo(List.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentAnnotatedType() {
|
||||
assertThat(COMPONENT.annotatedType(), is(FIELD.getAnnotatedType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentValue() {
|
||||
assertThat(COMPONENT.value(new C()), is(List.of("20")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void declaringType() {
|
||||
assertThat(COMPONENT.declaringType(), equalTo(C.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotation() {
|
||||
assertThat(COMPONENT.annotation(Comment.class), notNullValue());
|
||||
}
|
||||
}
|
||||
|
||||
static final class ConfigurationRecordComponentTest {
|
||||
private static final RecordComponent RECORD_COMPONENT = R.class.getRecordComponents()[0];
|
||||
private static final ConfigurationRecordComponent COMPONENT =
|
||||
new ConfigurationRecordComponent(RECORD_COMPONENT);
|
||||
|
||||
record R(@Comment("") Set<Integer> comp) {}
|
||||
|
||||
@Test
|
||||
void componentName() {
|
||||
assertThat(COMPONENT.name(), is("comp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentType() {
|
||||
assertThat(COMPONENT.type(), equalTo(Set.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentAnnotatedType() {
|
||||
assertThat(COMPONENT.annotatedType(), is(RECORD_COMPONENT.getAnnotatedType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void componentValue() {
|
||||
assertThat(COMPONENT.value(new R(Set.of(1))), is(Set.of(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void declaringType() {
|
||||
assertThat(COMPONENT.declaringType(), equalTo(R.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotation() {
|
||||
assertThat(COMPONENT.annotation(Comment.class), notNullValue());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue