added setterIterator and jdbc module
This commit is contained in:
parent
4d1ae5acf4
commit
f778f0456c
24 changed files with 359 additions and 66 deletions
14
demo/pom.xml
14
demo/pom.xml
|
|
@ -18,19 +18,9 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>nl.sanderhautvast</groupId>
|
||||
<artifactId>contiguous</artifactId>
|
||||
<artifactId>contiguous-jdbc</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>2.7.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||
<version>2.7.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
|
@ -55,7 +45,7 @@
|
|||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.7.10</version>
|
||||
<version>2.7.12</version>
|
||||
<configuration>
|
||||
<mainClass>nl.sanderhautvast.contiguous.demo.DemoApplication</mainClass>
|
||||
</configuration>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package nl.sanderhautvast.contiguous.demo.repository;
|
|||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import nl.sanderhautvast.contiguous.ContiguousList;
|
||||
import nl.sanderhautvast.contiguous.JdbcResults;
|
||||
import nl.sanderhautvast.contiguous.demo.model.Customer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
|
@ -21,20 +22,7 @@ public class CustomerRepository {
|
|||
|
||||
public ContiguousList<Customer> getAllCustomers() {
|
||||
return jdbcTemplate.query("select * from customers limit 5", rs -> {
|
||||
ContiguousList<Customer> customers = new ContiguousList<>(Customer.class);
|
||||
while (rs.next()) {
|
||||
Customer customer = Customer.builder()
|
||||
.name(rs.getString("name"))
|
||||
.email(rs.getString("email"))
|
||||
.streetname(rs.getString("streetname"))
|
||||
.housenumber(rs.getInt("housenumber"))
|
||||
.city(rs.getString("city"))
|
||||
.country(rs.getString("country"))
|
||||
.build();
|
||||
log.info("{}", customer);
|
||||
customers.add(customer);
|
||||
}
|
||||
return customers;
|
||||
return JdbcResults.toList(rs, Customer.class);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
<groupId>nl.sanderhautvast</groupId>
|
||||
<artifactId>contiguous-jackson</artifactId>
|
||||
<version>1.1</version>
|
||||
<description>Using Jackson to convert Contiguous data to JSON</description>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
52
jdbc/pom.xml
Normal file
52
jdbc/pom.xml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<groupId>nl.sanderhautvast</groupId>
|
||||
<artifactId>contiguous-jdbc</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<description>JDBC functions for Contiguous data</description>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>nl.sanderhautvast</groupId>
|
||||
<artifactId>contiguous</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>5.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.26</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package nl.sanderhautvast.contiguous;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Enables the end user to add values from JDBC to a list of results without creating Objects.
|
||||
* Every property must have a corresponding field in the ResultSet record (table/view/join etc)
|
||||
* optionally applying a name mapping if they are not equal
|
||||
* <p>
|
||||
* // what about null values?
|
||||
* // test test test
|
||||
*/
|
||||
public class JdbcResults {
|
||||
|
||||
/**
|
||||
* Adds the data to an existing CList
|
||||
*
|
||||
* @param result the JDBC ResultSet
|
||||
* @param list The list to add to
|
||||
* @throws SQLException when db throws error..
|
||||
*/
|
||||
public static void addAll(ResultSet result, ContiguousList<?> list) throws SQLException {
|
||||
addAll(result, list, Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the data to an existing CList.
|
||||
*
|
||||
* @param result the JDBC ResultSet
|
||||
* @param list The list to add to
|
||||
* @param fieldNameMapper maps the name from the element type property to the actual database column name
|
||||
* @throws SQLException when db throws error..
|
||||
*/
|
||||
public static void addAll(ResultSet result, ContiguousList<?> list, Function<String, String> fieldNameMapper) throws SQLException {
|
||||
ContiguousList<?>.SetterIterator setterIterator = list.setterIterator();
|
||||
while (result.next()) {
|
||||
while (setterIterator.hasNext()) {
|
||||
ContiguousList<?>.Setter next = setterIterator.next();
|
||||
String fieldName = next.getFieldName();
|
||||
Object fieldValue;
|
||||
if (fieldName != null) {
|
||||
fieldValue = result.getObject(fieldNameMapper.apply(fieldName));
|
||||
} else {
|
||||
// assume single Primitive as Contiguous<String>, so just 1 column in the record
|
||||
fieldValue = result.getObject(1);
|
||||
}
|
||||
next.set(fieldValue);
|
||||
}
|
||||
setterIterator.nextRecord();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as addAll, but creates a new CList.
|
||||
*
|
||||
* @param result The CList
|
||||
* @param elementType the desired Object type
|
||||
* @throws SQLException when db throws error..
|
||||
*/
|
||||
public static <E> ContiguousList<E> toList(ResultSet result, Class<E> elementType) throws SQLException {
|
||||
ContiguousList<E> list = new ContiguousList<>(elementType);
|
||||
return toList(result, elementType, Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as addAll, but creates a new CList.
|
||||
*
|
||||
* @param result The CList
|
||||
* @param elementType the desired Object type
|
||||
* @param fieldNameMapper maps the name from the element type property to the actual database column name
|
||||
* @throws SQLException when db throws error..
|
||||
*/
|
||||
public static <E> ContiguousList<E> toList(ResultSet result, Class<E> elementType, Function<String, String> fieldNameMapper) throws SQLException {
|
||||
ContiguousList<E> list = new ContiguousList<>(elementType);
|
||||
addAll(result, list, fieldNameMapper);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package nl.sanderhautvast.contiguous;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JdbcResultsTest {
|
||||
|
||||
@Mock
|
||||
private ResultSet mockResults;
|
||||
|
||||
@Test
|
||||
public void testListOfString() throws SQLException {
|
||||
when(mockResults.next()).thenReturn(true, false);
|
||||
when(mockResults.getObject(1)).thenReturn("Zaphod");
|
||||
|
||||
List<String> presidents = JdbcResults.toList(mockResults, String.class);
|
||||
assertFalse(presidents.isEmpty());
|
||||
assertEquals(1, presidents.size());
|
||||
|
||||
String president = presidents.get(0);
|
||||
assertEquals("Zaphod", president);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListOfBean() throws SQLException {
|
||||
when(mockResults.next()).thenReturn(true, false);
|
||||
// the shape of the result equals that of the result (name:String, age:int)
|
||||
when(mockResults.getObject("name")).thenReturn("Zaphod");
|
||||
when(mockResults.getObject("age")).thenReturn(42); // coincidence?
|
||||
|
||||
List<President> presidents = JdbcResults.toList(mockResults, President.class);
|
||||
assertFalse(presidents.isEmpty());
|
||||
assertEquals(1, presidents.size());
|
||||
|
||||
President president = presidents.get(0);
|
||||
assertEquals("Zaphod", president.getName());
|
||||
assertEquals(42, president.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameMapping() throws SQLException {
|
||||
when(mockResults.next()).thenReturn(true, false);
|
||||
when(mockResults.getObject("name")).thenReturn("Trillian");
|
||||
when(mockResults.getObject("realName")).thenReturn("Tricia MacMillan");
|
||||
|
||||
Map<String, String> nameMapping = Map.of("name", "name", "earthName", "realName");
|
||||
List<Scientist> scientists = JdbcResults.toList(mockResults, Scientist.class, nameMapping::get);
|
||||
|
||||
assertFalse(scientists.isEmpty());
|
||||
assertEquals(1, scientists.size());
|
||||
|
||||
Scientist scientist = scientists.get(0);
|
||||
assertEquals("Trillian", scientist.getName());
|
||||
assertEquals("Tricia MacMillan", scientist.getEarthName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package nl.sanderhautvast.contiguous;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class President {
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package nl.sanderhautvast.contiguous;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Scientist {
|
||||
private String name;
|
||||
private String earthName;
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>nl.sanderhautvast</groupId>
|
||||
<artifactId>contiguous</artifactId>
|
||||
<description>Datastructures with contiguous storage</description>
|
||||
<description>Datastructures with contiguous storage. Core library with no external dependencies</description>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import java.lang.invoke.MethodHandle;
|
|||
import java.math.BigDecimal;
|
||||
|
||||
class BigDecimalHandler extends BuiltinTypeHandler<BigDecimal> {
|
||||
public BigDecimalHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(BigDecimal.class, getter, setter);
|
||||
public BigDecimalHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(BigDecimal.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import java.lang.invoke.MethodHandle;
|
|||
import java.math.BigInteger;
|
||||
|
||||
class BigIntegerHandler extends BuiltinTypeHandler<BigInteger> {
|
||||
public BigIntegerHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(BigInteger.class, getter, setter);
|
||||
public BigIntegerHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(BigInteger.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import java.lang.invoke.MethodHandle;
|
|||
* ie. when a bean is added or retrieved from the list
|
||||
*/
|
||||
public abstract class BuiltinTypeHandler<T> extends TypeHandler {
|
||||
public BuiltinTypeHandler(Class<?> type, MethodHandle getter, MethodHandle setter) {
|
||||
super(type, getter, setter);
|
||||
public BuiltinTypeHandler(Class<?> type, String name, MethodHandle getter, MethodHandle setter) {
|
||||
super(type, name, getter, setter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -29,6 +29,10 @@ public abstract class BuiltinTypeHandler<T> extends TypeHandler {
|
|||
store(propertyValue, typedList);
|
||||
}
|
||||
|
||||
void storeValue(Object value, ContiguousList<?> contiguousList) {
|
||||
store((T)value, contiguousList);
|
||||
}
|
||||
|
||||
private T getValue(Object propertyValue) {
|
||||
// I don't trust this
|
||||
if (getter == null) {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import java.lang.invoke.MethodHandle;
|
|||
*/
|
||||
class ByteHandler extends BuiltinTypeHandler<Byte> {
|
||||
|
||||
public ByteHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(Byte.class, getter, setter);
|
||||
public ByteHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(Byte.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ class CompoundTypeHandler extends TypeHandler {
|
|||
|
||||
|
||||
|
||||
CompoundTypeHandler(Class<?> type) {
|
||||
super(type, null,null);
|
||||
CompoundTypeHandler(Class<?> type, String propertyName) {
|
||||
super(type, propertyName, null,null);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,17 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.*;
|
||||
|
||||
//notes:
|
||||
//1. should find out growth factor of arraylist
|
||||
//2. elementIndices can be arrayList
|
||||
// should find out growth factor of arraylist
|
||||
// investigate data array reuse (pooling, SoftReferences etc)
|
||||
|
||||
/**
|
||||
* Short for Contiguous Layout List, an Experimental List implementation
|
||||
* Behaves like an ArrayList in that it's resizable and indexed.
|
||||
* The difference is that it uses an efficiently dehydrated version of the object in a cpu cache friendly, contiguous storage in a bytearray,
|
||||
* without object instance overhead.
|
||||
* <p>
|
||||
* Only uses reflection api on creation of the list.
|
||||
* Only uses reflection api on creation of the list (and in the get() method, but the end user should employ value
|
||||
* iteration rather than element iteration using said get method).
|
||||
* Adding/Retrieving/Deleting depend on VarHandles and are aimed to be O(L) runtime complexity
|
||||
* where L is the nr of attributes to get/set from the objects (recursively).So O(1) for length of the list
|
||||
* <p>
|
||||
|
|
@ -35,6 +37,11 @@ import java.util.*;
|
|||
* Implements java.util.List but some methods are not (yet) implemented mainly because they don't make much sense
|
||||
* performance-wise, like the indexed add and set methods. They mess with the memory layout. The list is meant to
|
||||
* be appended at the tail.
|
||||
* <p>
|
||||
* What I think is a potential use case is a simple CRUD application.
|
||||
* Here it would become possible to skip Object (when reading from the database),
|
||||
* and directly map the results to JSON. Both writing and reading should ideally be faster
|
||||
* than doing it the regular way.
|
||||
*/
|
||||
public class ContiguousList<E> extends NotImplementedList<E> implements List<E> {
|
||||
|
||||
|
|
@ -52,7 +59,8 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
|||
|
||||
private int currentElementValueIndex;
|
||||
|
||||
private int[] elementIndices = new int[10];
|
||||
private int[] elementIndices = new int[10]; // avoids autoboxing. Could also use standard ArrayList though
|
||||
// is there a standard lib IntList??
|
||||
|
||||
private int size;
|
||||
|
||||
|
|
@ -75,7 +83,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
|||
if (PropertyHandlerFactory.isKnownType(type)) {
|
||||
this.rootHandler = PropertyHandlerFactory.forType(type);
|
||||
} else {
|
||||
CompoundTypeHandler compoundType = new CompoundTypeHandler(type);
|
||||
CompoundTypeHandler compoundType = new CompoundTypeHandler(type, null);//TODO revisit
|
||||
this.rootHandler = compoundType;
|
||||
try {
|
||||
addPropertyHandlersForCompoundType(type, compoundType);
|
||||
|
|
@ -95,11 +103,11 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
|||
MethodHandle setter = lookup.findSetter(type, field.getName(), fieldType);
|
||||
|
||||
if (PropertyHandlerFactory.isKnownType(fieldType)) {
|
||||
BuiltinTypeHandler<?> primitiveType = PropertyHandlerFactory.forType(fieldType, getter, setter);
|
||||
BuiltinTypeHandler<?> primitiveType = PropertyHandlerFactory.forType(fieldType, field.getName(), getter, setter);
|
||||
|
||||
parentCompoundType.addHandler(field.getName(), primitiveType);
|
||||
} else {
|
||||
CompoundTypeHandler newParent = new CompoundTypeHandler(fieldType);
|
||||
CompoundTypeHandler newParent = new CompoundTypeHandler(fieldType, field.getName());
|
||||
newParent.setGetter(getter);
|
||||
newParent.setSetter(setter);
|
||||
parentCompoundType.addChild(field, newParent);
|
||||
|
|
@ -170,7 +178,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
|||
try {
|
||||
if (rootHandler instanceof BuiltinTypeHandler<?>) {
|
||||
Object read = ValueReader.read(data);
|
||||
return (E) ((BuiltinTypeHandler<?>) rootHandler).transform(read);
|
||||
return (E) ((BuiltinTypeHandler<?>) rootHandler).cast(read);
|
||||
}
|
||||
// create a new instance of the list element type
|
||||
E newInstance = (E) rootHandler.getType().getDeclaredConstructor().newInstance();
|
||||
|
|
@ -295,14 +303,74 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
|||
}
|
||||
handler = typeHandlersIterator.next();
|
||||
|
||||
return handler.transform(rawValue);
|
||||
return handler.cast(rawValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Iterator} over the property values of the specified element in the List.
|
||||
* Allows 'iterating insertion of data'. Returns an iterator of Setter
|
||||
* Does not work for compound types yet
|
||||
*
|
||||
* @return
|
||||
* @return A Reusable iterator
|
||||
*/
|
||||
public SetterIterator setterIterator() {
|
||||
return new SetterIterator();
|
||||
}
|
||||
|
||||
public class Setter {
|
||||
|
||||
private final BuiltinTypeHandler<?> currentHandler;
|
||||
|
||||
public Setter(BuiltinTypeHandler<?> currentHandler) {
|
||||
this.currentHandler = currentHandler;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return currentHandler.getName();
|
||||
}
|
||||
|
||||
public void set(Object fieldValue) {
|
||||
currentHandler.storeValue(fieldValue, ContiguousList.this);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO proper naming
|
||||
// BTW do we even need this as a class??
|
||||
public class SetterIterator implements Iterator<Setter> {
|
||||
private final List<Setter> properties = new ArrayList<>();
|
||||
private Iterator<Setter> currentSetterIterator;
|
||||
|
||||
public SetterIterator() {
|
||||
List<BuiltinTypeHandler<?>> builtinTypeHandlers = getBuiltinTypeHandlers();
|
||||
for (BuiltinTypeHandler<?> builtinTypeHandler : builtinTypeHandlers) {
|
||||
properties.add(new Setter(builtinTypeHandler));
|
||||
}
|
||||
// what to do with compound?
|
||||
currentSetterIterator = this.properties.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
boolean hasNext = currentSetterIterator.hasNext();
|
||||
if (!hasNext){
|
||||
extend(); // marks the end of an object
|
||||
}
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Setter next() {
|
||||
return currentSetterIterator.next();
|
||||
}
|
||||
|
||||
public void nextRecord() {
|
||||
currentSetterIterator = properties.iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an {@link Iterator} over the property values of the specified element in the List.
|
||||
*/
|
||||
public Iterator<Object> valueIterator(int index) {
|
||||
//TODO
|
||||
|
|
@ -402,6 +470,12 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
|||
}
|
||||
}
|
||||
|
||||
// to be called by framework to force element count
|
||||
// used by SetterIterator
|
||||
void extend() {
|
||||
size += 1;
|
||||
}
|
||||
|
||||
void storeLong(Long value) {
|
||||
if (value == null) {
|
||||
store0();
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import java.lang.invoke.MethodHandle;
|
|||
* Stores a double value.
|
||||
*/
|
||||
class DoubleHandler extends BuiltinTypeHandler<Double> {
|
||||
public DoubleHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(Double.class, getter, setter);
|
||||
public DoubleHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(Double.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package nl.sanderhautvast.contiguous;
|
|||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
class FloatHandler extends BuiltinTypeHandler<Float> {
|
||||
public FloatHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(Float.class, getter, setter);
|
||||
public FloatHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(Float.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package nl.sanderhautvast.contiguous;
|
|||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
class IntegerHandler extends BuiltinTypeHandler<Integer> {
|
||||
public IntegerHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(Integer.class, getter, setter);
|
||||
public IntegerHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(Integer.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package nl.sanderhautvast.contiguous;
|
|||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
class LongHandler extends BuiltinTypeHandler<Long> {
|
||||
public LongHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(Long.class, getter, setter);
|
||||
public LongHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(Long.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ final class PropertyHandlerFactory {
|
|||
return TYPE_HANDLERS.containsKey(type);
|
||||
}
|
||||
|
||||
public static <T> BuiltinTypeHandler<T> forType(Class<T> type, MethodHandle getter, MethodHandle setter) {
|
||||
public static <T> BuiltinTypeHandler<T> forType(Class<T> type, String name, MethodHandle getter, MethodHandle setter) {
|
||||
try {
|
||||
Class<? extends BuiltinTypeHandler<?>> appenderClass = TYPE_HANDLERS.get(type);
|
||||
if (appenderClass == null) {
|
||||
throw new IllegalStateException("No Handler for " + type.getName());
|
||||
}
|
||||
return (BuiltinTypeHandler<T>) appenderClass.getDeclaredConstructor(MethodHandle.class, MethodHandle.class)
|
||||
.newInstance(getter, setter);
|
||||
return (BuiltinTypeHandler<T>) appenderClass.getDeclaredConstructor(String.class, MethodHandle.class, MethodHandle.class)
|
||||
.newInstance(name, getter, setter);
|
||||
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
|
||||
InvocationTargetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
|
|
@ -56,7 +56,7 @@ final class PropertyHandlerFactory {
|
|||
}
|
||||
|
||||
public static <T> BuiltinTypeHandler<T> forType(Class<T> type) {
|
||||
return forType(type, null, null);
|
||||
return forType(type, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package nl.sanderhautvast.contiguous;
|
|||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
class ShortHandler extends BuiltinTypeHandler<Short> {
|
||||
public ShortHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(Short.class, getter, setter);
|
||||
public ShortHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(Short.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package nl.sanderhautvast.contiguous;
|
|||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
class StringHandler extends BuiltinTypeHandler<String> {
|
||||
public StringHandler(MethodHandle getter, MethodHandle setter) {
|
||||
super(String.class, getter, setter);
|
||||
public StringHandler(String propertyName, MethodHandle getter, MethodHandle setter) {
|
||||
super(String.class, propertyName, getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import java.lang.invoke.MethodHandle;
|
|||
/**
|
||||
* Abstract basertype over handlers for 'primitives' (ie. long, but also Long,
|
||||
* String..=> built-in types) and compound types (your own).
|
||||
*
|
||||
* Common ancestor primarily to iterator over properties of any type.
|
||||
* The respective functions are completely different though, and we need `instanceof` to check for the
|
||||
* actual type. (Rust enums!)
|
||||
|
|
@ -15,9 +14,11 @@ public abstract class TypeHandler {
|
|||
protected MethodHandle getter; // both can be null, if it's for a known ('primitive') type
|
||||
protected MethodHandle setter;
|
||||
private final Class<?> type;
|
||||
private final String name;
|
||||
|
||||
public TypeHandler(Class<?> type, MethodHandle getter, MethodHandle setter) {
|
||||
public TypeHandler(Class<?> type, String name, MethodHandle getter, MethodHandle setter) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
|
@ -42,4 +43,7 @@ public abstract class TypeHandler {
|
|||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
pom.xml
1
pom.xml
|
|
@ -10,6 +10,7 @@
|
|||
<modules>
|
||||
<module>lib</module>
|
||||
<module>demo</module>
|
||||
<module>jdbc</module>
|
||||
<module>jackson</module>
|
||||
</modules>
|
||||
<name>contiguous</name>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue