View Javadoc

1   /*
2    * JaspertReports JSF Plugin Copyright (C) 2011 A. Alonso Dominguez
3    *
4    * This library is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as published by
6    * the Free Software Foundation; either version 2.1 of the License, or (at
7    * your option) any later version. This library is distributed in the hope
8    * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9    * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   *
11   * See the GNU Lesser General Public License for more details. You should have
12   * received a copy of the GNU Lesser General Public License along with this
13   * library; if not, write to the Free Software Foundation, Inc., 59 Temple
14   * Place, Suite 330, Boston, MA 02111-1307 USA A.
15   *
16   * Alonso Dominguez
17   * alonsoft@users.sf.net
18   */
19  package net.sf.jasperreports.jsf.engine.fill;
20  
21  import java.sql.Connection;
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.logging.Level;
25  import java.util.logging.Logger;
26  
27  import javax.faces.component.UIComponent;
28  import javax.faces.component.UIParameter;
29  import javax.faces.context.FacesContext;
30  
31  import net.sf.jasperreports.engine.JRDataSource;
32  import net.sf.jasperreports.engine.JRException;
33  import net.sf.jasperreports.engine.JasperPrint;
34  import net.sf.jasperreports.engine.JasperReport;
35  import net.sf.jasperreports.engine.fill.JRBaseFiller;
36  import net.sf.jasperreports.engine.fill.JRFiller;
37  import net.sf.jasperreports.jsf.Constants;
38  import net.sf.jasperreports.jsf.component.UIReport;
39  import net.sf.jasperreports.jsf.component.UISource;
40  import net.sf.jasperreports.jsf.component.UISubreport;
41  import net.sf.jasperreports.jsf.convert.SourceConverter;
42  import net.sf.jasperreports.jsf.engine.Source;
43  import net.sf.jasperreports.jsf.engine.FillerException;
44  import net.sf.jasperreports.jsf.engine.Filler;
45  import net.sf.jasperreports.jsf.util.Util;
46  
47  import static net.sf.jasperreports.jsf.util.ComponentUtil.*;
48  
49  /**
50   * Default Filler implementation.
51   *
52   * @author A. Alonso Dominguez
53   */
54  public class DefaultFiller implements Filler {
55  
56      public static final String SUBREPORT_PARAMETER_SEPARATOR = ".";
57  
58      // Report Parameters
59  
60      /** The Constant PARAM_REPORT_CLASSLOADER. */
61      public static final String PARAM_REPORT_CLASSLOADER = "REPORT_CLASS_LOADER";
62      /** The Constant PARAM_REPORT_LOCALE. */
63      public static final String PARAM_REPORT_LOCALE = "REPORT_LOCALE";
64  
65      public static final String PARAM_APPLICATION_SCOPE = "APPLICATION_SCOPE";
66      public static final String PARAM_SESSION_SCOPE = "SESSION_SCOPE";
67      public static final String PARAM_REQUEST_SCOPE = "REQUEST_SCOPE";
68  
69      /** The logger. */
70      private static final Logger logger = Logger.getLogger(
71              DefaultFiller.class.getPackage().getName(),
72              Constants.LOG_MESSAGES_BUNDLE);
73  
74      /**
75       * Fill the report object with data comming from the
76       * submitted source object (if specified).
77       *
78       * @param context current faces' context.
79       * @param component report component.
80       * @throws FillerException if filler throws any exception.
81       */
82      public final void fill(final FacesContext context, final UIReport component)
83              throws FillerException {
84          final String reportName = getStringAttribute(component, "name",
85                  component.getClientId(context));
86          logger.log(Level.FINE, "JRJSF_0003", reportName);
87  
88          final Map<String, Object> params =
89              buildParamMap(context, component);
90          JasperPrint print = doFill(context, component, params);
91      	component.setSubmittedPrint(print);
92      }
93  
94      /**
95       * Builds the param map.
96       *
97       * @param context the context
98       * @param component the component
99       *
100      * @return the map<string, object>
101      */
102     protected Map<String, Object> buildParamMap(final FacesContext context,
103             final UIReport component)
104     throws FillerException {
105         final Map<String, Object> parameters = new HashMap<String, Object>();
106 
107         // Build param map using component's child parameters and subreports
108         processParameterMap(context, component, parameters, null);
109 
110         // Include implicit parameters
111         processImplicitParameters(context, component, parameters);
112 
113         return parameters;
114     }
115 
116     /**
117      * Performs the internal fill operation.
118      *
119      * @param context current faces' context.
120      * @param component report component
121      * @param parameters report parameters.
122      * @return the generated <tt>JasperPrint</tt> result.
123      * @throws FillerException if some error happens.
124      */
125     protected JasperPrint doFill(FacesContext context, UIReport component,
126             Map<String, Object> parameters)
127     throws FillerException {
128         JasperReport report = component.getSubmittedReport();
129 
130         JRBaseFiller jrFiller;
131         try {
132             jrFiller = JRFiller.createFiller(report);
133         } catch (JRException e) {
134             throw new FillerException(e);
135         }
136         
137         Source reportSource = findReportSource(component);
138         SourceConverter converter = component.getSourceConverter();
139         JasperPrint print = null;
140         try {
141             if (reportSource == null) {
142                 print = jrFiller.fill(parameters);
143             } else {
144                 Object sourceObj = converter.convertFromSource(context,
145                         component, reportSource);
146                 if (reportSource instanceof JRDataSource) {
147                     print = jrFiller.fill(parameters, (JRDataSource) sourceObj);
148                 } else if (reportSource instanceof Connection) {
149                     print = jrFiller.fill(parameters, (Connection) sourceObj);
150                 }
151             }
152         } catch (final JRException e) {
153             throw new FillerException(e);
154         } finally {
155         	if (reportSource != null) {
156                 try {
157                     reportSource.dispose();
158                     reportSource = null;
159                 } catch (Exception e) { ; }  
160             }
161         }
162         return print;
163     }
164 
165     private Source findReportSource(UIReport report) {
166         Source result = report.getSubmittedSource();
167         if (result == null) {
168             UISource source = null;
169             for (UIComponent component : report.getChildren()) {
170                 if (component instanceof UISource) {
171                     source = (UISource) component;
172                     break;
173                 }
174             }
175 
176             if (source != null) {
177                 result = source.getSubmittedSource();
178             }
179         }
180         return result;
181     }
182 
183     private void processImplicitParameters(FacesContext context,
184             UIReport component, Map<String, Object> parameters) {
185         // Specific component parameters
186         parameters.put(PARAM_REPORT_CLASSLOADER,
187                 Util.getClassLoader(component));
188         parameters.put(PARAM_REPORT_LOCALE,
189                 context.getViewRoot().getLocale());
190 
191         parameters.put(PARAM_APPLICATION_SCOPE,
192                 context.getExternalContext().getApplicationMap());
193         parameters.put(PARAM_SESSION_SCOPE,
194                 context.getExternalContext().getSessionMap());
195         parameters.put(PARAM_REQUEST_SCOPE,
196                 context.getExternalContext().getRequestMap());
197     }
198 
199     /**
200      * Builds parameter map recursively through the report/subreport tree.
201      *
202      * @param context cuurent faces' context.
203      * @param component report component.
204      * @param parameters report parameters.
205      * @param prefix parent's report name, used as a parameter prefix.
206      */
207     private void processParameterMap(FacesContext context, UIReport component,
208             Map<String, Object> parameters, String prefix) {
209         for (final UIComponent kid : component.getChildren()) {
210             if (kid instanceof UISubreport) {
211                 final UISubreport subreport = (UISubreport) kid;
212                 parameters.put(subreport.getName(),
213                         subreport.getSubmittedReport());
214                 processParameterMap(context, subreport, parameters,
215                         (prefix != null && prefix.length() > 0 ?
216                             prefix + SUBREPORT_PARAMETER_SEPARATOR : "")
217                         + subreport.getName());
218             } else if (kid instanceof UIParameter) {
219                 final UIParameter param = (UIParameter) kid;
220                 String paramName;
221                 if (prefix != null && prefix.length() > 0) {
222                     paramName = prefix + SUBREPORT_PARAMETER_SEPARATOR +
223                             param.getName();
224                 } else {
225                     paramName = param.getName();
226                 }
227 
228                 parameters.put(paramName, param.getValue());
229             }
230         }
231     }
232 
233 }