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.UUID;
30
31 import net.sf.jasperreports.engine.DatasetPropertyExpression;
32 import net.sf.jasperreports.engine.JRConstants;
33 import net.sf.jasperreports.engine.JRDataset;
34 import net.sf.jasperreports.engine.JRExpression;
35 import net.sf.jasperreports.engine.JRField;
36 import net.sf.jasperreports.engine.JRGroup;
37 import net.sf.jasperreports.engine.JRParameter;
38 import net.sf.jasperreports.engine.JRPropertiesHolder;
39 import net.sf.jasperreports.engine.JRPropertiesMap;
40 import net.sf.jasperreports.engine.JRQuery;
41 import net.sf.jasperreports.engine.JRRuntimeException;
42 import net.sf.jasperreports.engine.JRScriptlet;
43 import net.sf.jasperreports.engine.JRSortField;
44 import net.sf.jasperreports.engine.JRVariable;
45 import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
46 import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
47 import net.sf.jasperreports.engine.type.WhenResourceMissingTypeEnum;
48 import net.sf.jasperreports.engine.util.JRCloneUtils;
49
50 /**
51  * The base implementation of {@link net.sf.jasperreports.engine.JRDataset JRDataset}.
52  * 
53  * @author Lucian Chirita (lucianc@users.sourceforge.net)
54  */

55 public class JRBaseDataset implements JRDataset, Serializable, JRChangeEventsSupport
56 {
57     private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID;
58     
59     public static final String PROPERTY_WHEN_RESOURCE_MISSING_TYPE = "whenResourceMissingType";
60
61     protected final boolean isMain;
62     protected UUID uuid;
63     protected String name;
64     protected String scriptletClass;
65     protected JRScriptlet[] scriptlets;
66     protected JRParameter[] parameters;
67     protected JRQuery query;
68     protected JRField[] fields;
69     protected JRSortField[] sortFields;
70     protected JRVariable[] variables;
71     protected JRGroup[] groups;
72     protected String resourceBundle;
73     protected WhenResourceMissingTypeEnum whenResourceMissingTypeValue = WhenResourceMissingTypeEnum.NULL;
74     protected JRPropertiesMap propertiesMap;
75     protected JRExpression filterExpression;
76
77     private DatasetPropertyExpression[] propertyExpressions;
78     
79     protected JRBaseDataset(boolean isMain)
80     {
81         this.isMain = isMain;
82         
83         propertiesMap = new JRPropertiesMap();
84     }
85     
86     protected JRBaseDataset(JRDataset dataset, JRBaseObjectFactory factory)
87     {
88         factory.put(dataset, this);
89         
90         uuid = dataset.getUUID();
91         name = dataset.getName();
92         scriptletClass = dataset.getScriptletClass();
93         resourceBundle = dataset.getResourceBundle();
94         whenResourceMissingTypeValue = dataset.getWhenResourceMissingTypeValue();
95
96         /*   */
97         this.propertiesMap = dataset.getPropertiesMap().cloneProperties();
98         propertyExpressions = factory.getPropertyExpressions(dataset.getPropertyExpressions());
99
100         query = factory.getQuery(dataset.getQuery());
101
102         isMain = dataset.isMainDataset();
103         
104         /*   */
105         JRScriptlet[] jrScriptlets = dataset.getScriptlets();
106         if (jrScriptlets != null && jrScriptlets.length > 0)
107         {
108             scriptlets = new JRScriptlet[jrScriptlets.length];
109             for(int i = 0; i < scriptlets.length; i++)
110             {
111                 scriptlets[i] = factory.getScriptlet(jrScriptlets[i]);
112             }
113         }
114         
115         /*   */
116         JRParameter[] jrParameters = dataset.getParameters();
117         if (jrParameters != null && jrParameters.length > 0)
118         {
119             parameters = new JRParameter[jrParameters.length];
120             for(int i = 0; i < parameters.length; i++)
121             {
122                 parameters[i] = factory.getParameter(jrParameters[i]);
123             }
124         }
125         
126         /*   */
127         JRField[] jrFields = dataset.getFields();
128         if (jrFields != null && jrFields.length > 0)
129         {
130             fields = new JRField[jrFields.length];
131             for(int i = 0; i < fields.length; i++)
132             {
133                 fields[i] = factory.getField(jrFields[i]);
134             }
135         }
136
137         /*   */
138         JRSortField[] jrSortFields = dataset.getSortFields();
139         if (jrSortFields != null && jrSortFields.length > 0)
140         {
141             sortFields = new JRSortField[jrSortFields.length];
142             for(int i = 0; i < sortFields.length; i++)
143             {
144                 sortFields[i] = factory.getSortField(jrSortFields[i]);
145             }
146         }
147
148         /*   */
149         JRVariable[] jrVariables = dataset.getVariables();
150         if (jrVariables != null && jrVariables.length > 0)
151         {
152             variables = new JRVariable[jrVariables.length];
153             for(int i = 0; i < variables.length; i++)
154             {
155                 variables[i] = factory.getVariable(jrVariables[i]);
156             }
157         }
158
159         /*   */
160         JRGroup[] jrGroups = dataset.getGroups();
161         if (jrGroups != null && jrGroups.length > 0)
162         {
163             groups = new JRGroup[jrGroups.length];
164             for(int i = 0; i < groups.length; i++)
165             {
166                 groups[i] = factory.getGroup(jrGroups[i]);
167             }
168         }
169         
170         filterExpression = factory.getExpression(dataset.getFilterExpression());
171     }
172
173     
174     @Override
175     public UUID getUUID()
176     {
177         if (uuid == null)
178         {
179             uuid = UUID.randomUUID();
180         }
181         return uuid;
182     }
183     
184     @Override
185     public String getName()
186     {
187         return name;
188     }
189     
190     @Override
191     public String getScriptletClass()
192     {
193         return scriptletClass;
194     }
195
196     @Override
197     public JRQuery getQuery()
198     {
199         return query;
200     }
201
202     @Override
203     public JRScriptlet[] getScriptlets()
204     {
205         return scriptlets;
206     }
207
208     @Override
209     public JRParameter[] getParameters()
210     {
211         return parameters;
212     }
213
214     @Override
215     public JRField[] getFields()
216     {
217         return fields;
218     }
219
220     @Override
221     public JRSortField[] getSortFields()
222     {
223         return sortFields;
224     }
225
226     @Override
227     public JRVariable[] getVariables()
228     {
229         return variables;
230     }
231
232     @Override
233     public JRGroup[] getGroups()
234     {
235         return groups;
236     }
237
238     @Override
239     public boolean isMainDataset()
240     {
241         return isMain;
242     }
243
244     @Override
245     public String getResourceBundle()
246     {
247         return resourceBundle;
248     }
249
250     @Override
251     public WhenResourceMissingTypeEnum getWhenResourceMissingTypeValue()
252     {
253         return whenResourceMissingTypeValue;
254     }
255
256     @Override
257     public void setWhenResourceMissingType(WhenResourceMissingTypeEnum whenResourceMissingTypeValue)
258     {
259         Object old = this.whenResourceMissingTypeValue;
260         this.whenResourceMissingTypeValue = whenResourceMissingTypeValue;
261         getEventSupport().firePropertyChange(PROPERTY_WHEN_RESOURCE_MISSING_TYPE, old, this.whenResourceMissingTypeValue);
262     }
263
264     @Override
265     public boolean hasProperties()
266     {
267         return propertiesMap != null && propertiesMap.hasProperties();
268     }
269
270     @Override
271     public JRPropertiesMap getPropertiesMap()
272     {
273         return propertiesMap;
274     }
275
276     @Override
277     public JRPropertiesHolder getParentProperties()
278     {
279         return null;
280     }
281
282     @Override
283     public DatasetPropertyExpression[] getPropertyExpressions()
284     {
285         return propertyExpressions;
286     }
287
288     @Override
289     public JRExpression getFilterExpression()
290     {
291         return filterExpression;
292     }
293     
294     @Override
295     public Object clone() 
296     {
297         JRBaseDataset clone = null;
298
299         try
300         {
301             clone = (JRBaseDataset)super.clone();
302         }
303         catch (CloneNotSupportedException e)
304         {
305             throw new JRRuntimeException(e);
306         }
307         
308         clone.query = JRCloneUtils.nullSafeClone(query);
309         clone.filterExpression = JRCloneUtils.nullSafeClone(filterExpression);
310         if (propertiesMap != null)
311         {
312             clone.propertiesMap = (JRPropertiesMap)propertiesMap.clone();
313         }
314         clone.propertyExpressions = JRCloneUtils.cloneArray(propertyExpressions);
315
316         clone.parameters = JRCloneUtils.cloneArray(parameters);
317         clone.fields = JRCloneUtils.cloneArray(fields);
318         clone.sortFields = JRCloneUtils.cloneArray(sortFields);
319         //FIXME use CloneStore to preserve variable and group references
320         clone.variables = JRCloneUtils.cloneArray(variables);
321         clone.groups = JRCloneUtils.cloneArray(groups);
322         
323         clone.eventSupport = null;
324         clone.uuid = null;
325
326         return clone;
327     }
328
329     private transient JRPropertyChangeSupport eventSupport;
330     
331     @Override
332     public JRPropertyChangeSupport getEventSupport()
333     {
334         synchronized (this)
335         {
336             if (eventSupport == null)
337             {
338                 eventSupport = new JRPropertyChangeSupport(this);
339             }
340         }
341         
342         return eventSupport;
343     }
344
345     
346     /*
347      * These fields are only for serialization backward compatibility.
348      */

349     private int PSEUDO_SERIAL_VERSION_UID = JRConstants.PSEUDO_SERIAL_VERSION_UID; //NOPMD
350     /**
351      * @deprecated
352      */

353     private byte whenResourceMissingType;
354     
355     @SuppressWarnings("deprecation")
356     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
357     {
358         in.defaultReadObject();
359         
360         if (PSEUDO_SERIAL_VERSION_UID < JRConstants.PSEUDO_SERIAL_VERSION_UID_3_7_2)
361         {
362             whenResourceMissingTypeValue = WhenResourceMissingTypeEnum.getByValue(whenResourceMissingType);
363         }
364     }
365
366 }
367