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

org.sfm.jdbc.impl.DiscriminatorJdbcMapper 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: 1.10.3
Show newest version
package org.sfm.jdbc.impl;

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

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
//IFJAVA8_START
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
//IFJAVA8_END



public final class DiscriminatorJdbcMapper implements JdbcMapper {


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

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


    @Override
    public final T map(ResultSet source) throws MappingException {
        return map(source, null);
    }

    @Override
	public final T map(final ResultSet source, final MappingContext mappingContext) throws MappingException {
		try {
			final Mapper mapper = getMapper(source);
			return mapper.map(source, mappingContext);
		} catch(SQLException e) {
			throw new SQLMappingException(e.getMessage(), e);
		}
	}

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

    @Override
    public final void mapTo(final ResultSet source, final T target, final MappingContext mappingContext) throws MappingException {
        try {
            final Mapper mapper = getMapper(source);
            mapper.mapTo(source, target, mappingContext);
        } catch(SQLException e) {
            throw new SQLMappingException(e.getMessage(), e);
        } catch(Exception e) {
            throw new MappingException(e.getMessage(), e);
        }
    }

	@Override
	public final > H forEach(final ResultSet rs, final H handler)
			throws SQLException, MappingException {
        try  {
            newForEachIterator(rs).forEach(handler);
            return handler;
        } catch(RuntimeException e) {
            throw e;
        } catch(SQLException e) {
            throw e;
        } catch(Exception e) {
            throw new MappingException(e.getMessage(), 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;
    }

    @Override
    @Deprecated
	public final Iterator iterate(final ResultSet rs)
			throws SQLException, MappingException {
		return new ForEachIteratorIterator(newForEachIterator(rs));
	}

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

    @Override
    @SuppressWarnings("deprecation")
    public final Iterator iterator(final ResultSet rs)
			throws SQLException, MappingException {
		return iterate(rs);
	}

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


    //IFJAVA8_START
    @Override
    public Stream stream(ResultSet rs) throws SQLException, MappingException {
        return StreamSupport.stream(new ForEachIteratorSpliterator(newForEachIterator(rs)), false);
    }

    //IFJAVA8_END


    private 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);
	}

    @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