org.simpleflatmapper.datastax.impl.RowGetterFactory Maven / Gradle / Ivy
Show all versions of sfm-datastax Show documentation
package org.simpleflatmapper.datastax.impl;
import com.datastax.driver.core.*;
import org.simpleflatmapper.converter.ConverterService;
import org.simpleflatmapper.reflect.getter.GetterFactoryRegistry;
import org.simpleflatmapper.reflect.getter.GetterWithConverter;
import org.simpleflatmapper.reflect.getter.GetterFactory;
import org.simpleflatmapper.datastax.DataHelper;
import org.simpleflatmapper.datastax.DataTypeHelper;
import org.simpleflatmapper.datastax.DatastaxColumnKey;
import org.simpleflatmapper.datastax.DatastaxMapperFactory;
import org.simpleflatmapper.reflect.getter.EnumUnspecifiedTypeGetter;
import org.simpleflatmapper.reflect.getter.OrdinalEnumGetter;
import org.simpleflatmapper.reflect.getter.StringEnumGetter;
import org.simpleflatmapper.reflect.Getter;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import org.simpleflatmapper.converter.Converter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxBigDecimalGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxBigIntegerGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxBooleanGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxByteGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxDateGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxDoubleGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxFloatGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericBigDecimalGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericBigIntegerGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericByteGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericDoubleGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericFloatGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericIntegerGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericLongGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxGenericShortGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxInetAddressGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxIntegerGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxListGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxListWithConverterGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxLongGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxMapGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxMapWithConverterGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxObjectGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxSetGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxSetWithConverterGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxShortGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxStringGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxTimeGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxTimestampGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxToStringGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxTupleGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxTupleValueGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxUDTGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxUUIDFromStringGetter;
import org.simpleflatmapper.datastax.impl.getter.DatastaxUUIDGetter;
import org.simpleflatmapper.util.TupleHelper;
import org.simpleflatmapper.util.TypeHelper;
import java.util.*;
public class RowGetterFactory implements GetterFactory {
private final GetterFactoryRegistry getterFactories = new GetterFactoryRegistry();
private final DatastaxMapperFactory datastaxMapperFactory;
public RowGetterFactory(DatastaxMapperFactory datastaxMapperFactory) {
this.datastaxMapperFactory = datastaxMapperFactory;
GetterFactory dateGetterFactory = new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
return (Getter) new DatastaxTimestampGetter(key.getIndex());
}
};
getterFactories.put(Byte.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(Byte.class)) {
if (DataHelper.hasByteAccessor()) {
return (Getter) new DatastaxByteGetter(key.getIndex());
}
} else if (javaClass != null && Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericByteGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.mapFromTo(byte.class, Byte.class);
getterFactories.put(Short.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(Short.class)) {
if (DataHelper.hasShortAccessor()) {
return (Getter) new DatastaxShortGetter(key.getIndex());
}
} else if (javaClass != null && Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericShortGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.mapFromTo(short.class, Short.class);
getterFactories.put(Integer.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(Integer.class)) {
return (Getter) new DatastaxIntegerGetter(key.getIndex());
} else if (Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericIntegerGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.mapFromTo(int.class, Integer.class);
getterFactories.put(Long.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (key.getDataType() != null && DataTypeHelper.isTime(key.getDataType().getName())) {
return (Getter) new DatastaxTimeGetter(key.getIndex());
} else if (javaClass == null || javaClass.equals(Long.class)) {
return (Getter) new DatastaxLongGetter(key.getIndex());
} else if (Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericLongGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.mapFromTo(long.class, Long.class);
getterFactories.put(Float.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(Float.class)) {
return (Getter) new DatastaxFloatGetter(key.getIndex());
} else if (Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericFloatGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.mapFromTo(float.class, Float.class);
getterFactories.put(Double.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(Double.class)) {
return (Getter) new DatastaxDoubleGetter(key.getIndex());
} else if (Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericDoubleGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.mapFromTo(double.class, Double.class);
getterFactories.put(BigInteger.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(BigInteger.class)) {
return (Getter) new DatastaxBigIntegerGetter(key.getIndex());
} else if (Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericBigIntegerGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.put(BigDecimal.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (javaClass == null || javaClass.equals(BigDecimal.class)) {
return (Getter) new DatastaxBigDecimalGetter(key.getIndex());
} else if (Number.class.isAssignableFrom(javaClass)) {
return (Getter) new DatastaxGenericBigDecimalGetter(key.getIndex(), key.getDataType());
}
return null;
}
});
getterFactories.put(String.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
if (key.getDataType() == null || String.class.equals(DataTypeHelper.asJavaClass(key.getDataType()))) {
return (Getter) new DatastaxStringGetter(key.getIndex());
} else {
Getter getter = RowGetterFactory.this.newGetter(DataTypeHelper.asJavaClass(key.getDataType()), key, properties);
if (getter != null) {
return (Getter) new DatastaxToStringGetter(getter);
}
}
return null;
}
});
getterFactories.put(UUID.class, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
if (key.getDataType() == null || UUID.class.equals(DataTypeHelper.asJavaClass(key.getDataType()))) {
return (Getter) new DatastaxUUIDGetter(key.getIndex());
} else if (String.class.equals(DataTypeHelper.asJavaClass(key.getDataType()))){
return (Getter) new DatastaxUUIDFromStringGetter(key.getIndex());
}
return null;
}
});
if (DataTypeHelper.localDateClass != null) {
getterFactories.put(DataTypeHelper.localDateClass, new GetterFactory() {
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
return (Getter) new DatastaxDateGetter(key.getIndex());
}
});
}
}
@SuppressWarnings("unchecked")
@Override
public Getter newGetter(Type target, DatastaxColumnKey key, Object... properties) {
Class> targetClass = TypeHelper.toClass(target);
if (Date.class.equals(targetClass)) {
return (Getter) new DatastaxTimestampGetter(key.getIndex());
}
if (boolean.class.equals(targetClass) || Boolean.class.equals(targetClass)) {
return (Getter) new DatastaxBooleanGetter(key.getIndex());
}
if (InetAddress.class.equals(targetClass)) {
return (Getter) new DatastaxInetAddressGetter(key.getIndex());
}
if (TupleValue.class.equals(targetClass)) {
return (Getter) new DatastaxTupleValueGetter(key.getIndex());
}
if (Collection.class.isAssignableFrom(targetClass)) {
Type elementType = TypeHelper.getComponentTypeOfListOrArray(target);
Class> dataTypeClass = Object.class;
Class> dataTypeElt = null;
DataType dtElt = null;
if (key.getDataType() != null) {
DataType dataType = key.getDataType();
dataTypeClass = DataTypeHelper.asJavaClass(dataType);
if (dataType.isCollection()) {
dtElt = key.getDataType().getTypeArguments().get(0);
dataTypeElt = DataTypeHelper.asJavaClass(dtElt);
}
} else {
dataTypeElt = TypeHelper.toClass(elementType);
}
if (dataTypeElt != null) {
if (TypeHelper.areEquals(elementType, dataTypeElt)) {
if (Set.class.equals(dataTypeClass)) {
if (targetClass.isAssignableFrom(dataTypeClass)) {
return new DatastaxSetGetter(key.getIndex(), TypeHelper.toClass(elementType));
}
}
if (List.class.equals(dataTypeClass)) {
if (targetClass.isAssignableFrom(dataTypeClass)) {
return new DatastaxListGetter(key.getIndex(), TypeHelper.toClass(elementType));
}
}
} else {
Converter, ?> converter = getConverter(elementType, dataTypeElt, dtElt);
if (converter != null) {
if (Set.class.equals(dataTypeClass)) {
if (targetClass.isAssignableFrom(dataTypeClass)) {
return new DatastaxSetWithConverterGetter(key.getIndex(), dataTypeElt, converter);
}
}
if (List.class.equals(dataTypeClass)) {
if (targetClass.isAssignableFrom(dataTypeClass)) {
return new DatastaxListWithConverterGetter(key.getIndex(), dataTypeElt, converter);
}
}
}
}
}
}
if (Map.class.equals(targetClass)) {
TypeHelper.MapEntryTypes keyValueTypeOfMap = TypeHelper.getKeyValueTypeOfMap(target);
Class> dtKeyType = null;
Class> dtValueType = null;
DataType dtKey = null;
DataType dtValue = null;
if (key.getDataType() != null) {
List typeArguments = key.getDataType().getTypeArguments();
if (typeArguments.size() == 2) {
dtKey = typeArguments.get(0);
dtKeyType = DataTypeHelper.asJavaClass(dtKey);
dtValue = typeArguments.get(1);
dtValueType = DataTypeHelper.asJavaClass(dtValue);
}
} else {
dtKeyType = TypeHelper.toClass(keyValueTypeOfMap.getKeyType());
dtValueType = TypeHelper.toClass(keyValueTypeOfMap.getValueType());
}
if (dtKeyType != null && dtValueType != null) {
if (TypeHelper.areEquals(keyValueTypeOfMap.getKeyType(), dtKeyType)
&& TypeHelper.areEquals(keyValueTypeOfMap.getValueType(), dtValueType)) {
return new DatastaxMapGetter(key.getIndex(), TypeHelper.toClass(keyValueTypeOfMap.getKeyType()), TypeHelper.toClass(keyValueTypeOfMap.getValueType()));
} else {
Converter, ?> keyConverter = getConverter(keyValueTypeOfMap.getKeyType(), dtKeyType, dtKey);
Converter, ?> valueConverter = getConverter(keyValueTypeOfMap.getValueType(), dtValueType, dtValue);
if (keyConverter != null && valueConverter != null) {
return new DatastaxMapWithConverterGetter(key.getIndex(), dtKeyType, dtValueType, keyConverter, valueConverter);
}
}
}
}
if (TupleHelper.isTuple(target)) {
if (key.getDataType() != null && key.getDataType() instanceof TupleType) {
TupleType tt = (TupleType) key.getDataType();
List typeArguments = tt.getTypeArguments();
TypeVariable extends Class>>[] typeParameters = targetClass.getTypeParameters();
if (typeArguments.size() <= typeParameters.length) {
return (Getter) DatastaxTupleGetter.newInstance(datastaxMapperFactory, target, tt, key.getIndex());
}
}
}
if (TypeHelper.isEnum(target)) {
final Getter getter = enumGetter(key, TypeHelper.toClass(target));
if (getter != null) {
return (Getter)getter;
}
}
if (key.getDataType() != null && key.getDataType() instanceof UserType) {
UserType ut = (UserType) key.getDataType();
return (Getter) DatastaxUDTGetter.newInstance(datastaxMapperFactory, target, ut, key.getIndex());
}
Getter getter = getterFromFactories(target, key, properties);
if (getter != null) return getter;
return null;
}
private Getter getterFromFactories(Type target, DatastaxColumnKey key, Object[] properties) {
final GetterFactory rowGetterFactory = getterFactories.findFactoryFor(target);
if (rowGetterFactory != null) {
Getter getter = rowGetterFactory.newGetter(target, key, properties);
if (getter != null) return getter;
}
return null;
}
@SuppressWarnings("unchecked")
private Converter, ?> getConverter(Type elementType, Class> dataTypeElt, DataType dtElt) {
if (dtElt != null) {
if (UDTValue.class.equals(dataTypeElt)) {
return new ConverterMapper(DatastaxUDTGetter.newUDTMapper(elementType, (UserType) dtElt, datastaxMapperFactory));
}
if (TupleValue.class.equals(dataTypeElt)) {
return new ConverterMapper(DatastaxTupleGetter.newTupleMapper(elementType, (TupleType) dtElt, datastaxMapperFactory));
}
}
return ConverterService.getInstance().findConverter(dataTypeElt, elementType);
}
@SuppressWarnings("unchecked")
public > Getter enumGetter(DatastaxColumnKey key, Class> enumClass) {
if (key.getDataType() != null) {
final Class> javaClass = key.getDataType() != null ? DataTypeHelper.asJavaClass(key.getDataType()) : null;
if (Number.class.isAssignableFrom(javaClass)) {
return new OrdinalEnumGetter(new DatastaxIntegerGetter(key.getIndex()), (Class)enumClass);
} else if (String.class.equals(javaClass)) {
return new StringEnumGetter(new DatastaxStringGetter(key.getIndex()), (Class)enumClass);
}
} else {
return new EnumUnspecifiedTypeGetter(new DatastaxObjectGetter(key.getIndex()), (Class)enumClass);
}
return null;
}
}