Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.sfm.jdbc;
import org.sfm.jdbc.impl.*;
import org.sfm.jdbc.impl.getter.ResultSetGetterFactory;
import org.sfm.map.*;
import org.sfm.map.impl.*;
import org.sfm.reflect.Instantiator;
import org.sfm.reflect.ReflectionService;
import org.sfm.reflect.TypeReference;
import org.sfm.reflect.meta.ClassMeta;
import org.sfm.reflect.meta.PropertyNameMatcherFactory;
import org.sfm.tuples.Tuple2;
import org.sfm.utils.ErrorHelper;
import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* @param the targeted type of the mapper
*/
public final class JdbcMapperBuilder extends AbstractFieldMapperMapperBuilder {
public static final int NO_ASM_MAPPER_THRESHOLD = 792; // see https://github.com/arnaudroger/SimpleFlatMapper/issues/152
public static final JdbcColumnKey[] EMPTY_COLUMNKEYS = new JdbcColumnKey[0];
private int calculatedIndex = 1;
private RowHandlerErrorHandler jdbcMapperErrorHandler = new RethrowRowHandlerErrorHandler();
private final boolean failOnAsm;
private final int asmMapperNbFieldsLimit;
/**
* Build a new JdbcMapperBuilder targeting the type specified by the TypeReference. The TypeReference
* allow you to provide a generic type with check of T
* new TypeReference<List<String>>() {}
*
* @param target the TypeReference to the type T to map to
*/
public JdbcMapperBuilder(final TypeReference target) {
this(target.getType());
}
/**
* Build a new JdbcMapperBuilder targeting the specified type.
*
* @param target the type
*/
public JdbcMapperBuilder(final Type target) {
this(target, ReflectionService.newInstance());
}
/**
* Build a new JdbcMapperBuilder targeting the specified type with the specified ReflectionService.
*
* @param target the type
* @param reflectService the ReflectionService
*/
public JdbcMapperBuilder(final Type target, ReflectionService reflectService) {
this(reflectService.getRootClassMeta(target),
new RethrowMapperBuilderErrorHandler(),
new IdentityFieldMapperColumnDefinitionProvider(),
new DefaultPropertyNameMatcherFactory(),
new ResultSetGetterFactory(),
false,
NO_ASM_MAPPER_THRESHOLD,
new JdbcMappingContextFactoryBuilder());
}
/**
* @param classMeta the meta for the target class.
* @param mapperBuilderErrorHandler the error handler.
* @param columnDefinitions the predefined ColumnDefinition.
* @param propertyNameMatcherFactory the PropertyNameMatcher factory.
* @param getterFactory the Getter factory.
* @param failOnAsm should we fail on asm generation.
* @param parentBuilder the parent builder, null if none.
*/
public JdbcMapperBuilder(final ClassMeta classMeta, final MapperBuilderErrorHandler mapperBuilderErrorHandler,
final ColumnDefinitionProvider, JdbcColumnKey> columnDefinitions,
PropertyNameMatcherFactory propertyNameMatcherFactory,
GetterFactory getterFactory, boolean failOnAsm, int asmMapperNbFieldsLimit,
MappingContextFactoryBuilder parentBuilder) {
super(ResultSet.class, classMeta, getterFactory, new ResultSetFieldMapperFactory(getterFactory), columnDefinitions, propertyNameMatcherFactory, mapperBuilderErrorHandler, parentBuilder);
this.failOnAsm = failOnAsm;
this.asmMapperNbFieldsLimit = asmMapperNbFieldsLimit;
}
/**
* @return a new instance of the mapper based on the current state of the builder.
*/
@Override
public JdbcMapper mapper() {
JdbcMapper mapper = buildMapper();
if (!mappingContextFactoryBuilder.isRoot()
|| mappingContextFactoryBuilder.hasNoDependentKeys()) {
return mapper;
} else {
return new JoinJdbcMapper(mapper, jdbcMapperErrorHandler);
}
}
private JdbcMapper buildMapper() {
FieldMapper[] fields = fields();
Tuple2[], Instantiator> constructorFieldMappersAndInstantiator = getConstructorFieldMappersAndInstantiator();
MappingContextFactory mappingContextFactory = null;
if (mappingContextFactoryBuilder.isRoot()) {
mappingContextFactory = mappingContextFactoryBuilder.newFactory();
}
if (isEligibleForAsmMapper()) {
try {
return reflectionService.getAsmFactory().createJdbcMapper(
getKeys(),
fields, constructorFieldMappersAndInstantiator.first(),
constructorFieldMappersAndInstantiator.second(),
getTargetClass(), jdbcMapperErrorHandler, mappingContextFactory);
} catch (Exception e) {
if (failOnAsm) {
return ErrorHelper.rethrow(e);
} else {
return new JdbcMapperImpl(fields, constructorFieldMappersAndInstantiator.first(), constructorFieldMappersAndInstantiator.second(), jdbcMapperErrorHandler, mappingContextFactory);
}
}
} else {
return new JdbcMapperImpl(fields, constructorFieldMappersAndInstantiator.first(), constructorFieldMappersAndInstantiator.second(), jdbcMapperErrorHandler, mappingContextFactory);
}
}
private JdbcColumnKey[] getKeys() {
return propertyMappingsBuilder.getKeys().toArray(EMPTY_COLUMNKEYS);
}
private boolean isEligibleForAsmMapper() {
return reflectionService.isAsmActivated()
&& propertyMappingsBuilder.size() < asmMapperNbFieldsLimit;
}
/**
* add a new mapping to the specified column with a key column definition and an undefined type.
* The index is incremented for each non indexed column mapping.
*
* @param column the column name
* @return the current builder
*/
public JdbcMapperBuilder addKey(String column) {
return addMapping(column, calculatedIndex++, FieldMapperColumnDefinition.key());
}
/**
* add a new mapping to the specified column with an undefined type. The index is incremented for each non indexed column mapping.
*
* @param column the column name
* @return the current builder
*/
public JdbcMapperBuilder addMapping(String column) {
return addMapping(column, calculatedIndex++);
}
/**
* add a new mapping to the specified column with the specified columnDefinition and an undefined type. The index is incremented for each non indexed column mapping.
*
* @param column the column name
* @param columnDefinition the definition
* @return the current builder
*/
public JdbcMapperBuilder addMapping(final String column, final FieldMapperColumnDefinition columnDefinition) {
return addMapping(column, calculatedIndex++, columnDefinition);
}
/**
* add a new mapping to the specified column with the specified index and an undefined type.
*
* @param column the column name
* @param index the column index
* @return the current builder
*/
public JdbcMapperBuilder addMapping(String column, int index) {
return addMapping(column, index, JdbcColumnKey.UNDEFINED_TYPE);
}
/**
* add a new mapping to the specified column with the specified index, specified column definition and an undefined type.
*
* @param column the column name
* @param index the column index
* @param columnDefinition the column definition
* @return the current builder
*/
public JdbcMapperBuilder addMapping(String column, int index, final FieldMapperColumnDefinition columnDefinition) {
return addMapping(column, index, JdbcColumnKey.UNDEFINED_TYPE, columnDefinition);
}
/**
* append a FieldMapper to the mapping list.
*
* @param mapper the field mapper
* @return the current builder
*/
public JdbcMapperBuilder addMapper(FieldMapper mapper) {
_addMapper(mapper);
return this;
}
/**
* add a new mapping to the specified column with the specified index and the specified type.
*
* @param column the column name
* @param index the column index
* @param sqlType the column type, @see java.sql.Types
* @return the current builder
*/
public JdbcMapperBuilder addMapping(final String column, final int index, final int sqlType) {
addMapping(column, index, sqlType, FieldMapperColumnDefinition.identity());
return this;
}
/**
* add a new mapping to the specified column with the specified index, the specified type.
*
* @param column the column name
* @param index the column index
* @param sqlType the column type, @see java.sql.Types
* @param columnDefinition the column definition
* @return the current builder
*/
public JdbcMapperBuilder addMapping(final String column, final int index, final int sqlType, FieldMapperColumnDefinition columnDefinition) {
_addMapping(new JdbcColumnKey(column, index, sqlType), columnDefinition);
return this;
}
/**
* add the all the column present in the metaData
*
* @param metaData the metaDAta
* @return the current builder
* @throws SQLException when an error occurs getting the metaData
*/
public JdbcMapperBuilder addMapping(final ResultSetMetaData metaData) throws SQLException {
for (int i = 1; i <= metaData.getColumnCount(); i++) {
addMapping(metaData.getColumnLabel(i), i, metaData.getColumnType(i));
}
return this;
}
@Override
protected AbstractFieldMapperMapperBuilder newSubBuilder(Type type, ClassMeta classMeta, MappingContextFactoryBuilder mappingContextFactoryBuilder) {
return new JdbcMapperBuilder(classMeta, mapperBuilderErrorHandler, columnDefinitions, propertyNameMatcherFactory,
new ResultSetGetterFactory(), failOnAsm, asmMapperNbFieldsLimit, mappingContextFactoryBuilder);
}
/**
* the FieldMapperErrorHandler is called when a error occurred when mapping a field from the source to the target.
* By default it just throw the Exception.
* @param errorHandler the new FieldMapperErrorHandler
* @return the current builder
*/
public JdbcMapperBuilder fieldMapperErrorHandler(FieldMapperErrorHandler errorHandler) {
setFieldMapperErrorHandler(errorHandler);
return this;
}
/**
* the RowHandlerErrorHandler is called when an exception is thrown by the RowHandler in the forEach call.
* @param jdbcMapperErrorHandler the new RowHandlerErrorHandler
* @return the current builder
*/
public JdbcMapperBuilder jdbcMapperErrorHandler(RowHandlerErrorHandler jdbcMapperErrorHandler) {
this.jdbcMapperErrorHandler = jdbcMapperErrorHandler;
return this;
}
}