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

org.simpleflatmapper.jdbc.PreparedStatementMapperBuilder 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: 9.0.2
Show newest version
package org.simpleflatmapper.jdbc;


import org.simpleflatmapper.jdbc.impl.CollectionIndexFieldMapper;
import org.simpleflatmapper.jdbc.impl.MultiIndexQueryPreparer;
import org.simpleflatmapper.jdbc.impl.PreparedStatementIndexedSetterFactory;
import org.simpleflatmapper.jdbc.impl.SingleIndexFieldMapper;
import org.simpleflatmapper.jdbc.impl.MapperQueryPreparer;
import org.simpleflatmapper.jdbc.impl.setter.PreparedStatementIndexSetter;
import org.simpleflatmapper.jdbc.impl.setter.PreparedStatementIndexSetterOnGetter;
import org.simpleflatmapper.jdbc.named.NamedSqlQuery;
import org.simpleflatmapper.map.MappingContext;
import org.simpleflatmapper.map.mapper.AbstractConstantTargetMapperBuilder;
import org.simpleflatmapper.map.MapperConfig;
import org.simpleflatmapper.map.mapper.ColumnDefinition;
import org.simpleflatmapper.map.property.FieldMapperColumnDefinition;
import org.simpleflatmapper.jdbc.property.IndexedSetterFactoryProperty;
import org.simpleflatmapper.jdbc.property.IndexedSetterProperty;
import org.simpleflatmapper.map.mapper.ConstantTargetFieldMapperFactory;
import org.simpleflatmapper.map.mapper.PropertyMapping;
import org.simpleflatmapper.reflect.BiInstantiator;
import org.simpleflatmapper.reflect.Getter;
import org.simpleflatmapper.reflect.IndexedGetter;
import org.simpleflatmapper.reflect.IndexedSetter;
import org.simpleflatmapper.reflect.IndexedSetterFactory;
import org.simpleflatmapper.reflect.getter.ArrayIndexedGetter;
import org.simpleflatmapper.reflect.getter.ArraySizeGetter;
import org.simpleflatmapper.reflect.getter.ListIndexedGetter;
import org.simpleflatmapper.reflect.getter.ListSizeGetter;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import org.simpleflatmapper.reflect.meta.DefaultPropertyNameMatcher;
import org.simpleflatmapper.reflect.meta.ObjectClassMeta;
import org.simpleflatmapper.reflect.meta.PropertyMeta;
import org.simpleflatmapper.reflect.primitive.IntGetter;
import org.simpleflatmapper.util.ConstantPredicate;
import org.simpleflatmapper.util.ErrorDoc;
import org.simpleflatmapper.util.ForEachCallBack;
import org.simpleflatmapper.util.TypeHelper;

import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;


public class PreparedStatementMapperBuilder extends AbstractConstantTargetMapperBuilder> {

    private IndexedSetterFactory>> indexedSetterFactory = PreparedStatementIndexedSetterFactory.INSTANCE;

    public PreparedStatementMapperBuilder(
            ClassMeta classMeta,
            MapperConfig> mapperConfig,
            ConstantTargetFieldMapperFactory preparedStatementFieldMapperFactory) {
        super(classMeta, PreparedStatement.class, mapperConfig, preparedStatementFieldMapperFactory);
    }

    private PreparedStatementMapperBuilder(PreparedStatementMapperBuilder builder) {
        this(builder.classMeta, builder.mapperConfig, builder.fieldAppenderFactory);
    }

    @Override
    protected BiInstantiator, PreparedStatement> getInstantiator() {
        return new NullInstantiator();
    }

    @Override
    protected JdbcColumnKey newKey(String column, int i, FieldMapperColumnDefinition columnDefinition) {
        JdbcColumnKey key = new JdbcColumnKey(column, i);

        SqlTypeColumnProperty typeColumnProperty = columnDefinition.lookFor(SqlTypeColumnProperty.class);

        if (typeColumnProperty == null) {
            FieldMapperColumnDefinition globalDef = mapperConfig.columnDefinitions().getColumnDefinition(key);
            typeColumnProperty = globalDef.lookFor(SqlTypeColumnProperty.class);
        }

        if (typeColumnProperty != null) {
            return new JdbcColumnKey(key.getName(), key.getIndex(), typeColumnProperty.getSqlType(), key);
        }

        return key;
    }

    private static class NullInstantiator implements BiInstantiator,  PreparedStatement> {
        @Override
        public PreparedStatement newInstance(T o, MappingContext context) throws Exception {
            throw new UnsupportedOperationException();
        }
    }

    protected int getStartingIndex() {
        return 1;
    }

    public QueryPreparer to(NamedSqlQuery query) {
        return to(query, null);
    }

    public QueryPreparer to(NamedSqlQuery query, String[] generatedKeys) {

        PreparedStatementMapperBuilder builder =
                new PreparedStatementMapperBuilder(this);

        return builder.preparedStatementMapper(query, generatedKeys);
    }

    private QueryPreparer preparedStatementMapper(NamedSqlQuery query, String[] generatedKeys) {

        for(int i = 0; i < query.getParametersSize(); i++) {
            addColumn(query.getParameter(i).getName());
        }

        boolean hasMultiIndex =
                propertyMappingsBuilder.forEachProperties(new ForEachCallBack>>() {
                    boolean hasMultiIndex;

                    @Override
                    public void handle(PropertyMapping> pm) {
                        hasMultiIndex |= isMultiIndex(pm.getPropertyMeta());
                    }


                }).hasMultiIndex;


        if (hasMultiIndex) {
            return new MultiIndexQueryPreparer(query, buildIndexFieldMappers(), generatedKeys);
        } else {
            return new MapperQueryPreparer(query, mapper(), generatedKeys);
        }
    }

    private boolean isMultiIndex(PropertyMeta propertyMeta) {
        return
                TypeHelper.isArray(propertyMeta.getPropertyType())
                || TypeHelper.isAssignable(List.class, propertyMeta.getPropertyType());
    }

    @SuppressWarnings("unchecked")
    public MultiIndexFieldMapper[] buildIndexFieldMappers() {
        final List> fields = new ArrayList>();

        propertyMappingsBuilder.forEachProperties(new ForEachCallBack>>() {
            @Override
            public void handle(PropertyMapping> pm) {

                if (isMultiIndex(pm.getPropertyMeta())) {
                    fields.add(newCollectionFieldMapper(pm));
                } else {
                    fields.add(newFieldMapper(pm));
                }
            }

            private  MultiIndexFieldMapper newCollectionFieldMapper(PropertyMapping> pm) {

                PropertyMeta propertyMeta = pm.getPropertyMeta();

                IndexedGetter indexedGetter;
                IntGetter sizeGetter;
                Getter collectionGetter = (Getter) propertyMeta.getGetter();


                if (TypeHelper.isAssignable(List.class, propertyMeta.getPropertyType())) {
                    indexedGetter = (IndexedGetter) new ListIndexedGetter

(); sizeGetter = (IntGetter) new ListSizeGetter(); } else if (TypeHelper.isArray(propertyMeta.getPropertyType())) { indexedGetter = (IndexedGetter) new ArrayIndexedGetter

(); sizeGetter = new ArraySizeGetter(); } else { throw new IllegalArgumentException("Unexpected elementMeta" + propertyMeta); } PropertyMeta childProperty = (PropertyMeta) pm.getPropertyMeta().getPropertyClassMeta().newPropertyFinder( ConstantPredicate.>truePredicate()).findProperty(DefaultPropertyNameMatcher.of("0"), pm.getColumnDefinition().properties(), pm.getColumnKey()); final PropertyMapping> pmchildProperttMeta = pm.propertyMeta(childProperty); IndexedSetter setter = getSetter(pmchildProperttMeta); return new CollectionIndexFieldMapper(setter, collectionGetter, sizeGetter, indexedGetter); } private IndexedSetter getSetter(PropertyMapping> pm) { IndexedSetter setter = null; IndexedSetterProperty indexedSetterProperty = pm.getColumnDefinition().lookFor(IndexedSetterProperty.class); if (indexedSetterProperty != null) { setter = (IndexedSetter) indexedSetterProperty.getIndexedSetter(); } if (setter == null) { setter = indexedSetterFactory(pm); } if (setter == null) { mapperConfig.mapperBuilderErrorHandler().accessorNotFound( "Could not find setter for " + pm.getColumnKey() + " type " + pm.getPropertyMeta().getPropertyType() + " path " + pm.getPropertyMeta().getPath() + " See " + ErrorDoc.toUrl("PS_SETTER_NOT_FOUND")); } return setter; } private IndexedSetter indexedSetterFactory(PropertyMapping> pm) { IndexedSetter setter = null; final IndexedSetterFactoryProperty indexedSetterPropertyFactory = pm.getColumnDefinition().lookFor(IndexedSetterFactoryProperty.class); if (indexedSetterPropertyFactory != null) { IndexedSetterFactory>> setterFactory = (IndexedSetterFactory>>) indexedSetterPropertyFactory.getIndexedSetterFactory(); setter = setterFactory.getIndexedSetter(pm); } if (setter == null) { setter = indexedSetterFactory.getIndexedSetter(pm); } if (setter == null) { final ClassMeta

classMeta = pm.getPropertyMeta().getPropertyClassMeta(); if (classMeta instanceof ObjectClassMeta) { ObjectClassMeta

ocm = (ObjectClassMeta

) classMeta; if (ocm.getNumberOfProperties() == 1) { PropertyMeta subProp = ocm.getFirstProperty(); final PropertyMapping> subPropertyMapping = pm.propertyMeta(subProp); IndexedSetter subSetter = indexedSetterFactory(subPropertyMapping); if (subSetter != null) { setter = new PreparedStatementIndexSetterOnGetter((PreparedStatementIndexSetter) subSetter, (Getter) subProp.getGetter()); } } } } return setter; } private

MultiIndexFieldMapper newFieldMapper(PropertyMapping> pm) { return new SingleIndexFieldMapper(getSetter(pm), pm.getPropertyMeta().getGetter()); } }); return fields.toArray(new MultiIndexFieldMapper[0]); } }