improvements
This commit is contained in:
parent
5619f8c2ae
commit
e1530d076c
7 changed files with 101 additions and 38 deletions
|
|
@ -0,0 +1,21 @@
|
|||
package nl.sanderhautvast.contiguous;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
class BigDecimalHandler extends PrimitiveType<BigDecimal> {
|
||||
public BigDecimalHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(BigDecimal.class, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(BigDecimal value, ContiguousList<?> list) {
|
||||
list.storeString(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return new BigDecimal((String) value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package nl.sanderhautvast.contiguous;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.math.BigInteger;
|
||||
|
||||
class BigIntegerHandler extends PrimitiveType<BigInteger> {
|
||||
public BigIntegerHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(BigInteger.class, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(BigInteger value, ContiguousList<?> list) {
|
||||
list.storeString(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return new BigInteger((String) value);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,9 +22,9 @@ import java.util.function.UnaryOperator;
|
|||
* <p>
|
||||
* Employs the SQLite style of data storage, most notably integer numbers are stored with variable byte length
|
||||
* <p>
|
||||
* The classes stored in DehydrateList MUST have a no-args constructor.
|
||||
* The classes stored in {@link ContiguousList} MUST have a no-args constructor.
|
||||
* <p>
|
||||
* Like ArrayList mutating operations are not synchronized.
|
||||
* Like ArrayList, mutating operations are not synchronized.
|
||||
* <p>
|
||||
* Does not allow null elements.
|
||||
* <p>
|
||||
|
|
@ -169,7 +169,7 @@ public class ContiguousList<E> implements List<E> {
|
|||
data.position(elementIndices[index]);
|
||||
try {
|
||||
if (type instanceof PrimitiveType<?>) {
|
||||
return (E) ValueReader.read(data);
|
||||
return (E)((PrimitiveType<?>)type).transform(ValueReader.read(data));
|
||||
}
|
||||
// create a new instance of the list element type
|
||||
E newInstance = (E) type.type.getDeclaredConstructor().newInstance();
|
||||
|
|
@ -187,7 +187,8 @@ public class ContiguousList<E> implements List<E> {
|
|||
private void setProperties(Object element, CompoundType compoundType) {
|
||||
compoundType.getProperties().forEach(property -> {
|
||||
if (property instanceof PrimitiveType) {
|
||||
((PrimitiveType<?>) property).setValue(element, ValueReader.read(data));
|
||||
PrimitiveType<?> type =((PrimitiveType<?>) property);
|
||||
type.setValue(element, ValueReader.read(data));
|
||||
} else {
|
||||
try {
|
||||
CompoundType p = (CompoundType) property;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package nl.sanderhautvast.contiguous;
|
|||
|
||||
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.
|
||||
*
|
||||
* Can be extended for types that you need to handle.
|
||||
|
|
@ -12,22 +12,6 @@ import java.lang.invoke.MethodHandle;
|
|||
* ie. when a bean is added or retrieved from the list
|
||||
*/
|
||||
public abstract class PrimitiveType<T> extends Type {
|
||||
|
||||
/*
|
||||
* Apology:
|
||||
* This was the simplest thing I could think of when trying to accomodate for nested types.
|
||||
*
|
||||
* What you end up with after inspection in the DehydrateList is a flat list of getters and setters
|
||||
* of properties that are in a tree-like structure (primitive properties within (nested) compound types)
|
||||
* So to read or write a property in a 'root object' (element type in list) with compound property types
|
||||
* you first have to traverse to the bean graph to the right container (bean) of the property you set/get
|
||||
* (that is what the childGetters are for)
|
||||
*
|
||||
* Ideally you'd do this only once per containing class. In the current implementation it's once per
|
||||
* property in the containing class.
|
||||
*/
|
||||
// private final List<MethodHandle> childGetters = new ArrayList<>();
|
||||
|
||||
public PrimitiveType(Class<?> type, MethodHandle getter, MethodHandle setter) {
|
||||
super(type, getter, setter);
|
||||
}
|
||||
|
|
@ -70,10 +54,23 @@ public abstract class PrimitiveType<T> extends Type {
|
|||
*/
|
||||
public void setValue(Object instance, Object value) {
|
||||
try {
|
||||
setter.invokeWithArguments(instance, value);
|
||||
setter.invokeWithArguments(instance, transform(value));
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package nl.sanderhautvast.contiguous;
|
|||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -15,23 +17,24 @@ final class PropertyHandlerFactory {
|
|||
}
|
||||
|
||||
static {
|
||||
STANDARD_HANDLERS.put(String.class, StringHandler.class);
|
||||
STANDARD_HANDLERS.put(byte.class, ByteHandler.class);
|
||||
STANDARD_HANDLERS.put(Byte.class, ByteHandler.class);
|
||||
STANDARD_HANDLERS.put(int.class, IntegerHandler.class);
|
||||
STANDARD_HANDLERS.put(Integer.class, IntegerHandler.class);
|
||||
STANDARD_HANDLERS.put(short.class, ShortHandler.class);
|
||||
STANDARD_HANDLERS.put(Short.class, ShortHandler.class);
|
||||
STANDARD_HANDLERS.put(long.class, LongHandler.class);
|
||||
STANDARD_HANDLERS.put(Long.class, LongHandler.class);
|
||||
STANDARD_HANDLERS.put(float.class, FloatHandler.class);
|
||||
STANDARD_HANDLERS.put(Float.class, FloatHandler.class);
|
||||
STANDARD_HANDLERS.put(double.class, DoubleHandler.class);
|
||||
STANDARD_HANDLERS.put(Double.class, DoubleHandler.class);
|
||||
register(String.class, StringHandler.class);
|
||||
register(byte.class, ByteHandler.class);
|
||||
register(Byte.class, ByteHandler.class);
|
||||
register(int.class, IntegerHandler.class);
|
||||
register(Integer.class, IntegerHandler.class);
|
||||
register(short.class, ShortHandler.class);
|
||||
register(Short.class, ShortHandler.class);
|
||||
register(long.class, LongHandler.class);
|
||||
register(Long.class, LongHandler.class);
|
||||
register(float.class, FloatHandler.class);
|
||||
register(Float.class, FloatHandler.class);
|
||||
register(double.class, DoubleHandler.class);
|
||||
register(Double.class, DoubleHandler.class);
|
||||
register(BigDecimal.class, StringHandler.class);
|
||||
register(BigInteger.class, BigIntegerHandler.class);
|
||||
register(BigDecimal.class, BigDecimalHandler.class);
|
||||
//Date/Timestamp
|
||||
//LocalDate/time
|
||||
//BigDecimal
|
||||
//BigInteger
|
||||
}
|
||||
|
||||
public static boolean isKnownType(Class<?> type) {
|
||||
|
|
@ -55,4 +58,11 @@ final class PropertyHandlerFactory {
|
|||
public static <T> PrimitiveType<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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ package nl.sanderhautvast.contiguous;
|
|||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
/**
|
||||
/*
|
||||
* ok, sorry
|
||||
*
|
||||
* 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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package nl.sanderhautvast.contiguous;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
|
@ -129,5 +130,15 @@ public class ContiguousListTest {
|
|||
beanList.add(new StringBean(null));
|
||||
}
|
||||
assertEquals(100, beanList.size());
|
||||
for (int i = 0; i < 100; i++) {
|
||||
assertNull(beanList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigInteger() {
|
||||
ContiguousList<BigInteger> bigIntegers = new ContiguousList<>(BigInteger.class);
|
||||
bigIntegers.add(new BigInteger("1000000000"));
|
||||
assertEquals(1_000_000_000L, bigIntegers.get(0).longValue());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue