1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  *   Licensed to the Apache Software Foundation (ASF) under one or more
11  *   contributor license agreements. See the NOTICE file distributed
12  *   with this work for additional information regarding copyright
13  *   ownership. The ASF licenses this file to you under the Apache
14  *   License, Version 2.0 (the "License"); you may not use this file
15  *   except in compliance with the License. You may obtain a copy of
16  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package org.libreoffice.report.pentaho.layoutprocessor;
20 
21 import org.libreoffice.report.pentaho.model.OfficeGroupSection;
22 import org.libreoffice.report.pentaho.model.VariablesDeclarationSection;
23 
24 import org.jfree.layouting.util.AttributeMap;
25 import org.jfree.report.DataSourceException;
26 import org.jfree.report.JFreeReportInfo;
27 import org.jfree.report.ReportDataFactoryException;
28 import org.jfree.report.ReportProcessingException;
29 import org.jfree.report.expressions.Expression;
30 import org.jfree.report.flow.FlowController;
31 import org.jfree.report.flow.ReportContext;
32 import org.jfree.report.flow.ReportTarget;
33 import org.jfree.report.flow.layoutprocessor.ElementLayoutController;
34 import org.jfree.report.flow.layoutprocessor.LayoutController;
35 import org.jfree.report.flow.layoutprocessor.LayoutControllerFactory;
36 import org.jfree.report.flow.layoutprocessor.LayoutControllerUtil;
37 import org.jfree.report.flow.layoutprocessor.SectionLayoutController;
38 import org.jfree.report.structure.Element;
39 import org.jfree.report.structure.Node;
40 
41 /**
42  * Creation-Date: 25.07.2007, 14:50:45
43  *
44  */
45 public class OfficeGroupInstanceSectionLayoutController extends SectionLayoutController
46 {
47 
48     public static final int STATE_PROCESS_VARIABLES = 2;
49     public static final int STATE_PROCESS_NORMAL_FLOW = 3;
50     private int state;
51     private boolean waitForJoin;
52 
53     @Override
initialize(final Object node, final FlowController flowController, final LayoutController parent)54     public void initialize(final Object node, final FlowController flowController, final LayoutController parent)
55             throws DataSourceException, ReportDataFactoryException, ReportProcessingException
56     {
57         super.initialize(node, flowController, parent);
58         state = STATE_PROCESS_VARIABLES;
59     }
60 
61     @Override
processContent(final ReportTarget target)62     protected LayoutController processContent(final ReportTarget target)
63             throws DataSourceException, ReportProcessingException, ReportDataFactoryException
64     {
65         if (state == OfficeGroupInstanceSectionLayoutController.STATE_PROCESS_VARIABLES)
66         {
67             // todo: Fill the variables section with something sensible ..
68             final VariablesDeclarationSection variables = new VariablesDeclarationSection();
69             final OfficeGroupInstanceSectionLayoutController controller =
70                     (OfficeGroupInstanceSectionLayoutController) clone();
71             controller.state =
72                     OfficeGroupLayoutController.STATE_PROCESS_NORMAL_FLOW;
73             controller.waitForJoin = true;
74             return processChild(controller, variables, getFlowController());
75         }
76         return super.processContent(target);
77     }
78 
79     // isDisplayable is private in version 0.9.1, so until the upgrade we keep this copy of the method
80     // todo: Delete it once the sun-cvs contains version 0.9.2.
81     @Override
processChild(final SectionLayoutController derived, final Node node, final FlowController flowController)82     protected LayoutController processChild(final SectionLayoutController derived,
83             final Node node,
84             final FlowController flowController)
85             throws DataSourceException, ReportProcessingException,
86             ReportDataFactoryException
87     {
88         final ReportContext reportContext = flowController.getReportContext();
89         final LayoutControllerFactory layoutControllerFactory = reportContext.getLayoutControllerFactory();
90         if (isDisplayable(node))
91         {
92             derived.setProcessingState(ElementLayoutController.WAITING_FOR_JOIN);
93             return layoutControllerFactory.create(flowController, node, derived);
94         }
95         else
96         {
97             derived.setProcessingState(ElementLayoutController.WAITING_FOR_JOIN);
98             final LayoutController childLc = layoutControllerFactory.create(flowController, node, derived);
99             return LayoutControllerUtil.skipInvisibleElement(childLc);
100         }
101     }
102 
103     @Override
isDisplayable(final Node node)104     protected boolean isDisplayable(final Node node) throws DataSourceException
105     {
106         if (!(node instanceof OfficeGroupSection))
107         {
108             return _isDisplayable(node);
109         }
110 
111         final OfficeGroupSection section = (OfficeGroupSection) node;
112         return !section.isRepeatSection() && _isDisplayable(node);
113     }
114 
_isDisplayable(final Node node)115     protected boolean _isDisplayable(final Node node)
116             throws DataSourceException
117     {
118         // temp method until the pending upgrade to 0.9.2. Later we just call super.isDisplayable(..) instead.
119         if (!node.isEnabled())
120         {
121             return false;
122         }
123 
124         final Expression expression = node.getDisplayCondition();
125         if (expression == null)
126         {
127             return true;
128         }
129 
130         final Object result = LayoutControllerUtil.evaluateExpression(getFlowController(), node, expression);
131         return Boolean.TRUE.equals(result);
132     }
133 
134     @Override
resetSectionForRepeat()135     protected void resetSectionForRepeat()
136     {
137         super.resetSectionForRepeat();
138         state = STATE_PROCESS_VARIABLES;
139     }
140 
141     /**
142      * Joins with a delegated process flow. This is generally called from a child
143      * flow and should *not* (I mean it!) be called from outside. If you do,
144      * you'll suffer.
145      *
146      * @param flowController the flow controller of the parent.
147      * @return the joined layout controller that incorporates all changes from the
148      *         delegate.
149      */
150     @Override
join(final FlowController flowController)151     public LayoutController join(final FlowController flowController)
152     {
153         if (waitForJoin)
154         {
155             final OfficeGroupInstanceSectionLayoutController derived = (OfficeGroupInstanceSectionLayoutController) clone();
156             derived.setProcessingState(ElementLayoutController.OPENED);
157             derived.setFlowController(flowController);
158             derived.waitForJoin = false;
159             return derived;
160         }
161         return super.join(flowController);
162     }
163 
164     @Override
computeAttributes(final FlowController fc, final Element element, final ReportTarget target)165     protected AttributeMap computeAttributes(final FlowController fc, final Element element, final ReportTarget target)
166             throws DataSourceException
167     {
168         final AttributeMap map = new AttributeMap(super.computeAttributes(fc, element, target));
169         map.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "iteration-count", getIterationCount());
170         map.makeReadOnly();
171         return map;
172     }
173 }
174