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.math.BigDecimal;
import java.math.BigInteger;
class BigDecimalHandler extends PrimitiveType<BigDecimal> {
class BigDecimalHandler extends PrimitiveTypeHandler<BigDecimal> {
public BigDecimalHandler(MethodHandle getter, MethodHandle setter) {
super(BigDecimal.class, getter, setter);
}

View file

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

View file

@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle;
/**
* Stores a byte value.
*/
class ByteHandler extends PrimitiveType<Byte> {
class ByteHandler extends PrimitiveTypeHandler<Byte> {
public ByteHandler(MethodHandle getter, MethodHandle 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 Type type;
private TypeHandler type;
public ContiguousList(Class<E> type) {
inspectType(type);
@ -71,7 +71,7 @@ public class ContiguousList<E> implements List<E> {
if (PropertyHandlerFactory.isKnownType(type)) {
this.type = PropertyHandlerFactory.forType(type);
} else {
CompoundType compoundType = new CompoundType(type);
CompoundTypeHandler compoundType = new CompoundTypeHandler(type);
this.type = compoundType;
try {
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());
Arrays.stream(type.getDeclaredFields())
.forEach(field -> {
@ -91,11 +91,11 @@ public class ContiguousList<E> implements List<E> {
MethodHandle setter = lookup.findSetter(type, field.getName(), fieldType);
if (PropertyHandlerFactory.isKnownType(fieldType)) {
PrimitiveType<?> primitiveType = PropertyHandlerFactory.forType(fieldType, getter, setter);
PrimitiveTypeHandler<?> primitiveType = PropertyHandlerFactory.forType(fieldType, getter, setter);
parentCompoundType.addHandler(field.getName(), primitiveType);
} else {
CompoundType newParent = new CompoundType(fieldType);
CompoundTypeHandler newParent = new CompoundTypeHandler(fieldType);
newParent.setGetter(getter);
newParent.setSetter(setter);
parentCompoundType.addChild(field, newParent);
@ -126,18 +126,18 @@ public class ContiguousList<E> implements List<E> {
return true;
}
private void getProperties(Object element, Type type) {
private void getProperties(Object element, TypeHandler type) {
// passed type is primitive
if (type instanceof PrimitiveType<?>) {
((PrimitiveType<?>) type).storePropertyValue(element, this);
if (type instanceof PrimitiveTypeHandler<?>) {
((PrimitiveTypeHandler<?>) type).storePropertyValue(element, this);
} else {
// passed type is compund ie. has child properties
((CompoundType)type).getProperties().forEach(property -> {
if (property instanceof PrimitiveType<?>) {
((CompoundTypeHandler)type).getProperties().forEach(property -> {
if (property instanceof PrimitiveTypeHandler<?>) {
// recurse once more -> property is stored
getProperties(element, property);
} else {
CompoundType child = ((CompoundType) property);
CompoundTypeHandler child = ((CompoundTypeHandler) property);
try {
Object result = child.getGetter().invoke(element);
getProperties(result, child);
@ -168,14 +168,14 @@ public class ContiguousList<E> implements List<E> {
}
data.position(elementIndices[index]);
try {
if (type instanceof PrimitiveType<?>) {
return (E)((PrimitiveType<?>)type).transform(ValueReader.read(data));
if (type instanceof PrimitiveTypeHandler<?>) {
return (E)((PrimitiveTypeHandler<?>)type).transform(ValueReader.read(data));
}
// 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
setProperties(newInstance, (CompoundType) type);
setProperties(newInstance, (CompoundTypeHandler) type);
return newInstance;
} 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 -> {
if (property instanceof PrimitiveType) {
PrimitiveType<?> type =((PrimitiveType<?>) property);
if (property instanceof PrimitiveTypeHandler) {
PrimitiveTypeHandler<?> type =((PrimitiveTypeHandler<?>) property);
type.setValue(element, ValueReader.read(data));
} else {
try {
CompoundType p = (CompoundType) property;
CompoundTypeHandler p = (CompoundTypeHandler) property;
// create a new instance of the property
Object newInstance = p.getType().getDeclaredConstructor().newInstance();

View file

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

View file

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

View file

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

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle;
class LongHandler extends PrimitiveType<Long> {
class LongHandler extends PrimitiveTypeHandler<Long> {
public LongHandler(MethodHandle getter, MethodHandle 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.
*
* <p>
* 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
* 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
*/
public abstract class PrimitiveType<T> extends Type {
public PrimitiveType(Class<?> type, MethodHandle getter, MethodHandle setter) {
public abstract class PrimitiveTypeHandler<T> extends TypeHandler {
public PrimitiveTypeHandler(Class<?> type, MethodHandle getter, MethodHandle 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
* a BigDecimal can be stored as a String.
*
* The {@link PrimitiveType} for BigDecimal would in that case be responsible for turning the String
* <p>
* 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
*
* @param value raw value to transform to the desired output type
* @return the transformed object
*/
public Object transform(Object value){
public Object transform(Object value) {
return value;
}
}

View file

@ -11,7 +11,7 @@ import java.util.Map;
* Maps the propertyvalue type to a PropertyHandler
*/
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() {
}
@ -38,16 +38,16 @@ final class PropertyHandlerFactory {
}
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 {
Class<? extends PrimitiveType<?>> appenderClass = STANDARD_HANDLERS.get(type);
Class<? extends PrimitiveTypeHandler<?>> appenderClass = TYPE_HANDLERS.get(type);
if (appenderClass == null) {
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);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
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);
}
/**
* register a new TypeHandler that cannot be derived from bean properties
*/
public static void register(Class<?> type, Class<? extends PrimitiveType<?>> typehandler) {
STANDARD_HANDLERS.put(type, typehandler);
public static void register(Class<?> type, Class<? extends PrimitiveTypeHandler<?>> typehandler) {
TYPE_HANDLERS.put(type, typehandler);
}
}

View file

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

View file

@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
import java.lang.invoke.MethodHandle;
class StringHandler extends PrimitiveType<String> {
class StringHandler extends PrimitiveTypeHandler<String> {
public StringHandler(MethodHandle getter, MethodHandle 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)
* 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 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.getter = getter;
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());
for (int i = 0; i < 100; i++) {
assertNull(beanList.get(i));
assertNull(beanList.get(i).getName());
}
}