001/*
002 * Copyright (c) 2005 Jens Schou, Staffan Gustafsson, Bjorn 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 */
023package csheets.ext.test;
024        
025import java.util.Set;
026
027import csheets.core.Cell;
028import csheets.core.Value;
029import csheets.core.formula.Expression;
030import csheets.core.formula.Literal;
031import csheets.core.formula.Reference;
032import csheets.core.formula.lang.CellReference;
033import csheets.core.formula.lang.RangeReference;
034import csheets.core.formula.lang.ReferenceOperation;
035import csheets.core.formula.util.ExpressionBuilder;
036import 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 */
043public 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}