1:
31:
32: package ;
33:
34: import ;
35: import ;
36: import ;
37: import ;
38: import ;
39: import ;
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52:
57: public abstract class ElementLayoutController
58: implements LayoutController
59: {
60: protected static class ElementPrecomputeKey implements PrecomputeNodeKey
61: {
62: private String name;
63: private String id;
64: private String namespace;
65: private String tagName;
66:
67: protected ElementPrecomputeKey(final Element element)
68: {
69: this.name = element.getName();
70: this.tagName = element.getType();
71: this.namespace = element.getNamespace();
72: this.id = element.getId();
73: }
74:
75: public boolean equals(final Object obj)
76: {
77: if (this == obj)
78: {
79: return true;
80: }
81: if (obj == null || getClass() != obj.getClass())
82: {
83: return false;
84: }
85:
86: final ElementPrecomputeKey that = (ElementPrecomputeKey) obj;
87:
88: if (id != null ? !id.equals(that.id) : that.id != null)
89: {
90: return false;
91: }
92: if (name != null ? !name.equals(that.name) : that.name != null)
93: {
94: return false;
95: }
96: if (namespace != null ? !namespace.equals(
97: that.namespace) : that.namespace != null)
98: {
99: return false;
100: }
101: if (tagName != null ? !tagName.equals(
102: that.tagName) : that.tagName != null)
103: {
104: return false;
105: }
106:
107: return true;
108: }
109:
110: public int hashCode()
111: {
112: int result = (name != null ? name.hashCode() : 0);
113: result = 29 * result + (id != null ? id.hashCode() : 0);
114: result = 29 * result + (namespace != null ? namespace.hashCode() : 0);
115: result = 29 * result + (tagName != null ? tagName.hashCode() : 0);
116: return result;
117: }
118:
119: public boolean equals(final PrecomputeNodeKey otherKey)
120: {
121: return false;
122: }
123: }
124:
125: public static final int NOT_STARTED = 0;
126: public static final int OPENED = 1;
127: public static final int WAITING_FOR_JOIN = 2;
128: public static final int FINISHING = 3;
129:
130: public static final int FINISHED = 4;
131:
132: private int processingState;
133: private FlowController flowController;
134: private Element element;
135: private LayoutController parent;
136: private boolean precomputing;
137: private AttributeMap attributeMap;
138: private int expressionsCount;
139: private int iterationCount;
140:
141: protected ElementLayoutController()
142: {
143: this.processingState = ElementLayoutController.NOT_STARTED;
144: }
145:
146:
147: public String toString()
148: {
149: return "ElementLayoutController{" +
150: "processingState=" + processingState +
151: ", element=" + element +
152: ", precomputing=" + precomputing +
153: ", expressionsCount=" + expressionsCount +
154: ", iterationCount=" + iterationCount +
155: '}';
156: }
157:
158:
165: public LayoutController getParent()
166: {
167: return parent;
168: }
169:
170:
171:
188: public void initialize(final Object node,
189: final FlowController flowController,
190: final LayoutController parent)
191: throws DataSourceException, ReportDataFactoryException,
192: ReportProcessingException
193: {
194:
195: if (processingState != ElementLayoutController.NOT_STARTED)
196: {
197: throw new IllegalStateException();
198: }
199:
200: this.element = (Element) node;
201: this.flowController = flowController;
202: this.parent = parent;
203: this.iterationCount = -1;
204: }
205:
206:
222: public final LayoutController advance(final ReportTarget target)
223: throws DataSourceException, ReportProcessingException,
224: ReportDataFactoryException
225: {
226: final int processingState = getProcessingState();
227: switch (processingState)
228: {
229: case ElementLayoutController.NOT_STARTED:
230: return startElement(target);
231: case ElementLayoutController.OPENED:
232: return processContent(target);
233: case ElementLayoutController.FINISHING:
234: return finishElement(target);
235:
236:
237: default:
238: throw new IllegalStateException();
239: }
240: }
241:
242:
257: protected LayoutController startElement(final ReportTarget target)
258: throws DataSourceException, ReportProcessingException,
259: ReportDataFactoryException
260: {
261: final Element s = getElement();
262:
263: FlowController fc = getFlowController();
264:
265:
266: fc = startData(target, fc);
267:
268: final Expression[] expressions = s.getExpressions();
269: fc = performElementPrecomputation(expressions, fc);
270:
271: if (s.isVirtual() == false)
272: {
273: attributeMap = computeAttributes(fc, s, target);
274: target.startElement(attributeMap);
275: }
276:
277: final ElementLayoutController derived = (ElementLayoutController) clone();
278: derived.setProcessingState(ElementLayoutController.OPENED);
279: derived.setFlowController(fc);
280: derived.expressionsCount = expressions.length;
281: derived.attributeMap = attributeMap;
282: derived.iterationCount += 1;
283: return derived;
284: }
285:
286: public AttributeMap getAttributeMap()
287: {
288: return attributeMap;
289: }
290:
291: public int getExpressionsCount()
292: {
293: return expressionsCount;
294: }
295:
296: public int getIterationCount()
297: {
298: return iterationCount;
299: }
300:
301:
302: protected FlowController startData(final ReportTarget target,
303: final FlowController fc)
304: throws DataSourceException, ReportProcessingException,
305: ReportDataFactoryException
306: {
307: return fc;
308: }
309:
310: protected AttributeMap computeAttributes(final FlowController fc,
311: final Element element,
312: final ReportTarget target)
313: throws DataSourceException
314: {
315: final LayoutExpressionRuntime ler =
316: LayoutControllerUtil.getExpressionRuntime(fc, element);
317: return LayoutControllerUtil.processAttributes(element, target, ler);
318: }
319:
320:
321:
337: protected abstract LayoutController processContent(final ReportTarget target)
338: throws DataSourceException, ReportProcessingException,
339: ReportDataFactoryException;
340:
341:
357: protected LayoutController finishElement(final ReportTarget target)
358: throws ReportProcessingException, DataSourceException,
359: ReportDataFactoryException
360: {
361: final FlowController fc = handleDefaultEndElement(target);
362: final ElementLayoutController derived = (ElementLayoutController) clone();
363: derived.setProcessingState(ElementLayoutController.FINISHED);
364: derived.setFlowController(fc);
365: return derived;
366: }
367:
368: protected FlowController handleDefaultEndElement (final ReportTarget target)
369: throws ReportProcessingException, DataSourceException,
370: ReportDataFactoryException
371: {
372: final Element e = getElement();
373:
374: if (e.isVirtual() == false)
375: {
376: target.endElement(getAttributeMap());
377: }
378:
379: FlowController fc = getFlowController();
380: final PrecomputedValueRegistry pcvr =
381: fc.getPrecomputedValueRegistry();
382:
383: final int expressionsCount = getExpressionsCount();
384: if (expressionsCount != 0)
385: {
386: final ExpressionSlot[] activeExpressions = fc.getActiveExpressions();
387: for (int i = activeExpressions.length - expressionsCount; i < activeExpressions.length; i++)
388: {
389: final ExpressionSlot slot = activeExpressions[i];
390: pcvr.addFunction(slot.getName(), slot.getValue());
391: }
392: fc = fc.deactivateExpressions();
393: }
394:
395: if (isPrecomputing() == false)
396: {
397: pcvr.finishElement(new ElementPrecomputeKey(e));
398: }
399:
400: return fc;
401: }
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427: public boolean isAdvanceable()
428: {
429: return processingState != ElementLayoutController.FINISHED;
430: }
431:
432: public Element getElement()
433: {
434: return element;
435: }
436:
437: public FlowController getFlowController()
438: {
439: return flowController;
440: }
441:
442: public int getProcessingState()
443: {
444: return processingState;
445: }
446:
447: public void setProcessingState(final int processingState)
448: {
449: this.processingState = processingState;
450: }
451:
452: public void setFlowController(final FlowController flowController)
453: {
454: this.flowController = flowController;
455: }
456:
457: public void setParent(final LayoutController parent)
458: {
459: this.parent = parent;
460: }
461:
462: public Object clone()
463: {
464: try
465: {
466: return super.clone();
467: }
468: catch (CloneNotSupportedException e)
469: {
470: Log.error("Clone not supported: ", e);
471: throw new IllegalStateException("Clone must be supported.");
472: }
473: }
474:
475: public boolean isPrecomputing()
476: {
477: return precomputing;
478: }
479:
480: protected FlowController performElementPrecomputation(
481: final Expression[] expressions,
482: FlowController fc)
483: throws ReportProcessingException, ReportDataFactoryException,
484: DataSourceException
485: {
486: final Element element = getElement();
487: final PrecomputedValueRegistry pcvr = fc.getPrecomputedValueRegistry();
488: if (isPrecomputing() == false)
489: {
490: pcvr.startElement(new ElementPrecomputeKey(element));
491: }
492:
493: if (expressions.length > 0)
494: {
495: final ExpressionSlot[] slots = new ExpressionSlot[expressions.length];
496: final StaticExpressionRuntimeData runtimeData =
497: LayoutControllerUtil.getStaticExpressionRuntime(fc, element);
498:
499: for (int i = 0; i < expressions.length; i++)
500: {
501: final Expression expression = expressions[i];
502: if (isPrecomputing() == false && expression.isPrecompute())
503: {
504:
505:
506:
507: final Object value = LayoutControllerUtil.performPrecompute
508: (i, new ElementPrecomputeKey(element),
509: this, getFlowController());
510: slots[i] = new PrecomputedExpressionSlot(expression.getName(), value,
511: expression.isPreserve());
512: }
513: else
514: {
515:
516: slots[i] = new RunningExpressionSlot(expression, runtimeData,
517: pcvr.currentNode());
518: }
519: }
520:
521: fc = fc.activateExpressions(slots);
522: }
523: return fc;
524: }
525:
526:
527: protected FlowController tryRepeatingCommit(final FlowController fc)
528: throws DataSourceException
529: {
530: if (isPrecomputing() == false)
531: {
532:
533:
534:
535: final boolean advanceRequested = fc.isAdvanceRequested();
536: final boolean advanceable = fc.getMasterRow().isAdvanceable();
537: if (advanceable && advanceRequested)
538: {
539:
540:
541: final FlowController cfc =
542: fc.performOperation(FlowControlOperation.COMMIT);
543: final boolean groupFinished =
544: LayoutControllerUtil.isGroupFinished(cfc, getElement());
545: if (groupFinished == false)
546: {
547: return cfc;
548: }
549: }
550: }
551: return null;
552: }
553:
554:
555:
562: public LayoutController createPrecomputeInstance(final FlowController fc)
563: {
564: final ElementLayoutController lc = (ElementLayoutController) clone();
565: lc.setFlowController(fc);
566: lc.setParent(null);
567: lc.precomputing = true;
568: return lc;
569: }
570:
571:
572: public Object getNode()
573: {
574: return getElement();
575: }
576: }