View Javadoc
1   /*
2    * Copyright 2010 James Pether Sörling
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   *	$Id$
17   *  $HeadURL$
18   */
19  package com.hack23.cia.service.data.impl;
20  
21  import java.util.List;
22  import java.util.Locale;
23  
24  import javax.annotation.PostConstruct;
25  import javax.persistence.EntityManager;
26  import javax.persistence.PersistenceContext;
27  import javax.persistence.TypedQuery;
28  import javax.persistence.criteria.CriteriaBuilder;
29  import javax.persistence.criteria.CriteriaQuery;
30  import javax.persistence.criteria.Expression;
31  import javax.persistence.criteria.Join;
32  import javax.persistence.criteria.Path;
33  import javax.persistence.criteria.Predicate;
34  import javax.persistence.criteria.Root;
35  import javax.persistence.metamodel.SingularAttribute;
36  
37  import org.hibernate.CacheMode;
38  import org.springframework.stereotype.Repository;
39  
40  import com.hack23.cia.service.data.api.DataViewer;
41  import com.hack23.cia.service.data.impl.util.LoadHelper;
42  
43  /**
44   * The Class DataViewerImpl.
45   */
46  
47  @Repository("DataViewer")
48  final class DataViewerImpl implements DataViewer {
49  
50  	/** The entity manager. */
51  	@PersistenceContext(name = "ciaPersistenceUnit")
52  	private EntityManager entityManager;
53  
54  	/** The criteria builder. */
55  	private CriteriaBuilder criteriaBuilder;
56  
57  	/**
58  	 * Instantiates a new data viewer impl.
59  	 */
60  	public DataViewerImpl() {
61  		super();
62  	}
63  
64  	/**
65  	 * Adds the cache hints.
66  	 *
67  	 * @param typedQuery
68  	 *            the typed query
69  	 * @param comment
70  	 *            the comment
71  	 */
72  	private static void addCacheHints(final TypedQuery<?> typedQuery, final String comment) {
73  		typedQuery.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
74  		typedQuery.setHint("org.hibernate.cacheable", Boolean.TRUE);
75  		typedQuery.setHint("org.hibernate.comment", comment);
76  	}
77  
78  	@Override
79  	public <T,V> T findByQueryProperty(final Class<T> clazz,
80  			final SingularAttribute<T, ? extends Object> property,final Class<V> clazz2,
81  			final SingularAttribute<V, ? extends Object> property2, final Object value) {
82  
83  		final CriteriaQuery<V> criteriaQuery = criteriaBuilder
84  				.createQuery(clazz2);
85  		final Root<V> root = criteriaQuery.from(clazz2);
86  		criteriaQuery.select(root);
87  
88  		if (value instanceof String) {
89  			final Expression<String> propertyObject = (Expression<String>) root.get(property2);
90  			final Predicate condition = criteriaBuilder.equal(criteriaBuilder.upper(propertyObject), ((String) value).toUpperCase(Locale.ENGLISH));
91  			criteriaQuery.where(condition);
92  		} else {
93  			final Predicate condition = criteriaBuilder.equal(root.get(property2), value);
94  			criteriaQuery.where(condition);
95  		}
96  
97  		final TypedQuery<V> typedQuery = entityManager
98  				.createQuery(criteriaQuery);
99  
100 		addCacheHints(typedQuery, "findByQueryProperty." + clazz.getSimpleName());
101 
102 
103 		final List<V> resultList = typedQuery.getResultList();
104 
105 		if (!resultList.isEmpty()) {
106 			final List<T> findListByProperty = findListByProperty(clazz,property,resultList.get(0));
107 			if (!findListByProperty.isEmpty()) {
108 				return LoadHelper.recursiveInitialize(findListByProperty.get(0));
109 			}
110 		}
111 
112 		return null;
113 
114 	}
115 
116 	@Override
117 	public <T> T findFirstByProperty(final Class<T> clazz,
118 			final SingularAttribute<T, ? extends Object> property, final Object value) {
119 		final List<T> resultList = findListByProperty(clazz,property,value);
120 
121 		if (resultList.isEmpty()) {
122 			return null;
123 		} else {
124 			return LoadHelper.recursiveInitialize(resultList.get(0));
125 		}
126 	}
127 
128 
129 	@Override
130 	public <T, V> List<T> findListByEmbeddedProperty(final Class<T> clazz,
131 			final SingularAttribute<T, V> property, final Class<V> clazz2,
132 			final SingularAttribute<V, ? extends Object> property2, final Object value) {
133 		return findOrderedListByEmbeddedProperty(clazz,property,clazz2,property2,value,null);
134 
135 	}
136 
137 	@Override
138 	public <T> List<T> findListByProperty(final Class<T> clazz, final Object[] values,
139 			final SingularAttribute<T, ? extends Object>... properties) {
140 
141 		return findOrderedListByProperty(clazz,null,values,properties);
142 	}
143 
144 
145 	@Override
146 	public <T> List<T> findListByProperty(final Class<T> clazz,
147 			final SingularAttribute<T, ? extends Object> property, final Object value) {
148 
149 		return findOrderedListByProperty(clazz,property,value,null);
150 	}
151 
152 	@Override
153 	public <T, V> List<T> findOrderedByPropertyListByEmbeddedProperty(final Class<T> clazz, final SingularAttribute<T, V> property,
154 			final Class<V> clazz2, final SingularAttribute<V, ? extends Object> property2, final Object value,
155 			final SingularAttribute<T, ? extends Object> orderByProperty) {
156 		final CriteriaQuery<T> criteriaQuery = criteriaBuilder
157 				.createQuery(clazz);
158 		final Root<T> root = criteriaQuery.from(clazz);
159 		criteriaQuery.select(root);
160 
161 		if (orderByProperty != null) {
162 			criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderByProperty)));
163 		}
164 
165 
166 		final Join<T, V> join = root.join(property);
167 
168 		final Path<? extends Object> path = join.get(property2);
169 
170 		final Predicate condition = criteriaBuilder.equal(path, value);
171 
172 		criteriaQuery.where(condition);
173 
174 		final TypedQuery<T> typedQuery = entityManager
175 				.createQuery(criteriaQuery);
176 
177 		addCacheHints(typedQuery, "findListByEmbeddedProperty." + clazz.getSimpleName());
178 
179 
180 		return typedQuery.getResultList();
181 	}
182 
183 
184 
185 	@Override
186 	public <T, V> List<T> findOrderedListByEmbeddedProperty(final Class<T> clazz, final SingularAttribute<T, V> property,
187 			final Class<V> clazz2, final SingularAttribute<V, ? extends Object> property2, final Object value,
188 			final SingularAttribute<V, ? extends Object> orderByProperty) {
189 		final CriteriaQuery<T> criteriaQuery = criteriaBuilder
190 				.createQuery(clazz);
191 		final Root<T> root = criteriaQuery.from(clazz);
192 		criteriaQuery.select(root);
193 
194 		final Join<T, V> join = root.join(property);
195 
196 		final Path<? extends Object> path = join.get(property2);
197 
198 		if (orderByProperty != null) {
199 			criteriaQuery.orderBy(criteriaBuilder.desc(join.get(orderByProperty)));
200 		}
201 
202 		final Predicate condition = criteriaBuilder.equal(path, value);
203 
204 		criteriaQuery.where(condition);
205 
206 		final TypedQuery<T> typedQuery = entityManager
207 				.createQuery(criteriaQuery);
208 
209 		addCacheHints(typedQuery, "findListByEmbeddedProperty." + clazz.getSimpleName());
210 
211 
212 		return typedQuery.getResultList();
213 	}
214 
215 	@Override
216 	public <T> List<T> findOrderedListByProperty(final Class<T> clazz, final SingularAttribute<T, ? extends Object> property,
217 			final Object value, final SingularAttribute<T, ? extends Object> orderByProperty) {
218 		final CriteriaQuery<T> criteriaQuery = criteriaBuilder
219 				.createQuery(clazz);
220 		final Root<T> root = criteriaQuery.from(clazz);
221 		criteriaQuery.select(root);
222 
223 		if (orderByProperty != null) {
224 			criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderByProperty)));
225 		}
226 
227 		if (value instanceof String) {
228 			final Expression<String> propertyObject = (Expression<String>) root.get(property);
229 			final Predicate condition = criteriaBuilder.equal(criteriaBuilder.upper(propertyObject), ((String) value).toUpperCase(Locale.ENGLISH));
230 			criteriaQuery.where(condition);
231 
232 		} else {
233 			final Predicate condition = criteriaBuilder.equal(root.get(property), value);
234 			criteriaQuery.where(condition);
235 
236 		}
237 
238 		final TypedQuery<T> typedQuery = entityManager
239 				.createQuery(criteriaQuery);
240 		addCacheHints(typedQuery, "findListByProperty." + clazz.getSimpleName());
241 
242 		return typedQuery.getResultList();
243 	}
244 
245 	@Override
246 	public <T> List<T> findOrderedListByProperty(final Class<T> clazz, final SingularAttribute<T, ? extends Object> orderByProperty,
247 			final Object[] values, final SingularAttribute<T, ? extends Object>... properties) {
248 		final CriteriaQuery<T> criteriaQuery = criteriaBuilder
249 				.createQuery(clazz);
250 		final Root<T> root = criteriaQuery.from(clazz);
251 		criteriaQuery.select(root);
252 
253 		if (orderByProperty != null) {
254 			criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderByProperty)));
255 		}
256 
257 
258 		final Object value=values[0];
259 		final SingularAttribute<T, ? extends Object> property = properties[0];
260 		Predicate condition;
261 
262 		condition = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder,root, value, property);
263 
264 		if (values.length > 1) {
265 			for (int i = 1; i < properties.length; i++) {
266 				final SingularAttribute<T, ? extends Object> property2 = properties[i];
267 				final Object value2=values[i];
268 				final Predicate condition2 = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder,root, value2, property2);
269 
270 				condition = criteriaBuilder.and(condition,condition2);
271 			}
272 		}
273 
274 
275 		criteriaQuery.where(condition);
276 
277 		final TypedQuery<T> typedQuery = entityManager
278 				.createQuery(criteriaQuery);
279 		addCacheHints(typedQuery, "findListByProperty." + clazz.getSimpleName());
280 
281 		return typedQuery.getResultList();
282 	}
283 
284 	@Override
285 	public <T> List<T> getAll(final Class<T> clazz) {
286 		return getAllOrderBy(clazz,null);
287 	}
288 
289 	@Override
290 	public <T> List<T> getAllOrderBy(final Class<T> clazz, final SingularAttribute<T, ? extends Object> property) {
291 		return getInternalPageOrderBy(clazz, null, null, property);
292 	}
293 
294 
295 	@Override
296 	public <T> List<T> getPage(Class<T> clazz, int pageNr, int resultPerPage) {
297 		return getPageOrderBy(clazz, pageNr, resultPerPage, null);
298 	}
299 
300 	@Override
301 	public <T> List<T> getPageOrderBy(Class<T> clazz, int pageNr, int resultPerPage,
302 			SingularAttribute<T, ? extends Object> property) {
303 		return getInternalPageOrderBy(clazz, pageNr, resultPerPage, property);
304 	}
305 
306 	private <T> List<T> getInternalPageOrderBy(final Class<T> clazz, Integer pageNr,Integer resultPerPage,final SingularAttribute<T, ? extends Object> property) {
307 		final CriteriaQuery<T> criteriaQuery = criteriaBuilder
308 				.createQuery(clazz);
309 		final Root<T> root = criteriaQuery.from(clazz);
310 
311 		criteriaQuery.select(root);
312 
313 		if (property != null) {
314 			criteriaQuery.orderBy(criteriaBuilder.desc(root.get(property)));
315 		}
316 
317 		final TypedQuery<T> typedQuery = entityManager
318 				.createQuery(criteriaQuery);
319 		addCacheHints(typedQuery, "getAll." + clazz.getSimpleName());
320 
321 		if (pageNr != null && resultPerPage != null) {
322 			typedQuery.setFirstResult((pageNr-1) * resultPerPage);
323 			typedQuery.setMaxResults(resultPerPage);
324 
325 		}
326 
327 		return typedQuery.getResultList();
328 	}
329 
330 	@Override
331 	public <T> Long getSize(final Class<T> clazz) {
332 		final CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
333 		countQuery.select(criteriaBuilder.count(countQuery.from(clazz)));
334 		return entityManager.createQuery(countQuery).getSingleResult();
335 	}
336 
337 	/**
338 	 * Inits the.
339 	 */
340 	@PostConstruct
341 	private void init() {
342 		criteriaBuilder = entityManager.getCriteriaBuilder();
343 	}
344 
345 	@Override
346 	public <T> T load(final Class<T> clazz,final Object id) {
347 		return LoadHelper.recursiveInitialize(entityManager.find(clazz, id));
348 	}
349 
350 
351 }