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

org.sfm.jdbc.impl.DiscriminatorJdbcMapper Maven / Gradle / Ivy

package org.sfm.jdbc.impl;

import org.sfm.map.*;
import org.sfm.tuples.Tuple2;
import org.sfm.utils.*;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;



public final class DiscriminatorJdbcMapper extends AbstractForEachDynamicJdbcMapper {


    private final String discriminatorColumn;
    private final List, Mapper>> mappers;

    public DiscriminatorJdbcMapper(String discriminatorColumn, List, Mapper>> mappers, RowHandlerErrorHandler rowHandlerErrorHandler) {
        super(rowHandlerErrorHandler);
        this.discriminatorColumn = discriminatorColumn;
        this.mappers = mappers;
    }


    @Override
    public MappingContext newMappingContext(ResultSet source) throws MappingException {
        try {
            return getMapper(source).newMappingContext(source);
        } catch (SQLException e) {
            return ErrorHelper.rethrow(e);
        }
    }


    private MappingContext[] getMappingContexts(ResultSet rs) throws SQLException {
        @SuppressWarnings("unchecked")
        MappingContext[] mappingContexts = new MappingContext[mappers.size()];

        int i = 0;
        for(Tuple2, Mapper> tm : mappers) {
            mappingContexts[i] = tm.getElement1().newMappingContext(rs);
            i++;
        }
        return mappingContexts;
    }

    private Mapper getMapper(int index) {
        return mappers.get(index).getElement1();
    }

    protected Mapper getMapper(final ResultSet rs) throws MappingException, SQLException {
        String value = rs.getString(discriminatorColumn);

        for(Tuple2, Mapper> tm : mappers) {
            if (tm.first().test(value)) {
                return tm.second();
            }
        }
        throw new MappingException("No mapper found for " + discriminatorColumn + " = " + value);
    }

    private int getMapperIndex(final ResultSet rs) throws MappingException, SQLException {

        String value = rs.getString(discriminatorColumn);

        int i = 0;
        for(Tuple2, Mapper> tm : mappers) {
            if (tm.first().test(value)) {
                return i;
            }
            i++;
        }
		throw new MappingException("No mapper found for " + discriminatorColumn + " = " + value);
	}


    protected DiscriminatorForEach newForEachIterator(ResultSet rs) throws SQLException {
        return new DiscriminatorForEach(this, getMappingContexts(rs), errorHandler, rs);
    }

    @Override
    public String toString() {
        return "DiscriminatorJdbcMapper{" +
                "discriminatorColumn='" + discriminatorColumn + '\'' +
                ", mappers=" + mappers +
                '}';
    }


    private static class DiscriminatorForEach implements ForEachIterator {

        private final DiscriminatorJdbcMapper mapper;
        private final MappingContext[] mappingContexts;
        private final RowHandlerErrorHandler rowHandlerErrorHandler;


        private final ResultSet resultSet;
        private int currentMapperIndex = -1;
        private T currentValue;
        private Mapper currentMapper;
        private MappingContext currentMappingContext;


        public DiscriminatorForEach(DiscriminatorJdbcMapper mapper,
                                    MappingContext[] mappingContexts,
                                    RowHandlerErrorHandler rowHandlerErrorHandler, ResultSet resultSet) {
            this.mapper = mapper;
            this.mappingContexts = mappingContexts;
            this.rowHandlerErrorHandler = rowHandlerErrorHandler;
            this.resultSet = resultSet;
        }

        @Override
        public boolean next(RowHandler rowHandler) throws Exception {
            return forEach(true, rowHandler);
        }

        @Override
        public void forEach(RowHandler rowHandler) throws Exception {
            forEach(false, rowHandler);
        }

        private boolean forEach(boolean stopOnNext, RowHandler rowHandler) throws Exception {
            while (resultSet.next()) {

                checkMapper();

                currentMappingContext.handle(resultSet);

                if (currentMappingContext.rootBroke()) {
                    if (currentValue != null) {
                        callHandler(rowHandler);
                        currentValue = currentMapper.map(resultSet, currentMappingContext);
                        if (stopOnNext) {
                            return true;
                        }
                    } else {
                        currentValue = currentMapper.map(resultSet, currentMappingContext);
                    }
                } else {
                    currentMapper.mapTo(resultSet, currentValue, currentMappingContext);
                }
            }

            if (currentValue != null) {
                callHandler(rowHandler);
                currentValue = null;
                return true;
            } else {
                return false;
            }
        }

        private void callHandler(RowHandler rowHandler) throws Exception {
            try {
                rowHandler.handle(currentValue);
            } catch(Exception e) {
                rowHandlerErrorHandler.handlerError(e, currentValue);
            }

        }

        private void checkMapper() throws java.sql.SQLException {
            int mapperIndex = mapper.getMapperIndex(resultSet);
            if (currentMapperIndex != mapperIndex) {
                mapperChange(mapperIndex);
            }
        }

        private void mapperChange(int newMapperIndex) {
            markAsBroken(mappingContexts);
            currentMapper = this.mapper.getMapper(newMapperIndex);
            currentMappingContext = mappingContexts[newMapperIndex];
            currentMapperIndex = newMapperIndex;
        }

        private void markAsBroken(MappingContext[] mappingContexts) {
            for(int i = 0; i < mappingContexts.length; i++) {
                mappingContexts[i].markAsBroken();
            }
        }
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy