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.OfficeToken; 26 import com.sun.star.report.pentaho.OfficeNamespaces; 27 import com.sun.star.report.pentaho.model.FormattedTextElement; 28 import com.sun.star.report.pentaho.model.OfficeDocument; 29 import com.sun.star.report.pentaho.model.OfficeStyle; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 34 import org.jfree.layouting.util.AttributeMap; 35 import org.jfree.report.DataFlags; 36 import org.jfree.report.DataSourceException; 37 import org.jfree.report.JFreeReportInfo; 38 import org.jfree.report.ReportDataFactoryException; 39 import org.jfree.report.ReportProcessingException; 40 import org.jfree.report.expressions.FormulaExpression; 41 import org.jfree.report.flow.ReportTarget; 42 import org.jfree.report.flow.layoutprocessor.LayoutController; 43 import org.jfree.report.structure.Element; 44 45 import org.pentaho.reporting.libraries.formula.Formula; 46 import org.pentaho.reporting.libraries.formula.lvalues.LValue; 47 import org.pentaho.reporting.libraries.formula.parser.ParseException; 48 49 /** 50 * Todo: Document me! 51 * 52 * @author Thomas Morgner 53 * @since 05.03.2007 54 */ 55 public class FormattedTextLayoutController 56 extends AbstractReportElementLayoutController 57 { 58 59 private static final Log LOGGER = LogFactory.getLog(FormattedTextLayoutController.class); 60 FormattedTextLayoutController()61 public FormattedTextLayoutController() 62 { 63 } 64 getVariablesCollection()65 private VariablesCollection getVariablesCollection() 66 { 67 LayoutController parent = getParent(); 68 while (parent != null) 69 { 70 if (parent instanceof OfficeRepeatingStructureLayoutController) 71 { 72 final OfficeRepeatingStructureLayoutController orslc = 73 (OfficeRepeatingStructureLayoutController) parent; 74 if (orslc.isNormalFlowProcessing()) 75 { 76 return null; 77 } 78 79 return orslc.getVariablesCollection(); 80 } 81 parent = parent.getParent(); 82 } 83 return null; 84 } 85 isValueChanged()86 protected boolean isValueChanged() 87 { 88 try 89 { 90 final FormattedTextElement element = (FormattedTextElement) getNode(); 91 final FormulaExpression formulaExpression = element.getValueExpression(); 92 final Formula formula = formulaExpression.getCompiledFormula(); 93 final LValue lValue = formula.getRootReference(); 94 return isReferenceChanged(lValue); 95 } 96 catch (final ParseException e) 97 { 98 LOGGER.debug("Parse Exception", e); 99 return false; 100 } 101 } 102 delegateContentGeneration(final ReportTarget target)103 protected LayoutController delegateContentGeneration(final ReportTarget target) 104 throws ReportProcessingException, ReportDataFactoryException, 105 DataSourceException 106 { 107 final FormattedTextElement element = (FormattedTextElement) getNode(); 108 final VariablesCollection vc = getVariablesCollection(); 109 if (vc != null) 110 { 111 final String name = vc.addVariable(element); 112 final AttributeMap variablesGet = new AttributeMap(); 113 variablesGet.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, 114 Element.TYPE_ATTRIBUTE, "variable-get"); 115 variablesGet.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, 116 Element.NAMESPACE_ATTRIBUTE, OfficeNamespaces.TEXT_NS); 117 variablesGet.setAttribute(OfficeNamespaces.TEXT_NS, "name", name); 118 //variablesGet.setAttribute(OfficeNamespaces.TEXT_NS, "display", "value"); 119 120 final String dataStyleName = computeValueStyle(); 121 if (dataStyleName != null) 122 { 123 variablesGet.setAttribute(OfficeNamespaces.STYLE_NS, "data-style-name", dataStyleName); 124 } 125 126 final String valueType = computeValueType(); 127 variablesGet.setAttribute(OfficeNamespaces.OFFICE_NS, FormatValueUtility.VALUE_TYPE, valueType); 128 target.startElement(variablesGet); 129 130 target.endElement(variablesGet); 131 } 132 else 133 { 134 final DataFlags df = FormatValueUtility.computeDataFlag(element, getFlowController()); 135 if (df != null) 136 { 137 if (df.getValue() instanceof String) 138 { 139 target.processContent(df); 140 } 141 else //@see http://qa.openoffice.org/issues/show_bug.cgi?id=108954 142 { 143 Element cell = getParentTableCell(); 144 if (cell != null && "string".equals(cell.getAttribute(OfficeNamespaces.OFFICE_NS, FormatValueUtility.VALUE_TYPE))) 145 { 146 target.processContent(df); 147 } 148 } 149 } 150 } 151 152 return join(getFlowController()); 153 } 154 getDocument()155 private OfficeDocument getDocument() 156 { 157 LayoutController parent = getParent(); 158 while (parent != null) 159 { 160 final Object node = parent.getNode(); 161 if (node instanceof OfficeDocument) 162 { 163 return (OfficeDocument) node; 164 } 165 parent = parent.getParent(); 166 } 167 return null; 168 } 169 getParentTableCell()170 private Element getParentTableCell() 171 { 172 LayoutController parent = getParent(); 173 while (parent != null) 174 { 175 if (parent instanceof TableCellLayoutController) 176 { 177 final TableCellLayoutController cellController = (TableCellLayoutController) parent; 178 return cellController.getElement(); 179 } 180 parent = parent.getParent(); 181 } 182 return null; 183 } 184 computeValueStyle()185 private String computeValueStyle() 186 { 187 final Element tce = getParentTableCell(); 188 if (tce == null) 189 { 190 return null; 191 } 192 193 final String cellStyleName = (String) tce.getAttribute(OfficeNamespaces.TABLE_NS, OfficeToken.STYLE_NAME); 194 if (cellStyleName == null) 195 { 196 return null; 197 } 198 final OfficeDocument document = getDocument(); 199 if (document == null) 200 { 201 return null; 202 } 203 204 final OfficeStyle style = document.getStylesCollection().getStyle("table-cell", cellStyleName); 205 return (String) style.getAttribute(OfficeNamespaces.STYLE_NS, "data-style-name"); 206 } 207 computeValueType()208 private String computeValueType() 209 { 210 final Element tce = getParentTableCell(); 211 if (tce == null) 212 { 213 // NO particular format means: Fallback to string and hope and pray .. 214 throw new IllegalStateException("A formatted text element must be a child of a Table-Cell."); 215 } 216 217 final String type = (String) tce.getAttribute(OfficeNamespaces.OFFICE_NS, FormatValueUtility.VALUE_TYPE); 218 if (type == null) 219 { 220 LOGGER.error("The Table-Cell does not have a office:value attribute defined. Your content will be messed up."); 221 return "string"; 222 } 223 return type; 224 } 225 } 226