org.sfm.jdbc.impl.ResultSetFieldMapperFactory Maven / Gradle / Ivy
package org.sfm.jdbc.impl;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.Date;
import org.sfm.jdbc.JdbcColumnKey;
import org.sfm.jdbc.impl.getter.BooleanResultSetGetter;
import org.sfm.jdbc.impl.getter.ByteResultSetGetter;
import org.sfm.jdbc.impl.getter.CharacterResultSetGetter;
import org.sfm.jdbc.impl.getter.DoubleResultSetGetter;
import org.sfm.jdbc.impl.getter.FloatResultSetGetter;
import org.sfm.jdbc.impl.getter.IntResultSetGetter;
import org.sfm.jdbc.impl.getter.LongResultSetGetter;
import org.sfm.jdbc.impl.getter.ShortResultSetGetter;
import org.sfm.map.FieldMapperErrorHandler;
import org.sfm.map.MapperBuilderErrorHandler;
import org.sfm.map.impl.FieldMapper;
import org.sfm.map.impl.FieldMapperFactory;
import org.sfm.map.impl.GetterFactory;
import org.sfm.map.impl.fieldmapper.BooleanFieldMapper;
import org.sfm.map.impl.fieldmapper.ByteFieldMapper;
import org.sfm.map.impl.fieldmapper.CharacterFieldMapper;
import org.sfm.map.impl.fieldmapper.DoubleFieldMapper;
import org.sfm.map.impl.fieldmapper.FieldMapperImpl;
import org.sfm.map.impl.fieldmapper.FloatFieldMapper;
import org.sfm.map.impl.fieldmapper.IntFieldMapper;
import org.sfm.map.impl.fieldmapper.LongFieldMapper;
import org.sfm.map.impl.fieldmapper.ShortFieldMapper;
import org.sfm.reflect.ConstructorOnGetter;
import org.sfm.reflect.Getter;
import org.sfm.reflect.Setter;
import org.sfm.reflect.SetterFactory;
import org.sfm.reflect.TypeHelper;
public final class ResultSetFieldMapperFactory implements FieldMapperFactory {
private final GetterFactory getterFactory;
public ResultSetFieldMapperFactory(GetterFactory getterFactory) {
this.getterFactory = getterFactory;
}
private FieldMapper primitiveIndexedFieldMapper(final Class> type, final Setter setter, final JdbcColumnKey key, final FieldMapperErrorHandler errorHandler) {
if (type.equals(Boolean.TYPE)) {
return new BooleanFieldMapper(
new BooleanResultSetGetter(key.getIndex()),
SetterFactory.toBooleanSetter(setter));
} else if (type.equals(Integer.TYPE)) {
return new IntFieldMapper(
new IntResultSetGetter(key.getIndex()),
SetterFactory.toIntSetter(setter));
} else if (type.equals(Long.TYPE)) {
return new LongFieldMapper(
new LongResultSetGetter(key.getIndex()),
SetterFactory.toLongSetter(setter));
} else if (type.equals(Float.TYPE)) {
return new FloatFieldMapper(
new FloatResultSetGetter(key.getIndex()),
SetterFactory.toFloatSetter(setter));
} else if (type.equals(Double.TYPE)) {
return new DoubleFieldMapper(
new DoubleResultSetGetter(key.getIndex()),
SetterFactory.toDoubleSetter(setter));
} else if (type.equals(Byte.TYPE)) {
return new ByteFieldMapper(
new ByteResultSetGetter(key.getIndex()),
SetterFactory.toByteSetter(setter));
} else if (type.equals(Character.TYPE)) {
return new CharacterFieldMapper(
new CharacterResultSetGetter(key.getIndex()),
SetterFactory.toCharacterSetter(setter));
} else if (type.equals(Short.TYPE)) {
return new ShortFieldMapper(
new ShortResultSetGetter(key.getIndex()),
SetterFactory.toShortSetter(setter));
} else {
throw new UnsupportedOperationException("Type " + type
+ " is not primitive");
}
}
@Override
public FieldMapper newFieldMapper(Type propretyType, Setter setter,
JdbcColumnKey key, FieldMapperErrorHandler errorHandler, MapperBuilderErrorHandler mappingErrorHandler) {
final Class> type = TypeHelper.toClass(propretyType);
if (type.isPrimitive()) {
return primitiveIndexedFieldMapper(type, setter, key, errorHandler);
}
Getter getter = getterFactory.newGetter(propretyType, key);
if (getter == null) {
// check if has a one arg construct
final Constructor>[] constructors = type.getConstructors();
if (constructors != null && constructors.length == 1 && constructors[0].getParameterTypes().length == 1) {
@SuppressWarnings("unchecked")
final Constructor constructor = (Constructor
) constructors[0];
getter = getterFactory.newGetter(constructor.getParameterTypes()[0], key);
if (getter != null) {
getter = new ConstructorOnGetter(constructor, getter);
}
} else if (key.getSqlType() != JdbcColumnKey.UNDEFINED_TYPE) {
Class> targetType = getTargetTypeFromSqlType(key.getSqlType());
if (targetType != null) {
try {
@SuppressWarnings("unchecked")
Constructor constructor = (Constructor
) type.getConstructor(targetType);
getter = getterFactory.newGetter(targetType, key);
if (getter != null) {
getter = new ConstructorOnGetter(constructor, getter);
}
} catch (Exception e) {
// ignore
}
}
}
}
if (getter == null) {
mappingErrorHandler.getterNotFound("Could not find getter for " + key + " type " + propretyType);
return null;
} else {
return new FieldMapperImpl(getter, setter);
}
}
public Class> getTargetTypeFromSqlType(int sqlType) {
switch (sqlType) {
case Types.LONGNVARCHAR:
case Types.LONGVARCHAR:
case Types.CHAR:
case Types.CLOB:
case Types.NCHAR:
case Types.NCLOB:
case Types.NVARCHAR:
case Types.VARCHAR:
return String.class;
case Types.BIGINT:
return Long.class;
case Types.INTEGER:
return Integer.class;
case Types.SMALLINT:
return Short.class;
case Types.TINYINT:
return Byte.class;
case Types.NUMERIC:
return BigDecimal.class;
case Types.FLOAT:
return Float.class;
case Types.DOUBLE:
return Double.class;
case Types.BOOLEAN:
return Boolean.class;
case Types.DATE:
case Types.TIMESTAMP:
return Date.class;
}
return null;
}
}