package org.simpleflatmapper.map.mapper; import org.simpleflatmapper.converter.UncheckedConverter; import org.simpleflatmapper.map.Mapper; import org.simpleflatmapper.map.MappingException; import org.simpleflatmapper.map.ConsumerErrorHandler; import org.simpleflatmapper.map.context.MappingContextFactoryFromRows; import org.simpleflatmapper.util.Enumarable; import org.simpleflatmapper.util.Predicate; import org.simpleflatmapper.util.UnaryFactory; import java.util.List; public class DiscriminatorMapper<ROW, ROWS, T, EX extends Exception> extends AbstractEnumarableDelegateMapper<ROW, ROWS, T, EX> { private final List<PredicatedMapper<ROW, ROWS, T, EX>> mappers; private final UncheckedConverter<ROW, String> errorConverter; private final UnaryFactory<ROWS, Enumarable<ROW>> rowEnumarableFactory; public DiscriminatorMapper(List<PredicatedMapper<ROW, ROWS, T, EX>> mappers, UnaryFactory<ROWS, Enumarable<ROW>> rowEnumarableFactory, UncheckedConverter<ROW, String> errorConverter, ConsumerErrorHandler consumerErrorHandler) { super(consumerErrorHandler); this.mappers = mappers; this.errorConverter = errorConverter; this.rowEnumarableFactory = rowEnumarableFactory; } @Override protected Mapper<ROW, T> getMapper(final ROW row) throws MappingException { for (PredicatedMapper<ROW, ROWS, T, EX> tm : mappers) { if (tm.getPredicate().test(row)) { return tm.getMapper(); } } throw new MappingException("No mapper found for " + errorConverter.convert(row)); } @SuppressWarnings("unchecked") protected DiscriminatorEnumerable<ROW, T> newEnumarableOfT(ROWS rows) throws EX { DiscriminatorEnumerable.PredicatedMapperWithContext<ROW, T>[] mapperDiscriminators = new DiscriminatorEnumerable.PredicatedMapperWithContext[this.mappers.size()]; for(int i = 0; i < mapperDiscriminators.length; i++) { PredicatedMapper<ROW, ROWS, T, EX> predicatedMapper = mappers.get(i); mapperDiscriminators[i] = new DiscriminatorEnumerable.PredicatedMapperWithContext<ROW, T>( predicatedMapper.getPredicate(), predicatedMapper.getMapper(), predicatedMapper.getMappingContextFactory().newMappingContext(rows)); } return new DiscriminatorEnumerable<ROW, T>( mapperDiscriminators, rowEnumarableFactory.newInstance(rows), errorConverter); } public static class PredicatedMapper<ROW, ROWS, T, EX extends Throwable> { private final Predicate<ROW> predicate; private final Mapper<ROW, T> mapper; private final MappingContextFactoryFromRows<ROW, ROWS, EX> mappingContextFactory; public PredicatedMapper(Predicate<ROW> predicate, Mapper<ROW, T> mapper, MappingContextFactoryFromRows<ROW, ROWS, EX> mappingContextFactory) { this.predicate = predicate; this.mapper = mapper; this.mappingContextFactory = mappingContextFactory; } public Predicate<ROW> getPredicate() { return predicate; } public Mapper<ROW, T> getMapper() { return mapper; } public MappingContextFactoryFromRows<ROW, ROWS, EX> getMappingContextFactory() { return mappingContextFactory; } } }