Source for org.jfree.formula.lvalues.DefaultDataTable

   1: /**
   2:  * =========================================
   3:  * LibFormula : a free Java formula library
   4:  * =========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/libformula/
   7:  *
   8:  * (C) Copyright 2006-2007, by Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  *
  26:  * ------------
  27:  * $Id: DefaultDataTable.java,v 1.5 2007/05/31 20:14:36 mimil Exp $
  28:  * ------------
  29:  * (C) Copyright 2006-2007, by Pentaho Corporation.
  30:  */
  31: package org.jfree.formula.lvalues;
  32: 
  33: import org.jfree.formula.EvaluationException;
  34: import org.jfree.formula.FormulaContext;
  35: import org.jfree.formula.LibFormulaErrorValue;
  36: import org.jfree.formula.typing.Type;
  37: import org.jfree.formula.typing.coretypes.DataTableType;
  38: import org.jfree.util.ObjectTable;
  39: 
  40: /**
  41:  * Creation-Date: 05.11.2006, 13:34:01
  42:  *
  43:  * @author Thomas Morgner
  44:  * @author Cedric Pronzato
  45:  */
  46: public class DefaultDataTable extends ObjectTable implements DataTable
  47: {
  48:   private transient Boolean constant;
  49: 
  50:   /**
  51:    * Creates a new table.
  52:    */
  53:   public DefaultDataTable()
  54:   {
  55:   }
  56: 
  57:   public DefaultDataTable(LValue[][] array)
  58:   {
  59:     if(array != null && array.length > 0)
  60:     {
  61:       int colCount = array[0].length;
  62:       //TODO: check if it is safe to do that
  63:       setData(array, colCount);
  64:     }
  65:   }
  66: 
  67:   public String getColumnName(int column)
  68:   {
  69:     StringBuffer result = new StringBuffer();
  70:     for (; column >= 0; column = column / 26 - 1)
  71:     {
  72:       final int colChar = (char) (column % 26) + 'A';
  73:       result.append(colChar);
  74:     }
  75:     return result.toString();
  76:   }
  77: 
  78:   /**
  79:    * Sets the object for a cell in the table.  The table is expanded if
  80:    * necessary.
  81:    *
  82:    * @param row    the row index (zero-based).
  83:    * @param column the column index (zero-based).
  84:    * @param object the object.
  85:    */
  86:   public void setObject(final int row, final int column, final LValue object)
  87:   {
  88:     super.setObject(row, column, object);
  89:   }
  90: 
  91:   public LValue getValueAt(int row, int column)
  92:   {
  93:     return (LValue) getObject(row, column);
  94:   }
  95: 
  96:   public void initialize(FormulaContext context) throws EvaluationException
  97:   {
  98:     final int rows = getRowCount();
  99:     final int cols = getColumnCount();
 100:     for (int row = 0; row < rows; row++)
 101:     {
 102:       for (int col = 0; col < cols; col++)
 103:       {
 104:         LValue value = getValueAt(row, col);
 105:         if(value != null)
 106:         {
 107:           value.initialize(context);
 108:         }
 109:       }
 110:     }
 111:   }
 112: 
 113:   public TypeValuePair evaluate() throws EvaluationException
 114:   {
 115:     int colCount = -1;
 116:     LValue[][] array = (LValue[][])getData();
 117:     for(int i=0; i<array.length; i++)
 118:     {
 119:       LValue[] row = array[i];
 120:       if(colCount > 0 && row.length != colCount)
 121:       {
 122:         // error, different column count is not allowed
 123:         throw new EvaluationException(LibFormulaErrorValue.ERROR_ILLEGAL_ARRAY_VALUE);
 124:       }
 125:       else
 126:       {
 127:         colCount = row.length;
 128:       }
 129:     }
 130:     return new TypeValuePair(DataTableType.TYPE, this);
 131:   }
 132: 
 133:   public Object clone() throws CloneNotSupportedException
 134:   {
 135:     final DefaultDataTable table = (DefaultDataTable) super.clone();
 136:     final Object[][] data = getData();
 137:     final Object[][] targetData = (Object[][]) data.clone();
 138:     for (int i = 0; i < targetData.length; i++)
 139:     {
 140:       final Object[] objects = targetData[i];
 141:       if (objects == null)
 142:       {
 143:         continue;
 144:       }
 145: 
 146:       targetData[i] = (Object[]) objects.clone();
 147:       for (int j = 0; j < objects.length; j++)
 148:       {
 149:         final LValue object = (LValue) objects[j];
 150:         if (object == null)
 151:         {
 152:           continue;
 153:         }
 154:         objects[j] = object.clone();
 155:       }
 156:     }
 157: 
 158:     table.setData(targetData, getColumnCount());
 159:     return table;
 160:   }
 161: 
 162:   /**
 163:    * Querying the value type is only valid *after* the value has been
 164:    * evaluated.
 165:    *
 166:    * @return
 167:    */
 168:   public Type getValueType()
 169:   {
 170:     return DataTableType.TYPE;
 171:   }
 172: 
 173:   /**
 174:    * Returns any dependent lvalues (parameters and operands, mostly).
 175:    *
 176:    * @return
 177:    */
 178:   public LValue[] getChildValues()
 179:   {
 180:     // too expensive ...
 181:     return new LValue[0];
 182:   }
 183: 
 184:   /**
 185:    * Checks, whether the LValue is constant. Constant lvalues always return the
 186:    * same value.
 187:    *
 188:    * @return
 189:    */
 190:   public boolean isConstant()
 191:   {
 192:     if (constant == null)
 193:     {
 194:       if (computeConstantValue())
 195:       {
 196:         constant = Boolean.TRUE;
 197:       }
 198:       else
 199:       {
 200:         constant = Boolean.FALSE;
 201:       }
 202:     }
 203: 
 204:     return Boolean.TRUE.equals(constant);
 205:   }
 206: 
 207:   private boolean computeConstantValue()
 208:   {
 209:     final int rows = getRowCount();
 210:     final int cols = getColumnCount();
 211:     for (int row = 0; row < rows; row++)
 212:     {
 213:       for (int col = 0; col < cols; col++)
 214:       {
 215:         LValue value = getValueAt(row, col);
 216:         if (value.isConstant() == false)
 217:         {
 218:           return false;
 219:         }
 220:       }
 221:     }
 222:     return true;
 223:   }
 224: }