View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2006 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  
20  import java.util.Iterator;
21  import java.util.List;
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.hibernate.criterion.Criterion;
26  import org.hibernate.criterion.DetachedCriteria;
27  import org.hibernate.criterion.Junction;
28  import org.hibernate.criterion.Restrictions;
29  
30  import ch.elca.el4j.services.search.QueryObject;
31  import ch.elca.el4j.services.search.criterias.AbstractCriteria;
32  import ch.elca.el4j.services.search.criterias.AndCriteria;
33  import ch.elca.el4j.services.search.criterias.ComparisonCriteria;
34  import ch.elca.el4j.services.search.criterias.Criteria;
35  import ch.elca.el4j.services.search.criterias.LikeCriteria;
36  import ch.elca.el4j.services.search.criterias.NotCriteria;
37  import ch.elca.el4j.services.search.criterias.OrCriteria;
38  import ch.elca.el4j.services.search.criterias.Order;
39  
40  /**
41   *
42   * This class transforms the EL4J Criteria of a given <code>QueryObject</code>
43   * into the corresponding Hibernate DetachedCriteria.
44   *
45   * @svnLink $Revision: 3874 $;$Date: 2009-08-04 14:25:40 +0200 (Di, 04. Aug 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/CriteriaTransformer.java $
46   *
47   * @author Alex Mathey (AMA)
48   * @author Philipp Oser (POS)
49   */
50  public class CriteriaTransformer {
51  
52  	private static Logger s_logger = LoggerFactory.getLogger(CriteriaTransformer.class);
53  	
54  	/**
55  	 * Hide default constructor.
56  	 */
57  	protected CriteriaTransformer() { };
58  	
59  	/**
60  	 * Transforms EL4J Criteria of the given <code>QueryObject</code> into the
61  	 * corresponding Hibernate DetachedCriteria.
62  	 *
63  	 * @param query
64  	 *            the query object whose criteria will be transformed
65  	 * @param domainObjectClass
66  	 *            the class of the domain object for which the Hibernate
67  	 *            criteria will be generated
68  	 * @return the Hibernate criteria corresponding to the
69  	 *         <code>QueryObject</code>'s EL4J criteria.
70  	 */
71  	public static DetachedCriteria transform(QueryObject query,
72  		Class<?> domainObjectClass) {
73  		
74  		// Hibernate criteria for the domain object.
75  		DetachedCriteria hibernateCriteria
76  			= DetachedCriteria.forClass(domainObjectClass);
77  		
78  		// List of EL4J criteria.
79  		List<Criteria> el4jCriteriaList = query.getCriteriaList();
80  		
81  		// Conversion from EL4J criteria to Hibernate criteria.
82  		Iterator<Criteria> it = el4jCriteriaList.iterator();
83  		
84  		while (it.hasNext()) {
85  			Criteria currentEl4jCriteria = (Criteria) it.next();
86  			
87  			Criterion hibernateCriterion =
88  				el4jCriteria2HibernateCriterion(currentEl4jCriteria);
89  			if (hibernateCriterion != null) {
90  				hibernateCriteria.add(hibernateCriterion);
91  			}
92  		}
93  		
94  		addOrderConstraints(hibernateCriteria, query);
95  		
96  		return hibernateCriteria;
97  	}
98  
99  	protected static void addOrderConstraints (DetachedCriteria hibernateCriteria,
100 		QueryObject query) {
101 		
102 		List<Order> orderConstraints = query.getOrderConstraints();
103 		for (Order o : orderConstraints){
104 			if (o.isAscending()) {
105 				hibernateCriteria.addOrder(org.hibernate.criterion.Order.asc(o.getPropertyName()));
106 			} else {
107 				hibernateCriteria.addOrder(org.hibernate.criterion.Order.desc(o.getPropertyName()));
108 			}
109 		}
110 		
111 	}
112 	
113 	
114 	/**
115 	 * Converts EL4J Criteria to Hibernate Criterion.
116 	 * @param criteria
117 	 * @return the converted Criterion
118 	 */
119 	protected static Criterion el4jCriteria2HibernateCriterion(Criteria criteria) {
120 		Criterion criterion = null;
121 		
122 		if (criteria instanceof OrCriteria) {
123 			Junction combination = Restrictions.disjunction();
124 			
125 			addCriteriaListToJunction(((OrCriteria) criteria).getCriterias(), combination);
126 			criterion = combination;
127 		} else if (criteria instanceof AndCriteria) {
128 			Junction combination = Restrictions.conjunction();
129 			
130 			addCriteriaListToJunction(((AndCriteria) criteria).getCriterias(), combination);
131 			criterion = combination;
132 		} else if (criteria instanceof NotCriteria) {
133 			Criteria innerCriteria = ((NotCriteria) criteria).getCriteria();
134 			criterion = Restrictions.not(el4jCriteria2HibernateCriterion(innerCriteria));
135 		} else if (criteria instanceof AbstractCriteria) {
136 			AbstractCriteria abstractCrit = (AbstractCriteria) criteria;
137 			
138 			String currentCriteriaField = abstractCrit.getField();
139 			Object currentCriteriaValue = abstractCrit.getValue();
140 
141 			if (criteria instanceof LikeCriteria) {
142 				LikeCriteria currentEl4jLikeCriteria = (LikeCriteria) criteria;
143 				if (currentEl4jLikeCriteria.isCaseSensitive().booleanValue()) {
144 					criterion = Restrictions.like(currentCriteriaField,
145 						currentCriteriaValue);
146 				} else {
147 					criterion = Restrictions.like(currentCriteriaField,
148 						currentCriteriaValue).ignoreCase();
149 				}
150 			} else if (criteria instanceof ComparisonCriteria) {
151 				String operator = ((ComparisonCriteria) criteria).getOperator();
152 				if (operator.equals("=")) {
153 					criterion = Restrictions.eq(currentCriteriaField,
154 										currentCriteriaValue);
155 				} else if (operator.equals("<")) {
156 					criterion = Restrictions.lt(currentCriteriaField,
157 						currentCriteriaValue);
158 				} else if (operator.equals("<=")) {
159 					criterion = Restrictions.le(currentCriteriaField,
160 						currentCriteriaValue);
161 				} else if (operator.equals(">")) {
162 					criterion = Restrictions.gt(currentCriteriaField,
163 						currentCriteriaValue);
164 				} else if (operator.equals(">=")) {
165 					criterion = Restrictions.ge(currentCriteriaField,
166 						currentCriteriaValue);
167 				} else if (operator.equals("!=")) {
168 					criterion = Restrictions.ne(currentCriteriaField,
169 						currentCriteriaValue);
170 				} else {
171 					s_logger.info(" Operator not handled " + operator);
172 				}
173 				
174 			} else {
175 				s_logger.info(" Criteria not handled " + criteria);
176 			}
177 		} else {
178 			s_logger.info(" Criteria not handled " + criteria);
179 		}
180 		return criterion;
181 	}
182 
183 	/**
184 	 * @param currentEl4jCriteria
185 	 * @param combination
186 	 */
187 	protected static void addCriteriaListToJunction(
188 		List<Criteria> criterias, Junction combination) {
189 		for (Criterion c : apply2HibernateCriterion(criterias)) {
190 			combination.add(c);
191 		}
192 	}
193 	
194 	/**
195 	 * Apply operator (from functional programming)
196 	 * @param criterias must not be null
197 	 * @return
198 	 */
199 	protected static Criterion[] apply2HibernateCriterion(List<Criteria> criterias ){
200 		Criterion[] result = new Criterion[criterias.size()];
201 		
202 		for (int i = 0; i < criterias.size(); i++) {
203 			result[i] = el4jCriteria2HibernateCriterion(criterias.get(i));
204 		}
205 		return result;
206 	}
207 	
208 }