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

org.simpleflatmapper.map.mapper.DiscriminatorEnumerable 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.MappingContext;
import org.simpleflatmapper.map.MappingException;
import org.simpleflatmapper.map.SourceFieldMapper;
import org.simpleflatmapper.util.Enumerable;
import org.simpleflatmapper.util.ErrorHelper;
import org.simpleflatmapper.util.Function;
import org.simpleflatmapper.util.Predicate;


public class DiscriminatorEnumerable implements Enumerable {

    private final PredicatedMapperWithContext[] discriminatorMappers;
    private final Enumerable sourceEnumerable;
    private final Function errorMessageGenerator;

    private T currentValue;
    private T nextValue;
    private SourceFieldMapper currentMapper;
    private MappingContext currentMappingContext;


    public DiscriminatorEnumerable(
            PredicatedMapperWithContext[] discriminatorMappers,
            Enumerable sourceEnumerable,
            Function errorMessageGenerator) {
        this.discriminatorMappers = discriminatorMappers;
        this.sourceEnumerable = sourceEnumerable;
        this.errorMessageGenerator = errorMessageGenerator;
    }

    @Override
    public boolean next() {
        try {
            currentValue = nextValue;
            nextValue = null;
            while (sourceEnumerable.next()) {

                checkMapper();

                S source = sourceEnumerable.currentValue();

                if (currentMappingContext.broke(source)) {
                    if (currentValue == null) {
                        currentValue = currentMapper.map(source, currentMappingContext);
                    } else {
                        nextValue = currentMapper.map(source, currentMappingContext);
                        return true;
                    }
                } else {
                    currentMapper.mapTo(source, currentValue, currentMappingContext);
                }
            }

            return currentValue != null;
        } catch (Exception e) {
            ErrorHelper.rethrow(e);
            return false;
        }
    }

    public T currentValue() {
        return currentValue;
    }

    private void checkMapper() {
        for(PredicatedMapperWithContext pmm : discriminatorMappers ) {
            if (pmm.predicate.test(sourceEnumerable.currentValue())) {
                if (pmm.mapper != currentMapper) {
                    markAsBroken();
                    currentMapper = pmm.mapper;
                    currentMappingContext = pmm.mappingContext;
                }
                return;
            }
        }
        mapperNotFound();
    }

    private void mapperNotFound() {
        CharSequence errorMessage = errorMessageGenerator.apply(sourceEnumerable.currentValue());
        throw new MappingException("No mapper found for " + errorMessage);
    }

    private void markAsBroken() {
        for(PredicatedMapperWithContext pmm : discriminatorMappers ) {
           pmm.mappingContext.markAsBroken();
        }
    }

    public static class PredicatedMapperWithContext {
        private final Predicate predicate;
        private final SourceFieldMapper mapper;
        private final MappingContext mappingContext;

        public PredicatedMapperWithContext(Predicate predicate, SourceFieldMapper mapper, MappingContext mappingContext) {
            this.predicate = predicate;
            this.mapper = mapper;
            this.mappingContext = mappingContext;
        }
    }
}