1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.report.pentaho.layoutprocessor;
24 
25 import com.sun.star.report.pentaho.model.OfficeReport;
26 import com.sun.star.report.pentaho.model.VariablesDeclarationSection;
27 
28 import org.jfree.report.DataSourceException;
29 import org.jfree.report.ReportDataFactoryException;
30 import org.jfree.report.ReportProcessingException;
31 import org.jfree.report.flow.FlowController;
32 import org.jfree.report.flow.ReportContext;
33 import org.jfree.report.flow.ReportTarget;
34 import org.jfree.report.flow.layoutprocessor.ElementLayoutController;
35 import org.jfree.report.flow.layoutprocessor.LayoutController;
36 import org.jfree.report.flow.layoutprocessor.LayoutControllerFactory;
37 import org.jfree.report.structure.Node;
38 
39 /**
40  * Todo: Document me!
41  *
42  * @author Thomas Morgner
43  * @since 06.03.2007
44  */
45 public class OfficeReportLayoutController extends ElementLayoutController
46         implements OfficeRepeatingStructureLayoutController
47 {
48 
49     private static final int STATE_NOT_STARTED = 0;
50     private static final int STATE_TEMPLATES = 1;
51     private static final int STATE_PAGE_HEADER_DONE = 2;
52     private static final int STATE_PAGE_FOOTER_DONE = 3;
53     private static final int STATE_SPREADSHEET_PAGE_HEADER_DONE = 4;
54     private static final int STATE_SPREADSHEET_PAGE_FOOTER_DONE = 5;
55     private static final int STATE_COLUMN_HEADER_DONE = 6;
56     private static final int STATE_COLUMN_FOOTER_DONE = 7;
57     private static final int STATE_INITIAL_VARIABLES_DONE = 8;
58     private static final int STATE_REPORT_HEADER_DONE = 9;
59     private static final int STATE_REPORT_BODY_DONE = 10;
60     private static final int STATE_REPORT_FOOTER_VARIABLES = 11;
61     private static final int STATE_REPORT_FOOTER_DONE = 12;
62     private int state;
63     private VariablesCollection variablesCollection;
64 
OfficeReportLayoutController()65     public OfficeReportLayoutController()
66     {
67     }
68 
69     /**
70      * Initializes the layout controller. This method is called exactly once. It
71      * is the creators responsibility to call this method.
72      * <p/>
73      * Calling initialize after the first advance must result in a
74      * IllegalStateException.
75      *
76      * @param node           the currently processed object or layout node.
77      * @param flowController the current flow controller.
78      * @param parent         the parent layout controller that was responsible for
79      *                       instantiating this controller.
80      * @throws org.jfree.report.DataSourceException
81      *          if there was a problem reading data from the datasource.
82      * @throws org.jfree.report.ReportProcessingException
83      *          if there was a general problem during the report processing.
84      * @throws org.jfree.report.ReportDataFactoryException
85      *          if a query failed.
86      */
initialize(final Object node, final FlowController flowController, final LayoutController parent)87     public void initialize(final Object node, final FlowController flowController,
88             final LayoutController parent)
89             throws DataSourceException, ReportDataFactoryException,
90             ReportProcessingException
91     {
92         super.initialize(node, flowController, parent);
93         variablesCollection = new VariablesCollection("auto_report_");
94     }
95 
96     /**
97      * Processes any content in this element. This method is called when the
98      * processing state is 'OPENED'. The returned layout controller will retain
99      * the 'OPENED' state as long as there is more content available. Once all
100      * content has been processed, the returned layout controller should carry a
101      * 'FINISHED' state.
102      *
103      * @param target the report target that receives generated events.
104      * @return the new layout controller instance representing the new state.
105      *
106      * @throws org.jfree.report.DataSourceException
107      *          if there was a problem reading data from the datasource.
108      * @throws org.jfree.report.ReportProcessingException
109      *          if there was a general problem during the report processing.
110      * @throws org.jfree.report.ReportDataFactoryException
111      *          if a query failed.
112      */
processContent(final ReportTarget target)113     protected LayoutController processContent(final ReportTarget target)
114             throws DataSourceException, ReportProcessingException,
115             ReportDataFactoryException
116     {
117         final OfficeReport or = (OfficeReport) getElement();
118 
119         switch (state)
120         {
121             case OfficeReportLayoutController.STATE_NOT_STARTED:
122             {
123                 return delegateToTemplates(OfficeReportLayoutController.STATE_TEMPLATES);
124             }
125             case OfficeReportLayoutController.STATE_TEMPLATES:
126             {
127                 return delegateSection(or.getPageHeader(),
128                         OfficeReportLayoutController.STATE_PAGE_HEADER_DONE);
129             }
130             case OfficeReportLayoutController.STATE_PAGE_HEADER_DONE:
131             {
132                 return delegateSpreadsheetSection(or.getPageHeader(),
133                         OfficeReportLayoutController.STATE_SPREADSHEET_PAGE_HEADER_DONE);
134             }
135             case OfficeReportLayoutController.STATE_SPREADSHEET_PAGE_HEADER_DONE:
136             {
137                 return delegateSection(or.getPageFooter(),
138                         OfficeReportLayoutController.STATE_PAGE_FOOTER_DONE);
139             }
140             case OfficeReportLayoutController.STATE_PAGE_FOOTER_DONE:
141             {
142                 return delegateSection(or.getColumnHeader(),
143                         OfficeReportLayoutController.STATE_COLUMN_HEADER_DONE);
144             }
145             case OfficeReportLayoutController.STATE_COLUMN_HEADER_DONE:
146             {
147                 return delegateSection(or.getColumnFooter(),
148                         OfficeReportLayoutController.STATE_COLUMN_FOOTER_DONE);
149             }
150             case OfficeReportLayoutController.STATE_COLUMN_FOOTER_DONE:
151             {
152                 return delegateSection(new VariablesDeclarationSection(),
153                         OfficeReportLayoutController.STATE_INITIAL_VARIABLES_DONE);
154             }
155             case OfficeReportLayoutController.STATE_INITIAL_VARIABLES_DONE:
156             {
157                 return delegateSection(or.getReportHeader(),
158                         OfficeReportLayoutController.STATE_REPORT_HEADER_DONE);
159             }
160             case OfficeReportLayoutController.STATE_REPORT_HEADER_DONE:
161             {
162                 return delegateSection(or.getBodySection(),
163                         OfficeReportLayoutController.STATE_REPORT_BODY_DONE);
164             }
165             case OfficeReportLayoutController.STATE_REPORT_BODY_DONE:
166             {
167                 return delegateSection(new VariablesDeclarationSection(),
168                         OfficeReportLayoutController.STATE_REPORT_FOOTER_VARIABLES);
169             }
170             case OfficeReportLayoutController.STATE_REPORT_FOOTER_VARIABLES:
171             {
172                 return delegateSection(or.getReportFooter(),
173                         OfficeReportLayoutController.STATE_REPORT_FOOTER_DONE);
174             }
175             case OfficeReportLayoutController.STATE_REPORT_FOOTER_DONE:
176             {
177                 return delegateSpreadsheetSection(or.getPageFooter(),
178                         OfficeReportLayoutController.STATE_SPREADSHEET_PAGE_FOOTER_DONE);
179             }
180             case OfficeReportLayoutController.STATE_SPREADSHEET_PAGE_FOOTER_DONE:
181             {
182                 final OfficeReportLayoutController olc = (OfficeReportLayoutController) clone();
183                 olc.setProcessingState(ElementLayoutController.FINISHING);
184                 return olc;
185             }
186             default:
187             {
188                 throw new IllegalStateException("Invalid processing state encountered.");
189             }
190         }
191     }
192 
delegateSpreadsheetSection(final Node node, final int nextState)193     private LayoutController delegateSpreadsheetSection(final Node node, final int nextState)
194             throws DataSourceException, ReportProcessingException, ReportDataFactoryException
195     {
196         final OfficeReportLayoutController olc = (OfficeReportLayoutController) clone();
197         olc.state = nextState;
198 
199         if (node == null)
200         {
201             return olc;
202         }
203 
204         final OfficePageSectionLayoutController templateLc = new OfficePageSectionLayoutController();
205         templateLc.initialize(node, getFlowController(), olc);
206         return templateLc;
207     }
208 
delegateToTemplates(final int nextState)209     private LayoutController delegateToTemplates(final int nextState)
210             throws ReportProcessingException, ReportDataFactoryException,
211             DataSourceException
212     {
213         final OfficeReportLayoutController olc = (OfficeReportLayoutController) clone();
214         olc.state = nextState;
215 
216         final OfficeTableTemplateLayoutController templateLc = new OfficeTableTemplateLayoutController();
217         templateLc.initialize(getElement(), getFlowController(), olc);
218         return templateLc;
219 
220     }
221 
delegateSection(final Node n, final int nextState)222     private LayoutController delegateSection(final Node n, final int nextState)
223             throws ReportProcessingException, ReportDataFactoryException,
224             DataSourceException
225     {
226         final OfficeReportLayoutController olc = (OfficeReportLayoutController) clone();
227         olc.state = nextState;
228         if (n == null)
229         {
230             return olc;
231         }
232 
233         final FlowController flowController = getFlowController();
234         final ReportContext reportContext = flowController.getReportContext();
235         final LayoutControllerFactory layoutControllerFactory =
236                 reportContext.getLayoutControllerFactory();
237         return layoutControllerFactory.create(flowController, n, olc);
238 
239     }
240 
241     /**
242      * Joins with a delegated process flow. This is generally called from a child
243      * flow and should *not* (I mean it!) be called from outside. If you do,
244      * you'll suffer.
245      *
246      * @param flowController the flow controller of the parent.
247      * @return the joined layout controller that incorperates all changes from the
248      *         delegate.
249      */
join(final FlowController flowController)250     public LayoutController join(final FlowController flowController)
251     {
252         final OfficeReportLayoutController derived = (OfficeReportLayoutController) clone();
253         derived.setFlowController(flowController);
254         return derived;
255     }
256 
isNormalFlowProcessing()257     public boolean isNormalFlowProcessing()
258     {
259         return state != OfficeReportLayoutController.STATE_PAGE_HEADER_DONE && state != OfficeReportLayoutController.STATE_PAGE_FOOTER_DONE;
260     }
261 
getVariablesCollection()262     public VariablesCollection getVariablesCollection()
263     {
264         return variablesCollection;
265     }
266 }
267