1:
31:
32: package ;
33:
34: import ;
35: import ;
36:
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: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74:
75:
80: public class LayoutControllerUtil
81: {
82: public static final EmptyReportData EMPTY_REPORT_DATA = new EmptyReportData();
83:
84: private LayoutControllerUtil()
85: {
86: }
87:
88: public static int findNodeInParent(final Section parentSection,
89: final Node n)
90: {
91: final Node[] nodes = parentSection.getNodeArray();
92: for (int i = 0; i < nodes.length; i++)
93: {
94: final Node node = nodes[i];
95: if (node == n)
96: {
97: return i;
98: }
99: }
100: return -1;
101: }
102:
103: public static StaticExpressionRuntimeData getStaticExpressionRuntime
104: (final FlowController fc,
105: final Object declaringParent)
106: {
107: final GlobalMasterRow dataRow = fc.getMasterRow();
108: final ReportJob reportJob = fc.getReportJob();
109: final StaticExpressionRuntimeData sdd = new StaticExpressionRuntimeData();
110: sdd.setData(dataRow.getReportDataRow().getReportData());
111: sdd.setDeclaringParent(declaringParent);
112: sdd.setConfiguration(reportJob.getConfiguration());
113: sdd.setReportContext(fc.getReportContext());
114: return sdd;
115: }
116:
117:
118: public static LayoutExpressionRuntime getExpressionRuntime
119: (final FlowController fc, final Object node)
120: {
121: final LayoutExpressionRuntime ler = new LayoutExpressionRuntime();
122: ler.setConfiguration(fc.getReportJob().getConfiguration());
123: ler.setReportContext(fc.getReportContext());
124:
125: final GlobalMasterRow masterRow = fc.getMasterRow();
126: ler.setDataRow(masterRow.getGlobalView());
127:
128: final ReportDataRow reportDataRow = masterRow.getReportDataRow();
129: if (reportDataRow == null)
130: {
131: ler.setData(EMPTY_REPORT_DATA);
132: ler.setCurrentRow(-1);
133: }
134: else
135: {
136: ler.setData(reportDataRow.getReportData());
137: ler.setCurrentRow(reportDataRow.getCursor());
138: }
139:
140: ler.setDeclaringParent(node);
141: return ler;
142: }
143:
144:
145: public static FlowController processFlowOperations(FlowController fc,
146: final FlowControlOperation[] ops)
147: throws DataSourceException
148: {
149: for (int i = 0; i < ops.length; i++)
150: {
151: final FlowControlOperation op = ops[i];
152: fc = fc.performOperation(op);
153: }
154: return fc;
155: }
156:
157:
158:
169: public static boolean isGroupFinished(final FlowController fc,
170: final Node node)
171: throws DataSourceException
172: {
173: final Node nodeParent = node.getParent();
174: if (nodeParent == null)
175: {
176: return false;
177: }
178: Group group = nodeParent.getGroup();
179: if (group == null)
180: {
181: return false;
182: }
183:
184:
185:
186: LayoutExpressionRuntime ler = null;
187:
188:
189: while (group != null)
190: {
191: if (ler == null)
192: {
193: ler = getExpressionRuntime(fc, node);
194: }
195:
196: ler.setDeclaringParent(group);
197:
198: final Expression groupingExpression = group.getGroupingExpression();
199: if (groupingExpression != null)
200: {
201: groupingExpression.setRuntime(ler);
202: final Object groupFinished;
203: try
204: {
205: groupFinished = groupingExpression.computeValue();
206: }
207: finally
208: {
209: groupingExpression.setRuntime(null);
210: }
211:
212: if (Boolean.TRUE.equals(groupFinished))
213: {
214:
215:
216:
217:
218: return true;
219: }
220: }
221:
222: final Node parent = group.getParent();
223: if (parent == null)
224: {
225: group = null;
226: }
227: else
228: {
229: group = parent.getGroup();
230: }
231: }
232: return false;
233: }
234:
235:
236: private static void mergeDeclarationRule(final CSSDeclarationRule target,
237: final CSSDeclarationRule source)
238: {
239: final Iterator it = source.getPropertyKeys();
240: while (it.hasNext())
241: {
242: final StyleKey key = (StyleKey) it.next();
243: final CSSValue value = source.getPropertyCSSValue(key);
244: final boolean sourceImportant = source.isImportant(key);
245: final boolean targetImportant = target.isImportant(key);
246: if (targetImportant)
247: {
248: continue;
249: }
250: target.setPropertyValue(key, value);
251: target.setImportant(key, sourceImportant);
252: }
253: }
254:
255: private static CSSDeclarationRule processStyleAttribute
256: (final Object styleAttributeValue,
257: final Element node,
258: final ExpressionRuntime runtime,
259: CSSDeclarationRule targetRule)
260: throws DataSourceException
261: {
262: if (targetRule == null)
263: {
264: try
265: {
266: targetRule = (CSSDeclarationRule) node.getStyle().clone();
267: }
268: catch (CloneNotSupportedException e)
269: {
270: targetRule = new CSSStyleRule(null, null);
271: }
272: }
273:
274:
275: if (styleAttributeValue instanceof String)
276: {
277:
278:
279: final String styleText = (String) styleAttributeValue;
280: try
281: {
282: final ReportContext reportContext = runtime.getReportContext();
283: final ReportStructureRoot root = reportContext.getReportStructureRoot();
284: final ResourceKey baseResource = root.getBaseResource();
285: final ResourceManager resourceManager = root.getResourceManager();
286:
287: final byte[] bytes = styleText.getBytes("UTF-8");
288: final ResourceKey key = resourceManager.createKey(bytes);
289: final Resource resource = resourceManager.create
290: (key, baseResource, StyleRule.class);
291:
292: final CSSDeclarationRule parsedRule =
293: (CSSDeclarationRule) resource.getResource();
294: mergeDeclarationRule(targetRule, parsedRule);
295: }
296: catch (Exception e)
297: {
298:
299: e.printStackTrace();
300: }
301: }
302: else if (styleAttributeValue instanceof CSSStyleRule)
303: {
304: final CSSStyleRule styleRule =
305: (CSSStyleRule) styleAttributeValue;
306: mergeDeclarationRule(targetRule, styleRule);
307: }
308:
309:
310: final Map styleExpressions = node.getStyleExpressions();
311: final Iterator styleExIt = styleExpressions.entrySet().iterator();
312:
313: while (styleExIt.hasNext())
314: {
315: final Map.Entry entry = (Map.Entry) styleExIt.next();
316: final String name = (String) entry.getKey();
317: final Expression expression = (Expression) entry.getValue();
318: try
319: {
320: expression.setRuntime(runtime);
321: final Object value = expression.computeValue();
322: if (value instanceof CSSValue)
323: {
324: final CSSValue cssvalue = (CSSValue) value;
325: final StyleKey keyByName =
326: StyleKeyRegistry.getRegistry().findKeyByName(name);
327: if (keyByName != null)
328: {
329: targetRule.setPropertyValue(keyByName, cssvalue);
330: }
331: else
332: {
333: targetRule.setPropertyValueAsString(name, cssvalue.getCSSText());
334: }
335: }
336: else if (value != null)
337: {
338: targetRule.setPropertyValueAsString(name, String.valueOf(value));
339: }
340: }
341: finally
342: {
343: expression.setRuntime(null);
344: }
345: }
346: return targetRule;
347: }
348:
349: private static AttributeMap collectAttributes(final Element node,
350: final ExpressionRuntime runtime)
351: throws DataSourceException
352: {
353: final AttributeMap attributes = node.getAttributeMap();
354: final AttributeMap attributeExpressions = node.getAttributeExpressionMap();
355: final String[] namespaces = attributeExpressions.getNameSpaces();
356: for (int i = 0; i < namespaces.length; i++)
357: {
358: final String namespace = namespaces[i];
359: final Map attrEx = attributeExpressions.getAttributes(namespace);
360:
361: final Iterator attributeExIt = attrEx.entrySet().iterator();
362: while (attributeExIt.hasNext())
363: {
364: final Map.Entry entry = (Map.Entry) attributeExIt.next();
365: final String name = (String) entry.getKey();
366: final Expression expression = (Expression) entry.getValue();
367: try
368: {
369: expression.setRuntime(runtime);
370: final Object value = expression.computeValue();
371: attributes.setAttribute(namespace, name, value);
372: }
373: finally
374: {
375: expression.setRuntime(null);
376: }
377: }
378: }
379: return attributes;
380: }
381:
382: public static AttributeMap processAttributes(final Element node,
383: final ReportTarget target,
384: final ExpressionRuntime runtime)
385: throws DataSourceException
386: {
387: final AttributeMap attributes = collectAttributes(node, runtime);
388: CSSDeclarationRule rule = null;
389:
390: final AttributeMap retval = new AttributeMap();
391:
392: final String[] attrNamespaces = attributes.getNameSpaces();
393: for (int i = 0; i < attrNamespaces.length; i++)
394: {
395: final String namespace = attrNamespaces[i];
396: final Map attributeMap = attributes.getAttributes(namespace);
397: if (attributeMap == null)
398: {
399: continue;
400: }
401:
402: final NamespaceDefinition nsDef = target.getNamespaceByUri(namespace);
403: final Iterator attributeIt = attributeMap.entrySet().iterator();
404: while (attributeIt.hasNext())
405: {
406: final Map.Entry entry = (Map.Entry) attributeIt.next();
407: final String key = (String) entry.getKey();
408: if (isStyleAttribute(nsDef, node.getType(), key))
409: {
410: final Object styleAttributeValue = entry.getValue();
411: rule = processStyleAttribute(styleAttributeValue, node, runtime,
412: rule);
413: }
414: else
415: {
416: retval.setAttribute(namespace, key, entry.getValue());
417: }
418: }
419: }
420:
421:
422: if (rule == null)
423: {
424: rule = processStyleAttribute(null, node, runtime, rule);
425: }
426:
427: if (rule != null && rule.getSize() > 0)
428: {
429: retval.setAttribute(Namespaces.LIBLAYOUT_NAMESPACE, "style", rule);
430: }
431:
432: return retval;
433: }
434:
435: private static boolean isStyleAttribute(final NamespaceDefinition def,
436: final String elementName,
437: final String attrName)
438: {
439: if (def == null)
440: {
441: return false;
442: }
443:
444: final String[] styleAttr = def.getStyleAttribute(elementName);
445: for (int i = 0; i < styleAttr.length; i++)
446: {
447: final String styleAttrib = styleAttr[i];
448: if (attrName.equals(styleAttrib))
449: {
450: return true;
451: }
452: }
453: return false;
454: }
455:
456: public static AttributeMap createEmptyMap(final String namespace,
457: final String tagName)
458: {
459: final AttributeMap map = new AttributeMap();
460: map.setAttribute(JFreeReportInfo.REPORT_NAMESPACE,
461: Element.NAMESPACE_ATTRIBUTE, namespace);
462: map.setAttribute(JFreeReportInfo.REPORT_NAMESPACE,
463: Element.TYPE_ATTRIBUTE, tagName);
464: return map;
465: }
466:
467:
468: public static Object performPrecompute(final int expressionPosition,
469: final PrecomputeNodeKey nodeKey,
470: final LayoutController layoutController,
471: final FlowController flowController)
472: throws ReportProcessingException, ReportDataFactoryException,
473: DataSourceException
474: {
475: final FlowController fc = flowController.createPrecomputeInstance();
476: final PrecomputedValueRegistry pcvr = fc.getPrecomputedValueRegistry();
477:
478: pcvr.startElementPrecomputation(nodeKey);
479:
480: final LayoutController rootLc = layoutController.createPrecomputeInstance(fc);
481: final LayoutController rootParent = rootLc.getParent();
482: final ReportTarget target = new EmptyReportTarget(fc.getReportJob(), fc.getExportDescriptor());
483:
484: LayoutController lc = rootLc;
485: while (lc.isAdvanceable())
486: {
487: lc = lc.advance(target);
488: while (lc.isAdvanceable() == false && lc.getParent() != null)
489: {
490: final LayoutController parent = lc.getParent();
491: lc = parent.join(lc.getFlowController());
492: }
493: }
494:
495: target.commit();
496: final PrecomputeNode precomputeNode = pcvr.currentNode();
497: final Object functionResult = precomputeNode.getFunctionResult(expressionPosition);
498: pcvr.finishElementPrecomputation(nodeKey);
499: return functionResult;
500:
501:
502: }
503:
504:
505: public static LayoutController skipInvisibleElement(final LayoutController layoutController)
506: throws ReportProcessingException, ReportDataFactoryException, DataSourceException
507: {
508: final FlowController fc = layoutController.getFlowController();
509: final ReportTarget target = new EmptyReportTarget(fc.getReportJob(), fc.getExportDescriptor());
510: final LayoutController rootParent = layoutController.getParent();
511:
512:
513:
514: LayoutController lc = layoutController;
515: while (lc.isAdvanceable())
516: {
517: lc = lc.advance(target);
518: while (lc.isAdvanceable() == false && lc.getParent() != null)
519: {
520: final LayoutController parent = lc.getParent();
521: lc = parent.join(lc.getFlowController());
522: if (parent == rootParent)
523: {
524: target.commit();
525: return lc;
526: }
527: }
528: }
529: target.commit();
530: throw new IllegalStateException
531: ("Ups - we did not get to the root parent again. This is awful and we cannot continue.");
532:
533: }
534:
535: public static Object evaluateExpression(final FlowController flowController,
536: final Object declaringParent,
537: final Expression expression)
538: throws DataSourceException
539: {
540: final ExpressionRuntime runtime =
541: getExpressionRuntime(flowController, declaringParent);
542:
543: try
544: {
545: expression.setRuntime(runtime);
546: return expression.computeValue();
547: }
548: catch (DataSourceException dse)
549: {
550: throw dse;
551: }
552: catch (Exception e)
553: {
554: throw new DataSourceException("Failed to evaluate expression", e);
555: }
556: finally
557: {
558: expression.setRuntime(null);
559: }
560: }
561: }