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

org.sfm.csv.impl.CsvMapperImpl Maven / Gradle / Ivy

Go to download

Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.

The newest version!
package org.sfm.csv.impl;

import org.sfm.csv.CsvColumnKey;
import org.sfm.csv.CsvMapper;
import org.sfm.csv.CsvParser;
import org.sfm.csv.CsvReader;
import org.sfm.csv.parser.CellConsumer;
import org.sfm.map.MappingException;
import org.sfm.map.RowHandlerErrorHandler;
import org.sfm.utils.ErrorHelper;
import org.sfm.utils.RowHandler;

import java.io.IOException;
import java.io.Reader;
import java.util.*;
//IFJAVA8_START
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
//IFJAVA8_END



public final class CsvMapperImpl implements CsvMapper {
    private static final DelayedCellSetter[] EMPTY_DELAYED_CELL_SETTERS = new DelayedCellSetter[0];

    private final DelayedCellSetterFactory[] delayedCellSetterFactories;
    private final CellSetter[] setters;


    private final CsvColumnKey[] joinKeys;
	private final RowHandlerErrorHandler rowHandlerErrorHandlers;
    protected final CsvMapperCellHandlerFactory csvMapperCellHandlerFactory;

    private final boolean hasSetterSubProperties;
    private final boolean hasSubProperties;

	public CsvMapperImpl(CsvMapperCellHandlerFactory csvMapperCellHandlerFactory,
                         DelayedCellSetterFactory[] delayedCellSetterFactories,
                         CellSetter[] setters,
                         CsvColumnKey[] joinKeys,
                         RowHandlerErrorHandler rowHandlerErrorHandlers) {
		super();
		this.csvMapperCellHandlerFactory = csvMapperCellHandlerFactory;
		this.delayedCellSetterFactories = delayedCellSetterFactories;
		this.setters = setters;
        this.joinKeys = joinKeys;
		this.rowHandlerErrorHandlers = rowHandlerErrorHandlers;
        this.hasSetterSubProperties = hasSetterSubProperties(setters);
        this.hasSubProperties = hasSetterSubProperties || hasDelayedMarker(delayedCellSetterFactories);
	}

    private boolean hasDelayedMarker(DelayedCellSetterFactory[] delayedCellSetterFactories) {
        for(DelayedCellSetterFactory setter : delayedCellSetterFactories) {
            if (setter instanceof DelegateMarkerDelayedCellSetterFactory) {
                return true;
            }
        }
        return false;
    }

    private boolean hasSetterSubProperties(CellSetter[] setters) {
        for(CellSetter setter : setters) {
            if (setter instanceof DelegateMarkerSetter) {
                return true;
            }
        }
        return false;
    }

    @Override
	public final > H forEach(final Reader reader, final H handler) throws IOException, MappingException {
		return forEach(CsvParser.reader(reader), handler);
	}

	@Override
	public > H forEach(CsvReader reader, H handle) throws IOException, MappingException {
		reader.parseAll(newCellConsumer(handle));
		return handle;
	}

	@Override
	public final > H forEach(final Reader reader, final H handler, final int skip) throws IOException, MappingException {
		return forEach(CsvParser.skip(skip).reader(reader), handler);
	}

	@Override
	public final > H forEach(final Reader reader, final H handler, final int skip, final int limit) throws IOException, MappingException {
		return forEach(CsvParser.skip(skip).reader(reader), handler, limit);
	}

	@Override
	public final > H forEach(CsvReader reader, H handle, int limit) throws IOException, MappingException {
		reader.parseRows(newCellConsumer(handle), limit);
		return handle;
	}

	@Override
	public Iterator iterator(Reader reader) throws IOException {
		return iterator(CsvParser.reader(reader));
	}

	@Override
	public Iterator iterator(CsvReader csvReader) {
		return new CsvMapperIterator(csvReader, this);
	}

	@Override
	public Iterator iterator(Reader reader, int skip) throws IOException {
		return iterator(CsvParser.skip(skip).reader(reader));
	}

	//IFJAVA8_START
	@Override
	public Stream stream(Reader reader) throws IOException {
		return stream(CsvParser.reader(reader));
	}

	@Override
	public Stream stream(CsvReader csvReader) {
		return StreamSupport.stream(new CsvSpliterator(csvReader), false);
	}

	@Override
	public Stream stream(Reader reader, int skip) throws IOException {
		return stream(CsvParser.skip(skip).reader(reader));
	}

	public class CsvSpliterator implements Spliterator {
		private final CsvReader csvReader;
		private final CellConsumer cellConsumer;
		private T current;

		public CsvSpliterator(CsvReader csvReader) {
			this.csvReader = csvReader;
			this.cellConsumer = newCellConsumer(new RowHandler() {
				@Override
				public void handle(T t) throws Exception {
					current = t;
				}
			});
		}

		@Override
		public boolean tryAdvance(Consumer action) {
			current = null;
			try {
				csvReader.parseRow(cellConsumer);
			} catch (IOException e) {
                return ErrorHelper.rethrow(e);
			}
			if (current != null) {
				action.accept(current);
				return true;
			} else {
				return false;
			}
		}

		@Override
		public void forEachRemaining(Consumer action) {
			try {
				csvReader.parseAll(newCellConsumer(new RowHandler() {
                    @Override
                    public void handle(T t) throws Exception {
						action.accept(t);
                    }
                }));
			} catch (IOException e) {
                ErrorHelper.rethrow(e);
			}
		}

		@Override
		public Spliterator trySplit() {
			return null;
		}

		@Override
		public long estimateSize() {
			return Long.MAX_VALUE;
		}

		@Override
		public int characteristics() {
			return Spliterator.ORDERED | Spliterator.NONNULL;
		}
	}

	//IFJAVA8_END

    protected CsvMapperCellConsumer newCellConsumer(final RowHandler handler) {
        return newCellConsumer(handler, null);
    }

	protected CsvMapperCellConsumer newCellConsumer(final RowHandler handler, BreakDetector parentBreakDetector) {
        CsvMapperCellConsumer[] cellHandlers = null;

        if (hasSubProperties) {
            cellHandlers = new CsvMapperCellConsumer[delayedCellSetterFactories.length + setters.length];
        }
        final BreakDetector breakDetector = newBreakDetector(parentBreakDetector, delayedCellSetterFactories.length - 1);

        DelayedCellSetter[] outDelayedCellSetters = getDelayedCellSetters(cellHandlers, breakDetector);
        CellSetter[] outSetters = getCellSetters(cellHandlers, breakDetector);

        CsvMapperCellHandler mapperSetters = csvMapperCellHandlerFactory.newInstance(outDelayedCellSetters, outSetters);

        return new CsvMapperCellConsumer(mapperSetters,
                rowHandlerErrorHandlers,
                handler,
                breakDetector, toList(cellHandlers));
	}

    @SuppressWarnings("unchecked")
    private DelayedCellSetter[] getDelayedCellSetters(CsvMapperCellConsumer[] cellHandlers, BreakDetector breakDetector) {
        if (delayedCellSetterFactories.length == 0) {
            return EMPTY_DELAYED_CELL_SETTERS;
        } else {
            return buildDelayedCellSetters(cellHandlers, breakDetector);
        }
    }

    @SuppressWarnings("unchecked")
    private DelayedCellSetter[] buildDelayedCellSetters(CsvMapperCellConsumer[] cellHandlers, BreakDetector breakDetector) {
        DelayedCellSetter[] outDelayedCellSetters = new DelayedCellSetter[delayedCellSetterFactories.length];
        for(int i = delayedCellSetterFactories.length - 1; i >= 0 ; i--) {
            DelayedCellSetterFactory delayedCellSetterFactory = delayedCellSetterFactories[i];
            if (delayedCellSetterFactory != null) {
                outDelayedCellSetters[i] = delayedCellSetterFactory.newCellSetter(breakDetector, cellHandlers);
            }
        }
        return outDelayedCellSetters;
    }

    private Collection> toList(CsvMapperCellConsumer[] cellHandlers) {
        if (cellHandlers == null) return Collections.emptyList();

        List> consumers = new ArrayList>();
        for(CsvMapperCellConsumer consumer : cellHandlers) {
            if (consumer != null) {
                consumers.add(consumer);
            }
        }
        return consumers;
    }

    @SuppressWarnings("unchecked")
    private CellSetter[] getCellSetters(CsvMapperCellConsumer[] cellHandlers, BreakDetector breakDetector) {
        if (hasSetterSubProperties) {
            return rebuildCellSetters(cellHandlers, breakDetector);
        } else {
            return setters;
        }
    }

    @SuppressWarnings("unchecked")
    private CellSetter[] rebuildCellSetters(CsvMapperCellConsumer[] cellHandlers, BreakDetector breakDetector) {
        CellSetter[] outSetters = new CellSetter[setters.length];
        for(int i = setters.length - 1; i >= 0 ; i--) {
            if (setters[i] instanceof DelegateMarkerSetter) {
                DelegateCellSetter delegateCellSetter = getDelegateCellSetter((DelegateMarkerSetter)setters[i], cellHandlers, breakDetector, i);
                outSetters[i] = delegateCellSetter;
            } else {
                outSetters[i] = setters[i];
            }
        }
        return outSetters;
    }

    @SuppressWarnings("unchecked")
    private 

DelegateCellSetter getDelegateCellSetter(DelegateMarkerSetter marker, CsvMapperCellConsumer[] cellHandlers, BreakDetector breakDetector, int i) { final int parent = marker.getParent(); final int cellIndex = i + delayedCellSetterFactories.length; if(parent == cellIndex) { final DelegateCellSetter tpDelegateCellSetter = new DelegateCellSetter(marker, cellIndex, breakDetector); cellHandlers[cellIndex] = tpDelegateCellSetter.getCellConsumer(); return tpDelegateCellSetter; } else { final CsvMapperCellConsumer cellHandler = cellHandlers[parent]; if (cellHandler==null) { throw new NullPointerException("No cell handler on parent " + parent); } return new DelegateCellSetter(marker, (CsvMapperCellConsumer

) cellHandler, cellIndex); } } private BreakDetector newBreakDetector(BreakDetector parentBreakDetector, int delayedSetterEnd) { if (parentBreakDetector != null || joinKeys.length > 0) { return new BreakDetector(joinKeys, parentBreakDetector, delayedSetterEnd); } else { return null; } } @Override public String toString() { return "CsvMapperImpl{" + "targetSettersFactory=" + csvMapperCellHandlerFactory + ", delayedCellSetters=" + Arrays.toString(delayedCellSetterFactories) + ", setters=" + Arrays.toString(setters) + '}'; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy