1:
31: package ;
32:
33: import ;
34: import ;
35: import ;
36: import ;
37: import ;
38: import ;
39: import ;
40:
41:
47: public class DefaultDataTable extends ObjectTable implements DataTable
48: {
49:
50: private static class DefaultArrayCallback implements ArrayCallback
51: {
52: private DefaultDataTable table;
53: private TypeValuePair[][] backend;
54:
55: private DefaultArrayCallback(final DefaultDataTable table)
56: {
57: this.table = table;
58: backend = new TypeValuePair[table.getRowCount()][table.getColumnCount()];
59: }
60:
61: public LValue getRaw(final int row, final int column)
62: {
63: return table.getValueAt(row, column);
64: }
65:
66: public Object getValue(final int row, final int column) throws EvaluationException
67: {
68: final TypeValuePair value = get(row, column);
69: return value.getValue();
70: }
71:
72: private TypeValuePair get(final int row, final int column)
73: throws EvaluationException
74: {
75: TypeValuePair value = backend[row][column];
76: if(value == null)
77: {
78: value = getRaw(row, column).evaluate();
79: backend[row][column] = value;
80: }
81: return value;
82: }
83:
84: public Type getType(final int row, final int column) throws EvaluationException
85: {
86: return get(row, column).getType();
87: }
88:
89: public int getColumnCount()
90: {
91: return table.getColumnCount();
92: }
93:
94: public int getRowCount()
95: {
96: return table.getRowCount();
97: }
98: }
99:
100: private transient Boolean constant;
101: private static final LValue[] EMPTY_LVALUES = new LValue[0];
102:
103:
106: public DefaultDataTable()
107: {
108: }
109:
110: public DefaultDataTable(final LValue[][] array)
111: {
112: if(array != null && array.length > 0)
113: {
114: final int colCount = array[0].length;
115:
116: setData(array, colCount);
117: }
118: }
119:
120: public String getColumnName(int column)
121: {
122: final StringBuffer result = new StringBuffer();
123: for (; column >= 0; column = column / 26 - 1)
124: {
125: final int colChar = (char) (column % 26) + 'A';
126: result.append(colChar);
127: }
128: return result.toString();
129: }
130:
131:
139: public void setObject(final int row, final int column, final LValue object)
140: {
141: super.setObject(row, column, object);
142: }
143:
144: public LValue getValueAt(final int row, final int column)
145: {
146: return (LValue) getObject(row, column);
147: }
148:
149: public void initialize(final FormulaContext context) throws EvaluationException
150: {
151: final int rows = getRowCount();
152: final int cols = getColumnCount();
153: for (int row = 0; row < rows; row++)
154: {
155: for (int col = 0; col < cols; col++)
156: {
157: final LValue value = getValueAt(row, col);
158: if(value != null)
159: {
160: value.initialize(context);
161: }
162: }
163: }
164: }
165:
166: public TypeValuePair evaluate() throws EvaluationException
167: {
168: int colCount = -1;
169: final LValue[][] array = (LValue[][])getData();
170: for(int i=0; i<array.length; i++)
171: {
172: final LValue[] row = array[i];
173: if(colCount > 0 && row.length != colCount)
174: {
175:
176: throw new EvaluationException(LibFormulaErrorValue.ERROR_ILLEGAL_ARRAY_VALUE);
177: }
178: else
179: {
180: colCount = row.length;
181: }
182: }
183: return new TypeValuePair(AnyType.ANY_ARRAY, new DefaultArrayCallback(this));
184: }
185:
186: public Object clone() throws CloneNotSupportedException
187: {
188: final DefaultDataTable table = (DefaultDataTable) super.clone();
189: final Object[][] data = getData();
190: final Object[][] targetData = (Object[][]) data.clone();
191: for (int i = 0; i < targetData.length; i++)
192: {
193: final Object[] objects = targetData[i];
194: if (objects == null)
195: {
196: continue;
197: }
198:
199: targetData[i] = (Object[]) objects.clone();
200: for (int j = 0; j < objects.length; j++)
201: {
202: final LValue object = (LValue) objects[j];
203: if (object == null)
204: {
205: continue;
206: }
207: objects[j] = object.clone();
208: }
209: }
210:
211: table.setData(targetData, getColumnCount());
212: return table;
213: }
214:
215:
221: public Type getValueType()
222: {
223: return AnyType.ANY_ARRAY;
224: }
225:
226:
231: public LValue[] getChildValues()
232: {
233:
234: return EMPTY_LVALUES;
235: }
236:
237:
243: public boolean isConstant()
244: {
245: if (constant == null)
246: {
247: if (computeConstantValue())
248: {
249: constant = Boolean.TRUE;
250: }
251: else
252: {
253: constant = Boolean.FALSE;
254: }
255: }
256:
257: return Boolean.TRUE.equals(constant);
258: }
259:
260: private boolean computeConstantValue()
261: {
262: final int rows = getRowCount();
263: final int cols = getColumnCount();
264: for (int row = 0; row < rows; row++)
265: {
266: for (int col = 0; col < cols; col++)
267: {
268: final LValue value = getValueAt(row, col);
269: if (value.isConstant() == false)
270: {
271: return false;
272: }
273: }
274: }
275: return true;
276: }
277: }