org.simpleflatmapper.csv.impl.CellSetterFactory Maven / Gradle / Ivy
package org.simpleflatmapper.csv.impl;
import org.simpleflatmapper.csv.CellValueReader;
import org.simpleflatmapper.csv.CellValueReaderFactory;
import org.simpleflatmapper.csv.CsvColumnDefinition;
import org.simpleflatmapper.csv.CsvColumnKey;
import org.simpleflatmapper.csv.impl.cellreader.*;
import org.simpleflatmapper.csv.impl.primitive.*;
import org.simpleflatmapper.csv.ParsingContextFactoryBuilder;
import org.simpleflatmapper.csv.mapper.CellSetter;
import org.simpleflatmapper.csv.mapper.CsvMapperCellHandler;
import org.simpleflatmapper.csv.mapper.DelayedCellSetterFactory;
import org.simpleflatmapper.map.MapperBuilderErrorHandler;
import org.simpleflatmapper.map.property.DefaultValueProperty;
import org.simpleflatmapper.reflect.Getter;
import org.simpleflatmapper.reflect.Instantiator;
import org.simpleflatmapper.reflect.InstantiatorDefinition;
import org.simpleflatmapper.reflect.instantiator.InstantiatorDefinitions;
import org.simpleflatmapper.reflect.meta.SubPropertyMeta;
import org.simpleflatmapper.reflect.setter.NullSetter;
import org.simpleflatmapper.reflect.ObjectSetterFactory;
import org.simpleflatmapper.reflect.Parameter;
import org.simpleflatmapper.reflect.Setter;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import org.simpleflatmapper.reflect.meta.DefaultPropertyNameMatcher;
import org.simpleflatmapper.reflect.meta.PropertyMeta;
import org.simpleflatmapper.util.ConstantPredicate;
import org.simpleflatmapper.util.ErrorDoc;
import org.simpleflatmapper.util.Predicate;
import org.simpleflatmapper.util.TypeHelper;
import java.lang.reflect.Type;
import java.util.Date;
public final class CellSetterFactory {
public static final InstantiatorDefinitions.CompatibilityScorer COMPATIBILITY_SCORER = new InstantiatorDefinitions.CompatibilityScorer() {
@Override
public int score(InstantiatorDefinition id) {
Class> type = TypeHelper.toBoxedClass(id.getParameters()[0].getType());
if (type == String.class || type == CharSequence.class) {
return 10;
}
if (Number.class.isAssignableFrom(type)) {
return 9;
}
if (Date.class.isAssignableFrom(type)) {
return 8;
}
return 0;
}
};
private final CellValueReaderFactory cellValueReaderFactory;
private final MapperBuilderErrorHandler mapperBuilderErrorHandler;
public CellSetterFactory(CellValueReaderFactory cellValueReaderFactory, MapperBuilderErrorHandler mapperBuilderErrorHandler) {
this.cellValueReaderFactory = cellValueReaderFactory;
this.mapperBuilderErrorHandler = mapperBuilderErrorHandler;
}
@SuppressWarnings("unchecked")
public CellSetter getPrimitiveCellSetter(Class> clazz, CellValueReader extends P> reader, Setter super T, ? super P> setter) {
if (boolean.class.equals(clazz)) {
return new BooleanCellSetter(ObjectSetterFactory.toBooleanSetter((Setter super T, ? super Boolean>) setter), booleanReader(reader));
} else if (byte.class.equals(clazz)) {
return new ByteCellSetter(ObjectSetterFactory.toByteSetter((Setter super T, ? super Byte>) setter), byteReader(reader));
} else if (char.class.equals(clazz)) {
return new CharCellSetter(ObjectSetterFactory.toCharacterSetter((Setter super T, ? super Character>) setter), charReader(reader));
} else if (short.class.equals(clazz)) {
return new ShortCellSetter(ObjectSetterFactory.toShortSetter((Setter super T, ? super Short>) setter), shortReader(reader));
} else if (int.class.equals(clazz)) {
return new IntCellSetter(ObjectSetterFactory.toIntSetter((Setter super T, ? super Integer>) setter), intReader(reader));
} else if (long.class.equals(clazz)) {
return new LongCellSetter(ObjectSetterFactory.toLongSetter((Setter super T, ? super Long>) setter), longReader(reader));
} else if (float.class.equals(clazz)) {
return new FloatCellSetter(ObjectSetterFactory.toFloatSetter((Setter super T, ? super Float>) setter), floatReader(reader));
} else if (double.class.equals(clazz)) {
return new DoubleCellSetter(ObjectSetterFactory.toDoubleSetter((Setter super T, ? super Double>) setter), doubleReader(reader));
}
throw new IllegalArgumentException("Invalid primitive type " + clazz);
}
@SuppressWarnings("unchecked")
private DoubleCellValueReader doubleReader(CellValueReader> reader) {
if (reader instanceof DoubleCellValueReader) {
return (DoubleCellValueReader) reader;
} else {
return new BoxedDoubleCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private FloatCellValueReader floatReader(CellValueReader> reader) {
if (reader instanceof FloatCellValueReader) {
return (FloatCellValueReader) reader;
} else {
return new BoxedFloatCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private LongCellValueReader longReader(CellValueReader> reader) {
if (reader instanceof LongCellValueReader) {
return (LongCellValueReader) reader;
} else {
return new BoxedLongCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private IntegerCellValueReader intReader(CellValueReader> reader) {
if (reader instanceof IntegerCellValueReader) {
return (IntegerCellValueReader) reader;
} else {
return new BoxedIntegerCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private ShortCellValueReader shortReader(CellValueReader> reader) {
if (reader instanceof ShortCellValueReader) {
return (ShortCellValueReader) reader;
} else {
return new BoxedShortCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private CharCellValueReader charReader(CellValueReader> reader) {
if (reader instanceof CharCellValueReader) {
return (CharCellValueReader) reader;
} else {
return new BoxedCharCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private ByteCellValueReader byteReader(CellValueReader> reader) {
if (reader instanceof ByteCellValueReader) {
return (ByteCellValueReader) reader;
} else {
return new BoxedByteCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private BooleanCellValueReader booleanReader(CellValueReader> reader) {
if (reader instanceof BooleanCellValueReader) {
return (BooleanCellValueReader) reader;
} else {
return new BoxedBooleanCellValueReader((CellValueReader) reader);
}
}
@SuppressWarnings("unchecked")
private DelayedCellSetterFactory getPrimitiveDelayedCellSetter(Class> clazz, CellValueReader extends P> reader, Setter super T, ? super P> setter) {
if (boolean.class.equals(clazz)) {
return (DelayedCellSetterFactory) new BooleanDelayedCellSetterFactory(ObjectSetterFactory.toBooleanSetter((Setter super T, ? super Boolean>) setter), booleanReader(reader));
} else if (byte.class.equals(clazz)) {
return (DelayedCellSetterFactory) new ByteDelayedCellSetterFactory(ObjectSetterFactory.toByteSetter((Setter super T, ? super Byte>) setter), byteReader(reader));
} else if (char.class.equals(clazz)) {
return (DelayedCellSetterFactory) new CharDelayedCellSetterFactory(ObjectSetterFactory.toCharacterSetter((Setter super T, ? super Character>) setter), charReader(reader));
} else if (short.class.equals(clazz)) {
return (DelayedCellSetterFactory) new ShortDelayedCellSetterFactory(ObjectSetterFactory.toShortSetter((Setter super T, ? super Short>) setter), shortReader(reader));
} else if (int.class.equals(clazz)) {
return (DelayedCellSetterFactory) new IntDelayedCellSetterFactory(ObjectSetterFactory.toIntSetter((Setter super T, ? super Integer>) setter), intReader(reader));
} else if (long.class.equals(clazz)) {
return (DelayedCellSetterFactory) new LongDelayedCellSetterFactory(ObjectSetterFactory.toLongSetter((Setter super T, ? super Long>) setter), longReader(reader));
} else if (float.class.equals(clazz)) {
return (DelayedCellSetterFactory) new FloatDelayedCellSetterFactory(ObjectSetterFactory.toFloatSetter((Setter super T, ? super Float>) setter), floatReader(reader));
} else if (double.class.equals(clazz)) {
return (DelayedCellSetterFactory) new DoubleDelayedCellSetterFactory(ObjectSetterFactory.toDoubleSetter((Setter super T, ? super Double>) setter), doubleReader(reader));
}
throw new IllegalArgumentException("Invalid primitive type " + clazz);
}
@SuppressWarnings("unchecked")
public Getter, P> newDelayedGetter(CsvColumnKey key, Type type) {
Class> clazz = TypeHelper.toClass(type);
Getter getter;
int columnIndex = key.getIndex();
if (clazz.isPrimitive()) {
if (boolean.class.equals(clazz)) {
getter = new BooleanDelayedGetter(columnIndex);
} else if (byte.class.equals(clazz)) {
getter = new ByteDelayedGetter(columnIndex);
} else if (char.class.equals(clazz)) {
getter = new CharDelayedGetter(columnIndex);
} else if (short.class.equals(clazz)) {
getter = new ShortDelayedGetter(columnIndex);
} else if (int.class.equals(clazz)) {
getter = new IntDelayedGetter(columnIndex);
} else if (long.class.equals(clazz)) {
getter = new LongDelayedGetter(columnIndex);
} else if (float.class.equals(clazz)) {
getter = new FloatDelayedGetter(columnIndex);
} else if (double.class.equals(clazz)) {
getter = new DoubleDelayedGetter(columnIndex);
} else {
throw new IllegalArgumentException("Unexpected primitive " + clazz);
}
} else {
getter = new DelayedGetter(columnIndex);
}
return getter;
}
@SuppressWarnings({"unchecked" })
private CellValueReader
getReader(PropertyMeta, P> pm, int index, CsvColumnDefinition columnDefinition, ParsingContextFactoryBuilder parsingContextFactoryBuilder) {
CellValueReader
reader = null;
if (columnDefinition.hasCustomSourceFrom(pm.getOwnerType())) {
reader = (CellValueReader
) columnDefinition.getCustomReader();
}
if (reader == null) {
reader = cellValueReaderFromFactory(pm, index, columnDefinition, parsingContextFactoryBuilder);
}
if (reader == null) {
mapperBuilderErrorHandler.accessorNotFound("Could not find reader for "
+ pm + " See " + ErrorDoc.toUrl("CSFM_GETTER_NOT_FOUND"));
}
return reader;
}
private
CellValueReader
cellValueReaderFromFactory(PropertyMeta, ?> pm, int index, CsvColumnDefinition columnDefinition, ParsingContextFactoryBuilder parsingContextFactoryBuilder) {
Type propertyType = pm.getPropertyType();
CellValueReader
reader = null;
if (columnDefinition.hasCustomReaderFactory()) {
CellValueReaderFactory factory = columnDefinition.getCustomCellValueReaderFactory();
reader = factory.getReader(propertyType, index, columnDefinition, parsingContextFactoryBuilder);
}
if (reader == null) {
reader = cellValueReaderFactory.getReader(propertyType, index, columnDefinition, parsingContextFactoryBuilder);
}
if (reader == null) {
if (!pm.isSelf()) {
final ClassMeta> classMeta = pm.getPropertyClassMeta();
InstantiatorDefinition id = InstantiatorDefinitions.lookForCompatibleOneArgument(classMeta.getInstantiatorDefinitions(), COMPATIBILITY_SCORER);
if (id != null) {
final Parameter parameter = id.getParameters()[0];
// look for constructor property matching name
final PropertyMeta, Object> property = classMeta.newPropertyFinder(new Predicate>() {
@Override
public boolean test(PropertyMeta, ?> propertyMeta) {
return propertyMeta.isConstructorProperty()
|| propertyMeta.isSubProperty() && ((SubPropertyMeta)propertyMeta).getOwnerProperty().isConstructorProperty();
}
}).findProperty(DefaultPropertyNameMatcher.exact(parameter.getName()));
reader = cellValueReaderFromFactory(property, index, columnDefinition, parsingContextFactoryBuilder);
if (reader != null) {
Instantiator instantiator =
classMeta.getReflectionService().getInstantiatorFactory().getOneArgIdentityInstantiator(id);
return
new InstantiatorOnReader
(instantiator, reader);
}
}
}
}
return reader;
}
@SuppressWarnings("unchecked")
public CellSetter getCellSetter(PropertyMeta prop, int index, CsvColumnDefinition columnDefinition, ParsingContextFactoryBuilder parsingContextFactoryBuilder) {
Class extends P> propertyClass = (Class extends P>) TypeHelper.toClass(prop.getPropertyType());
CellValueReader extends P> reader = getReader(prop, index, columnDefinition, parsingContextFactoryBuilder);
if (propertyClass.isPrimitive()) {
return getPrimitiveCellSetter(propertyClass, reader, getSetter(prop));
} else {
return new CellSetterImpl(reader, getSetter(prop));
}
}
public DelayedCellSetterFactory getDelayedCellSetter(PropertyMeta prop, int index, CsvColumnDefinition columnDefinition, ParsingContextFactoryBuilder parsingContextFactoryBuilder) {
Class extends P> propertyClass = TypeHelper.toClass(prop.getPropertyType());
CellValueReader extends P> reader = getReader(prop, index, columnDefinition, parsingContextFactoryBuilder);
DelayedCellSetterFactory factory;
final Setter super T, ? super P> setter = getSetter(prop);
if (propertyClass.isPrimitive()) {
factory = getPrimitiveDelayedCellSetter(propertyClass, reader, setter);
} else {
factory = new DelayedCellSetterFactoryImpl(reader, setter);
}
final DefaultValueProperty defaultValueProperty = columnDefinition.lookFor(DefaultValueProperty.class);
if (defaultValueProperty != null) {
factory = new DefaultValueDelayedCallSetterFactory(factory, defaultValueProperty, setter);
}
return factory;
}
private Setter super T, ? super P> getSetter(PropertyMeta prop) {
Setter super T, ? super P> setter = prop.getSetter();
if (NullSetter.isNull(setter)) {
return null;
} else {
return setter;
}
}
}