1 /*
2 * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3 * the spring framework, http://el4j.sf.net
4 * Copyright (C) 2009 by ELCA Informatique SA, Av. de la Harpe 22-24,
5 * 1000 Lausanne, Switzerland, http://www.elca.ch
6 *
7 * EL4J is published under the GNU Lesser General Public License (LGPL)
8 * Version 2.1. See http://www.gnu.org/licenses/
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * For alternative licensing, please contact info@elca.ch
16 */
17 package ch.elca.el4j.services.persistence.hibernate.criteria;
18
19 import java.lang.reflect.Field;
20 import java.util.List;
21
22 import org.apache.commons.lang.SerializationUtils;
23 import org.hibernate.Criteria;
24 import org.hibernate.criterion.Criterion;
25 import org.hibernate.criterion.DetachedCriteria;
26 import org.hibernate.criterion.Order;
27 import org.hibernate.impl.CriteriaImpl;
28 import org.hibernate.impl.CriteriaImpl.OrderEntry;
29
30 /**
31 * A utility class that allows to perform some modifications on {@link DetachedCriteria}s.
32 * <b>ATTENTION: This class depends on the actual Hibernate Criteria implementation ({@link CriteriaImpl})</b>
33 *
34 * @svnLink $Revision: 3916 $;$Date: 2009-09-15 12:19:53 +0200 (Di, 15. Sep 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/hibernate/src/main/java/ch/elca/el4j/services/persistence/hibernate/criteria/DetachedCriteriaUtils.java $
35 *
36 * @author Stefan Wismer (SWI)
37 */
38 public final class DetachedCriteriaUtils {
39
40 /**
41 * The hidden constructor.
42 */
43 private DetachedCriteriaUtils() { }
44
45 /**
46 * @param criteria the criteria to clone
47 * @return the cloned criteria
48 */
49 public static DetachedCriteria clone(DetachedCriteria criteria) {
50 return (DetachedCriteria) SerializationUtils.clone(criteria);
51 }
52
53 /**
54 * @param criteria the criteria to manipulate
55 * @param orders the orders to remove. If no orders are provided, all orders will be removed
56 * @return the criteria
57 */
58 @SuppressWarnings("unchecked")
59 public static DetachedCriteria removeOrders(DetachedCriteria criteria, Order... orders) {
60 List<OrderEntry> orderEntries = (List<OrderEntry>) getCriteriaField(criteria, "orderEntries");
61 orderEntries.clear();
62
63 return criteria;
64 }
65
66 /**
67 * @param criteria the criteria whose projection should be removed
68 * @return the "clean" criteria
69 */
70 public static DetachedCriteria removeProjection(DetachedCriteria criteria) {
71 criteria.setProjection(null);
72 criteria.setResultTransformer(Criteria.ROOT_ENTITY);
73 return criteria;
74 }
75
76 /**
77 * @param criteria the criteria whose projection should be removed
78 * @return the "clean" criteria
79 */
80 @SuppressWarnings("unchecked")
81 public static DetachedCriteria removeCriterionEntries(DetachedCriteria criteria) {
82 List<Criterion> criterionEntries = (List<Criterion>) getCriteriaField(criteria, "criterionEntries");
83 criterionEntries.clear();
84
85 return criteria;
86 }
87
88 /**
89 * @param criteria the criteria whose criterion entries to get
90 * @return a list of criterion entries
91 */
92 @SuppressWarnings("unchecked")
93 public static List<Criterion> getCriterionEntries(DetachedCriteria criteria) {
94 return (List<Criterion>) getCriteriaField(criteria, "criterionEntries");
95 }
96
97 /**
98 * Get the field value of the Criteria.
99 *
100 * @param criteria the criteria to get the field
101 * @param fieldName the field name
102 * @return the value stored in that field
103 */
104 private static Object getCriteriaField(DetachedCriteria criteria, String fieldName) {
105 try {
106 Field implField = DetachedCriteria.class.getDeclaredField("impl");
107 implField.setAccessible(true);
108 CriteriaImpl impl = (CriteriaImpl) implField.get(criteria);
109
110 Field orderField = CriteriaImpl.class.getDeclaredField(fieldName);
111 orderField.setAccessible(true);
112
113 return orderField.get(impl);
114 } catch (Exception e) {
115 throw new IllegalStateException("Implementation of DetachedCriteria or CriteriaImpl has changed!");
116 }
117 }
118 }