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