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

org.simpleflatmapper.map.mapper.DiscriminatorConstantSourceMapperBuilder 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.FieldKey;
import org.simpleflatmapper.map.FieldMapper;
import org.simpleflatmapper.map.MapperBuilderErrorHandler;
import org.simpleflatmapper.map.MapperBuildingException;
import org.simpleflatmapper.map.MapperConfig;
import org.simpleflatmapper.map.MappingContext;
import org.simpleflatmapper.map.SourceFieldMapper;
import org.simpleflatmapper.map.context.MappingContextFactory;
import org.simpleflatmapper.map.context.MappingContextFactoryBuilder;
import org.simpleflatmapper.map.impl.DiscriminatorPropertyFinder;
import org.simpleflatmapper.map.property.OptionalProperty;
import org.simpleflatmapper.reflect.BiInstantiator;
import org.simpleflatmapper.reflect.Getter;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import org.simpleflatmapper.reflect.meta.PropertyFinder;
import org.simpleflatmapper.reflect.meta.PropertyMeta;
import org.simpleflatmapper.util.BiConsumer;
import org.simpleflatmapper.util.EqualsPredicate;
import org.simpleflatmapper.util.ForEachCallBack;
import org.simpleflatmapper.util.Predicate;
import org.simpleflatmapper.util.TypeHelper;

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;


public class DiscriminatorConstantSourceMapperBuilder>  extends ConstantSourceMapperBuilder {
    
    private final DiscriminatedBuilder[] builders;
    private final MappingContextFactoryBuilder mappingContextFactoryBuilder;
    private final CaptureError mapperBuilderErrorHandler;
    private final MapperConfig mapperConfig;

    @SuppressWarnings("unchecked")
    public DiscriminatorConstantSourceMapperBuilder(
            MapperConfig.Discriminator discriminator,
            final MapperSource mapperSource,
            final ClassMeta classMeta,
            final MapperConfig mapperConfig,
            MappingContextFactoryBuilder mappingContextFactoryBuilder,
            KeyFactory keyFactory,
            PropertyFinder propertyFinder) throws MapperBuildingException {
        this.mappingContextFactoryBuilder = mappingContextFactoryBuilder;
        this.mapperConfig = mapperConfig;
        builders = new DiscriminatedBuilder[discriminator.cases.length];

        mapperBuilderErrorHandler = new CaptureError(mapperConfig.mapperBuilderErrorHandler(), builders.length);
        MapperConfig kMapperConfig = mapperConfig.mapperBuilderErrorHandler(mapperBuilderErrorHandler);
        
        for(int i = 0; i < discriminator.cases.length; i++) {
            MapperConfig.DiscriminatorCase discriminatorCase = discriminator.cases[i];

            PropertyFinder subPropertyFinder = propertyFinder;
            
            if (propertyFinder instanceof DiscriminatorPropertyFinder) {
                subPropertyFinder = ((DiscriminatorPropertyFinder)subPropertyFinder).getImplementationPropertyFinder(discriminatorCase.classMeta.getType());
            }
            
            builders[i] = getDiscriminatedBuilder(mapperSource, mappingContextFactoryBuilder, keyFactory, subPropertyFinder, kMapperConfig, discriminatorCase, classMeta);
        }
    }

    private  DiscriminatedBuilder getDiscriminatedBuilder(MapperSource mapperSource, MappingContextFactoryBuilder mappingContextFactoryBuilder, KeyFactory keyFactory, PropertyFinder propertyFinder, MapperConfig kMapperConfig, MapperConfig.DiscriminatorCase discrimnatorCase, ClassMeta commonClassMeta) {
        return new DiscriminatedBuilder((MapperConfig.DiscriminatorCase) discrimnatorCase, 
                new DefaultConstantSourceMapperBuilder(mapperSource, (ClassMeta) discrimnatorCase.classMeta.withReflectionService(commonClassMeta.getReflectionService()), kMapperConfig, mappingContextFactoryBuilder, keyFactory, propertyFinder));
    }

    @Override
    public ConstantSourceMapperBuilder addMapping(K key, ColumnDefinition columnDefinition) {
        for(DiscriminatedBuilder builder : builders) {
            builder.builder.addMapping(key, columnDefinition);
        }
        final ColumnDefinition composedDefinition = columnDefinition.compose(mapperConfig.columnDefinitions().getColumnDefinition(key));
        mapperBuilderErrorHandler.successfullyMapAtLeastToOne(composedDefinition);
        return this;
    }

    @Override
    protected 

void addMapping(final K columnKey, final ColumnDefinition columnDefinition, final PropertyMeta prop) { if (prop instanceof DiscriminatorPropertyFinder.DiscriminatorPropertyMeta) { DiscriminatorPropertyFinder.DiscriminatorPropertyMeta pm = (DiscriminatorPropertyFinder.DiscriminatorPropertyMeta) prop; pm.forEachProperty(new BiConsumer>() { @Override public void accept(Type type, PropertyMeta propertyMeta) { getBuilder(type).addMapping(columnKey, columnDefinition, propertyMeta); } }); } else { for (DiscriminatedBuilder builder : builders) { builder.builder.addMapping(columnKey, columnDefinition, prop); } } } private ConstantSourceMapperBuilder getBuilder(Type type) { for (DiscriminatedBuilder builder : builders) { if (TypeHelper.areEquals(builder.builder.getTargetType(), type)) { return builder.builder; } } throw new IllegalArgumentException("Unknown type " + type); } @Override public List getKeys() { HashSet keys = new HashSet(); for(DiscriminatedBuilder builder : builders) { keys.addAll(builder.builder.getKeys()); } return new ArrayList(keys); } @Override public >> H forEachProperties(H handler) { for(DiscriminatedBuilder builder : builders) { builder.builder.forEachProperties(handler); } return handler; } @Override public ContextualSourceFieldMapperImpl mapper() { SourceFieldMapper mapper = sourceFieldMapper(); return new ContextualSourceFieldMapperImpl(mappingContextFactoryBuilder.build(), mapper); } @SuppressWarnings("unchecked") @Override public SourceFieldMapper sourceFieldMapper() { PredicatedInstantiator[] predicatedInstantiator = new PredicatedInstantiator[builders.length]; List> fieldMappers = new ArrayList>(); for(int i = 0; i < builders.length; i++) { DiscriminatedBuilder builder = builders[i]; final Predicate predicate = builder.discrimnatorCase.predicate; DefaultConstantSourceMapperBuilder.GenericBuilderMapping genericBuilderMapping = builder.builder.getGenericBuilderMapping(); predicatedInstantiator[i] = new PredicatedInstantiator(predicate, genericBuilderMapping.genericBuilderInstantiator); final FieldMapper[] targetFieldMappers = genericBuilderMapping.targetFieldMappers; fieldMappers.add(new FieldMapper() { @Override public void mapTo(S source, T target, MappingContext context) throws Exception { if (predicate.test(source)) { for(FieldMapper fm : targetFieldMappers) { fm.mapTo(source, target, context); } } } }); } boolean oneColumn = isOneColumn(predicatedInstantiator); BiInstantiator, GenericBuilder> gbi = oneColumn ? new OneColumnBuildBiInstantiator(predicatedInstantiator) : new GenericBuildBiInstantiator(predicatedInstantiator); DiscriminatorGenericBuilderMapper mapper = new DiscriminatorGenericBuilderMapper(gbi); FieldMapper[] targetFieldMappers = fieldMappers.toArray(new FieldMapper[0]); // return new TransformSourceFieldMapper, T>(mapper, targetFieldMappers, GenericBuilder.buildFunction()); } private boolean isOneColumn(PredicatedInstantiator[] predicatedInstantiator) { Getter getter = null; for(PredicatedInstantiator pi : predicatedInstantiator) { if (!(pi.predicate instanceof AbstractMapperFactory.DiscriminatorConditionBuilder.SourcePredicate)) { return false; } AbstractMapperFactory.DiscriminatorConditionBuilder.SourcePredicate sp = (AbstractMapperFactory.DiscriminatorConditionBuilder.SourcePredicate) pi.predicate; Getter lg = sp.getter; if (getter == null) { getter = lg; } else if (getter != lg) return false; if (!(sp.predicate instanceof EqualsPredicate)) return false; } return true; } @Override public boolean isRootAggregate() { return builders[0].builder.isRootAggregate(); } @Override public MappingContextFactory contextFactory() { return builders[0].builder.contextFactory(); } @Override public void addMapper(FieldMapper mapper) { for(DiscriminatedBuilder builder : builders) { builder.builder.addMapper(mapper); } } private static class DiscriminatedBuilder> { private final MapperConfig.DiscriminatorCase discrimnatorCase; private final DefaultConstantSourceMapperBuilder builder; private DiscriminatedBuilder(MapperConfig.DiscriminatorCase discrimnatorCase, DefaultConstantSourceMapperBuilder builder) { this.discrimnatorCase = discrimnatorCase; this.builder = builder; } } private static class GenericBuildBiInstantiator implements BiInstantiator, GenericBuilder> { private final PredicatedInstantiator[] predicatedInstantiators; public GenericBuildBiInstantiator(PredicatedInstantiator[] predicatedInstantiators) { this.predicatedInstantiators = predicatedInstantiators; } @SuppressWarnings("unchecked") @Override public GenericBuilder newInstance(S o, MappingContext o2) throws Exception { for(PredicatedInstantiator pi : predicatedInstantiators) { //noinspection unchecked if (pi.predicate.test(o)) { return pi.instantiator.newInstance(o, o2); } } throw new IllegalArgumentException("No discrimator matched " + o); } } private static class OneColumnBuildBiInstantiator implements BiInstantiator, GenericBuilder> { private final Getter getter; private final Map, GenericBuilder>> instantiators; public OneColumnBuildBiInstantiator(PredicatedInstantiator[] predicatedInstantiators) { if (predicatedInstantiators == null || predicatedInstantiators.length == 0) throw new IllegalArgumentException("predicatedInstantiators is null or empty"); getter = ((AbstractMapperFactory.DiscriminatorConditionBuilder.SourcePredicate)predicatedInstantiators[0].predicate).getter; instantiators = new HashMap, GenericBuilder>>(); for(PredicatedInstantiator pi : predicatedInstantiators) { EqualsPredicate ep = (EqualsPredicate) ((AbstractMapperFactory.DiscriminatorConditionBuilder.SourcePredicate)pi.predicate).predicate; instantiators.put(ep.expected, pi.instantiator); } } @SuppressWarnings("unchecked") @Override public GenericBuilder newInstance(S o, MappingContext o2) throws Exception { Object value = getter.get(o); BiInstantiator, GenericBuilder> instantiator = instantiators.get(value); if (instantiator == null) throw new IllegalArgumentException("No discrimator matched " + value); return instantiator.newInstance(o, o2); } } private static class PredicatedInstantiator { private final Predicate predicate; private final BiInstantiator, GenericBuilder> instantiator; private PredicatedInstantiator(Predicate predicate, BiInstantiator, GenericBuilder> instantiator) { this.predicate = predicate; this.instantiator = instantiator; } } private class DiscriminatorGenericBuilderMapper extends AbstractMapper> { public DiscriminatorGenericBuilderMapper(BiInstantiator, GenericBuilder> gbi) { super(gbi); } @Override protected void mapFields(S source, GenericBuilder target, MappingContext mappingContext) throws Exception { target.mapFrom(source, mappingContext); } @Override protected void mapToFields(S source, GenericBuilder target, MappingContext mappingContext) throws Exception { target.mapFrom(source, mappingContext); } } private static class CaptureError implements MapperBuilderErrorHandler { private final MapperBuilderErrorHandler delegate; private final List errorCollector; private final int nbBuilders; private CaptureError(MapperBuilderErrorHandler delegate, int nbBuilders) { this.delegate = delegate; this.nbBuilders = nbBuilders; errorCollector = new ArrayList(); } @Override public void accessorNotFound(String msg) { delegate.accessorNotFound(msg); } @Override public void propertyNotFound(Type target, String property) { errorCollector.add(new PropertyNotFound(target, property)); } @Override public void customFieldError(FieldKey key, String message) { delegate.customFieldError(key, message); } public void successfullyMapAtLeastToOne(ColumnDefinition columnDefinition) { try { if (errorCollector.size() == nbBuilders && ! columnDefinition.has(OptionalProperty.class)) { PropertyNotFound propertyNotFound = errorCollector.get(0); delegate.propertyNotFound(propertyNotFound.target, propertyNotFound.property); } } finally { errorCollector.clear(); } } private static class PropertyNotFound { final Type target; final String property; private PropertyNotFound(Type target, String property) { this.target = target; this.property = property; } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy