1 /*
2  * JasperReports - Free Java Reporting Library.
3  * Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
4  * http://www.jaspersoft.com
5  *
6  * Unless you have purchased a commercial license agreement from Jaspersoft,
7  * the following license terms apply:
8  *
9  * This program is part of JasperReports.
10  *
11  * JasperReports is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * JasperReports is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
23  */

24 package net.sf.jasperreports.engine.base;
25
26 import java.io.IOException;
27 import java.io.ObjectInputStream;
28 import java.io.Serializable;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Set;
34 import java.util.UUID;
35
36 import net.sf.jasperreports.engine.DatasetPropertyExpression;
37 import net.sf.jasperreports.engine.JRBand;
38 import net.sf.jasperreports.engine.JRConstants;
39 import net.sf.jasperreports.engine.JRDataset;
40 import net.sf.jasperreports.engine.JRExpressionCollector;
41 import net.sf.jasperreports.engine.JRField;
42 import net.sf.jasperreports.engine.JRGroup;
43 import net.sf.jasperreports.engine.JRParameter;
44 import net.sf.jasperreports.engine.JRPropertiesHolder;
45 import net.sf.jasperreports.engine.JRPropertiesMap;
46 import net.sf.jasperreports.engine.JRQuery;
47 import net.sf.jasperreports.engine.JRReport;
48 import net.sf.jasperreports.engine.JRReportTemplate;
49 import net.sf.jasperreports.engine.JRScriptlet;
50 import net.sf.jasperreports.engine.JRSection;
51 import net.sf.jasperreports.engine.JRSortField;
52 import net.sf.jasperreports.engine.JRStyle;
53 import net.sf.jasperreports.engine.JRVariable;
54 import net.sf.jasperreports.engine.JasperReportsContext;
55 import net.sf.jasperreports.engine.design.JasperDesign;
56 import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
57 import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
58 import net.sf.jasperreports.engine.type.OrientationEnum;
59 import net.sf.jasperreports.engine.type.PrintOrderEnum;
60 import net.sf.jasperreports.engine.type.RunDirectionEnum;
61 import net.sf.jasperreports.engine.type.SectionTypeEnum;
62 import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;
63 import net.sf.jasperreports.engine.type.WhenResourceMissingTypeEnum;
64 import net.sf.jasperreports.engine.util.StyleResolver;
65
66
67 /**
68  * Base class that implements the {@link net.sf.jasperreports.engine.JRReport} interface.
69  * 
70  * @see net.sf.jasperreports.engine.JRReport
71  * @author Teodor Danciu (teodord@users.sourceforge.net)
72  * 
73  */

74 public class JRBaseReport implements JRReport, Serializable, JRChangeEventsSupport
75 {
76
77
78     /**
79      *
80      */

81     private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID;
82
83     public static final String PROPERTY_WHEN_NO_DATA_TYPE = "whenNoDataType";
84     public static final String PROPERTY_SECTION_TYPE = "sectionType";
85
86     /**
87      *
88      */

89     protected String name;
90     protected String language = LANGUAGE_JAVA;
91     protected int columnCount = 1;
92     protected PrintOrderEnum printOrderValue = PrintOrderEnum.VERTICAL;
93     protected RunDirectionEnum columnDirection = RunDirectionEnum.LTR;
94     protected int pageWidth = 595;
95     protected int pageHeight = 842;
96     protected OrientationEnum orientationValue = OrientationEnum.PORTRAIT;
97     protected WhenNoDataTypeEnum whenNoDataTypeValue;
98     protected SectionTypeEnum sectionType = SectionTypeEnum.BAND;
99     protected int columnWidth = 555;
100     protected int columnSpacing;
101     protected int leftMargin = 20;
102     protected int rightMargin = 20;
103     protected int topMargin = 30;
104     protected int bottomMargin = 30;
105     protected boolean isTitleNewPage;
106     protected boolean isSummaryNewPage;
107     protected boolean isSummaryWithPageHeaderAndFooter;
108     protected boolean isFloatColumnFooter;
109     protected boolean ignorePagination;//FIXMEBOOK remove default
110
111     /**
112      *
113      */

114     protected String formatFactoryClass;
115
116     /**
117      *
118      */

119     protected Set<String> importsSet;
120
121     /**
122      * Report templates.
123      */

124     protected JRReportTemplate[] templates;
125
126     protected JRStyle defaultStyle;
127     protected JRStyle[] styles;
128
129     protected transient StyleResolver styleResolver = StyleResolver.getInstance();
130
131     /**
132      * The main dataset of the report.
133      */

134     protected JRDataset mainDataset;
135
136     /**
137      * Sub datasets of the report.
138      */

139     protected JRDataset[] datasets;
140
141     protected JRBand background;
142     protected JRBand title;
143     protected JRBand pageHeader;
144     protected JRBand columnHeader;
145     protected JRSection detailSection;
146     protected JRBand columnFooter;
147     protected JRBand pageFooter;
148     protected JRBand lastPageFooter;
149     protected JRBand summary;
150     protected JRBand noData;
151
152
153     /**
154      * @deprecated Replaced by {@link JasperDesign#JasperDesign()}.
155      */

156     public JRBaseReport()
157     {
158     }
159
160     public JRBaseReport(JRReport report, JRExpressionCollector expressionCollector)
161     {
162         this(report, new JRBaseObjectFactory(expressionCollector));
163     }
164     
165     /**
166      * Constructs a copy of a report.
167      */

168     public JRBaseReport(JRReport report, JRBaseObjectFactory factory)
169     {
170         /*   */
171         name = report.getName();
172         language = report.getLanguage();
173         columnCount = report.getColumnCount();
174         printOrderValue = report.getPrintOrderValue();
175         columnDirection = report.getColumnDirection();
176         pageWidth = report.getPageWidth();
177         pageHeight = report.getPageHeight();
178         orientationValue = report.getOrientationValue();
179         whenNoDataTypeValue = report.getWhenNoDataTypeValue();
180         sectionType = report.getSectionType();
181         columnWidth = report.getColumnWidth();
182         columnSpacing = report.getColumnSpacing();
183         leftMargin = report.getLeftMargin();
184         rightMargin = report.getRightMargin();
185         topMargin = report.getTopMargin();
186         bottomMargin = report.getBottomMargin();
187         isTitleNewPage = report.isTitleNewPage();
188         isSummaryNewPage = report.isSummaryNewPage();
189         isSummaryWithPageHeaderAndFooter = report.isSummaryWithPageHeaderAndFooter();
190         isFloatColumnFooter = report.isFloatColumnFooter();
191         ignorePagination = report.isIgnorePagination();
192
193         formatFactoryClass = report.getFormatFactoryClass();
194
195         /*   */
196         String[] imports = report.getImports();
197         if (imports != null && imports.length > 0)
198         {
199             importsSet = new HashSet<String>(imports.length);
200             importsSet.addAll(Arrays.asList(imports));
201         }
202
203         /*   */
204         factory.setDefaultStyleProvider(this);
205
206         copyTemplates(report, factory);
207
208         /*   */
209         defaultStyle = factory.getStyle(report.getDefaultStyle());
210
211         /*   */
212         JRStyle[] jrStyles = report.getStyles();
213         if (jrStyles != null && jrStyles.length > 0)
214         {
215             styles = new JRStyle[jrStyles.length];
216             for(int i = 0; i < styles.length; i++)
217             {
218                 styles[i] = factory.getStyle(jrStyles[i]);
219             }
220         }
221
222         mainDataset = factory.getDataset(report.getMainDataset());
223
224         JRDataset[] datasetArray = report.getDatasets();
225         if (datasetArray != null && datasetArray.length > 0)
226         {
227             datasets = new JRDataset[datasetArray.length];
228             for (int i = 0; i < datasets.length; i++)
229             {
230                 datasets[i] = factory.getDataset(datasetArray[i]);
231             }
232         }
233
234         background = factory.getBand(report.getBackground());
235         title = factory.getBand(report.getTitle());
236         pageHeader = factory.getBand(report.getPageHeader());
237         columnHeader = factory.getBand(report.getColumnHeader());
238         detailSection = factory.getSection(report.getDetailSection());
239         columnFooter = factory.getBand(report.getColumnFooter());
240         pageFooter = factory.getBand(report.getPageFooter());
241         lastPageFooter = factory.getBand(report.getLastPageFooter());
242         summary = factory.getBand(report.getSummary());
243         noData = factory.getBand(report.getNoData());
244     }
245
246
247     protected void copyTemplates(JRReport report, JRBaseObjectFactory factory)
248     {
249         JRReportTemplate[] reportTemplates = report.getTemplates();
250         if (reportTemplates == null || reportTemplates.length == 0)
251         {
252             templates = null;
253         }
254         else
255         {
256             templates = new JRReportTemplate[reportTemplates.length];
257             for (int i = 0; i < reportTemplates.length; i++)
258             {
259                 templates[i] = factory.getReportTemplate(reportTemplates[i]);
260             }
261         }
262     }
263
264     public JRBaseReport(JRReport report)
265     {
266         this(report, (JRExpressionCollector) null);
267     }
268
269
270     /**
271      *
272      */

273     public synchronized void setJasperReportsContext(JasperReportsContext jasperReportsContext)
274     {
275         styleResolver = new StyleResolver(jasperReportsContext);
276     }
277
278     @Override
279     public String getName()
280     {
281         return name;
282     }
283
284     @Override
285     public String getLanguage()
286     {
287         return language;
288     }
289
290     @Override
291     public int getColumnCount()
292     {
293         return columnCount;
294     }
295
296     @Override
297     public PrintOrderEnum getPrintOrderValue()
298     {
299         return printOrderValue;
300     }
301
302     @Override
303     public RunDirectionEnum getColumnDirection()
304     {
305         return columnDirection;
306     }
307
308     @Override
309     public int getPageWidth()
310     {
311         return pageWidth;
312     }
313
314     @Override
315     public int getPageHeight()
316     {
317         return pageHeight;
318     }
319
320     @Override
321     public OrientationEnum getOrientationValue()
322     {
323         return orientationValue;
324     }
325
326     @Override
327     public WhenNoDataTypeEnum getWhenNoDataTypeValue()
328     {
329         return whenNoDataTypeValue;
330     }
331
332     @Override
333     public void setWhenNoDataType(WhenNoDataTypeEnum whenNoDataTypeValue)
334     {
335         Object old = this.whenNoDataTypeValue;
336         this.whenNoDataTypeValue = whenNoDataTypeValue;
337         getEventSupport().firePropertyChange(PROPERTY_WHEN_NO_DATA_TYPE, old, whenNoDataTypeValue);
338     }
339
340     @Override
341     public SectionTypeEnum getSectionType()
342     {
343         return sectionType;
344     }
345
346     /**
347      *
348      */

349     public void setSectionType(SectionTypeEnum sectionType)
350     {
351         Object old = this.sectionType;
352         this.sectionType = sectionType;
353         getEventSupport().firePropertyChange(PROPERTY_SECTION_TYPE, old, sectionType);
354     }
355
356     @Override
357     public int getColumnWidth()
358     {
359         return columnWidth;
360     }
361
362     @Override
363     public int getColumnSpacing()
364     {
365         return columnSpacing;
366     }
367
368     @Override
369     public int getLeftMargin()
370     {
371         return leftMargin;
372     }
373
374     @Override
375     public int getRightMargin()
376     {
377         return rightMargin;
378     }
379
380     @Override
381     public int getTopMargin()
382     {
383         return topMargin;
384     }
385
386     @Override
387     public int getBottomMargin()
388     {
389         return bottomMargin;
390     }
391
392     @Override
393     public boolean isTitleNewPage()
394     {
395         return isTitleNewPage;
396     }
397
398     @Override
399     public boolean isSummaryNewPage()
400     {
401         return isSummaryNewPage;
402     }
403
404     @Override
405     public boolean isSummaryWithPageHeaderAndFooter()
406     {
407         return isSummaryWithPageHeaderAndFooter;
408     }
409
410     @Override
411     public boolean isFloatColumnFooter()
412     {
413         return isFloatColumnFooter;
414     }
415
416     @Override
417     public String getScriptletClass()
418     {
419         return mainDataset.getScriptletClass();
420     }
421
422     @Override
423     public String getFormatFactoryClass()
424     {
425         return formatFactoryClass;
426     }
427
428     @Override
429     public String getResourceBundle()
430     {
431         return mainDataset.getResourceBundle();
432     }
433
434     @Override
435     public String[] getPropertyNames()
436     {
437         return mainDataset.getPropertiesMap().getPropertyNames();
438     }
439
440     @Override
441     public String getProperty(String propName)
442     {
443         return mainDataset.getPropertiesMap().getProperty(propName);
444     }
445
446     @Override
447     public void setProperty(String propName, String value)
448     {
449         mainDataset.getPropertiesMap().setProperty(propName, value);
450     }
451
452     @Override
453     public void removeProperty(String propName)
454     {
455         mainDataset.getPropertiesMap().removeProperty(propName);
456     }
457
458     @Override
459     public DatasetPropertyExpression[] getPropertyExpressions()
460     {
461         return mainDataset.getPropertyExpressions();
462     }
463
464     @Override
465     public String[] getImports()
466     {
467         if (importsSet != null)
468         {
469             return importsSet.toArray(new String[importsSet.size()]);
470         }
471         return null;
472     }
473
474     @Override
475     public JRStyle getDefaultStyle()
476     {
477         return defaultStyle;
478     }
479
480     @Override
481     public JRStyle[] getStyles()
482     {
483         return styles;
484     }
485
486     @Override
487     public StyleResolver getStyleResolver()
488     {
489         return styleResolver;
490     }
491
492     /**
493      * Gets an array of report scriptlets (excluding the scriptletClass one).
494      */

495     @Override
496     public JRScriptlet[] getScriptlets()
497     {
498         return mainDataset.getScriptlets();
499     }
500
501     /**
502      * Gets an array of report parameters (including built-in ones).
503      */

504     @Override
505     public JRParameter[] getParameters()
506     {
507         return mainDataset.getParameters();
508     }
509
510     @Override
511     public JRQuery getQuery()
512     {
513         return mainDataset.getQuery();
514     }
515
516     /**
517      *  Gets an array of report fields.
518      */

519     @Override
520     public JRField[] getFields()
521     {
522         return mainDataset.getFields();
523     }
524
525     /**
526      *  Gets an array of sort report fields.
527      */

528     @Override
529     public JRSortField[] getSortFields()
530     {
531         return mainDataset.getSortFields();
532     }
533
534     /**
535      * Gets an array of report variables.
536      */

537     @Override
538     public JRVariable[] getVariables()
539     {
540         return mainDataset.getVariables();
541     }
542
543     @Override
544     public JRGroup[] getGroups()
545     {
546         return mainDataset.getGroups();
547     }
548
549     @Override
550     public JRBand getBackground()
551     {
552         return background;
553     }
554
555     @Override
556     public JRBand getTitle()
557     {
558         return title;
559     }
560
561     @Override
562     public JRBand getPageHeader()
563     {
564         return pageHeader;
565     }
566
567     @Override
568     public JRBand getColumnHeader()
569     {
570         return columnHeader;
571     }
572
573     @Override
574     public JRSection getDetailSection()
575     {
576         return detailSection;
577     }
578
579     @Override
580     public JRBand getColumnFooter()
581     {
582         return columnFooter;
583     }
584
585     @Override
586     public JRBand getPageFooter()
587     {
588         return pageFooter;
589     }
590
591     @Override
592     public JRBand getLastPageFooter()
593     {
594         return lastPageFooter;
595     }
596
597     @Override
598     public JRBand getSummary()
599     {
600         return summary;
601     }
602
603
604     @Override
605     public WhenResourceMissingTypeEnum getWhenResourceMissingTypeValue()
606     {
607         return mainDataset.getWhenResourceMissingTypeValue();
608     }
609
610     @Override
611     public void setWhenResourceMissingType(WhenResourceMissingTypeEnum whenResourceMissingType)
612     {
613         mainDataset.setWhenResourceMissingType(whenResourceMissingType);
614     }
615
616
617     @Override
618     public JRDataset getMainDataset()
619     {
620         return mainDataset;
621     }
622
623
624     @Override
625     public JRDataset[] getDatasets()
626     {
627         return datasets;
628     }
629
630
631     @Override
632     public boolean isIgnorePagination()
633     {
634         return ignorePagination;
635     }
636
637     @Override
638     public boolean hasProperties()
639     {
640         return mainDataset.hasProperties();
641     }
642
643     @Override
644     public JRPropertiesMap getPropertiesMap()
645     {
646         return mainDataset.getPropertiesMap();
647     }
648
649     @Override
650     public JRPropertiesHolder getParentProperties()
651     {
652         return null;
653     }
654
655     @Override
656     public JRReportTemplate[] getTemplates()
657     {
658         return templates;
659     }
660
661     /**
662      * @return the noData
663      */

664     @Override
665     public JRBand getNoData() {
666         return noData;
667     }
668     
669     /**
670      *
671      */

672     public JRBand[] getAllBands()
673     {
674         List<JRBand> bands = new ArrayList<JRBand>();
675         
676         addBand(title, bands);
677         addBand(pageHeader, bands);
678         addBand(columnHeader, bands);
679
680         JRGroup[] groups = mainDataset.getGroups();
681         if (groups != null)
682         {
683             for (JRGroup group : groups)
684             {
685                 addBands(group.getGroupHeaderSection(), bands);
686                 addBands(group.getGroupFooterSection(), bands);
687             }
688         }
689
690         addBands(detailSection, bands);
691         
692         addBand(columnFooter, bands);
693         addBand(pageFooter, bands);
694         addBand(lastPageFooter, bands);
695         addBand(summary, bands);
696         addBand(noData, bands);
697         
698         return bands.toArray(new JRBand[bands.size()]);
699     }
700
701     /**
702      *
703      */

704     private void addBand(JRBand band, List<JRBand> bands)
705     {
706         if (band != null)
707         {
708             bands.add(band);
709         }
710     }
711
712     /**
713      *
714      */

715     private void addBands(JRSection section, List<JRBand> bands)
716     {
717         if (section != null)
718         {
719             JRBand[] sectionBands = section.getBands();
720             if (sectionBands != null)
721             {
722                 for (JRBand band : sectionBands)
723                 {
724                     addBand(band, bands);
725                 }
726             }
727         }
728     }
729
730     @Override
731     public UUID getUUID()
732     {
733         return mainDataset.getUUID();
734     }
735     
736     private transient JRPropertyChangeSupport eventSupport;//FIXMECLONE cloneable for reset?
737     
738     @Override
739     public JRPropertyChangeSupport getEventSupport()
740     {
741         synchronized (this)
742         {
743             if (eventSupport == null)
744             {
745                 eventSupport = new JRPropertyChangeSupport(this);
746             }
747         }
748         
749         return eventSupport;
750     }
751
752     
753     /*
754      * These fields are only for serialization backward compatibility.
755      */

756     private int PSEUDO_SERIAL_VERSION_UID = JRConstants.PSEUDO_SERIAL_VERSION_UID; //NOPMD
757     /**
758      * @deprecated
759      */

760     private JRBand detail;
761     /**
762      * @deprecated
763      */

764     private byte whenNoDataType;
765     /**
766      * @deprecated
767      */

768     private byte printOrder;
769     /**
770      * @deprecated
771      */

772     private byte orientation;
773     
774     @SuppressWarnings("deprecation")
775     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
776     {
777         in.defaultReadObject();
778
779         styleResolver = StyleResolver.getInstance();
780
781         if (detail != null)
782         {
783             detailSection = new JRBaseSection(detail);
784             detail = null;
785         }
786         
787         if (PSEUDO_SERIAL_VERSION_UID < JRConstants.PSEUDO_SERIAL_VERSION_UID_3_7_2)
788         {
789             whenNoDataTypeValue = WhenNoDataTypeEnum.getByValue(whenNoDataType);
790             printOrderValue = PrintOrderEnum.getByValue(printOrder);
791             orientationValue = OrientationEnum.getByValue(orientation);
792         }
793     }
794
795 }
796