001 /*
002 * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003 *
004 * This file is part of
005 * CleanSheets - a spreadsheet application for the Java platform.
006 *
007 * CleanSheets is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 2 of the License, or
010 * (at your option) any later version.
011 *
012 * CleanSheets is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with CleanSheets; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020 */
021 package csheets.core.formula.lang;
022
023 import java.util.SortedSet;
024 import java.util.TreeSet;
025
026 import csheets.core.Cell;
027 import csheets.core.Value;
028 import csheets.core.formula.BinaryOperation;
029 import csheets.core.formula.Reference;
030 import csheets.core.formula.util.ExpressionVisitor;
031 import csheets.core.formula.util.ExpressionVisitorException;
032
033 /**
034 * A binary reference operation in a formula.
035 * @author Einar Pehrson
036 */
037 public class ReferenceOperation extends BinaryOperation implements Reference {
038
039 /** The unique version identifier used for serialization */
040 private static final long serialVersionUID = 1767227655524985408L;
041
042 /** The cells that constitute the range */
043 private SortedSet<Cell> cells;
044
045 /**
046 * Creates a new reference operation.
047 * @param leftOperand the left(first) operand
048 * @param operator the reference operator
049 * @param rightOperand the right(second) operand
050 */
051 public ReferenceOperation(Reference leftOperand, RangeReference operator, Reference rightOperand) {
052 super(leftOperand, operator, rightOperand);
053 }
054
055 public SortedSet<Cell> getCells() {
056 if (cells == null) {
057 cells = new TreeSet<Cell>();
058 Cell[][] range = getOperator().getCells(getLeftOperand(), getRightOperand());
059 for (int row = 0; row < range.length; row++)
060 for (int column = 0; column < range[row].length; column++)
061 cells.add(range[row][column]);
062 }
063 return cells;
064 }
065
066 public RangeReference getOperator() {
067 return (RangeReference)operator;
068 }
069
070 public Reference getLeftOperand() {
071 return (Reference)super.getLeftOperand();
072 }
073
074 public Reference getRightOperand() {
075 return (Reference)super.getRightOperand();
076 }
077
078 public Value evaluate() {
079 return getOperator().applyTo(getLeftOperand(), getRightOperand());
080 }
081
082 public Object accept(ExpressionVisitor visitor) throws ExpressionVisitorException {
083 return visitor.visitReference(this);
084 }
085
086 public int compareTo(Reference reference) {
087 Cell otherCell = reference.getCells().first();
088 int firstDiff = getCells().first().compareTo(otherCell);
089 if (firstDiff != 0)
090 return firstDiff;
091 else
092 if (reference instanceof CellReference)
093 return 1;
094 else
095 return getCells().last().compareTo(reference.getCells().last());
096 }
097 }