All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sfm.jdbc.JdbcMapperFactory Maven / Gradle / Ivy

Go to download

Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.

There is a newer version: 1.10.3
Show newest version
package org.sfm.jdbc;

import org.sfm.jdbc.impl.DynamicJdbcMapper;
import org.sfm.jdbc.impl.getter.ResultSetGetterFactory;
import org.sfm.map.*;
import org.sfm.map.impl.*;
import org.sfm.reflect.Getter;
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.utils.Predicate;

import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Map;

/**
 *
 */
public final class JdbcMapperFactory {


    /**
	 * instantiate a new JdbcMapperFactory
	 * @return a new instance JdbcMapperFactory
	 */
	public static JdbcMapperFactory newInstance() {
		return new JdbcMapperFactory();
	}

	private FieldMapperErrorHandler fieldMapperErrorHandler = null;

    private MapperBuilderErrorHandler mapperBuilderErrorHandler = new RethrowMapperBuilderErrorHandler();
    private RowHandlerErrorHandler rowHandlerErrorHandler = new RethrowRowHandlerErrorHandler();
    private FieldMapperColumnDefinitionProviderImpl columnDefinitions = new FieldMapperColumnDefinitionProviderImpl();
	private PropertyNameMatcherFactory propertyNameMatcherFactory = new DefaultPropertyNameMatcherFactory();

    private GetterFactory getterFactory = new ResultSetGetterFactory();
	private boolean useAsm = true;

    private boolean disableAsm = false;
    private boolean failOnAsm = false;

    private ReflectionService reflectionService = null;

	private JdbcMapperFactory() {
	}

    /**
     * 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 fieldMapperErrorHandler the new FieldMapperErrorHandler
     * @return the current factory
     */
	public JdbcMapperFactory fieldMapperErrorHandler(final FieldMapperErrorHandler fieldMapperErrorHandler) {
		this.fieldMapperErrorHandler = fieldMapperErrorHandler;
		return this;
	}

    /**
     * Change the mapperBuilderErrorHandler to an IgnoreMapperBuilderErrorHandler.
     * @return the current factory
     */
    public JdbcMapperFactory ignorePropertyNotFound() {
        this.mapperBuilderErrorHandler = new IgnoreMapperBuilderErrorHandler();
        return this;
    }

    /**
	 * Set the new MapperBuilderErrorHandler. the MapperBuilderErrorHandler is called when an error occurred or a property is not found in the builder while creating the mapper.
	 * @param mapperBuilderErrorHandler the MapperBuilderErrorHandler
	 * @return the current factory
	 */
	public JdbcMapperFactory mapperBuilderErrorHandler(final MapperBuilderErrorHandler mapperBuilderErrorHandler) {
		this.mapperBuilderErrorHandler = mapperBuilderErrorHandler;
		return this;
	}


    /**
     * the RowHandlerErrorHandler is called when an exception is thrown by the RowHandler in the forEach call.
     * @param rowHandlerErrorHandler the new RowHandlerErrorHandler
     * @return the current factory
     */
	public JdbcMapperFactory rowHandlerErrorHandler(final RowHandlerErrorHandler rowHandlerErrorHandler) {
		this.rowHandlerErrorHandler = rowHandlerErrorHandler;
		return this;
	}

	/**
	 * 
	 * @param useAsm false if you want to disable asm generation of Mappers, Getter and Setter. This would be active by default if asm is present in a compatible version.
	 * @return the current factory
	 */
	public JdbcMapperFactory useAsm(final boolean useAsm) {
		this.useAsm = useAsm;
		return this;
	}
	
	/**
	 * @param disableAsm true if you want to disable asm for generation and to resolve constructor parameter names.
     * @return the current factory
	 */
	public JdbcMapperFactory disableAsm(final boolean disableAsm) {
		this.disableAsm = disableAsm;
		return this;
	}

    /**
     * Override the default implementation of the GetterFactory used to get access to value from the ResultSet.
     * @param getterFactory the getterFactory
     * @return the current factory
     */
	public JdbcMapperFactory getterFactory(final GetterFactory getterFactory) {
		this.getterFactory = getterFactory;
		return this;
	}

    /**
     * Override the default implementation of the ReflectionService.
     * @param reflectionService the overriding instance
     * @return the current factory
     */
    public JdbcMapperFactory reflectionService(final ReflectionService reflectionService) {
        this.reflectionService = reflectionService;
        return this;
    }


	/**
	 * Will create a instance of JdbcMapper based on the specified metadata and the target class.
	 * @param target the target class of the mapper
	 * @param metaData the metadata to create the mapper from
	 * @return a mapper that will map the data represented by the metadata to an instance of target
	 */
	public  JdbcMapper newMapper(final Class target, final ResultSetMetaData metaData) throws SQLException {
		JdbcMapperBuilder builder = newBuilder(target);
		builder.addMapping(metaData);
		return builder.mapper();
	}
	
	/**
	 * Will create a instance of JdbcMapperBuilder on the specified target class.
	 * @param target the target class
	 * @return the builder
	 */
	public  JdbcMapperBuilder newBuilder(final Class target) {
		return newBuilder((Type)target);
	}

    /**
     * Will create a instance of JdbcMapperBuilder on the type T specified by the typeReference.
     * @param target the typeReference
     * @return the builder
     */
    public  JdbcMapperBuilder newBuilder(final TypeReference target) {
        return newBuilder(target.getType());
    }

    /**
     * Will create a instance of JdbcMapperBuilder on the specified type.
     * @param target the type
     * @return the builder
     */
    public  JdbcMapperBuilder newBuilder(final Type target) {
		ClassMeta classMeta = getClassMeta(target);

		JdbcMapperBuilder builder = new JdbcMapperBuilder(classMeta, mapperBuilderErrorHandler, columnDefinitions, propertyNameMatcherFactory, getterFactory, failOnAsm, new JdbcMappingContextFactoryBuilder());
		
		builder.fieldMapperErrorHandler(fieldMapperErrorHandler);
		builder.jdbcMapperErrorHandler(rowHandlerErrorHandler);
		return builder;
	}

	/**
	 * Will create a DynamicMapper on the specified target class.
	 * @param target the class
	 * @return the DynamicMapper
	 */
	public  JdbcMapper newMapper(final Class target) {
		return newMapper((Type)target);
	}

    /**
     * Will create a DynamicMapper on the type specified by the TypeReference.
     * @param target the TypeReference
     * @return the DynamicMapper
     */
    public  JdbcMapper newMapper(final TypeReference target) {
        return newMapper(target.getType());
    }

    /**
     * Will create a DynamicMapper on the specified type.
     * @param target the type
     * @return the DynamicMapper
     */
	public  JdbcMapper newMapper(final Type target) {
		ClassMeta classMeta = getClassMeta(target);
		return new DynamicJdbcMapper(classMeta, fieldMapperErrorHandler, mapperBuilderErrorHandler, rowHandlerErrorHandler, columnDefinitions, propertyNameMatcherFactory, failOnAsm);
	}


	/**
	 * Associate an alias on the column key to rename to value.
	 * @param key the column to rename
	 * @param value then name to rename to
	 * @return the current factory
	 */
	public JdbcMapperFactory addAlias(String key, String value) {
		return addColumnDefinition(key, FieldMapperColumnDefinition.renameDefinition(value));
	}

	/**
	 * Associate the specified FieldMapper for the specified column.
	 * @param key the column
	 * @param fieldMapper the fieldmapper
	 * @return the current factory
	 */
	public JdbcMapperFactory addCustomFieldMapper(String key, FieldMapper fieldMapper) {
		return addColumnDefinition(key, FieldMapperColumnDefinition.customFieldMapperDefinition(fieldMapper));
	}

    /**
     * Associate the specified Getter for the specified column.
     * @param key the column
     * @param getter the getter
     * @return the current factory
     */
	public JdbcMapperFactory addCustomGetter(String key, Getter getter) {
		return addColumnDefinition(key, FieldMapperColumnDefinition.customGetter(getter));
	}

    /**
     * Associate the specified columnDefinition to the specified column.
     * @param key the column
     * @param columnDefinition the columnDefinition
     * @return the current factory
     */
	public JdbcMapperFactory addColumnDefinition(String key, FieldMapperColumnDefinition columnDefinition) {
		return addColumnDefinition(new CaseInsensitiveFieldKeyNamePredicate(key), columnDefinition);
	}

    /**
     * Associate the specified columnDefinition to the column matching the predicate.
     * @param predicate the column predicate
     * @param columnDefinition the columnDefinition
     * @return the current factory
     */
	public JdbcMapperFactory addColumnDefinition(Predicate predicate, FieldMapperColumnDefinition columnDefinition) {
		columnDefinitions.addColumnDefinition(predicate, columnDefinition);
		return this;
	}

    /**
     * Override the default PropertyNameMatcherFactory with the specified factory.
     * @param propertyNameMatcherFactory the factory
     * @return the current factory
     */
	public JdbcMapperFactory propertyNameMatcherFactory(PropertyNameMatcherFactory propertyNameMatcherFactory) {
		this.propertyNameMatcherFactory = propertyNameMatcherFactory;
		return this;
	}

    /**
     * Associate the aliases value to the column key.
     * @param aliases the key value pair
     * @return the current factory
     */
    public JdbcMapperFactory addAliases(Map aliases) {
		for(Map.Entry e : aliases.entrySet()) {
			addAlias(e.getKey(), e.getValue());
		}
		return this;
	}

    /**
     * @param b true if we want the builder to fail on asm generation failure
     * @return the current factory
     */
    public JdbcMapperFactory failOnAsm(boolean b) {
        this.failOnAsm = b;
        return this;
    }

    /**
     * Mark the specified columns as keys.
     * @param columns the columns
     * @return  the current factory
     */
    public JdbcMapperFactory addKeys(String... columns) {
        for(String col : columns) {
            addColumnDefinition(col, FieldMapperColumnDefinition.key());
        }
        return this;
    }

    /**
     * Create a discriminator builder based on the specified column
     * @param column the discriminator column
     * @param  the root type of the mapper
     * @return a builder to specify the type mapping
     */
    public  DiscriminatorJdbcBuilder newDiscriminator(String column) {
        ignorePropertyNotFound();
        addColumnDefinition(column, FieldMapperColumnDefinition.ignoreDefinition());
        return new DiscriminatorJdbcBuilder(column, this);
    }

    /**
     * @return the current RowHandlerErrorHandler
     */
    public RowHandlerErrorHandler rowHandlerErrorHandler() {
        return rowHandlerErrorHandler;
    }


    private  ClassMeta getClassMeta(Type target) {
        return getReflectionService().getRootClassMeta(target);
    }

    private ReflectionService getReflectionService() {
        if (reflectionService != null) {
            return reflectionService;
        } else {
            return ReflectionService.newInstance(disableAsm, useAsm);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy