001    /*
002     * Copyright (c) 2005 Jens Schou, Staffan Gustafsson, Björn Lanneskog, 
003     * Einar Pehrson and Sebastian Kekkonen
004     *
005     * This file is part of
006     * CleanSheets Extension for Test Cases
007     *
008     * CleanSheets Extension for Test Cases is free software; you can
009     * redistribute it and/or modify it under the terms of the GNU General Public
010     * License as published by the Free Software Foundation; either version 2 of
011     * the License, or (at your option) any later version.
012     *
013     * CleanSheets Extension for Test Cases is distributed in the hope that
014     * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
015     * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with CleanSheets Extension for Test Cases; if not, write to the
020     * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
021     * Boston, MA  02111-1307  USA
022     */
023    package csheets.ext.test;
024            
025    import java.util.Set;
026    
027    import csheets.core.Cell;
028    import csheets.core.Value;
029    import csheets.core.formula.Expression;
030    import csheets.core.formula.Literal;
031    import csheets.core.formula.Reference;
032    import csheets.core.formula.lang.CellReference;
033    import csheets.core.formula.lang.RangeReference;
034    import csheets.core.formula.lang.ReferenceOperation;
035    import csheets.core.formula.util.ExpressionBuilder;
036    import csheets.core.formula.util.ExpressionVisitorException;
037    
038    /**
039     * An expression visitor that creates the expression for a test case, by
040     * replacing references with test case parameters.
041     * @author Einar Pehrson
042     */
043    public class TestCaseBuilder extends ExpressionBuilder {
044    
045            /** The parameters of which the test case consists */
046            private Set<TestCaseParam> params;
047    
048            /**
049             * Creates a new reference replacer, that converts the given expression
050             * to a test case using the given set of test case parameters
051             * @param params the parameters of which the test case consists
052             */
053            public TestCaseBuilder(Set<TestCaseParam> params) {
054                    this.params = params;
055            }
056    
057            /**
058             * Replaces the reference with the appropriate test case parameter(s).
059             * @param reference the reference to visit
060             */
061            public Expression visitReference(Reference reference) {
062                    if (reference instanceof CellReference) {
063                            // Converts cell reference to literal
064                            CellReference cellRef = ((CellReference)reference);
065                            for (TestCaseParam param : params)
066                                    if (cellRef.getCell().equals(param.getCell().getDelegate()))
067                                            return new Literal(param.getValue());
068                            throw new ExpressionVisitorException(); // MissingTestCaseParamException
069                    } else {
070                            ReferenceOperation refOp = (ReferenceOperation)reference;
071                            if (refOp.getOperator() instanceof RangeReference) {
072                                    // Converts range reference to matrix literal
073                                    RangeReference op = (RangeReference)refOp.getOperator();
074                                    Cell[][] cells = op.getCells(refOp.getLeftOperand(), refOp.getRightOperand());
075                                    Value[][] values = new Value[cells.length][cells[0].length];
076                                    for (int row = 0; row < cells.length; row++)
077                                            for (int column = 0; column < cells[row].length; column++) {
078                                                    for (TestCaseParam param : params)
079                                                            if (cells[row][column].equals(param.getCell().getDelegate()))
080                                                                    values[row][column] = param.getValue();
081                                                    if (values[row][column] == null)
082                                                            throw new ExpressionVisitorException(); 
083                                            }
084                                    return new Literal(new Value(values));
085                            } else
086                                    return super.visitReference(reference);
087                    }
088            }
089    }