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.OfficeNamespaces; 26 import com.sun.star.report.pentaho.model.FormattedTextElement; 27 28 import java.text.SimpleDateFormat; 29 30 import java.util.Date; 31 32 import org.jfree.layouting.util.AttributeMap; 33 import org.jfree.report.DataSourceException; 34 import org.jfree.report.JFreeReportInfo; 35 import org.jfree.report.ReportDataFactoryException; 36 import org.jfree.report.ReportProcessingException; 37 import org.jfree.report.expressions.FormulaExpression; 38 import org.jfree.report.flow.FlowController; 39 import org.jfree.report.flow.ReportTarget; 40 import org.jfree.report.flow.layoutprocessor.AbstractLayoutController; 41 import org.jfree.report.flow.layoutprocessor.LayoutController; 42 import org.jfree.report.flow.layoutprocessor.LayoutControllerUtil; 43 import org.jfree.report.structure.Element; 44 45 /** 46 * Writes a full variables-declaration section. 47 * 48 * @author Thomas Morgner 49 * @since 20.03.2007 50 */ 51 public class VariablesDeclarationLayoutController 52 extends AbstractLayoutController 53 { 54 55 private boolean processed; 56 VariablesDeclarationLayoutController()57 public VariablesDeclarationLayoutController() 58 { 59 } 60 getRepeatingParent()61 private OfficeRepeatingStructureLayoutController getRepeatingParent() 62 { 63 LayoutController parent = getParent(); 64 while (parent != null) 65 { 66 if (parent instanceof OfficeRepeatingStructureLayoutController) 67 { 68 return (OfficeRepeatingStructureLayoutController) parent; 69 } 70 parent = parent.getParent(); 71 } 72 return null; 73 } 74 75 /** 76 * Advances the processing position. 77 * 78 * @param target the report target that receives generated events. 79 * @return the new layout controller instance representing the new state. 80 * 81 * @throws org.jfree.report.DataSourceException 82 * if there was a problem reading data from the datasource. 83 * @throws org.jfree.report.ReportProcessingException 84 * if there was a general problem during the report processing. 85 * @throws org.jfree.report.ReportDataFactoryException 86 * if a query failed. 87 */ advance(final ReportTarget target)88 public LayoutController advance(final ReportTarget target) 89 throws DataSourceException, ReportDataFactoryException, 90 ReportProcessingException 91 { 92 if (processed) 93 { 94 throw new IllegalStateException("Already processed."); 95 } 96 97 final VariablesDeclarationLayoutController vlc = 98 (VariablesDeclarationLayoutController) clone(); 99 vlc.processed = true; 100 101 final OfficeRepeatingStructureLayoutController orslc = getRepeatingParent(); 102 if (orslc == null) 103 { 104 // There is no repeating parent. What the heck are we doing here .. 105 return vlc; 106 } 107 108 final VariablesCollection collection = orslc.getVariablesCollection(); 109 if (collection.getVariablesCount() == 0) 110 { 111 // no processing necessary, as the header or footer contain no variables at all .. 112 return vlc; 113 } 114 115 116 final Element node = (Element) getNode(); 117 final AttributeMap vdSection = node.getAttributeMap(); 118 target.startElement(vdSection); 119 120 final FormattedTextElement[] variables = collection.getVariables(); 121 for (int i = 0; i < variables.length; i++) 122 { 123 final FormattedTextElement variable = variables[i]; 124 final String varName = collection.getNamePrefix() + (i + 1); 125 final AttributeMap map = generateVariableSetSection(variable); 126 map.setAttribute(OfficeNamespaces.TEXT_NS, "name", varName); 127 target.startElement(map); 128 target.endElement(map); 129 130 } 131 target.endElement(vdSection); 132 return vlc; 133 } 134 generateVariableSetSection(final FormattedTextElement variable)135 private AttributeMap generateVariableSetSection(final FormattedTextElement variable) 136 throws DataSourceException 137 { 138 final AttributeMap variableSection = new AttributeMap(); 139 variableSection.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, Element.NAMESPACE_ATTRIBUTE, OfficeNamespaces.TEXT_NS); 140 variableSection.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, Element.TYPE_ATTRIBUTE, "variable-set"); 141 variableSection.setAttribute(OfficeNamespaces.TEXT_NS, "display", "none"); 142 143 final FormulaExpression valueExpression = variable.getValueExpression(); 144 final Object value = LayoutControllerUtil.evaluateExpression(getFlowController(), variable, valueExpression); 145 String formula = FormatValueUtility.applyValueForVariable(value, variableSection); 146 if (formula == null) 147 { 148 formula = "" + value; 149 } 150 if (value instanceof java.sql.Date) 151 { 152 final Date date = (Date) value; 153 final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy;MM;dd"); 154 formula = "Date(" + dateFormat.format(date) + ")"; 155 } 156 variableSection.setAttribute(OfficeNamespaces.TEXT_NS, "formula", "ooow:" + formula); 157 158 return variableSection; 159 } 160 161 /** 162 * Checks, whether the layout controller would be advanceable. If this method 163 * returns true, it is generally safe to call the 'advance()' method. 164 * 165 * @return true, if the layout controller is advanceable, false otherwise. 166 */ isAdvanceable()167 public boolean isAdvanceable() 168 { 169 return !processed; 170 } 171 172 /** 173 * Joins with a delegated process flow. This is generally called from a child 174 * flow and should *not* (I mean it!) be called from outside. If you do, 175 * you'll suffer. 176 * 177 * @param flowController the flow controller of the parent. 178 * @return the joined layout controller that incorperates all changes from the 179 * delegate. 180 */ join(final FlowController flowController)181 public LayoutController join(final FlowController flowController) 182 throws DataSourceException, ReportDataFactoryException, 183 ReportProcessingException 184 { 185 throw new UnsupportedOperationException("Join is not supported in this layout controller"); 186 } 187 } 188