1:
31: package ;
32:
33: import ;
34:
35: import ;
36: import ;
37: import ;
38: import ;
39: import ;
40:
41:
48: public final class ExpressionDataRow implements DataRow
49: {
50: private ExpressionSlot[] expressions;
51: private int length;
52: private HashMap nameCache;
53: private GlobalMasterRow masterRow;
54: private ReportContext reportContext;
55:
56: public ExpressionDataRow(final GlobalMasterRow masterRow,
57: final ReportContext reportContext,
58: final int capacity)
59: {
60: this.masterRow = masterRow;
61: this.nameCache = new HashMap(capacity);
62: this.expressions = new ExpressionSlot[capacity];
63: this.reportContext = reportContext;
64: }
65:
66: private ExpressionDataRow(final GlobalMasterRow masterRow,
67: final ExpressionDataRow previousRow)
68: throws CloneNotSupportedException
69: {
70: this.reportContext = previousRow.reportContext;
71: this.masterRow = masterRow;
72: this.nameCache = (HashMap) previousRow.nameCache.clone();
73: this.expressions = new ExpressionSlot[previousRow.expressions.length];
74: this.length = previousRow.length;
75: for (int i = 0; i < length; i++)
76: {
77: final ExpressionSlot expression = previousRow.expressions[i];
78: if (expression == null)
79: {
80: Log.debug("Error: Expression is null...");
81: }
82: else
83: {
84: expressions[i] = (ExpressionSlot) expression.clone();
85: }
86: }
87: }
88:
89: private void ensureCapacity(final int requestedSize)
90: {
91: final int capacity = this.expressions.length;
92: if (capacity > requestedSize)
93: {
94: return;
95: }
96: final int newSize = Math.max(capacity * 2, requestedSize + 10);
97:
98: final ExpressionSlot[] newExpressions = new ExpressionSlot[newSize];
99:
100: System.arraycopy(expressions, 0, newExpressions, 0, length);
101:
102: this.expressions = newExpressions;
103: }
104:
105:
113: public synchronized void pushExpression(final ExpressionSlot expressionSlot)
114: throws DataSourceException
115: {
116: if (expressionSlot == null)
117: {
118: throw new NullPointerException();
119: }
120:
121: ensureCapacity(length + 1);
122:
123: this.expressions[length] = expressionSlot;
124: final String name = expressionSlot.getName();
125: if (name != null)
126: {
127: nameCache.put(name, expressionSlot);
128: }
129: length += 1;
130:
131: expressionSlot.updateDataRow(masterRow.getGlobalView());
132:
133: expressionSlot.advance();
134: if (name != null)
135: {
136: final Object value = expressionSlot.getValue();
137: final MasterDataRowChangeEvent chEvent = new MasterDataRowChangeEvent
138: (MasterDataRowChangeEvent.COLUMN_ADDED, name, value);
139: masterRow.dataRowChanged(chEvent);
140: }
141: }
142:
143: public synchronized void pushExpressions(final ExpressionSlot[] expressionSlots)
144: throws DataSourceException
145: {
146: if (expressionSlots == null)
147: {
148: throw new NullPointerException();
149: }
150:
151: ensureCapacity(length + expressionSlots.length);
152: for (int i = 0; i < expressionSlots.length; i++)
153: {
154: final ExpressionSlot expression = expressionSlots[i];
155: if (expression == null)
156: {
157: continue;
158: }
159: pushExpression(expression);
160: }
161: }
162:
163: public synchronized void popExpressions(final int counter) throws
164: DataSourceException
165: {
166: for (int i = 0; i < counter; i++)
167: {
168: popExpression();
169: }
170: }
171:
172: public synchronized void popExpression() throws DataSourceException
173: {
174: if (length == 0)
175: {
176: return;
177: }
178: final String originalName = expressions[length - 1].getName();
179: final boolean preserve = expressions[length - 1].isPreserve();
180: this.expressions[length - 1] = null;
181: this.length -= 1;
182: if (originalName != null)
183: {
184: int otherIndex = -1;
185: for (int i = length - 1; i >= 0; i -= 1)
186: {
187: final ExpressionSlot expression = expressions[i];
188: if (originalName.equals(expression.getName()))
189: {
190: otherIndex = i;
191: break;
192: }
193: }
194: if (otherIndex == -1)
195: {
196: nameCache.remove(originalName);
197: }
198: else
199: {
200: nameCache.put(originalName, expressions[otherIndex]);
201: }
202:
203: if (preserve == false)
204: {
205: final MasterDataRowChangeEvent chEvent = new MasterDataRowChangeEvent
206: (MasterDataRowChangeEvent.COLUMN_REMOVED, originalName, null);
207: masterRow.dataRowChanged(chEvent);
208: }
209:
210: }
211:
212: }
213:
214:
225: public Object get(final int col) throws DataSourceException
226: {
227: return expressions[col].getValue();
228: }
229:
230:
242: public Object get(final String col) throws DataSourceException
243: {
244: final ExpressionSlot es = (ExpressionSlot) nameCache.get(col);
245: if (es == null)
246: {
247: return null;
248: }
249:
250: return es.getValue();
251: }
252:
253:
262: public String getColumnName(final int col)
263: {
264: return expressions[col].getName();
265: }
266:
267:
273: public int getColumnCount()
274: {
275: return length;
276: }
277:
278: public DataFlags getFlags(final String col)
279: {
280: throw new UnsupportedOperationException();
281: }
282:
283: public DataFlags getFlags(final int col)
284: {
285: throw new UnsupportedOperationException();
286: }
287:
288:
297: public ExpressionDataRow advance(final GlobalMasterRow master,
298: final boolean deepTraversing)
299: throws DataSourceException
300: {
301: try
302: {
303: final ExpressionDataRow edr = new ExpressionDataRow(master, this);
304:
305:
306:
307: for (int i = edr.length - 1; i >= 0; i--)
308: {
309: final ExpressionSlot expressionSlot = edr.expressions[i];
310: expressionSlot.updateDataRow(master.getGlobalView());
311: if (deepTraversing == false ||
312: (expressionSlot.isDeepTraversing()))
313: {
314: expressionSlot.advance();
315: }
316:
317: final Object value = expressionSlot.getValue();
318: final String name = expressionSlot.getName();
319: if (name != null)
320: {
321: final MasterDataRowChangeEvent chEvent = new MasterDataRowChangeEvent
322: (MasterDataRowChangeEvent.COLUMN_UPDATED, name, value);
323: master.dataRowChanged(chEvent);
324: }
325: }
326: return edr;
327: }
328: catch (CloneNotSupportedException e)
329: {
330: throw new DataSourceException("Cloning failed", e);
331: }
332: }
333:
334: public ExpressionDataRow derive(final GlobalMasterRow master)
335: throws DataSourceException
336: {
337: try
338: {
339: return new ExpressionDataRow(master, this);
340: }
341: catch (CloneNotSupportedException e)
342: {
343: throw new DataSourceException("Cloning failed", e);
344: }
345: }
346:
347: public ExpressionSlot[] getSlots()
348: {
349:
350:
351: final ExpressionSlot[] slots = new ExpressionSlot[length];
352: System.arraycopy(expressions, 0, slots, 0, length);
353: return slots;
354: }
355: }