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 */ 021package csheets.core.formula.lang; 022 023import java.util.SortedSet; 024import java.util.TreeSet; 025 026import csheets.core.Cell; 027import csheets.core.Value; 028import csheets.core.formula.BinaryOperation; 029import csheets.core.formula.Reference; 030import csheets.core.formula.util.ExpressionVisitor; 031import csheets.core.formula.util.ExpressionVisitorException; 032 033/** 034 * A binary reference operation in a formula. 035 * @author Einar Pehrson 036 */ 037public 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}