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.FormatCondition;
28 import com.sun.star.report.pentaho.model.FormattedTextElement;
29 import com.sun.star.report.pentaho.model.ReportElement;
30 
31 import org.jfree.layouting.util.AttributeMap;
32 import org.jfree.report.DataFlags;
33 import org.jfree.report.DataSourceException;
34 import org.jfree.report.expressions.Expression;
35 import org.jfree.report.flow.FlowController;
36 import org.jfree.report.flow.ReportTarget;
37 import org.jfree.report.flow.layoutprocessor.LayoutControllerUtil;
38 import org.jfree.report.flow.layoutprocessor.SectionLayoutController;
39 import org.jfree.report.structure.Element;
40 import org.jfree.report.structure.Node;
41 import org.jfree.report.structure.Section;
42 
43 import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
44 
45 /**
46  * Before writing the table cell, we have to evaluate the childs of the cell. The cell itself can either be empty or it
47  * has a one ore more paragraphs inside. The paragraph contains a single report element, but may contain additional
48  * other content.
49  *
50  * @author Thomas Morgner
51  * @noinspection CloneableClassWithoutClone
52  * @since 05.03.2007
53  */
54 public class TableCellLayoutController extends SectionLayoutController
55 {
56 
TableCellLayoutController()57     public TableCellLayoutController()
58     {
59     }
60 
computeAttributes(final FlowController fc, final Element element, final ReportTarget target)61     protected AttributeMap computeAttributes(final FlowController fc,
62             final Element element,
63             final ReportTarget target)
64             throws DataSourceException
65     {
66         final AttributeMap attributeMap = new AttributeMap(super.computeAttributes(fc, element, target));
67         final String definedStyle = (String) attributeMap.getAttribute(OfficeNamespaces.TABLE_NS, OfficeToken.STYLE_NAME);
68         attributeMap.setAttribute(OfficeNamespaces.TABLE_NS, OfficeToken.STYLE_NAME, getDisplayStyleName((Section) element, definedStyle));
69 
70         try
71         {
72             final DataFlags value = computeValue(attributeMap);
73             final String valueType = (String) attributeMap.getAttribute(OfficeNamespaces.OFFICE_NS, FormatValueUtility.VALUE_TYPE);
74             if (value != null)
75             {
76                 FormatValueUtility.applyValueForCell(value.getValue(), attributeMap, valueType);
77             }
78             else if ( "float".equals(valueType))
79             {
80                 attributeMap.setAttribute(OfficeNamespaces.OFFICE_NS,
81                     FormatValueUtility.VALUE, "NaN");
82             }
83             // #i114108#: except on form elements, the only value-type that can
84             // occur without an accomanying value attribute is "string"
85             else if (!"string".equals(valueType))
86             {
87                 attributeMap.setAttribute(OfficeNamespaces.OFFICE_NS,
88                     FormatValueUtility.VALUE_TYPE, "string");
89             }
90         }
91         catch (Exception e)
92         {
93             // ignore ..
94         }
95         attributeMap.makeReadOnly();
96         return attributeMap;
97     }
98 
computeValue(final AttributeMap attributeMap)99     private DataFlags computeValue(final AttributeMap attributeMap) throws DataSourceException
100     {
101         // Search for the first FormattedTextElement
102         final Section cell = (Section) getElement();
103         final FormattedTextElement element = findFormattedTextElement(cell);
104         if (element == null)
105         {
106             return null;
107         }
108         final Expression dc = element.getDisplayCondition();
109         if (dc != null)
110         {
111             final Object o = LayoutControllerUtil.evaluateExpression(getFlowController(), element, dc);
112             if (Boolean.FALSE.equals(o))
113             {
114                 attributeMap.setAttribute(OfficeNamespaces.OFFICE_NS,
115                     FormatValueUtility.VALUE_TYPE, "string");
116                 return null;
117             }
118         }
119         return FormatValueUtility.computeDataFlag(element, getFlowController());
120     }
121 
findFormattedTextElement(final Section section)122     private FormattedTextElement findFormattedTextElement(final Section section)
123     {
124         final Node[] nodeArray = section.getNodeArray();
125         for (int i = 0; i < nodeArray.length; i++)
126         {
127             final Node node = nodeArray[i];
128             if (node instanceof FormattedTextElement)
129             {
130                 return (FormattedTextElement) node;
131             }
132             else if (node instanceof Section)
133             {
134                 final FormattedTextElement retval = findFormattedTextElement((Section) node);
135                 if (retval != null)
136                 {
137                     return retval;
138                 }
139             }
140         }
141         return null;
142     }
143 
getDisplayStyleName(final Section section, final String defaultStyle)144     private String getDisplayStyleName(final Section section,
145             final String defaultStyle)
146     {
147         if (!section.isEnabled() || section.getNodeCount() == 0)
148         {
149             return defaultStyle;
150         }
151 
152         final Node[] nodes = section.getNodeArray();
153         for (int i = 0; i < nodes.length; i++)
154         {
155             final Node child = nodes[i];
156             if (child instanceof ReportElement && child.isEnabled())
157             {
158                 final ReportElement element = (ReportElement) child;
159                 if (element.getFormatConditionCount() > 0)
160                 {
161                     final Expression displayCond = element.getDisplayCondition();
162                     if (displayCond != null)
163                     {
164                         try
165                         {
166                             if (Boolean.FALSE.equals(LayoutControllerUtil.evaluateExpression(getFlowController(), element, displayCond)))
167                             {
168                                 continue;
169                             }
170                         }
171                         catch (DataSourceException e)
172                         {
173                             // ignore silently ..
174                         }
175                     }
176 
177                     final FormatCondition[] conditions = element.getFormatConditions();
178                     for (int j = 0; j < conditions.length; j++)
179                     {
180                         final FormatCondition formCond = conditions[j];
181                         if (formCond.isEnabled())
182                         {
183                             try
184                             {
185                                 final Object o = LayoutControllerUtil.evaluateExpression(getFlowController(), element, formCond.getFormula());
186                                 if (Boolean.TRUE.equals(o))
187                                 {
188                                     return formCond.getStyleName();
189                                 }
190                             }
191                             catch (DataSourceException e)
192                             {
193                                 // ignore silently ..
194                             }
195                         }
196                     }
197                 }
198             }
199 
200             if (child instanceof Section)
201             {
202                 final String childFormatCondition =
203                         getDisplayStyleName((Section) child, defaultStyle);
204                 if (!ObjectUtilities.equal(childFormatCondition, defaultStyle))
205                 {
206                     return childFormatCondition;
207                 }
208             }
209         }
210         return defaultStyle;
211     }
212 }
213