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 }
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
108 Criteria criteria = session.createCriteria(searchCriteria.getClazz());
109
110
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
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
130 int numberOfCriterions = searchCriteria.getCriterias().size();
131
132 if (numberOfCriterions == 0) {
133 return criteria;
134 }
135
136
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
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 }
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
211
212
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
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 */