KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > data > JRHibernateAbstractDataSource


1 /*
2  * ============================================================================
3  * GNU Lesser General Public License
4  * ============================================================================
5  *
6  * JasperReports - Free Java report-generating library.
7  * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * JasperSoft Corporation
24  * 303 Second Street, Suite 450 North
25  * San Francisco, CA 94107
26  * http://www.jaspersoft.com
27  */

28 package net.sf.jasperreports.engine.data;
29
30 import java.util.HashMap JavaDoc;
31 import java.util.Map JavaDoc;
32
33 import net.sf.jasperreports.engine.JRDataSource;
34 import net.sf.jasperreports.engine.JRException;
35 import net.sf.jasperreports.engine.JRField;
36 import net.sf.jasperreports.engine.JRRuntimeException;
37 import net.sf.jasperreports.engine.query.JRHibernateQueryExecuter;
38
39 import org.apache.commons.beanutils.PropertyUtils;
40 import org.hibernate.type.Type;
41
42 /**
43  * Base abstract Hibernate data source.
44  *
45  * @author Lucian Chirita (lucianc@users.sourceforge.net)
46  * @version $Id: JRHibernateAbstractDataSource.java 1229 2006-04-19 13:27:35 +0300 (Wed, 19 Apr 2006) teodord $
47  */

48 public abstract class JRHibernateAbstractDataSource implements JRDataSource
49 {
50     private final boolean useFieldDescription;
51     private final Map JavaDoc fieldReaders;
52     protected final JRHibernateQueryExecuter queryExecuter;
53     private Object JavaDoc currentReturnValue;
54     
55     
56     /**
57      * Creates a Hibernate data source.
58      *
59      * @param queryExecuter the query executer
60      * @param useFieldDescription whether to use field descriptions for fields to results mapping
61      * @param useIndexOnSingleReturn whether to use indexed addressing even when the query has only one return column
62      */

63     protected JRHibernateAbstractDataSource(JRHibernateQueryExecuter queryExecuter, boolean useFieldDescription, boolean useIndexOnSingleReturn)
64     {
65         this.useFieldDescription = useFieldDescription;
66         
67         this.queryExecuter = queryExecuter;
68
69         fieldReaders = assignReaders(useIndexOnSingleReturn);
70     }
71     
72     /**
73      * Assigns field readers to report fields.
74      *
75      * @param useIndexOnSingleReturn whether to use indexed addressing even when the query has only one return column
76      * @return a report field name to field reader mapping
77      * @see FieldReader
78      */

79     protected Map JavaDoc assignReaders(boolean useIndexOnSingleReturn)
80     {
81         Map JavaDoc readers = new HashMap JavaDoc();
82         
83         JRField[] fields = queryExecuter.getDataset().getFields();
84         Type[] returnTypes = queryExecuter.getReturnTypes();
85         String JavaDoc[] aliases = queryExecuter.getReturnAliases();
86         
87         Map JavaDoc aliasesMap = new HashMap JavaDoc();
88         if (aliases != null)
89         {
90             for (int i = 0; i < aliases.length; i++)
91             {
92                 aliasesMap.put(aliases[i], new Integer JavaDoc(i));
93             }
94         }
95         
96         if (returnTypes.length == 1)
97         {
98             if (returnTypes[0].isEntityType() || returnTypes[0].isComponentType())
99             {
100                 for (int i = 0; i < fields.length; i++)
101                 {
102                     JRField field = fields[i];
103                     readers.put(field.getName(), getFieldReaderSingleReturn(aliasesMap, field, useIndexOnSingleReturn));
104                 }
105             }
106             else
107             {
108                 if (fields.length > 1)
109                 {
110                     throw new JRRuntimeException("The HQL query returns only one non-entity and non-component result but there are more than one fields.");
111                 }
112                 
113                 if (fields.length == 1)
114                 {
115                     JRField field = fields[0];
116                     if (useIndexOnSingleReturn)
117                     {
118                         readers.put(field.getName(), new IndexFieldReader(0));
119                     }
120                     else
121                     {
122                         readers.put(field.getName(), new IdentityFieldReader());
123                     }
124                 }
125             }
126         }
127         else
128         {
129             for (int i = 0; i < fields.length; i++)
130             {
131                 JRField field = fields[i];
132                 readers.put(field.getName(), getFieldReader(returnTypes, aliasesMap, field));
133             }
134         }
135
136         return readers;
137     }
138
139     protected FieldReader getFieldReaderSingleReturn(Map JavaDoc aliasesMap, JRField field, boolean useIndex)
140     {
141         FieldReader reader;
142         
143         String JavaDoc fieldMapping = getFieldMapping(field);
144         if (aliasesMap.containsKey(fieldMapping))
145         {
146             if (useIndex)
147             {
148                 reader = new IndexFieldReader(0);
149             }
150             else
151             {
152                 reader = new IdentityFieldReader();
153             }
154         }
155         else
156         {
157             int firstNestedIdx = fieldMapping.indexOf(PropertyUtils.NESTED_DELIM);
158
159             if (firstNestedIdx >= 0 && aliasesMap.containsKey(fieldMapping.substring(0, firstNestedIdx)))
160             {
161                 fieldMapping = fieldMapping.substring(firstNestedIdx + 1);
162             }
163
164             if (useIndex)
165             {
166                 reader = new IndexPropertyFieldReader(0, fieldMapping);
167             }
168             else
169             {
170                 reader = new PropertyFieldReader(fieldMapping);
171             }
172         }
173         
174         return reader;
175     }
176
177     protected FieldReader getFieldReader(Type[] returnTypes, Map JavaDoc aliasesMap, JRField field)
178     {
179         FieldReader reader;
180         
181         String JavaDoc fieldMapping = getFieldMapping(field);
182         Integer JavaDoc fieldIdx = (Integer JavaDoc) aliasesMap.get(fieldMapping);
183         if (fieldIdx == null)
184         {
185             int firstNestedIdx = fieldMapping.indexOf(PropertyUtils.NESTED_DELIM);
186             
187             if (firstNestedIdx < 0)
188             {
189                 throw new JRRuntimeException("Unknown HQL return alias \"" + fieldMapping + "\".");
190             }
191             
192             String JavaDoc fieldAlias = fieldMapping.substring(0, firstNestedIdx);
193             String JavaDoc fieldProperty = fieldMapping.substring(firstNestedIdx + 1);
194             
195             fieldIdx = (Integer JavaDoc) aliasesMap.get(fieldAlias);
196             if (fieldIdx == null)
197             {
198                 throw new JRRuntimeException("The HQL query does not have a \"" + fieldAlias + "\" alias.");
199             }
200             
201             Type type = returnTypes[fieldIdx.intValue()];
202             if (!type.isEntityType() && !type.isComponentType())
203             {
204                 throw new JRRuntimeException("The HQL query does not have a \"" + fieldAlias + "\" alias.");
205             }
206             
207             reader = new IndexPropertyFieldReader(fieldIdx.intValue(), fieldProperty);
208         }
209         else
210         {
211             reader = new IndexFieldReader(fieldIdx.intValue());
212         }
213         
214         return reader;
215     }
216
217     
218     /**
219      * Sets the current row of the query result.
220      *
221      * @param currentReturnValue the current row value
222      */

223     protected void setCurrentRowValue(Object JavaDoc currentReturnValue)
224     {
225         this.currentReturnValue = currentReturnValue;
226     }
227     
228     
229     public Object JavaDoc getFieldValue(JRField jrField) throws JRException
230     {
231         FieldReader reader = (FieldReader) fieldReaders.get(jrField.getName());
232         if (reader == null)
233         {
234             throw new JRRuntimeException("No filed reader for " + jrField.getName());
235         }
236         return reader.getFieldValue(currentReturnValue);
237     }
238
239     
240     protected String JavaDoc getFieldMapping(JRField field)
241     {
242         return (useFieldDescription ?
243                     JRAbstractBeanDataSource.FIELD_DESCRIPTION_PROPERTY_NAME_PROVIDER :
244                     JRAbstractBeanDataSource.FIELD_NAME_PROPERTY_NAME_PROVIDER)
245                 .getPropertyName(field);
246     }
247     
248     
249     /**
250      * Interface used to get the value of a report field from a result row.
251      */

252     protected static interface FieldReader
253     {
254         Object JavaDoc getFieldValue(Object JavaDoc resultValue) throws JRException;
255     }
256     
257     protected static class IdentityFieldReader implements FieldReader
258     {
259         public Object JavaDoc getFieldValue(Object JavaDoc resultValue)
260         {
261             return resultValue;
262         }
263     }
264     
265     protected static class IndexFieldReader implements FieldReader
266     {
267         private final int idx;
268
269         protected IndexFieldReader(int idx)
270         {
271             this.idx = idx;
272         }
273         
274         public Object JavaDoc getFieldValue(Object JavaDoc resultValue)
275         {
276             return ((Object JavaDoc[]) resultValue)[idx];
277         }
278     }
279     
280     protected static class PropertyFieldReader implements FieldReader
281     {
282         private final String JavaDoc property;
283
284         protected PropertyFieldReader(String JavaDoc property)
285         {
286             this.property = property;
287         }
288         
289         public Object JavaDoc getFieldValue(Object JavaDoc resultValue) throws JRException
290         {
291             return JRAbstractBeanDataSource.getBeanProperty(resultValue, property);
292         }
293     }
294     
295     protected static class IndexPropertyFieldReader implements FieldReader
296     {
297         private final int idx;
298         private final String JavaDoc property;
299
300         protected IndexPropertyFieldReader(int idx, String JavaDoc property)
301         {
302             this.idx = idx;
303             this.property = property;
304         }
305         
306         public Object JavaDoc getFieldValue(Object JavaDoc resultValue) throws JRException
307         {
308             return JRAbstractBeanDataSource.getBeanProperty(((Object JavaDoc[]) resultValue)[idx], property);
309         }
310     }
311 }
312
Popular Tags