KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > query > JRHibernateQueryExecuter


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.query;
29
30 import java.util.Collection JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.Set JavaDoc;
37
38 import net.sf.jasperreports.engine.JRDataSource;
39 import net.sf.jasperreports.engine.JRDataset;
40 import net.sf.jasperreports.engine.JRException;
41 import net.sf.jasperreports.engine.JRParameter;
42 import net.sf.jasperreports.engine.JRPropertiesMap;
43 import net.sf.jasperreports.engine.JRRuntimeException;
44 import net.sf.jasperreports.engine.JRValueParameter;
45 import net.sf.jasperreports.engine.data.JRHibernateIterateDataSource;
46 import net.sf.jasperreports.engine.data.JRHibernateListDataSource;
47 import net.sf.jasperreports.engine.data.JRHibernateScrollDataSource;
48 import net.sf.jasperreports.engine.util.JRProperties;
49 import net.sf.jasperreports.engine.util.JRStringUtil;
50
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53 import org.hibernate.Hibernate;
54 import org.hibernate.Query;
55 import org.hibernate.ScrollMode;
56 import org.hibernate.ScrollableResults;
57 import org.hibernate.Session;
58 import org.hibernate.type.Type;
59
60 /**
61  * HQL query executer that uses Hibernate 3.
62  *
63  * @author Lucian Chirita (lucianc@users.sourceforge.net)
64  * @version $Id: JRHibernateQueryExecuter.java 1472 2006-11-09 19:16:52 +0200 (Thu, 09 Nov 2006) lucianc $
65  */

66 public class JRHibernateQueryExecuter extends JRAbstractQueryExecuter
67 {
68     private static final Log log = LogFactory.getLog(JRHibernateQueryExecuter.class);
69     
70     private static final Map JavaDoc hibernateTypeMap;
71     
72     static
73     {
74         hibernateTypeMap = new HashMap JavaDoc();
75         hibernateTypeMap.put(Boolean JavaDoc.class, Hibernate.BOOLEAN);
76         hibernateTypeMap.put(Byte JavaDoc.class, Hibernate.BYTE);
77         hibernateTypeMap.put(Double JavaDoc.class, Hibernate.DOUBLE);
78         hibernateTypeMap.put(Float JavaDoc.class, Hibernate.FLOAT);
79         hibernateTypeMap.put(Integer JavaDoc.class, Hibernate.INTEGER);
80         hibernateTypeMap.put(Long JavaDoc.class, Hibernate.LONG);
81         hibernateTypeMap.put(Short JavaDoc.class, Hibernate.SHORT);
82         hibernateTypeMap.put(java.math.BigDecimal JavaDoc.class, Hibernate.BIG_DECIMAL);
83         hibernateTypeMap.put(java.math.BigInteger JavaDoc.class, Hibernate.BIG_INTEGER);
84         hibernateTypeMap.put(Character JavaDoc.class, Hibernate.CHARACTER);
85         hibernateTypeMap.put(String JavaDoc.class, Hibernate.STRING);
86         hibernateTypeMap.put(java.util.Date JavaDoc.class, Hibernate.DATE);
87         hibernateTypeMap.put(java.sql.Timestamp JavaDoc.class, Hibernate.TIMESTAMP);
88         hibernateTypeMap.put(java.sql.Time JavaDoc.class, Hibernate.TIME);
89     }
90
91     private final Integer JavaDoc reportMaxCount;
92     
93     private Session session;
94     private Query query;
95     private boolean queryRunning;
96     private ScrollableResults scrollableResults;
97
98     
99     public JRHibernateQueryExecuter(JRDataset dataset, Map JavaDoc parameters)
100     {
101         super(dataset, parameters);
102         
103         session = (Session) getParameterValue(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_SESSION);
104         reportMaxCount = (Integer JavaDoc) getParameterValue(JRParameter.REPORT_MAX_COUNT);
105
106         if (session == null)
107         {
108             log.warn("The supplied org.hibernate.Session object is null.");
109         }
110         
111         parseQuery();
112     }
113     
114     
115     /**
116      * Creates an instance of {@link JRHibernateListDataSource JRHibernateListDataSource},
117      * {@link JRHibernateIterateDataSource JRHibernateIterateDataSource} or
118      * {@link JRHibernateScrollDataSource JRHibernateScrollDataSource}, depending on the
119      */

120     public JRDataSource createDatasource() throws JRException
121     {
122         JRDataSource datasource = null;
123         String JavaDoc queryString = getQueryString();
124         
125         if (session != null && queryString != null && queryString.trim().length() > 0)
126         {
127             createQuery(queryString);
128
129             datasource = createResultDatasource();
130         }
131
132         return datasource;
133     }
134
135     /**
136      * Creates a data source out of the query result.
137      *
138      * @return the data source
139      */

140     protected JRDataSource createResultDatasource()
141     {
142         JRDataSource resDatasource;
143         
144         JRPropertiesMap datasetProperties = dataset.getPropertiesMap();
145         
146         String JavaDoc runType = JRProperties.getProperty(datasetProperties,
147                 JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_RUN_TYPE);
148         boolean useFieldDescriptions = JRProperties.getBooleanProperty(datasetProperties,
149                 JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_FIELD_MAPPING_DESCRIPTIONS,
150                 true);
151         
152         if (runType == null || runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_LIST))
153         {
154             try
155             {
156                 int pageSize = JRProperties.getIntegerProperty(datasetProperties,
157                         JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_LIST_PAGE_SIZE,
158                         0);
159
160                 resDatasource = new JRHibernateListDataSource(this, useFieldDescriptions, pageSize);
161             }
162             catch (NumberFormatException JavaDoc e)
163             {
164                 throw new JRRuntimeException("The " + JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_LIST_PAGE_SIZE +
165                         " property must be numerical.");
166             }
167         }
168         else if (runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_ITERATE))
169         {
170             resDatasource = new JRHibernateIterateDataSource(this, useFieldDescriptions);
171         }
172         else if (runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_SCROLL))
173         {
174             resDatasource = new JRHibernateScrollDataSource(this, useFieldDescriptions);
175         }
176         else
177         {
178             throw new JRRuntimeException("Unknown value for the " + JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_RUN_TYPE +
179                     " property. Possible values are " + JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_LIST + ", " +
180                     JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_ITERATE + " and " +
181                     JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_SCROLL + ".");
182         }
183         
184         return resDatasource;
185     }
186
187     
188     /**
189      * Creates the Hibernate query object.
190      * <p/>
191      * If the value of the {@link JRHibernateQueryExecuterFactory#PARAMETER_HIBERNATE_FILTER_COLLECTION PARAMETER_HIBERNATE_FILTER_COLLECTION}
192      * is not null, then a filter query is created using the value of the paramter as the collection.
193      *
194      * @param queryString the query string
195      */

196     protected synchronized void createQuery(String JavaDoc queryString)
197     {
198         if (log.isDebugEnabled())
199         {
200             log.debug("HQL query: " + queryString);
201         }
202         
203         Object JavaDoc filterCollection = getParameterValue(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_FILTER_COLLECTION);
204         if (filterCollection == null)
205         {
206             query = session.createQuery(queryString);
207         }
208         else
209         {
210             query = session.createFilter(filterCollection, queryString);
211         }
212         query.setReadOnly(true);
213         
214         int fetchSize = JRProperties.getIntegerProperty(dataset.getPropertiesMap(),
215                 JRJdbcQueryExecuterFactory.PROPERTY_JDBC_FETCH_SIZE,
216                 0);
217         if (fetchSize > 0)
218         {
219             query.setFetchSize(fetchSize);
220         }
221         
222         setParameters();
223     }
224
225     /**
226      * Binds values for all the query paramters.
227      */

228     protected void setParameters()
229     {
230         List JavaDoc parameterNames = getCollectedParameterNames();
231         
232         if (!parameterNames.isEmpty())
233         {
234             Set JavaDoc namesSet = new HashSet JavaDoc();
235             
236             for (Iterator JavaDoc iter = parameterNames.iterator(); iter.hasNext();)
237             {
238                 String JavaDoc parameterName = (String JavaDoc) iter.next();
239                 if (namesSet.add(parameterName))
240                 {
241                     JRValueParameter parameter = getValueParameter(parameterName);
242                     setParameter(parameter);
243                 }
244             }
245         }
246     }
247     
248     
249     /**
250      * Binds a paramter value to a query paramter.
251      *
252      * @param parameter the report parameter
253      */

254     protected void setParameter(JRValueParameter parameter)
255     {
256         String JavaDoc hqlParamName = getHqlParameterName(parameter.getName());
257         Class JavaDoc clazz = parameter.getValueClass();
258         Object JavaDoc parameterValue = parameter.getValue();
259         
260         if (log.isDebugEnabled())
261         {
262             log.debug("Parameter " + hqlParamName + " of type " + clazz.getName() + ": " + parameterValue);
263         }
264         
265         Type type = (Type) hibernateTypeMap.get(clazz);
266         
267         if (type != null)
268         {
269             query.setParameter(hqlParamName, parameterValue, type);
270         }
271         else if (Collection JavaDoc.class.isAssignableFrom(clazz))
272         {
273             query.setParameterList(hqlParamName, (Collection JavaDoc) parameterValue);
274         }
275         else
276         {
277             if (session.getSessionFactory().getClassMetadata(clazz) != null) //param type is a hibernate mapped entity
278
{
279                 query.setEntity(hqlParamName, parameterValue);
280             }
281             else //let hibernate try to guess the type
282
{
283                 query.setParameter(hqlParamName, parameterValue);
284             }
285         }
286     }
287
288     
289     /**
290      * Closes the scrollable result when <em>scroll</em> execution type is used.
291      */

292     public synchronized void close()
293     {
294         closeScrollableResults();
295
296         query = null;
297     }
298
299
300     /**
301      * Closes the scrollable results of the query.
302      */

303     public void closeScrollableResults()
304     {
305         if (scrollableResults != null)
306         {
307             try
308             {
309                 scrollableResults.close();
310             }
311             finally
312             {
313                 scrollableResults = null;
314             }
315         }
316     }
317
318     
319     public synchronized boolean cancelQuery() throws JRException
320     {
321         if (queryRunning)
322         {
323             session.cancelQuery();
324             return true;
325         }
326         
327         return false;
328     }
329
330     protected String JavaDoc getParameterReplacement(String JavaDoc parameterName)
331     {
332         return ':' + getHqlParameterName(parameterName);
333     }
334
335     protected String JavaDoc getHqlParameterName(String JavaDoc parameterName)
336     {
337         return '_' + JRStringUtil.getLiteral(parameterName);
338     }
339     
340     
341     /**
342      * Returns the return types of the HQL query.
343      *
344      * @return the return types of the HQL query
345      */

346     public Type[] getReturnTypes()
347     {
348         return query.getReturnTypes();
349     }
350     
351     
352     /**
353      * Returns the aliases of the HQL query.
354      *
355      * @return the aliases of the HQL query
356      */

357     public String JavaDoc[] getReturnAliases()
358     {
359         return query.getReturnAliases();
360     }
361     
362     
363     /**
364      * Returns the dataset for which the query executer has been created.
365      *
366      * @return the dataset for which the query executer has been created
367      */

368     public JRDataset getDataset()
369     {
370         return dataset;
371     }
372     
373     
374     /**
375      * Runs the query by calling <code>org.hibernate.Query.list()</code>.
376      * <p/>
377      * All the result rows are returned.
378      *
379      * @return the result of the query as a list
380      */

381     public List JavaDoc list()
382     {
383         setMaxCount();
384         
385         setQueryRunning(true);
386         try
387         {
388             return query.list();
389         }
390         finally
391         {
392             setQueryRunning(false);
393         }
394     }
395
396     protected synchronized void setQueryRunning(boolean queryRunning)
397     {
398         this.queryRunning = queryRunning;
399     }
400
401     
402     private void setMaxCount()
403     {
404         if (reportMaxCount != null)
405         {
406             query.setMaxResults(reportMaxCount.intValue());
407         }
408     }
409     
410     
411     /**
412      * Returns a page of the query results by calling <code>org.hibernate.Query.iterate()</code>.
413      *
414      * @param firstIndex the index of the first row to return
415      * @param resultCount the number of rows to return
416      * @return result row list
417      */

418     public List JavaDoc list(int firstIndex, int resultCount)
419     {
420         if (reportMaxCount != null && firstIndex + resultCount > reportMaxCount.intValue())
421         {
422             resultCount = reportMaxCount.intValue() - firstIndex;
423         }
424         
425         query.setFirstResult(firstIndex);
426         query.setMaxResults(resultCount);
427         return query.list();
428     }
429     
430     
431     /**
432      * Runs the query by calling <code>org.hibernate.Query.iterate()</code>.
433      *
434      * @return query iterator
435      */

436     public Iterator JavaDoc iterate()
437     {
438         setMaxCount();
439         
440         setQueryRunning(true);
441         try
442         {
443             return query.iterate();
444         }
445         finally
446         {
447             setQueryRunning(false);
448         }
449     }
450     
451     
452     /**
453      * Runs the query by calling <code>org.hibernate.Query.scroll()</code>.
454      *
455      * @return scrollable results of the query
456      */

457     public ScrollableResults scroll()
458     {
459         setMaxCount();
460         
461         setQueryRunning(true);
462         try
463         {
464             scrollableResults = query.scroll(ScrollMode.FORWARD_ONLY);
465         }
466         finally
467         {
468             setQueryRunning(false);
469         }
470         
471         return scrollableResults;
472     }
473 }
474
Popular Tags