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