Updated Branches: refs/heads/master 1018aee5d -> bd6796897
DELTASPIKE-518 DS Data should support Wrapped JPA APIs. Base don JL Monteiro patch, Thanks :) Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/bd679689 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/bd679689 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/bd679689 Branch: refs/heads/master Commit: bd6796897ec8e7602a8dcdabe143077bc2ee156c Parents: 1018aee Author: Romain Manni-Bucau <[email protected]> Authored: Thu Feb 6 19:34:33 2014 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Thu Feb 6 19:34:33 2014 +0100 ---------------------------------------------------------------------- deltaspike/modules/data/impl/pom.xml | 6 ++ .../impl/builder/AnnotatedQueryBuilder.java | 2 +- .../postprocessor/CountQueryPostProcessor.java | 2 +- .../jpa/EclipseLinkEjbQueryStringExtractor.java | 4 +- .../util/jpa/HibernateQueryStringExtractor.java | 4 +- .../util/jpa/OpenJpaQueryStringExtractor.java | 5 +- .../impl/util/jpa/QueryStringExtractor.java | 4 +- .../util/jpa/QueryStringExtractorFactory.java | 40 +++++++----- .../jpa/QueryStringExtractorFactoryTest.java | 65 ++++++++++++++++++++ 9 files changed, 101 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/pom.xml b/deltaspike/modules/data/impl/pom.xml index 7b262fb..3661270 100755 --- a/deltaspike/modules/data/impl/pom.xml +++ b/deltaspike/modules/data/impl/pom.xml @@ -121,6 +121,12 @@ <artifactId>shrinkwrap-resolver-impl-maven</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa</artifactId> + <version>2.3.0</version> + <scope>test</scope> + </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java index b201af4..b44d369 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java @@ -63,7 +63,7 @@ public class AnnotatedQueryBuilder extends QueryBuilder else { javax.persistence.Query namedQuery = entityManager.createNamedQuery(query.named()); - String named = factory.select(namedQuery).extractFrom(namedQuery); + String named = factory.extract(namedQuery); String jpqlQuery = context.applyQueryStringPostProcessors(named); result = params.applyTo(entityManager.createQuery(jpqlQuery)); } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/CountQueryPostProcessor.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/CountQueryPostProcessor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/CountQueryPostProcessor.java index 6659776..c34e269 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/CountQueryPostProcessor.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/CountQueryPostProcessor.java @@ -55,7 +55,7 @@ public class CountQueryPostProcessor implements JpaQueryPostProcessor { return context.getQueryString(); } - return factory.select(query).extractFrom(query); + return factory.extract(query); } private static class QueryExtraction http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/EclipseLinkEjbQueryStringExtractor.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/EclipseLinkEjbQueryStringExtractor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/EclipseLinkEjbQueryStringExtractor.java index 31cfd43..7f76cd4 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/EclipseLinkEjbQueryStringExtractor.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/EclipseLinkEjbQueryStringExtractor.java @@ -18,14 +18,12 @@ */ package org.apache.deltaspike.data.impl.util.jpa; -import javax.persistence.Query; - @ProviderSpecific("org.eclipse.persistence.jpa.JpaQuery") public class EclipseLinkEjbQueryStringExtractor extends BaseQueryStringExtractor { @Override - public String extractFrom(Query query) + public String extractFrom(Object query) { Object dbQuery = invoke("getDatabaseQuery", query); return (String) invoke("getJPQLString", dbQuery); http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/HibernateQueryStringExtractor.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/HibernateQueryStringExtractor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/HibernateQueryStringExtractor.java index ba8b7a5..7634db5 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/HibernateQueryStringExtractor.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/HibernateQueryStringExtractor.java @@ -18,14 +18,12 @@ */ package org.apache.deltaspike.data.impl.util.jpa; -import javax.persistence.Query; - @ProviderSpecific("org.hibernate.ejb.HibernateQuery") public class HibernateQueryStringExtractor extends BaseQueryStringExtractor { @Override - public String extractFrom(Query query) + public String extractFrom(Object query) { Object hibernateQuery = invoke("getHibernateQuery", query); return (String) invoke("getQueryString", hibernateQuery); http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaQueryStringExtractor.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaQueryStringExtractor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaQueryStringExtractor.java index 1abcb9e..fe9d32e 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaQueryStringExtractor.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaQueryStringExtractor.java @@ -18,14 +18,11 @@ */ package org.apache.deltaspike.data.impl.util.jpa; -import javax.persistence.Query; - @ProviderSpecific("org.apache.openjpa.persistence.OpenJPAQuery") public class OpenJpaQueryStringExtractor extends BaseQueryStringExtractor { - @Override - public String extractFrom(Query query) + public String extractFrom(Object query) { return (String) invoke("getQueryString", query); } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractor.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractor.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractor.java index 48d9f68..aea63d8 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractor.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractor.java @@ -18,11 +18,9 @@ */ package org.apache.deltaspike.data.impl.util.jpa; -import javax.persistence.Query; - public interface QueryStringExtractor { - String extractFrom(Query query); + String extractFrom(Object query); } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactory.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactory.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactory.java index b005292..a072460 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactory.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactory.java @@ -18,43 +18,51 @@ */ package org.apache.deltaspike.data.impl.util.jpa; -import java.util.Arrays; -import java.util.List; - import javax.persistence.Query; public class QueryStringExtractorFactory { - private final List<QueryStringExtractor> extractors = Arrays.<QueryStringExtractor> asList( - new HibernateQueryStringExtractor(), - new EclipseLinkEjbQueryStringExtractor(), - new OpenJpaQueryStringExtractor()); + private final QueryStringExtractor[] extractors = new QueryStringExtractor[] + { + new HibernateQueryStringExtractor(), + new EclipseLinkEjbQueryStringExtractor(), + new OpenJpaQueryStringExtractor() + }; - public QueryStringExtractor select(Query query) + public String extract(final Query query) { - for (QueryStringExtractor extractor : extractors) + for (final QueryStringExtractor extractor : extractors) { - String compare = extractor.getClass().getAnnotation(ProviderSpecific.class).value(); - if (isQueryClass(compare, query)) + final String compare = extractor.getClass().getAnnotation(ProviderSpecific.class).value(); + final Object implQuery = toImplQuery(compare, query); + if (implQuery != null) { - return extractor; + return extractor.extractFrom(implQuery); } } throw new RuntimeException("Persistence provider not supported"); } - private boolean isQueryClass(String clazzName, Query query) + private static Object toImplQuery(final String clazzName, final Query query) { try { Class<?> toClass = Class.forName(clazzName); - toClass.cast(query); - return true; + try + { + // throw a persistence exception if not possible + return query.unwrap(toClass); + } + catch (Exception e) + { + toClass.cast(query); + return query; + } } catch (Exception e) { - return false; + return null; } } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd679689/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactoryTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactoryTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactoryTest.java new file mode 100644 index 0000000..32fb06f --- /dev/null +++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactoryTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.deltaspike.data.impl.util.jpa; + +import org.junit.Assert; +import org.junit.Test; + +import javax.persistence.PersistenceException; +import javax.persistence.Query; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class QueryStringExtractorFactoryTest +{ + + @Test + public void should_unwrap_query_even_proxied() + { + // given + + // when + String extractor = new QueryStringExtractorFactory().extract((Query) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{Query.class}, new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("toString")) return "Unknown provider wrapper for tests."; + if (method.getName().equals("unwrap")) { + Class<?> clazz = (Class<?>) args[0]; + if (clazz.getName().contains("hibernate") || clazz.getName().contains("openjpa") || clazz.getName().contains("eclipse")) { + return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{clazz}, new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("getQueryString")) return "it works"; + return null; + } + }); // we don't care of teh result actually + } else { + throw new PersistenceException("Unable to unwrap for " + clazz); + } + } + return null; + } + })); + + // then + Assert.assertEquals("it works", extractor); + } + +}
