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

org.simpleflatmapper.map.mapper.SetRowMapperBuilderImpl 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.map.mapper;

import org.simpleflatmapper.map.ConsumerErrorHandler;
import org.simpleflatmapper.map.ContextualSourceFieldMapper;
import org.simpleflatmapper.map.FieldKey;
import org.simpleflatmapper.map.FieldMapper;
import org.simpleflatmapper.map.SetRowMapper;
import org.simpleflatmapper.map.MapperConfig;
import org.simpleflatmapper.map.context.KeySourceGetter;
import org.simpleflatmapper.map.context.MappingContextFactory;
import org.simpleflatmapper.map.context.MappingContextFactoryBuilder;
import org.simpleflatmapper.map.impl.DiscriminatorReflectionService;
import org.simpleflatmapper.map.property.IgnoreRowIfNullProperty;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import org.simpleflatmapper.util.Enumerable;
import org.simpleflatmapper.util.ErrorHelper;
import org.simpleflatmapper.util.ForEachCallBack;
import org.simpleflatmapper.util.Function;
import org.simpleflatmapper.util.Predicate;
import org.simpleflatmapper.util.PredicatedEnumerable;
import org.simpleflatmapper.util.TypeHelper;
import org.simpleflatmapper.util.UnaryFactory;

import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @param  the targeted type of the mapper
 */
public class SetRowMapperBuilderImpl, ROW, SET, T, K extends FieldKey, E extends Exception> implements SetRowMapperBuilder {

    private final ConstantSourceMapperBuilder constantSourceMapperBuilder;

    protected final MapperConfig mapperConfig;
    protected final MappingContextFactoryBuilder mappingContextFactoryBuilder;
    private final UnaryFactory> enumerableFactory;
    private final SetRowMapperFactory setRowMapperFactory;
    private final KeySourceGetter keySourceGetter;

    /**
     * @param classMeta                  the meta for the target class.
     * @param parentBuilder              the parent builder, null if none.
     * @param mapperConfig               the mapperConfig.
     * @param mapperSource               the Mapper source.
     * @param keyFactory
     * @param enumerableFactory
     * @param keySourceGetter
     */
    public SetRowMapperBuilderImpl(
            final ClassMeta classMeta,
            MappingContextFactoryBuilder parentBuilder,
            MapperConfig mapperConfig,
            MapperSource mapperSource,
            KeyFactory keyFactory,
            UnaryFactory> enumerableFactory,
            SetRowMapperFactory setRowMapperFactory, 
            KeySourceGetter keySourceGetter) {
        this.setRowMapperFactory = setRowMapperFactory;
        this.enumerableFactory = enumerableFactory;
        this.keySourceGetter = keySourceGetter;
        this.constantSourceMapperBuilder =
                ConstantSourceMapperBuilder.newConstantSourceMapperBuilder(
                        mapperSource,
                        prepareClassMetaForDiscriminator(classMeta, mapperConfig),
                        mapperConfig,
                        parentBuilder,
                        keyFactory);
        this.mapperConfig = mapperConfig;
        this.mappingContextFactoryBuilder = parentBuilder;
    }

    private ClassMeta prepareClassMetaForDiscriminator(ClassMeta classMeta, MapperConfig mapperConfig) {
        List> discriminators = mapperConfig.getDiscriminators();
        
        if (discriminators.isEmpty()) {
            return classMeta;
        } else {
            Map, List>> discriminatorMap = new HashMap, List>>();
            for(MapperConfig.Discriminator d : discriminators) {
                List> implementations = new ArrayList>();
                for(MapperConfig.DiscriminatorCase dc : d.cases) {
                    implementations.add(dc.classMeta);
                }
                discriminatorMap.put(TypeHelper.toClass(d.type), implementations);
            }
            DiscriminatorReflectionService dfs = new DiscriminatorReflectionService(classMeta.getReflectionService(), discriminatorMap);
            return classMeta.withReflectionService(dfs);
        }
    }

    /**
     * @return a new newInstance of the jdbcMapper based on the current state of the builder.
     */
    @Override
    public final M mapper() {
        ContextualSourceFieldMapperImpl mapper = sourceFieldMapper();

        if (mapper.getDelegate() instanceof TransformSourceFieldMapper) {
            TransformSourceFieldMapper transformSourceFieldMapper = (TransformSourceFieldMapper) mapper.getDelegate();
            ContextualSourceFieldMapper unwrappedMapper = new ContextualSourceFieldMapperImpl(mapper.getMappingContextFactory(), transformSourceFieldMapper.delegate);
            M m;

            if (constantSourceMapperBuilder.isRootAggregate()) {
                m = (M) setRowMapperFactory.newTransformer(setRowMapperFactory.newJoinMapper(unwrappedMapper, mapperConfig.consumerErrorHandler(), mappingContextFactoryBuilder.build(), enumerableFactory()), transformSourceFieldMapper.transform);
            } else {
                m = (M) setRowMapperFactory.newTransformer(setRowMapperFactory.newStaticMapper(unwrappedMapper, mapperConfig.consumerErrorHandler(), mappingContextFactoryBuilder.build(), enumerableFactory()), transformSourceFieldMapper.transform);
            }

            return m;
               
        } else {

            M m;

            if (constantSourceMapperBuilder.isRootAggregate()) {
                if (mapperConfig.unorderedJoin()) {
                    m = setRowMapperFactory.newUnorderedJoinMapper(mapper, mapperConfig.consumerErrorHandler(), mappingContextFactoryBuilder.build(), enumerableFactory());
                } else {
                    m = setRowMapperFactory.newJoinMapper(mapper, mapperConfig.consumerErrorHandler(), mappingContextFactoryBuilder.build(), enumerableFactory());
                }
            } else {
                m = setRowMapperFactory.newStaticMapper(mapper, mapperConfig.consumerErrorHandler(), mappingContextFactoryBuilder.build(), enumerableFactory());
            }

            return m;
        }
        
        
    }

    private UnaryFactory> enumerableFactory() {
        final Predicate filter = getRowPredicate();
        if (filter != null) {
            return new UnaryFactory>() {
                @Override
                public Enumerable newInstance(SET set) {
                    return new PredicatedEnumerable(enumerableFactory.newInstance(set), filter);
                }
            };
        }
        return enumerableFactory;
    }

    private Predicate getRowPredicate() {
        final Set mandatoryKeys = constantSourceMapperBuilder.forEachProperties(new ForEachCallBack>() {
            Set mandatoryKeys = new HashSet();

            @Override
            public void handle(PropertyMapping tkPropertyMapping) {
                if (tkPropertyMapping.getColumnDefinition().has(IgnoreRowIfNullProperty.class)) {
                    mandatoryKeys.add(tkPropertyMapping.getColumnKey());
                }
            }
        }).mandatoryKeys;
        
        if (mandatoryKeys.isEmpty()) {
            return null;
        } else {
            
            final K[] keys = (K[]) Array.newInstance(mandatoryKeys.iterator().next().getClass(), mandatoryKeys.size());
            int i = 0;
            for(K k : mandatoryKeys) {
                keys[i++] = k;
            }
            return new Predicate() {
                @Override
                public boolean test(ROW row) {
                    for(K k : keys) {
                        try {
                            if (keySourceGetter.getValue(k, row) == null) return false;
                        } catch (Exception e) {
                            ErrorHelper.rethrow(e);
                        }
                    }
                    return true;
                }
            };
        }
    }

    @Override
    public final ContextualSourceFieldMapperImpl sourceFieldMapper() {
        return constantSourceMapperBuilder.mapper();
    }
    
    @Override
    public boolean isRootAggregate() {
        return constantSourceMapperBuilder.isRootAggregate();
    }


    @Override
    public final void addMapper(FieldMapper mapper) {
        constantSourceMapperBuilder.addMapper(mapper);
    }


    @Override
    public final void addMapping(K key, ColumnDefinition columnDefinition) {
        constantSourceMapperBuilder.addMapping(key, columnDefinition);
    }


    @Override
    public MapperConfig  mapperConfig() {
        return mapperConfig;
    }

    @Override
    public MappingContextFactoryBuilder getMappingContextFactoryBuilder() {
        return mappingContextFactoryBuilder;
    }

    @Override
    public List getKeys() {
        return constantSourceMapperBuilder.getKeys();
    }

    public interface SetRowMapperFactory, ROW, SET, T, E extends Exception> {

        M newJoinMapper(ContextualSourceFieldMapper mapper, ConsumerErrorHandler consumerErrorHandler, MappingContextFactory mappingContextFactory, UnaryFactory> enumerableFactory);
        
        M newUnorderedJoinMapper(ContextualSourceFieldMapper mapper, ConsumerErrorHandler consumerErrorHandler, MappingContextFactory mappingContextFactory, UnaryFactory> enumerableFactory);

        M newStaticMapper(ContextualSourceFieldMapper mapper, ConsumerErrorHandler consumerErrorHandler, MappingContextFactory mappingContextFactory, UnaryFactory> enumerableFactory);

         M newTransformer(SetRowMapper setRowMapper, Function transform);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy