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