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

org.sfm.csv.CsvMapperCellHandler Maven / Gradle / Ivy

package org.sfm.csv;

import org.sfm.csv.parser.CharsCellHandler;
import org.sfm.map.FieldMapperErrorHandler;
import org.sfm.map.MappingException;
import org.sfm.map.RowHandlerErrorHandler;
import org.sfm.reflect.Instantiator;
import org.sfm.utils.RowHandler;

public final class CsvMapperCellHandler implements CharsCellHandler {

	private final DelayedCellSetter[] delayedCellSetters;
	private final CellSetter[] setters;
	@SuppressWarnings("rawtypes")
	private final Instantiator instantiator;
	private final FieldMapperErrorHandler fieldErrorHandler;
	private final RowHandlerErrorHandler rowHandlerErrorHandlers;
	private final RowHandler handler;
	private final int flushIndex;
	private final int totalLength;
	private final ParsingContext parsingContext;

	private final int rowStart;
	private final int limit;
	
	
	
	private T currentInstance;
	private int cellIndex = 0;
	private int currentRow = 0;

	public CsvMapperCellHandler(
			@SuppressWarnings("rawtypes") Instantiator instantiator,
			DelayedCellSetter[] delayedCellSetters,
			CellSetter[] setters,
			FieldMapperErrorHandler fieldErrorHandler,
			RowHandlerErrorHandler rowHandlerErrorHandlers,
			RowHandler handler, 
			ParsingContext parsingContext,
			int rowStart, int limit) {
		super();
		this.instantiator = instantiator;
		this.delayedCellSetters = delayedCellSetters;
		this.setters = setters;
		this.fieldErrorHandler = fieldErrorHandler;
		this.rowHandlerErrorHandlers = rowHandlerErrorHandlers;
		this.handler = handler;
		this.flushIndex = lastNonNullSetter(delayedCellSetters, setters);
		this.totalLength = delayedCellSetters.length + setters.length;
		this.rowStart = rowStart;
		this.limit = limit;
		this.parsingContext = parsingContext;
	}
	
	private int lastNonNullSetter(
			DelayedCellSetter[] dcs,
			CellSetter[] cs) {
		int lastNonNull = -1;
		
		for(int i = 0; i < dcs.length; i++) {
			if (dcs[i] != null) {
				lastNonNull = i;
			}
		}
		
		for(int i = 0; i < cs.length; i++) {
			if (cs[i] != null) {
				lastNonNull = i + dcs.length;
			}
		}
		
		return lastNonNull;
	}

	@Override
	public boolean endOfRow() {
		endOfRow(cellIndex);
		cellIndex = 0;
		return continueProcessing();
	}
	
	private boolean continueProcessing() {
		currentRow++;
		boolean continueProcessing =  limit == -1 || (currentRow - rowStart) < limit;
		return continueProcessing;
	} 
	
	public void endOfRow(int cellIndex) {
		flush(cellIndex);
	}
	public void flush(int cellIndex) {
		if (cellIndex > 0) {
			T instance = currentInstance;
			if (instance == null) {
				instance = createInstance();
				applyDelayedSetters(instance);
				callHandler(instance);
			} else {
				applyDelayedSetters(instance);
				callHandler(instance);
				currentInstance = null;
			}
			this.cellIndex = -1;
		}
	}


	private void callHandler(T instance) {
		try {
			handler.handle(instance);
		} catch (Exception e) {
			rowHandlerErrorHandlers.handlerError(e, instance);
		}
	}

	private void applyDelayedSetters(T instance) {
		for(int i = 0; i < delayedCellSetters.length; i++) {
			DelayedCellSetter delayedSetter = delayedCellSetters[i];
			if (delayedSetter != null && delayedSetter.isSettable()) {
				try {
					delayedSetter.set(instance);
				} catch (Exception e) {
					fieldErrorHandler.errorMappingField(i, this, instance, e);
				}
			}
		}
	}

	private T createInstance() {
		try {
			return instantiator.newInstance(delayedCellSetters);
		} catch (Exception e) {
			throw new MappingException(e.getMessage(), e);
		}
	}

	private void newCellForDelayedSetter(char[] chars, int offset, int length, int cellIndex) {
		try {
			DelayedCellSetter delayedCellSetter = delayedCellSetters[cellIndex];
			if (delayedCellSetter != null) {
				delayedCellSetter.set(chars, offset, length, parsingContext);
			}
		} catch (Exception e) {
			fieldErrorHandler.errorMappingField(cellIndex, this, currentInstance, e);
		}
	}

	private void newCellForSetter(char[] chars, int offset, int length, int cellIndex) {
		if (cellIndex < totalLength) {
			try {
				CellSetter cellSetter = setters[cellIndex - delayedCellSetters.length];
				if (cellSetter != null) {
					cellSetter.set(currentInstance, chars, offset, length, parsingContext);
				}
			} catch (Exception e) {
				fieldErrorHandler.errorMappingField(cellIndex, this, currentInstance, e);
			}
		}
	}
	
	@Override
	public void end() {
		endOfRow();
	}

	@Override
	public void newCell(char[] chars, int offset, int length) {
		if (rowStart == -1 || currentRow >= rowStart) {
			if (cellIndex == -1) {
				return;
			}
			newCell(chars, offset, length, cellIndex);
			if (cellIndex != -1) {
				cellIndex++;
			}
		}
	}
	
	public void newCell(char[] chars, int offset, int length, int cellIndex) {
		
		if (cellIndex < delayedCellSetters.length) {
			newCellForDelayedSetter(chars, offset, length, cellIndex);
		} else {
			if (currentInstance == null) {
				currentInstance = createInstance();
			}
			newCellForSetter(chars, offset, length, cellIndex);
		}
		
		if (cellIndex == flushIndex) {
			flush(cellIndex);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy