improvements, more renaming and a textfix

This commit is contained in:
Shautvast 2023-05-25 16:43:09 +02:00
parent e1530d076c
commit bce8a4bcf5
16 changed files with 97 additions and 99 deletions

View file

@ -2,9 +2,8 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger;
class BigDecimalHandler extends PrimitiveType<BigDecimal> { class BigDecimalHandler extends PrimitiveTypeHandler<BigDecimal> {
public BigDecimalHandler(MethodHandle getter, MethodHandle setter) { public BigDecimalHandler(MethodHandle getter, MethodHandle setter) {
super(BigDecimal.class, getter, setter); super(BigDecimal.class, getter, setter);
} }

View file

@ -3,7 +3,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.math.BigInteger; import java.math.BigInteger;
class BigIntegerHandler extends PrimitiveType<BigInteger> { class BigIntegerHandler extends PrimitiveTypeHandler<BigInteger> {
public BigIntegerHandler(MethodHandle getter, MethodHandle setter) { public BigIntegerHandler(MethodHandle getter, MethodHandle setter) {
super(BigInteger.class, getter, setter); super(BigInteger.class, getter, setter);
} }

View file

@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle;
/** /**
* Stores a byte value. * Stores a byte value.
*/ */
class ByteHandler extends PrimitiveType<Byte> { class ByteHandler extends PrimitiveTypeHandler<Byte> {
public ByteHandler(MethodHandle getter, MethodHandle setter) { public ByteHandler(MethodHandle getter, MethodHandle setter) {
super(Byte.class, getter, setter); super(Byte.class, getter, setter);

View file

@ -1,51 +0,0 @@
package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.util.*;
class CompoundType extends Type {
private final Map<String, Type> properties = new LinkedHashMap<>();
private MethodHandle getter;
private MethodHandle setter;
CompoundType(Class<?> type) {
super(type, null,null);
}
void setGetter(MethodHandle getter) {
this.getter = getter;
}
public MethodHandle getGetter() {
return getter;
}
public MethodHandle getSetter() {
return setter;
}
void setSetter(MethodHandle setter) {
this.setter = setter;
}
public Class<?> getType() {
return type;
}
Collection<Type> getProperties() {
return properties.values();
}
void addHandler(String propertyName, PrimitiveType<?> primitiveType) {
properties.put(propertyName, primitiveType);
}
void addChild(Field property, CompoundType childCompoundType) {
this.properties.put(property.getName(), childCompoundType);
}
}

View file

@ -0,0 +1,29 @@
package nl.sanderhautvast.contiguous;
import java.lang.reflect.Field;
import java.util.*;
class CompoundTypeHandler extends TypeHandler {
private final Map<String, TypeHandler> properties = new LinkedHashMap<>();
CompoundTypeHandler(Class<?> type) {
super(type, null,null);
}
Collection<TypeHandler> getProperties() {
return properties.values();
}
void addHandler(String propertyName, PrimitiveTypeHandler<?> primitiveType) {
properties.put(propertyName, primitiveType);
}
void addChild(Field property, CompoundTypeHandler childCompoundType) {
this.properties.put(property.getName(), childCompoundType);
}
}

View file

@ -52,7 +52,7 @@ public class ContiguousList<E> implements List<E> {
private int size; private int size;
private Type type; private TypeHandler type;
public ContiguousList(Class<E> type) { public ContiguousList(Class<E> type) {
inspectType(type); inspectType(type);
@ -71,7 +71,7 @@ public class ContiguousList<E> implements List<E> {
if (PropertyHandlerFactory.isKnownType(type)) { if (PropertyHandlerFactory.isKnownType(type)) {
this.type = PropertyHandlerFactory.forType(type); this.type = PropertyHandlerFactory.forType(type);
} else { } else {
CompoundType compoundType = new CompoundType(type); CompoundTypeHandler compoundType = new CompoundTypeHandler(type);
this.type = compoundType; this.type = compoundType;
try { try {
addPropertyHandlersForCompoundType(type, compoundType); addPropertyHandlersForCompoundType(type, compoundType);
@ -81,7 +81,7 @@ public class ContiguousList<E> implements List<E> {
} }
} }
private void addPropertyHandlersForCompoundType(Class<?> type, CompoundType parentCompoundType) throws IllegalAccessException { private void addPropertyHandlersForCompoundType(Class<?> type, CompoundTypeHandler parentCompoundType) throws IllegalAccessException {
final MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(type, MethodHandles.lookup()); final MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(type, MethodHandles.lookup());
Arrays.stream(type.getDeclaredFields()) Arrays.stream(type.getDeclaredFields())
.forEach(field -> { .forEach(field -> {
@ -91,11 +91,11 @@ public class ContiguousList<E> implements List<E> {
MethodHandle setter = lookup.findSetter(type, field.getName(), fieldType); MethodHandle setter = lookup.findSetter(type, field.getName(), fieldType);
if (PropertyHandlerFactory.isKnownType(fieldType)) { if (PropertyHandlerFactory.isKnownType(fieldType)) {
PrimitiveType<?> primitiveType = PropertyHandlerFactory.forType(fieldType, getter, setter); PrimitiveTypeHandler<?> primitiveType = PropertyHandlerFactory.forType(fieldType, getter, setter);
parentCompoundType.addHandler(field.getName(), primitiveType); parentCompoundType.addHandler(field.getName(), primitiveType);
} else { } else {
CompoundType newParent = new CompoundType(fieldType); CompoundTypeHandler newParent = new CompoundTypeHandler(fieldType);
newParent.setGetter(getter); newParent.setGetter(getter);
newParent.setSetter(setter); newParent.setSetter(setter);
parentCompoundType.addChild(field, newParent); parentCompoundType.addChild(field, newParent);
@ -126,18 +126,18 @@ public class ContiguousList<E> implements List<E> {
return true; return true;
} }
private void getProperties(Object element, Type type) { private void getProperties(Object element, TypeHandler type) {
// passed type is primitive // passed type is primitive
if (type instanceof PrimitiveType<?>) { if (type instanceof PrimitiveTypeHandler<?>) {
((PrimitiveType<?>) type).storePropertyValue(element, this); ((PrimitiveTypeHandler<?>) type).storePropertyValue(element, this);
} else { } else {
// passed type is compund ie. has child properties // passed type is compund ie. has child properties
((CompoundType)type).getProperties().forEach(property -> { ((CompoundTypeHandler)type).getProperties().forEach(property -> {
if (property instanceof PrimitiveType<?>) { if (property instanceof PrimitiveTypeHandler<?>) {
// recurse once more -> property is stored // recurse once more -> property is stored
getProperties(element, property); getProperties(element, property);
} else { } else {
CompoundType child = ((CompoundType) property); CompoundTypeHandler child = ((CompoundTypeHandler) property);
try { try {
Object result = child.getGetter().invoke(element); Object result = child.getGetter().invoke(element);
getProperties(result, child); getProperties(result, child);
@ -168,14 +168,14 @@ public class ContiguousList<E> implements List<E> {
} }
data.position(elementIndices[index]); data.position(elementIndices[index]);
try { try {
if (type instanceof PrimitiveType<?>) { if (type instanceof PrimitiveTypeHandler<?>) {
return (E)((PrimitiveType<?>)type).transform(ValueReader.read(data)); return (E)((PrimitiveTypeHandler<?>)type).transform(ValueReader.read(data));
} }
// create a new instance of the list element type // create a new instance of the list element type
E newInstance = (E) type.type.getDeclaredConstructor().newInstance(); E newInstance = (E) type.getType().getDeclaredConstructor().newInstance();
// set the data // set the data
setProperties(newInstance, (CompoundType) type); setProperties(newInstance, (CompoundTypeHandler) type);
return newInstance; return newInstance;
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
@ -184,14 +184,14 @@ public class ContiguousList<E> implements List<E> {
} }
} }
private void setProperties(Object element, CompoundType compoundType) { private void setProperties(Object element, CompoundTypeHandler compoundType) {
compoundType.getProperties().forEach(property -> { compoundType.getProperties().forEach(property -> {
if (property instanceof PrimitiveType) { if (property instanceof PrimitiveTypeHandler) {
PrimitiveType<?> type =((PrimitiveType<?>) property); PrimitiveTypeHandler<?> type =((PrimitiveTypeHandler<?>) property);
type.setValue(element, ValueReader.read(data)); type.setValue(element, ValueReader.read(data));
} else { } else {
try { try {
CompoundType p = (CompoundType) property; CompoundTypeHandler p = (CompoundTypeHandler) property;
// create a new instance of the property // create a new instance of the property
Object newInstance = p.getType().getDeclaredConstructor().newInstance(); Object newInstance = p.getType().getDeclaredConstructor().newInstance();

View file

@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle;
/** /**
* Stores a double value. * Stores a double value.
*/ */
class DoubleHandler extends PrimitiveType<Double> { class DoubleHandler extends PrimitiveTypeHandler<Double> {
public DoubleHandler(MethodHandle getter, MethodHandle setter) { public DoubleHandler(MethodHandle getter, MethodHandle setter) {
super(Double.class, getter, setter); super(Double.class, getter, setter);
} }

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
class FloatHandler extends PrimitiveType<Float> { class FloatHandler extends PrimitiveTypeHandler<Float> {
public FloatHandler(MethodHandle getter, MethodHandle setter) { public FloatHandler(MethodHandle getter, MethodHandle setter) {
super(Float.class, getter, setter); super(Float.class, getter, setter);
} }

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
class IntegerHandler extends PrimitiveType<Integer> { class IntegerHandler extends PrimitiveTypeHandler<Integer> {
public IntegerHandler(MethodHandle getter, MethodHandle setter) { public IntegerHandler(MethodHandle getter, MethodHandle setter) {
super(Integer.class, getter, setter); super(Integer.class, getter, setter);
} }

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
class LongHandler extends PrimitiveType<Long> { class LongHandler extends PrimitiveTypeHandler<Long> {
public LongHandler(MethodHandle getter, MethodHandle setter) { public LongHandler(MethodHandle getter, MethodHandle setter) {
super(Long.class, getter, setter); super(Long.class, getter, setter);
} }

View file

@ -4,15 +4,15 @@ import java.lang.invoke.MethodHandle;
/** /**
* Base class for handlers. Its responsibility is to read and write a property from the incoming object to the internal storage. * Base class for handlers. Its responsibility is to read and write a property from the incoming object to the internal storage.
* * <p>
* Can be extended for types that you need to handle. * Can be extended for types that you need to handle.
* * <p>
* A property handler is instantiated once per bean property and contains handles to the getter and setter methods * A property handler is instantiated once per bean property and contains handles to the getter and setter methods
* of the bean that it needs to call 'runtime' (after instantiation of the list), * of the bean that it needs to call 'runtime' (after instantiation of the list),
* ie. when a bean is added or retrieved from the list * ie. when a bean is added or retrieved from the list
*/ */
public abstract class PrimitiveType<T> extends Type { public abstract class PrimitiveTypeHandler<T> extends TypeHandler {
public PrimitiveType(Class<?> type, MethodHandle getter, MethodHandle setter) { public PrimitiveTypeHandler(Class<?> type, MethodHandle getter, MethodHandle setter) {
super(type, getter, setter); super(type, getter, setter);
} }
@ -63,14 +63,14 @@ public abstract class PrimitiveType<T> extends Type {
/** /**
* Certain types can easily be stored as another known type, for instance * Certain types can easily be stored as another known type, for instance
* a BigDecimal can be stored as a String. * a BigDecimal can be stored as a String.
* * <p>
* The {@link PrimitiveType} for BigDecimal would in that case be responsible for turning the String * The {@link PrimitiveTypeHandler} for BigDecimal would in that case be responsible for turning the String
* into a BigDecimal. It can do that by overriding this method * into a BigDecimal. It can do that by overriding this method
* *
* @param value raw value to transform to the desired output type * @param value raw value to transform to the desired output type
* @return the transformed object * @return the transformed object
*/ */
public Object transform(Object value){ public Object transform(Object value) {
return value; return value;
} }
} }

View file

@ -11,7 +11,7 @@ import java.util.Map;
* Maps the propertyvalue type to a PropertyHandler * Maps the propertyvalue type to a PropertyHandler
*/ */
final class PropertyHandlerFactory { final class PropertyHandlerFactory {
private static final Map<Class<?>, Class<? extends PrimitiveType<?>>> STANDARD_HANDLERS = new HashMap<>(); private static final Map<Class<?>, Class<? extends PrimitiveTypeHandler<?>>> TYPE_HANDLERS = new HashMap<>();
private PropertyHandlerFactory() { private PropertyHandlerFactory() {
} }
@ -38,16 +38,16 @@ final class PropertyHandlerFactory {
} }
public static boolean isKnownType(Class<?> type) { public static boolean isKnownType(Class<?> type) {
return STANDARD_HANDLERS.containsKey(type); return TYPE_HANDLERS.containsKey(type);
} }
public static <T> PrimitiveType<T> forType(Class<T> type, MethodHandle getter, MethodHandle setter) { public static <T> PrimitiveTypeHandler<T> forType(Class<T> type, MethodHandle getter, MethodHandle setter) {
try { try {
Class<? extends PrimitiveType<?>> appenderClass = STANDARD_HANDLERS.get(type); Class<? extends PrimitiveTypeHandler<?>> appenderClass = TYPE_HANDLERS.get(type);
if (appenderClass == null) { if (appenderClass == null) {
throw new IllegalStateException("No Handler for " + type.getName()); throw new IllegalStateException("No Handler for " + type.getName());
} }
return (PrimitiveType<T>) appenderClass.getDeclaredConstructor(MethodHandle.class, MethodHandle.class) return (PrimitiveTypeHandler<T>) appenderClass.getDeclaredConstructor(MethodHandle.class, MethodHandle.class)
.newInstance(getter, setter); .newInstance(getter, setter);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
InvocationTargetException e) { InvocationTargetException e) {
@ -55,14 +55,14 @@ final class PropertyHandlerFactory {
} }
} }
public static <T> PrimitiveType<T> forType(Class<T> type) { public static <T> PrimitiveTypeHandler<T> forType(Class<T> type) {
return forType(type, null, null); return forType(type, null, null);
} }
/** /**
* register a new TypeHandler that cannot be derived from bean properties * register a new TypeHandler that cannot be derived from bean properties
*/ */
public static void register(Class<?> type, Class<? extends PrimitiveType<?>> typehandler) { public static void register(Class<?> type, Class<? extends PrimitiveTypeHandler<?>> typehandler) {
STANDARD_HANDLERS.put(type, typehandler); TYPE_HANDLERS.put(type, typehandler);
} }
} }

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
class ShortHandler extends PrimitiveType<Short> { class ShortHandler extends PrimitiveTypeHandler<Short> {
public ShortHandler(MethodHandle getter, MethodHandle setter) { public ShortHandler(MethodHandle getter, MethodHandle setter) {
super(Short.class, getter, setter); super(Short.class, getter, setter);
} }

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
class StringHandler extends PrimitiveType<String> { class StringHandler extends PrimitiveTypeHandler<String> {
public StringHandler(MethodHandle getter, MethodHandle setter) { public StringHandler(MethodHandle getter, MethodHandle setter) {
super(String.class, getter, setter); super(String.class, getter, setter);
} }

View file

@ -8,15 +8,36 @@ import java.lang.invoke.MethodHandle;
* I needed to abstract over handlers for 'primitives' (ie. long, but also Long, String..=> built-in types) and compound types (your own) * I needed to abstract over handlers for 'primitives' (ie. long, but also Long, String..=> built-in types) and compound types (your own)
* So this is the common ancestor. The respective functions are completely different. * So this is the common ancestor. The respective functions are completely different.
*/ */
public abstract class Type { public abstract class TypeHandler {
protected MethodHandle getter; // both can be null, if it's for a known ('primitive') type protected MethodHandle getter; // both can be null, if it's for a known ('primitive') type
protected MethodHandle setter; protected MethodHandle setter;
protected Class<?> type; private final Class<?> type;
public Type(Class<?> type, MethodHandle getter, MethodHandle setter) { public TypeHandler(Class<?> type, MethodHandle getter, MethodHandle setter) {
this.type = type; this.type = type;
this.getter = getter; this.getter = getter;
this.setter = setter; this.setter = setter;
} }
void setGetter(MethodHandle getter) {
this.getter = getter;
}
public MethodHandle getGetter() {
return getter;
}
public MethodHandle getSetter() {
return setter;
}
void setSetter(MethodHandle setter) {
this.setter = setter;
}
public Class<?> getType() {
return type;
}
} }

View file

@ -131,7 +131,7 @@ public class ContiguousListTest {
} }
assertEquals(100, beanList.size()); assertEquals(100, beanList.size());
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
assertNull(beanList.get(i)); assertNull(beanList.get(i).getName());
} }
} }