/* * Copyright (c) 2002 Cunningham & Cunningham, Inc. * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence * * This file is part of FitGoodies. * * FitGoodies is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FitGoodies is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FitGoodies. If not, see <http://www.gnu.org/licenses/>. */ package de.cologneintelligence.fitgoodies; import de.cologneintelligence.fitgoodies.htmlparser.FitCell; import de.cologneintelligence.fitgoodies.htmlparser.FitRow; import de.cologneintelligence.fitgoodies.valuereceivers.ValueReceiver; import java.util.List; import static de.cologneintelligence.fitgoodies.util.FitUtils.saveGet; public class ColumnFixture extends Fixture { private String[] columnParameters; private ValueReceiver[] columnBindings; private boolean hasExecuted = false; // Traversal //////////////////////////////// /** * Replacement of {@code doRows(Parse)} which resolves question marks * in the first row and calls fit.ColumnFixture.doRows(Parse). * <p> * Question marks represent method calls, * so getValue() and getValue? are equivalent. * * @param rows rows to be processed */ @Override protected void doRows(final List<FitRow> rows) throws Exception { FitRow headerRow = rows.get(0); columnParameters = extractColumnParameters(headerRow); bind(headerRow); super.doRows(rows.subList(1, rows.size())); } @Override protected void doRow(FitRow row) { hasExecuted = false; try { reset(); super.doRow(row); if (!hasExecuted) { execute(); } } catch (Exception e) { row.exception(e); } } /** * Replacement of {@code doCell} which resolves cross-references * before calling the original {@code doCell} method of fit. * * @param cell the cell to check * @param column the selected column * @see Fixture#doCell(FitCell, int) fit.Fixture.doCell(Parse, int) */ @Override protected void doCell(final FitCell cell, final int column) { ValueReceiver receiver = columnBindings[column]; String currentCellParameter = saveGet(column, columnParameters); if (receiver != null && !cell.getFitValue().trim().isEmpty() && receiver.canSet()) { setValue(cell, receiver, currentCellParameter); } else { check(cell, receiver, currentCellParameter); } } private void setValue(FitCell cell, ValueReceiver receiver, String currentCellParameter) { try { String text = validator.preProcess(cell); Object object = typeHandlerFactory.getHandler(receiver.getType(), currentCellParameter).parse(text); receiver.set(this, object); } catch (Exception e) { cell.exception(e); } } public void check(FitCell cell, ValueReceiver valueReceiver, String currentCellParameter) { if (!hasExecuted) { try { execute(); } catch (Exception e) { cell.exception(e); } hasExecuted = true; } super.check(cell, valueReceiver, currentCellParameter); } public void reset() throws Exception { // about to process first cell of row } public void execute() throws Exception { // about to process first method call of row } // Utility ////////////////////////////////// protected void bind(FitRow heads) { columnBindings = new ValueReceiver[heads.size()]; for (int i = 0; i < columnBindings.length; i++) { FitCell cell = heads.cells().get(i); String name = cell.getFitValue(); try { columnBindings[i] = createReceiver(this, name); } catch (Exception e) { cell.exception(e); } } } }