View Javadoc

1   /***
2    Copyright (C) 2005 The Java Community
3   
4    This program is free software; you can redistribute it and/or modify  it under
5    the terms of the GNU General Public License as published by  the Free Software
6    Foundation; either version 2 of the License, or  (at your option) any later
7    version.
8   
9    This program is distributed in the hope that it will be useful,  but WITHOUT
10   ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS
11   FOR A PARTICULAR PURPOSE. See the  GNU General Public License for more details.
12  
13   You should have received a copy of the GNU General Public License  along with
14   this program; if not, write to the Free Software  Foundation, Inc., 59 Temple
15   Place, Suite 330, Boston, MA 02111-1307 USA.
16  
17   */
18  package org.bejug.javacareers.jobs.dao.hibernate.common;
19  
20  import org.bejug.javacareers.common.search.Criterium;
21  import org.bejug.javacareers.common.search.Order;
22  import org.bejug.javacareers.common.search.SearchCriteria;
23  import org.bejug.javacareers.common.search.SearchCriteriaService;
24  import org.hibernate.Criteria;
25  import org.hibernate.HibernateException;
26  import org.hibernate.Session;
27  import org.hibernate.criterion.Criterion;
28  import org.hibernate.criterion.Restrictions;
29  import org.springframework.orm.hibernate3.HibernateCallback;
30  import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
31  
32  import java.util.List;
33  import java.util.ListIterator;
34  
35  /***
36   * Implementation of the searchCriteriaService for Hibernate.
37   *
38   * @author Bart Meyers (last modified by $Author: shally $)
39   * @version $Revision: 1.4 $ $Date: 2005/12/20 15:36:46 $
40   */
41  public class SearchCriteriaServiceHibernateImpl
42          extends HibernateDaoSupport
43          implements SearchCriteriaService {
44  
45      /***
46       * {@inheritDoc}
47       */
48      public List executeQuery(SearchCriteria searchCriteria) {
49          return executeHibernateTemplate(searchCriteria);
50      }
51      
52      /***
53       * {@inheritDoc}
54       */
55      public int executeCountQuery(SearchCriteria searchCriteria) {
56          return executeHibernateTemplate(searchCriteria).size();
57      }
58      
59      /***
60       * {@inheritDoc}
61       */
62      public Object executeUniqueQuery(SearchCriteria searchCriteria) {
63      	return executeUniqueHibernateTemplate(searchCriteria);
64      }
65  
66      
67      /***
68       * calculates the first result of the query.
69       * @param searchCriteria the searchCriteria-object.
70       * @return int the index of the first result.
71       */
72      private int calculateFirstResult(SearchCriteria searchCriteria) {
73      	
74      	if (searchCriteria.getResultsPerPage() != -1 
75      			&& searchCriteria.getPageNumber() != -1) {
76      		if (searchCriteria.getPageNumber() == 1) {
77      			return 0;
78      		}
79  			return searchCriteria.getResultsPerPage() * 
80  				(searchCriteria.getPageNumber() - 1);
81      	}   	
82      	return -1;
83      } // calculateFirstResult
84      
85      
86      /***
87       * conveniant method to convert a SearchCriteria-Order to a hibernate-Order.
88       * @param order the searchCriteria-Order to convert.
89       * @return a hibernate-Order.
90       */
91      private org.hibernate.criterion.Order convertToHibernateOrder(Order order) {
92      	if (Order.ASC.equals(order.getOrdering())) {
93      		return org.hibernate.criterion.Order.asc(order.getField());
94      	}
95      	return org.hibernate.criterion.Order.desc(order.getField());
96      }
97      
98      /***
99       * 
100      * @param session is the session
101      * @param searchCriteria are the searchCriteria
102      * @return the criteria
103      */
104     Criteria buildHibernateCriteria(Session session,
105                                             SearchCriteria searchCriteria) {
106     	
107     	//get a Criteria-object
108         Criteria criteria = session.createCriteria(searchCriteria.getClazz());
109         
110 //      add some ordering
111         if (searchCriteria.getOrders().size() != 0) {
112         	Order currentOrder = null;
113         	for (ListIterator lit = searchCriteria.getOrders().listIterator();
114         		lit.hasNext(); ) {
115         		currentOrder = (Order) lit.next();
116         		criteria.addOrder(convertToHibernateOrder(currentOrder));
117         	}
118         }
119         
120         //set the maximum number of results
121         if (searchCriteria.getResultsPerPage() != -1) {
122         	criteria.setMaxResults(searchCriteria.getResultsPerPage());
123         	int firstResult = calculateFirstResult(searchCriteria);
124         	if (firstResult != -1) {
125         		criteria.setFirstResult(firstResult);
126         	}
127         }
128            
129         //get the number of criterions to create
130        int numberOfCriterions = searchCriteria.getCriterias().size();
131         //return if numberOfCriterions is 0
132         if (numberOfCriterions == 0) {
133            return criteria;
134         }
135 
136         //build up an array of criterions
137         Criterion[] criterions =
138                 new Criterion[searchCriteria.getCriterias().size()];
139         Criterium currentCriterium = null;
140         for (int i = 0; i < numberOfCriterions; i++) {
141             currentCriterium = (Criterium) searchCriteria.getCriterias().get(i);
142             insertAlias(criteria, currentCriterium, i);
143             criterions[i] = createCriterion(
144                     (Criterium) searchCriteria.getCriterias().get(i));
145         }
146 
147         Criterion criterion1 = criterions[0];
148         Criterion criterion2 = null; 
149         //make some junctions and disjunctions
150         for (int i = 1; i < numberOfCriterions; i++) {
151             criterion2 = criterions[i];
152             criterion1 = createLogicalOperation(criterion1, criterion2,
153                     (Criterium) searchCriteria.getCriterias().get(i));
154         }
155         criteria.add(criterion1);              
156         
157         
158         
159         return criteria;
160     } //buildHibernateCriteria
161 
162 
163     /***
164      * creates a logical operation between two criterions.
165      *
166      * @param crit1     the first criterion.
167      * @param crit2     the second criterion.
168      * @param criterium the second criterium containing the or or and clause.
169      * @return the resulting Criterion.
170      */
171     private Criterion createLogicalOperation(Criterion crit1,
172                                              Criterion crit2,
173                                              Criterium criterium) {
174         if (criterium.isAnd()) {
175             return Restrictions.and(crit1, crit2);
176         }
177 
178         return Restrictions.or(crit1, crit2);
179     }
180 
181     /***
182      * this method is responsible to insert an alias in the hibernatecriteria.
183      * Supports the use of the dot-notation for retrieving data.
184      * @param criteria the hibernate-criteria object.
185      * @param criterium the criterium to create the alias for.
186      * @param i the number of the criterium in the criterium-list.
187      */
188     private void insertAlias(Criteria criteria, Criterium criterium, int i) {
189         String aliasName = null;
190         String aliasValue = null;
191         int index = criterium.getName().lastIndexOf(".");
192         if (index != -1) {
193             aliasValue = criterium.getName().substring(0, index);
194             aliasName = criterium.getName().substring(index+1);
195             criteria.createAlias(aliasValue, "" + i);
196             criterium.setName(i + "." + aliasName);
197         }              
198     }
199     
200     /***
201      * @param currentCriterium Criterium
202      * @return Criterion
203      */
204     private Criterion createCriterion(Criterium currentCriterium) {
205       
206         if (currentCriterium.isEquals()) {
207             return Restrictions.eq(currentCriterium.getName(),
208                     currentCriterium.getValue1());
209         }
210         /*if (currentCriterium.isNot()) {
211             return Restrictions.(currentCriterium.getName(), 
212                     currentCriterium.getValue1());
213         }*/
214         if (currentCriterium.isLike()) {
215             return Restrictions.like(currentCriterium.getName(),
216                     currentCriterium.getValue1());
217         }
218         if (currentCriterium.isGreaterThan()) {
219             return Restrictions.gt(currentCriterium.getName(),
220                                    currentCriterium.getValue1());
221         }
222         if (currentCriterium.isGreaterThanEquals()) {
223             return Restrictions.ge(currentCriterium.getName(),
224                                    currentCriterium.getValue1());
225         }
226         if (currentCriterium.isLowerThan()) {
227             return Restrictions.lt(currentCriterium.getName(),
228                                    currentCriterium.getValue1());
229         }
230         if (currentCriterium.isLowerThanEquals()) {
231             return Restrictions.le(currentCriterium.getName(),
232                                    currentCriterium.getValue1());
233         }
234         if (currentCriterium.isBetween()) {
235             return Restrictions.between(currentCriterium.getName(),
236                     currentCriterium.getValue1(), currentCriterium.getValue2());
237         }
238         if (currentCriterium.isIn()) {
239             return Restrictions.in(currentCriterium.getName(), 
240                     currentCriterium.getValues());
241         }
242         
243         
244         //we have to return something
245         return null;
246     }
247 
248    
249     
250     /***
251      * spring-alike manner to execute the hibernatetemplate.
252      *
253      * @param searchCriteria the searchCriteria to use to perform the query.
254      * @return a List with the wanted results.
255      */
256     private List executeHibernateTemplate(final SearchCriteria searchCriteria) {
257         return getHibernateTemplate().executeFind(new HibernateCallback() {
258             public Object doInHibernate(Session session)
259                     throws HibernateException {
260 
261                 return buildHibernateCriteria(session, searchCriteria).list();
262             }
263         });
264     }
265     
266     
267     /***
268      * gives only one result back.
269      * spring-alike manner to execute the hibernatetemplate.
270      *
271      * @param searchCriteria the searchCriteria to use to perform the query.
272      * @return a List with the wanted results.
273      */
274     private Object executeUniqueHibernateTemplate(final SearchCriteria searchCriteria) {
275         return getHibernateTemplate().executeFind(new HibernateCallback() {
276             public Object doInHibernate(Session session)
277                     throws HibernateException {
278 
279                 return buildHibernateCriteria(session, searchCriteria).uniqueResult();
280             }
281         });
282     }
283     
284 }
285 /***
286  * $Log: SearchCriteriaServiceHibernateImpl.java,v $
287  * Revision 1.4  2005/12/20 15:36:46  shally
288  * CheckStyle and PMD changes.
289  *
290  * Revision 1.3  2005/12/09 10:46:55  shally
291  * Opkuis voor checkstyle en PMD
292  *
293  * Revision 1.2  2005/10/11 08:36:48  stephan_janssen
294  * Added copyright.
295  *
296  * Revision 1.1  2005/08/26 07:58:30  ge0ffrey
297  * split up the sources in service, serviceimpl and webclient
298  *
299  * Revision 1.5  2005/08/11 13:04:30  bme_jcs
300  * update searchCriteria to support ordering and paging
301  *
302  * Revision 1.4  2005/08/10 09:04:48  bavo_jcs
303  * Optimized imports according to checkstyle
304  *
305  * Revision 1.3  2005/08/09 12:59:55  bavo_jcs
306  * Optimized imports
307  *
308  * Revision 1.2  2005/06/09 08:18:43  bejug_cc
309  * Fix initial import
310  *
311  * Revision 1.8  2005/05/31 14:09:21  bme
312  * introducing aliasses for use of the dotnotation
313  *
314  * Revision 1.7  2005/05/31 07:35:51  bme
315  * introduced count-functionality
316  *
317  * Revision 1.6  2005/05/26 18:55:18  bme
318  * undo changes
319  *
320  * Revision 1.4  2005/05/17 14:22:17  ssc
321  * checkstyle
322  *
323  * Revision 1.3  2005/05/13 14:07:43  sja
324  * reformated to respect 80 chars rule  ;)
325  *
326  * Revision 1.2  2005/05/13 10:29:34  bme
327  * added functionality
328  *
329  * Revision 1.1  2005/05/13 05:54:52  bme
330  * First draft
331  *
332  */