Commit 41bc7ad0b8a45ce69225b88a7ec193b817222518

Authored by Thiago Mariano
2 parents bbd704ca 1279fa34
Exists in master

Merge branch 'master' of git@github.com:demoiselle/framework.git

impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/template/JPACrud.java
... ... @@ -39,6 +39,8 @@ package br.gov.frameworkdemoiselle.template;
39 39 import java.lang.reflect.Field;
40 40 import java.util.ArrayList;
41 41 import java.util.List;
  42 +import java.util.regex.Matcher;
  43 +import java.util.regex.Pattern;
42 44  
43 45 import javax.enterprise.inject.Instance;
44 46 import javax.inject.Inject;
... ... @@ -48,6 +50,7 @@ import javax.persistence.EntityManager;
48 50 import javax.persistence.Enumerated;
49 51 import javax.persistence.Query;
50 52 import javax.persistence.TransactionRequiredException;
  53 +import javax.persistence.TypedQuery;
51 54 import javax.persistence.criteria.CriteriaBuilder;
52 55 import javax.persistence.criteria.CriteriaQuery;
53 56 import javax.persistence.criteria.Predicate;
... ... @@ -159,20 +162,70 @@ public class JPACrud<T, I> implements Crud<T, I> {
159 162 }
160 163  
161 164 @Override
162   - @SuppressWarnings("unchecked")
163 165 public List<T> findAll() {
164   - final String jpql = "select this from " + getBeanClass().getSimpleName() + " this";
165   - final Query query = getEntityManager().createQuery(jpql);
  166 + return findByJPQL("select this from " + getBeanClass().getSimpleName() + " this");
  167 + }
166 168  
167   - final Pagination pagination = getPagination();
  169 + /**
  170 + * Search JPQL integrated into the context of paging
  171 + * @param jpql - query in syntax JPQL
  172 + * @return a list of entities
  173 + */
  174 + protected List<T> findByJPQL(String jpql) {
  175 + pagination = getPagination();
  176 + TypedQuery<T> listQuery = getEntityManager().createQuery(jpql, getBeanClass());
168 177 if (pagination != null) {
169   - pagination.setTotalResults(this.countAll().intValue());
170   - query.setFirstResult(pagination.getFirstResult());
171   - query.setMaxResults(pagination.getPageSize());
  178 + String countQueryString = createCountQueryString(jpql);
  179 + Query query = getEntityManager().createQuery(countQueryString);
  180 + Number cResults = (Number) query.getSingleResult();
  181 + pagination.setTotalResults(cResults.intValue());
  182 + listQuery.setFirstResult(pagination.getFirstResult());
  183 + listQuery.setMaxResults(pagination.getPageSize());
172 184 }
  185 + return listQuery.getResultList();
  186 + }
173 187  
174   - List<T> lista = query.getResultList();
175   - return lista;
  188 + /**
  189 + * Search CriteriaQuery integrated into the context of paging
  190 + * @param criteriaQuery - structure CriteriaQuery
  191 + * @return a list of entities
  192 + */
  193 + public List<T> findByCriteriaQuery(CriteriaQuery<T> criteriaQuery) {
  194 + pagination = getPagination();
  195 + TypedQuery<T> listQuery = getEntityManager().createQuery(criteriaQuery);
  196 + if (pagination != null) {
  197 + CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
  198 + CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
  199 + countQuery.select(builder.count(countQuery.from(getBeanClass())));
  200 + countQuery.where(criteriaQuery.getRestriction());
  201 + getEntityManager().createQuery(countQuery);
  202 + pagination.setTotalResults((int) (getEntityManager().createQuery(countQuery).getSingleResult() + 0));
  203 + listQuery.setFirstResult(pagination.getFirstResult());
  204 + listQuery.setMaxResults(pagination.getPageSize());
  205 + }
  206 + return listQuery.getResultList();
  207 + }
  208 +
  209 + /**
  210 + * Converts JPA query to JPA count query
  211 + * @param query
  212 + * @return
  213 + */
  214 + private String createCountQueryString(String query) {
  215 + query = query.toUpperCase();
  216 + Matcher matcher = Pattern.compile("SELECT(.+)FROM").matcher(query);
  217 + if (matcher.find()){
  218 + String group = matcher.group(1).trim();
  219 + query = query.replaceFirst(group, "COUNT(" + group + ")");
  220 + matcher = Pattern.compile("ORDER(.+)").matcher(query);
  221 + if (matcher.find()){
  222 + group = matcher.group(1);
  223 + query = query.replaceFirst("ORDER"+group, "");
  224 + }
  225 + return query;
  226 + }else{
  227 + throw new DemoiselleException(bundle.get().getString("malformed-jpql"));
  228 + }
176 229 }
177 230  
178 231 /**
... ...
impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties
... ... @@ -41,4 +41,5 @@ can-not-get-persistence-unit-from-persistence=N\u00E3o foi poss\u00EDvel obter a
41 41 more-than-one-persistence-unit-defined=Existe mais de uma unidade de persist\u00EAncia definida. Utilize @{0} no ponto de inje\u00E7\u00E3o ou defina o atributo "frameworkdemoiselle.persistence.unit.name" no arquivo demoiselle.properties.
42 42 persistence-unit-name-found=Unidade de persist\u00EAncia "{0}" encontrada.
43 43 entity-manager-closed=O gerenciador de entidades foi fechado.
44   -no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a configura\u00E7\u00E3o "{0}" no arquivo "{1}" e defina a sua estrat\u00E9gia de transa\u00E7\u00E3o.
45 44 \ No newline at end of file
  45 +no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a configura\u00E7\u00E3o "{0}" no arquivo "{1}" e defina a sua estrat\u00E9gia de transa\u00E7\u00E3o.
  46 +malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados.
... ...
impl/extension/jpa/src/test/java/br/gov/frameworkdemoiselle/template/JPACrudTest.java
... ... @@ -129,28 +129,37 @@ public class JPACrudTest {
129 129 this.contactDAO.delete(this.contact.getId());
130 130 verify(this.entityManager);
131 131 }
132   -
  132 +
  133 + private TypedQuery<Contact> makeTypedQuery() {
  134 + @SuppressWarnings("unchecked")
  135 + TypedQuery<Contact> typeQuery = EasyMock.createMock(TypedQuery.class);
  136 + expect(typeQuery.setFirstResult(EasyMock.anyInt())).andReturn(null);
  137 + expect(typeQuery.setMaxResults(EasyMock.anyInt())).andReturn(null);
  138 + expect(typeQuery.getResultList()).andReturn(createContacts(1));
  139 + return typeQuery;
  140 + }
  141 +
133 142 @Test
134 143 public void testCountAll() {
135 144  
136 145 Pagination pagination = new PaginationImpl();
  146 + pagination.setPageSize(10);
137 147 PaginationContext actualContext = PowerMock.createMock(PaginationContext.class);
138 148 expect(actualContext.getPagination(Contact.class)).andReturn(pagination);
139 149 @SuppressWarnings("unchecked")
140 150 Instance<PaginationContext> paginationContext = PowerMock.createMock(Instance.class);
141 151 expect(paginationContext.get()).andReturn(actualContext);
142 152 setInternalState(this.contactDAO, "paginationContext", paginationContext);
  153 +
  154 + TypedQuery<Contact> typeQuery = makeTypedQuery();
143 155  
144 156 Query query = EasyMock.createMock(Query.class);
145   - expect(query.setFirstResult(EasyMock.anyInt())).andReturn(query);
146   - expect(query.setMaxResults(EasyMock.anyInt())).andReturn(query);
147 157 expect(query.getSingleResult()).andReturn(10L);
  158 +
  159 + expect(this.entityManager.createQuery("select this from Contact this", Contact.class)).andReturn(typeQuery);
  160 + expect(this.entityManager.createQuery("SELECT COUNT(THIS) FROM CONTACT THIS")).andReturn(query);
148 161  
149   - expect(this.entityManager.createQuery("select this from Contact this")).andReturn(query);
150   - expect(this.entityManager.createQuery("select count(this) from Contact this")).andReturn(query);
151   - expect(query.getResultList()).andReturn(createContacts(1));
152   -
153   - replayAll(query, this.entityManager, paginationContext);
  162 + replayAll(typeQuery, query, this.entityManager, paginationContext);
154 163  
155 164 List<Contact> find = this.contactDAO.findAll();
156 165  
... ... @@ -171,11 +180,13 @@ public class JPACrudTest {
171 180 expect(paginationContext.get()).andReturn(actualContext);
172 181 setInternalState(this.contactDAO, "paginationContext", paginationContext);
173 182  
  183 + TypedQuery<Contact> typeQuery = makeTypedQuery();
  184 +
174 185 Query query = EasyMock.createMock(Query.class);
175 186  
176 187 expect(query.getSingleResult()).andThrow(new DemoiselleException(""));
177   - expect(this.entityManager.createQuery("select this from Contact this")).andReturn(query);
178   - expect(this.entityManager.createQuery("select count(this) from Contact this")).andReturn(query);
  188 + expect(this.entityManager.createQuery("select this from Contact this", Contact.class)).andReturn(typeQuery);
  189 + expect(this.entityManager.createQuery("SELECT COUNT(THIS) FROM CONTACT THIS")).andReturn(query);
179 190  
180 191 replayAll(query, this.entityManager, paginationContext);
181 192  
... ... @@ -280,27 +291,31 @@ public class JPACrudTest {
280 291  
281 292 @Test
282 293 public void testFindAll() {
283   -
  294 +
  295 + Pagination pagination = new PaginationImpl();
  296 + pagination.setPageSize(10);
284 297 PaginationContext actualContext = PowerMock.createMock(PaginationContext.class);
285   - expect(actualContext.getPagination(Contact.class)).andReturn(null);
  298 + expect(actualContext.getPagination(Contact.class)).andReturn(pagination);
286 299 @SuppressWarnings("unchecked")
287 300 Instance<PaginationContext> paginationContext = PowerMock.createMock(Instance.class);
288 301 expect(paginationContext.get()).andReturn(actualContext);
289 302 setInternalState(this.contactDAO, "paginationContext", paginationContext);
  303 +
  304 + TypedQuery<Contact> typeQuery = makeTypedQuery();
290 305  
291 306 Query query = EasyMock.createMock(Query.class);
292   - // expect(query.setFirstResult(EasyMock.anyInt())).andReturn(query);
293   - // expect(query.setMaxResults(EasyMock.anyInt())).andReturn(query);
294   - expect(this.entityManager.createQuery("select this from Contact this")).andReturn(query);
295   - expect(query.getResultList()).andReturn(createContacts(1));
  307 + expect(query.getSingleResult()).andReturn(10L);
  308 +
  309 + expect(this.entityManager.createQuery("select this from Contact this", Contact.class)).andReturn(typeQuery);
  310 + expect(this.entityManager.createQuery("SELECT COUNT(THIS) FROM CONTACT THIS")).andReturn(query);
296 311  
297   - replayAll(query, this.entityManager, paginationContext);
  312 + replayAll(typeQuery, query, this.entityManager, paginationContext);
298 313  
299 314 List<Contact> find = this.contactDAO.findAll();
300 315  
301 316 assertEquals(1, find.size());
302 317 assertTrue(find.iterator().next().getId().equals(1L));
303   -
  318 +
304 319 verifyAll();
305 320 }
306 321  
... ... @@ -313,12 +328,15 @@ public class JPACrudTest {
313 328 Instance<PaginationContext> paginationContext = PowerMock.createMock(Instance.class);
314 329 expect(paginationContext.get()).andReturn(actualContext);
315 330 setInternalState(this.contactDAO, "paginationContext", paginationContext);
  331 +
  332 + @SuppressWarnings("unchecked")
  333 + TypedQuery<Contact> typeQuery = EasyMock.createMock(TypedQuery.class);
  334 + expect(typeQuery.getResultList()).andThrow(new DemoiselleException(""));
316 335  
317 336 Query query = EasyMock.createMock(Query.class);
318   - expect(this.entityManager.createQuery("select this from Contact this")).andReturn(query);
319   - expect(query.getResultList()).andThrow(new DemoiselleException(""));
  337 + expect(this.entityManager.createQuery("select this from Contact this", Contact.class)).andReturn(typeQuery);
320 338  
321   - replayAll(query, this.entityManager, paginationContext);
  339 + replayAll(typeQuery, query, this.entityManager, paginationContext);
322 340  
323 341 try {
324 342 this.contactDAO.findAll();
... ...