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.component;
20  
21  import javax.el.ELException;
22  import javax.el.ValueExpression;
23  import javax.faces.FacesException;
24  import javax.faces.component.UIComponentBase;
25  import javax.faces.context.FacesContext;
26  import javax.faces.validator.Validator;
27  import javax.faces.validator.ValidatorException;
28  
29  import net.sf.jasperreports.engine.JasperPrint;
30  import net.sf.jasperreports.engine.JasperReport;
31  import net.sf.jasperreports.jsf.Constants;
32  import net.sf.jasperreports.jsf.context.JRFacesContext;
33  import net.sf.jasperreports.jsf.convert.ReportConverter;
34  import net.sf.jasperreports.jsf.convert.SourceConverter;
35  import net.sf.jasperreports.jsf.engine.Source;
36  import net.sf.jasperreports.jsf.validation.ReportValidatorBase;
37  
38  /**
39   * Base class for report components.
40   *
41   * @author A. Alonso Dominguez
42   */
43  public abstract class UIReport extends UIComponentBase {
44  
45      /** Name used to identify the reports component family. */
46      public static final String COMPONENT_FAMILY =
47              Constants.PACKAGE_PREFIX + ".Report";
48  
49      /** The source object from where obtain the report's data. */
50      private Object source;
51  
52      /** The report's name. */
53      private String name;
54  
55      /**
56       * Valid flag to determine if the component has been
57       * correclty configured.
58       */
59      private boolean valid = true;
60  
61      /** Report value, which is the report itself. */
62      private Object value;
63      /**
64       * Boolean flag used to know if report value has been
65       * programatically set.
66       */
67      private boolean valueSet = false;
68  
69      /**
70       * Converter instance used to interpret the value of the
71       * <tt>source</tt> attribute.
72       */
73      private SourceConverter sourceConverter;
74  
75      private ReportConverter reportConverter;
76  
77      /** Validator instance. */
78      private Validator validator;
79  
80      /** Interpretted source instance. */
81      private Source submittedSource;
82  
83      /** Intepretted report instance. */
84      private JasperReport submittedReport;
85  
86      private JasperPrint submittedPrint;
87  
88      /**
89       * Instantiates a new UIReport.
90       */
91      public UIReport() {
92          super();
93      }
94  
95      /**
96       * Obtains the family name.
97       *
98       * @return the family name.
99       */
100     @Override
101 	public final String getFamily() {
102         return COMPONENT_FAMILY;
103     }
104     
105     /**
106      * Obtains the established report source.
107      *
108      * @return the report source.
109      */
110     public final Object getSource() {
111         if (source != null) {
112             return source;
113         }
114         final ValueExpression ve = getValueExpression("source");
115         if (ve != null) {
116             try {
117                 return ve.getValue(
118                         getFacesContext().getELContext());
119             } catch (final ELException e) {
120                 throw new FacesException(e);
121             }
122         } else {
123             return source;
124         }
125     }
126 
127     /**
128      * Establishes a new report source.
129      *
130      * @param source the new report source.
131      */
132     public final void setSource(final Object source) {
133         this.source = source;
134     }
135 
136     /**
137      * Obtains the name of the report.
138      *
139      * @return the name of the report
140      */
141     public final String getName() {
142         if (name != null) {
143             return name;
144         }
145         final ValueExpression ve = getValueExpression("name");
146         if (ve != null) {
147             try {
148                 return (String) ve.getValue(
149                         getFacesContext().getELContext());
150             } catch (final ELException e) {
151                 throw new FacesException(e);
152             }
153         } else {
154             return name;
155         }
156     }
157 
158     /**
159      * Establishes a new name for the report.
160      *
161      * @param name the new report name.
162      */
163     public final void setName(final String name) {
164         this.name = name;
165     }
166 
167     /**
168      * Obtains the current report value.
169      *
170      * @return the report value
171      */
172     public final Object getValue() {
173         if (valueSet) {
174             return value;
175         }
176         ValueExpression ve = getValueExpression("value");
177         if (ve != null) {
178             try {
179                 return ve.getValue(
180                         getFacesContext().getELContext());
181             } catch (ELException e) {
182                 throw new FacesException(e);
183             }
184         } else {
185             return value;
186         }
187     }
188 
189     /**
190      * Establishes a new value for this project.
191      *
192      * @param value the new value.
193      */
194     public final void setValue(final Object value) {
195         this.value = value;
196         this.valueSet = true;
197     }
198 
199     /**
200      * Used to identify if current value has been programatically set.
201      *
202      * @return true if report's value has been set by means of the
203      *         <tt>setValue</tt> method, false otherwise.
204      */
205     public final boolean isLocalValueSet() {
206         return valueSet;
207     }
208 
209     /**
210      * Obtains the current sourceConverter instance.
211      *
212      * @return a source sourceConverter instance.
213      */
214     public final SourceConverter getSourceConverter() {
215         if (sourceConverter != null) {
216             return sourceConverter;
217         }
218         ValueExpression ve = getValueExpression("sourceConverter");
219         if (ve != null) {
220             try {
221                 return (SourceConverter) ve.getValue(
222                         getFacesContext().getELContext());
223             } catch (ELException e) {
224                 throw new FacesException(e);
225             }
226         } else {
227             return sourceConverter;
228         }
229     }
230 
231     /**
232      * Establishes a new source sourceConverter instance.
233      *
234      * @param sourceConverter a new sourceConverter instance.
235      */
236     public final void setSourceConverter(final SourceConverter converter) {
237         this.sourceConverter = converter;
238     }
239 
240     public final ReportConverter getReportConverter() {
241         if (reportConverter != null) {
242             return reportConverter;
243         }
244         ValueExpression ve = getValueExpression("reportConverter");
245         if (ve != null) {
246             try {
247                 return (ReportConverter) ve.getValue(
248                         getFacesContext().getELContext());
249             } catch (ELException e) {
250                 throw new FacesException(e);
251             }
252         } else {
253             return reportConverter;
254         }
255     }
256 
257     public void setReportConverter(final ReportConverter reportConverter) {
258         this.reportConverter = reportConverter;
259     }
260 
261     /**
262      * Obtain the report validator instance.
263      *
264      * @return the validator instance.
265      */
266     public final Validator getValidator() {
267         if (validator != null) {
268             return validator;
269         }
270         ValueExpression ve = getValueExpression("validator");
271         if (ve != null) {
272             try {
273                 return (Validator) ve.getValue(
274                         getFacesContext().getELContext());
275             } catch (ELException e) {
276                 throw new FacesException(e);
277             }
278         } else {
279             return validator;
280         }
281     }
282 
283     /**
284      * Establishes a new validator instance.
285      *
286      * @param validator the validator instance.
287      */
288     public final void setValidator(final Validator validator) {
289         this.validator = validator;
290     }
291 
292     /**
293      * Obtains the interpretted report source.
294      *
295      * @return the interpretted report source.
296      */
297     public final Source getSubmittedSource() {
298         return submittedSource;
299     }
300 
301     /**
302      * Establishes the value for the report source.
303      *
304      * @param submittedSource the report source.
305      */
306     public final void setSubmittedSource(final Source submittedSource) {
307         this.submittedSource = submittedSource;
308     }
309 
310     /**
311      * Obtains the interpretted report value.
312      *
313      * @return the interpretted report value.
314      */
315     public final JasperReport getSubmittedReport() {
316         return submittedReport;
317     }
318 
319     /**
320      * Establishes the interpretted report value.
321      *
322      * @param submittedReport the report value.
323      */
324     public final void setSubmittedReport(final JasperReport submittedReport) {
325         this.submittedReport = submittedReport;
326     }
327 
328     public JasperPrint getSubmittedPrint() {
329         return submittedPrint;
330     }
331 
332     public void setSubmittedPrint(JasperPrint submittedPrint) {
333         this.submittedPrint = submittedPrint;
334     }
335 
336     /**
337      * Obtains the valid flag.
338      *
339      * @return true is this report is well configured.
340      */
341     public final boolean isValid() {
342         return valid;
343     }
344 
345     /**
346      * Establishes the value for the valid flag.
347      *
348      * @param valid if this report is valid.
349      */
350     protected final void setValid(final boolean valid) {
351         this.valid = valid;
352     }
353 
354     /*
355      * (non-Javadoc)
356      *
357      * @seejavax.faces.component.StateHolder#restoreState(javax.faces.context.
358      * FacesContext, java.lang.Object)
359      */
360     @Override
361     public void restoreState(final FacesContext context, final Object state) {
362         final Object[] values = (Object[]) state;
363         super.restoreState(context, values[0]);
364         source = values[1];
365         name = (String) values[2];
366         value = values[3];
367         valueSet = ((Boolean) values[4]).booleanValue();
368         sourceConverter = (SourceConverter) values[5];
369         reportConverter = (ReportConverter) values[6];
370         valid = ((Boolean) values[7]).booleanValue();
371         validator = (Validator) values[8];
372     }
373 
374     /*
375      * (non-Javadoc)
376      *
377      * @see
378      * javax.faces.component.StateHolder#saveState(javax.faces.context.
379      * FacesContext
380      * )
381      */
382     @Override
383     public Object saveState(final FacesContext context) {
384         final Object[] values = new Object[9];
385         values[0] = super.saveState(context);
386         values[1] = source;
387         values[2] = name;
388         values[3] = value;
389         values[4] = valueSet;
390         values[5] = sourceConverter;
391         values[6] = reportConverter;
392         values[7] = valid;
393         values[8] = validator;
394         return values;
395     }
396 
397     /**
398      * Resets the report component state.
399      */
400     public void resetValue() {
401         this.value = null;
402         this.valueSet = false;
403         this.valid = true;
404         this.submittedSource = null;
405         this.submittedReport = null;
406         this.submittedPrint = null;
407     }
408 
409     /**
410      * Performs the decoding process in which the source value is interpretted.
411      *
412      * @param context current faces' context.
413      */
414     @Override
415     public void processDecodes(final FacesContext context) {
416         if (context == null) {
417             throw new IllegalArgumentException();
418         }
419 
420         if (!isRendered()) {
421             return;
422         }
423 
424         resetValue();
425         super.processDecodes(context);
426 
427         executeDecodes(context);
428     }
429 
430     /**
431      * Method invoked during the <tt>PROCESS_VALIDATORS</tt> phase.
432      *
433      * @param context current faces' instance.
434      */
435     @Override
436     public void processValidators(final FacesContext context) {
437         if (context == null) {
438             throw new NullPointerException();
439         }
440 
441         if (!isRendered()) {
442             return;
443         }
444 
445         super.processValidators(context);
446         executeValidate(context);
447     }
448 
449     /**
450      * Decodes the <tt>source</tt> value into a <tt>Source</tt> instace.
451      *
452      * @param context current faces' context.
453      */
454     protected final void decodeSource(final FacesContext context) {
455         if (context == null) {
456             throw new IllegalArgumentException();
457         }
458 
459         SourceConverter aConverter = getSourceConverter();
460         if (aConverter == null) {
461             aConverter = getJRFacesContext()
462                     .createSourceConverter(context, this);
463         }
464 
465         Source aSource = aConverter.convertFromValue(
466                 context, this, getSource());
467         setSubmittedSource(aSource);
468     }
469 
470     /**
471      * Decodes the report value.
472      *
473      * @param context current faces' context.
474      */
475     protected final void decodeReport(final FacesContext context) {
476         if (context == null) {
477             throw new IllegalArgumentException();
478         }
479 
480         ReportConverter aConverter = getReportConverter();
481         if (aConverter == null) {
482             aConverter = getJRFacesContext()
483                     .createReportConverter(context, this);
484         }
485 
486         JasperReport aReport = aConverter.convertFromValue(
487                 context, this, getValue());
488         setSubmittedReport(aReport);
489     }
490 
491     /**
492      * Validates the current report instance.
493      *
494      * @param context current faces' context
495      * @throws ValidatorException when report configuration is not valid.
496      */
497     public void validate(final FacesContext context)
498     throws ValidatorException {
499         if (context == null) {
500             throw new NullPointerException();
501         }
502 
503         Validator aValidator = getValidator();
504         if (aValidator == null) {
505             aValidator = getFacesContext().getApplication()
506                 .createValidator(ReportValidatorBase.VALIDATOR_TYPE);
507         }
508 
509         if (aValidator != null) {
510             try {
511                 aValidator.validate(context, this, getValue());
512             } catch (ValidatorException e) {
513                 setValid(false);
514                 throw e;
515             }
516         }
517     }
518 
519     /**
520      * Utility method for obtaining the current JRFacesContext instance.
521      *
522      * @return current JRFacesContext instance.
523      */
524     protected final JRFacesContext getJRFacesContext() {
525         return JRFacesContext.getInstance(getFacesContext());
526     }
527 
528     /**
529      * Executes the decoding process.
530      *
531      * @param context current faces' context.
532      */
533     protected final void executeDecodes(final FacesContext context) {
534         if (context == null) {
535             throw new NullPointerException();
536         }
537 
538         try {
539             decodeSource(context);
540             decodeReport(context);
541         } catch (RuntimeException e) {
542             context.renderResponse();
543             throw e;
544         }
545     }
546 
547     /**
548      * Executes the validation process.
549      *
550      * @param context current faces' context.
551      */
552     protected final void executeValidate(final FacesContext context) {
553         if (context == null) {
554             throw new NullPointerException();
555         }
556 
557         try {
558             validate(context);
559         } catch (ValidatorException e) {
560             context.renderResponse();
561             throw e;
562         }
563     }
564 
565 }