<commit_before>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.impl.DiscriminatorReflectionService;
import org.simpleflatmapper.map.property.DiscriminatorColumnProperty;
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.*;

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<S, T, K extends FieldKey<K>>  extends ConstantSourceMapperBuilder<S, T, K> {
    
    private final DiscriminatedBuilder<S, T, K>[][] builders;
    private final MapperConfig.Discriminator<? super S, K, T>[] discriminators;
    private final MappingContextFactoryBuilder<S, K> mappingContextFactoryBuilder;
    private final CaptureError mapperBuilderErrorHandler;
    private final MapperConfig<K, ? extends S> mapperConfig;

    @SuppressWarnings("unchecked")
    public DiscriminatorConstantSourceMapperBuilder(
            MapperConfig.Discriminator<? super S, K, T>[] discriminators,
            final MapperSource<? super S, K> mapperSource,
            final ClassMeta<T> classMeta,
            final MapperConfig<K, ? extends S> mapperConfig,
            MappingContextFactoryBuilder<S, K> mappingContextFactoryBuilder,
            KeyFactory<K> keyFactory,
            PropertyFinder<T> propertyFinder) throws MapperBuildingException {
        this.mappingContextFactoryBuilder = mappingContextFactoryBuilder;
        this.mapperConfig = mapperConfig;
        builders = new DiscriminatedBuilder[discriminators.length][];
        this.discriminators = discriminators;


        mapperBuilderErrorHandler = new CaptureError(mapperConfig.mapperBuilderErrorHandler(), numberOfBuilders(discriminators));
        MapperConfig<K, ? extends S> kMapperConfig = mapperConfig.mapperBuilderErrorHandler(mapperBuilderErrorHandler);
        for(int i = 0; i < discriminators.length; i++) {
            MapperConfig.Discriminator<? super S, K, T> discriminator = discriminators[i];

            builders[i] = new DiscriminatedBuilder[discriminator.cases.length];
            for (int ci = 0; ci < discriminator.cases.length; ci++) {
                MapperConfig.DiscriminatorCase<? super S, K, ? extends T> discriminatorCase = discriminator.cases[ci];

                PropertyFinder<T> subPropertyFinder = propertyFinder;

                if (propertyFinder instanceof DiscriminatorPropertyFinder) {
                    subPropertyFinder = ((DiscriminatorPropertyFinder<T>) subPropertyFinder).getImplementationPropertyFinder(discriminatorCase.classMeta.getType());
                }

                builders[i][ci] = getDiscriminatedBuilder(mapperSource, mappingContextFactoryBuilder, keyFactory, subPropertyFinder, kMapperConfig, discriminatorCase, classMeta);
            }
        }
    }

    private int numberOfBuilders(MapperConfig.Discriminator<? super S, K, T>[] discriminators) {
        int i = 0;
        for (MapperConfig.Discriminator<? super S, K, T> d : discriminators) {
            i += d.cases.length;
        }
        return i;
    }


    private <T> DiscriminatedBuilder<S, T, K> getDiscriminatedBuilder(MapperSource<? super S, K> mapperSource, MappingContextFactoryBuilder<S, K> mappingContextFactoryBuilder, KeyFactory<K> keyFactory, PropertyFinder<T> propertyFinder, MapperConfig<K, ? extends S> kMapperConfig, MapperConfig.DiscriminatorCase<? super S,  K, ? extends T> discrimnatorCase, ClassMeta<T> commonClassMeta) {
        return new DiscriminatedBuilder<S, T, K>((MapperConfig.DiscriminatorCase<? super S, K, T>) discrimnatorCase,
                new DefaultConstantSourceMapperBuilder<S, T, K>(mapperSource, (ClassMeta<T>) discrimnatorCase.classMeta.withReflectionService(commonClassMeta.getReflectionService()), kMapperConfig, mappingContextFactoryBuilder, keyFactory, propertyFinder));
    }

    @Override
    public ConstantSourceMapperBuilder<S, T, K> addMapping(K key, ColumnDefinition<K, ?> columnDefinition) {

        for(int i = 0; i < builders.length; i++) {
            for (DiscriminatedBuilder<S, T, K> builder : builders[i]) {
                builder.builder.addMapping(key, columnDefinition);
            }
        }
        final ColumnDefinition<K, ?> composedDefinition = columnDefinition.compose(mapperConfig.columnDefinitions().getColumnDefinition(key));
        mapperBuilderErrorHandler.successfullyMapAtLeastToOne(composedDefinition);
        return this;
    }

    @Override
    protected <P> void addMapping(final K columnKey, final ColumnDefinition<K, ?> columnDefinition, final PropertyMeta<T, P> prop) {

        if (prop instanceof DiscriminatorPropertyFinder.DiscriminatorPropertyMeta) {
            DiscriminatorPropertyFinder.DiscriminatorPropertyMeta pm = (DiscriminatorPropertyFinder.DiscriminatorPropertyMeta) prop;
            pm.forEachProperty(new BiConsumer<Type, PropertyMeta<?, ?>>() {
                @Override
                public void accept(Type type, PropertyMeta<?, ?> propertyMeta) {
                    forBuilderOfType(type, new Consumer<ConstantSourceMapperBuilder>() {
                        @Override
                        public void accept(ConstantSourceMapperBuilder constantSourceMapperBuilder) {
                            constantSourceMapperBuilder.addMapping(columnKey, columnDefinition, propertyMeta);
                        }
                    });
                }
            });
            
        } else {
            for(int i = 0; i < builders.length; i++) {
                for (DiscriminatedBuilder<S, T, K> builder : builders[i]) {
                    builder.builder.addMapping(columnKey, columnDefinition, prop);
                }
            }
        }
        
    }

    private void forBuilderOfType(Type type, Consumer<ConstantSourceMapperBuilder> consumer) {
        for(int i = 0; i < builders.length; i++) {
            for (DiscriminatedBuilder<S, T, K> builder : builders[i]) {
                if (TypeHelper.areEquals(builder.builder.getTargetType(), type)) {
                    consumer.accept(builder.builder);
                }
            }<commit_msg>java 7<commit_after>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.impl.DiscriminatorReflectionService;
import org.simpleflatmapper.map.property.DiscriminatorColumnProperty;
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.*;

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<S, T, K extends FieldKey<K>>  extends ConstantSourceMapperBuilder<S, T, K> {
    
    private final DiscriminatedBuilder<S, T, K>[][] builders;
    private final MapperConfig.Discriminator<? super S, K, T>[] discriminators;
    private final MappingContextFactoryBuilder<S, K> mappingContextFactoryBuilder;
    private final CaptureError mapperBuilderErrorHandler;
    private final MapperConfig<K, ? extends S> mapperConfig;

    @SuppressWarnings("unchecked")
    public DiscriminatorConstantSourceMapperBuilder(
            MapperConfig.Discriminator<? super S, K, T>[] discriminators,
            final MapperSource<? super S, K> mapperSource,
            final ClassMeta<T> classMeta,
            final MapperConfig<K, ? extends S> mapperConfig,
            MappingContextFactoryBuilder<S, K> mappingContextFactoryBuilder,
            KeyFactory<K> keyFactory,
            PropertyFinder<T> propertyFinder) throws MapperBuildingException {
        this.mappingContextFactoryBuilder = mappingContextFactoryBuilder;
        this.mapperConfig = mapperConfig;
        builders = new DiscriminatedBuilder[discriminators.length][];
        this.discriminators = discriminators;


        mapperBuilderErrorHandler = new CaptureError(mapperConfig.mapperBuilderErrorHandler(), numberOfBuilders(discriminators));
        MapperConfig<K, ? extends S> kMapperConfig = mapperConfig.mapperBuilderErrorHandler(mapperBuilderErrorHandler);
        for(int i = 0; i < discriminators.length; i++) {
            MapperConfig.Discriminator<? super S, K, T> discriminator = discriminators[i];

            builders[i] = new DiscriminatedBuilder[discriminator.cases.length];
            for (int ci = 0; ci < discriminator.cases.length; ci++) {
                MapperConfig.DiscriminatorCase<? super S, K, ? extends T> discriminatorCase = discriminator.cases[ci];

                PropertyFinder<T> subPropertyFinder = propertyFinder;

                if (propertyFinder instanceof DiscriminatorPropertyFinder) {
                    subPropertyFinder = ((DiscriminatorPropertyFinder<T>) subPropertyFinder).getImplementationPropertyFinder(discriminatorCase.classMeta.getType());
                }

                builders[i][ci] = getDiscriminatedBuilder(mapperSource, mappingContextFactoryBuilder, keyFactory, subPropertyFinder, kMapperConfig, discriminatorCase, classMeta);
            }
        }
    }

    private int numberOfBuilders(MapperConfig.Discriminator<? super S, K, T>[] discriminators) {
        int i = 0;
        for (MapperConfig.Discriminator<? super S, K, T> d : discriminators) {
            i += d.cases.length;
        }
        return i;
    }


    private <T> DiscriminatedBuilder<S, T, K> getDiscriminatedBuilder(MapperSource<? super S, K> mapperSource, MappingContextFactoryBuilder<S, K> mappingContextFactoryBuilder, KeyFactory<K> keyFactory, PropertyFinder<T> propertyFinder, MapperConfig<K, ? extends S> kMapperConfig, MapperConfig.DiscriminatorCase<? super S,  K, ? extends T> discrimnatorCase, ClassMeta<T> commonClassMeta) {
        return new DiscriminatedBuilder<S, T, K>((MapperConfig.DiscriminatorCase<? super S, K, T>) discrimnatorCase,
                new DefaultConstantSourceMapperBuilder<S, T, K>(mapperSource, (ClassMeta<T>) discrimnatorCase.classMeta.withReflectionService(commonClassMeta.getReflectionService()), kMapperConfig, mappingContextFactoryBuilder, keyFactory, propertyFinder));
    }

    @Override
    public ConstantSourceMapperBuilder<S, T, K> addMapping(K key, ColumnDefinition<K, ?> columnDefinition) {

        for(int i = 0; i < builders.length; i++) {
            for (DiscriminatedBuilder<S, T, K> builder : builders[i]) {
                builder.builder.addMapping(key, columnDefinition);
            }
        }
        final ColumnDefinition<K, ?> composedDefinition = columnDefinition.compose(mapperConfig.columnDefinitions().getColumnDefinition(key));
        mapperBuilderErrorHandler.successfullyMapAtLeastToOne(composedDefinition);
        return this;
    }

    @Override
    protected <P> void addMapping(final K columnKey, final ColumnDefinition<K, ?> columnDefinition, final PropertyMeta<T, P> prop) {

        if (prop instanceof DiscriminatorPropertyFinder.DiscriminatorPropertyMeta) {
            DiscriminatorPropertyFinder.DiscriminatorPropertyMeta pm = (DiscriminatorPropertyFinder.DiscriminatorPropertyMeta) prop;
            pm.forEachProperty(new BiConsumer<Type, PropertyMeta<?, ?>>() {
                @Override
                public void accept(Type type, final PropertyMeta<?, ?> propertyMeta) {
                    forBuilderOfType(type, new Consumer<ConstantSourceMapperBuilder>() {
                        @Override
                        public void accept(ConstantSourceMapperBuilder constantSourceMapperBuilder) {
                            constantSourceMapperBuilder.addMapping(columnKey, columnDefinition, propertyMeta);
                        }
                    });
                }
            });
            
        } else {
            for(int i = 0; i < builders.length; i++) {
                for (DiscriminatedBuilder<S, T, K> builder : builders[i]) {
                    builder.builder.addMapping(columnKey, columnDefinition, prop);
                }
            }
        }
        
    }

    private void forBuilderOfType(Type type, Consumer<ConstantSourceMapperBuilder> consumer) {
        for(int i = 0; i < builders.length; i++) {
            for (DiscriminatedBuilder<S, T, K> builder : builders[i]) {
                if (TypeHelper.areEquals(builder.builder.getTargetType(), type)) {
                    consumer.accept(builder.builder);
                }
            }
{'fraction_non_alphanumeric': 0.09104552276138068, 'fraction_numerical': 0.000929035946544701, 'mean_word_length': 3.460949952183615, 'pattern_counts': {'":': 0, '<': 109, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '264930', 'n_tokens_mistral': 3762, 'n_tokens_neox': 3667, 'n_words': 752}