Author: ggerla
Date: Sun Jul 5 08:00:47 2015
New Revision: 1689222
URL: http://svn.apache.org/r1689222
Log:
- Implemented ARIES-1345 scanning all jpa annotated methods
- Add integration test to verify new functionality
Added:
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMethodImpl.java
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMultiAnnotationImpl.java
aries/trunk/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintWithMethodTest.java
Modified:
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
aries/trunk/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaBeanProcessor.java
Added:
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMethodImpl.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMethodImpl.java?rev=1689222&view=auto
==============================================================================
---
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMethodImpl.java
(added)
+++
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMethodImpl.java
Sun Jul 5 08:00:47 2015
@@ -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 WARRANTIESOR 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.aries.jpa.itest.testbundle.service.impl;
+
+import java.util.Collection;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.apache.aries.jpa.itest.testbundle.entities.Car;
+import org.apache.aries.jpa.itest.testbundle.service.CarService;
+
+
+public class CarServiceWithMethodImpl implements CarService {
+
+ EntityManager em;
+
+ @Override
+ public Car getCar(String id) {
+ return em.find(Car.class, id);
+ }
+
+ @Override
+ public void addCar(Car car) {
+ em.persist(car);
+ em.flush();
+ }
+
+ public Collection<Car> getCars() {
+ return em.createQuery("select c from Car c", Car.class)
+ .getResultList();
+ }
+
+ @Override
+ public void updateCar(Car car) {
+ em.persist(car);
+ }
+
+ @Override
+ public void deleteCar(String id) {
+ em.remove(getCar(id));
+ }
+
+ @PersistenceContext(unitName="test_unit_blueprint")
+ public void setEm(EntityManager em) {
+ this.em = em;
+ }
+
+}
Added:
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMultiAnnotationImpl.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMultiAnnotationImpl.java?rev=1689222&view=auto
==============================================================================
---
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMultiAnnotationImpl.java
(added)
+++
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/java/org/apache/aries/jpa/itest/testbundle/service/impl/CarServiceWithMultiAnnotationImpl.java
Sun Jul 5 08:00:47 2015
@@ -0,0 +1,83 @@
+/*
+ * 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 WARRANTIESOR 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.aries.jpa.itest.testbundle.service.impl;
+
+import java.util.Collection;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceUnit;
+
+import org.apache.aries.jpa.itest.testbundle.entities.Car;
+import org.apache.aries.jpa.itest.testbundle.service.CarService;
+import org.apache.aries.jpa.supplier.EmSupplier;
+
+
+public class CarServiceWithMultiAnnotationImpl implements CarService {
+
+ @PersistenceContext(unitName="test_unit_blueprint")
+ EntityManager em;
+
+ @PersistenceUnit(unitName="test_unit_blueprint")
+ EntityManagerFactory emf;
+
+ @PersistenceContext(unitName="test_unit_blueprint")
+ EmSupplier ems;
+
+ @Override
+ public Car getCar(String id) {
+ return em.find(Car.class, id);
+ }
+
+ @Override
+ public void addCar(Car car) {
+ EntityManager localEm = emf.createEntityManager();
+ localEm.persist(car);
+ localEm.flush();
+ localEm.close();
+ }
+
+ public Collection<Car> getCars() {
+ return em.createQuery("select c from Car c", Car.class)
+ .getResultList();
+ }
+
+ @Override
+ public void updateCar(Car car) {
+ em.persist(car);
+ }
+
+ @Override
+ public void deleteCar(String id) {
+ ems.get().remove(getCar(id));
+ }
+
+ public void setEm(EntityManager em) {
+ this.em = em;
+ }
+
+ public void setEmf(EntityManagerFactory emf) {
+ this.emf = emf;
+ }
+
+ public void setEms(EmSupplier ems) {
+ this.ems = ems;
+ }
+}
Modified:
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
URL:
http://svn.apache.org/viewvc/aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml?rev=1689222&r1=1689221&r2=1689222&view=diff
==============================================================================
---
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
(original)
+++
aries/trunk/jpa/itests/jpa-container-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
Sun Jul 5 08:00:47 2015
@@ -54,6 +54,18 @@
class="org.apache.aries.jpa.itest.testbundle.service.impl.CarServiceWithMultiAnnotationImpl">
<tx:transaction method="*" value="Required" />
</bean>
+
+ <service ref="carServiceMethod"
+
interface="org.apache.aries.jpa.itest.testbundle.service.CarService">
+ <service-properties>
+ <entry key="type" value="method" />
+ </service-properties>
+ </service>
+
+ <bean id="carServiceMethod"
+
class="org.apache.aries.jpa.itest.testbundle.service.impl.CarServiceWithMethodImpl">
+ <tx:transaction method="*" value="Required" />
+ </bean>
</blueprint>
Added:
aries/trunk/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintWithMethodTest.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintWithMethodTest.java?rev=1689222&view=auto
==============================================================================
---
aries/trunk/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintWithMethodTest.java
(added)
+++
aries/trunk/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/blueprint/aries/itest/BlueprintWithMethodTest.java
Sun Jul 5 08:00:47 2015
@@ -0,0 +1,56 @@
+/* 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.aries.jpa.blueprint.aries.itest;
+
+import org.apache.aries.jpa.itest.AbstractJPAItest;
+import org.apache.aries.jpa.itest.testbundle.entities.Car;
+import org.apache.aries.jpa.itest.testbundle.service.CarService;
+import org.junit.Assert;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+
+public class BlueprintWithMethodTest extends AbstractJPAItest {
+
+ @Test
+ public void testEmfAddQuery() throws Exception {
+ CarService carService = getService(CarService.class,
"(type=method)");
+
+ resolveBundles();
+ Car c = new Car();
+ c.setColour("Blue");
+ c.setNumberPlate("AB11EMF");
+ c.setNumberOfSeats(7);
+ c.setEngineSize(1900);
+
+ carService.addCar(c);
+
+ Car car2 = carService.getCar("AB11EMF");
+ Assert.assertEquals(c.getNumberPlate(), car2.getNumberPlate());
+ }
+
+ @Configuration
+ public Option[] configuration() {
+ return new Option[] {
+ baseOptions(), //
+ ariesJpa20(), //
+ hibernate(), //
+ derbyDSF(), //
+ testBundleBlueprint(),
+ //debug()
+ };
+ }
+}
Modified:
aries/trunk/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaBeanProcessor.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaBeanProcessor.java?rev=1689222&r1=1689221&r2=1689222&view=diff
==============================================================================
---
aries/trunk/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaBeanProcessor.java
(original)
+++
aries/trunk/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaBeanProcessor.java
Sun Jul 5 08:00:47 2015
@@ -19,6 +19,7 @@
package org.apache.aries.jpa.blueprint.impl;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -80,14 +81,110 @@ public class JpaBeanProcessor implements
public Object beforeInit(Object bean, String beanName,
BeanCreator beanCreator, BeanMetadata beanData) {
+ managePersistenceFields(bean, beanName, beanCreator, beanData);
+ managePersistenceMethods(bean, beanName, beanCreator, beanData);
+ return bean;
+ }
+
+ private Object getEmfProxy(Class<?> clazz, EntityManagerFactory
supplierProxy) {
+ if (clazz == EntityManagerFactory.class) {
+ return supplierProxy;
+ } else {
+ throw new IllegalStateException(
+ "Field or setter Mthod with
@PersistenceUnit has class not supported "
+ + clazz);
+ }
+ }
+
+ private Object getEmProxy(Class<?> clazz, EmSupplierProxy
supplierProxy) {
+ if (clazz == EmSupplier.class) {
+ return supplierProxy;
+ } else if (clazz == EntityManager.class) {
+ return EmProxyFactory.create(supplierProxy);
+ } else {
+ throw new IllegalStateException(
+ "Field or setter Method with
@PersistenceContext has class not supported "
+ + clazz.getName());
+ }
+ }
+
+ private void managePersistenceMethods(Object bean, String beanName,
+ BeanCreator beanCreator, BeanMetadata beanData) {
+
Class<?> c = bean.getClass();
- List<Field> jpaAnnotated = new ArrayList<Field>();
- getPersistenceFields(c, jpaAnnotated);
+ List<Method> jpaAnnotated = getPersistenceMethods(c);
- for (Field field : jpaAnnotated) {
- if (field == null) {
- return bean;
+ for (Method method : jpaAnnotated) {
+ BundleContext context = FrameworkUtil.getBundle(c)
+ .getBundleContext();
+ method.setAccessible(true);
+
+ PersistenceContext pcAnn = method
+
.getAnnotation(PersistenceContext.class);
+ if (pcAnn != null) {
+ LOGGER.debug(
+ "Adding jpa/jta interceptor
bean {} with class {}",
+ beanName, c);
+
+ EmSupplierProxy supplierProxy = new
EmSupplierProxy(context,
+ pcAnn.unitName());
+ emProxies.put(bean, supplierProxy);
+ try {
+ method.invoke(bean,
getEmProxy(method.getParameterTypes()[0], supplierProxy));
+ } catch (Exception e) {
+ throw new IllegalStateException("Error
invoking method "
+ + method, e);
+ }
+ Interceptor interceptor = new
JpaInterceptor(supplierProxy);
+ cdr.registerInterceptorWithComponent(beanData,
interceptor);
+ } else {
+ PersistenceUnit puAnn = method
+
.getAnnotation(PersistenceUnit.class);
+ if (puAnn != null) {
+ LOGGER.debug("Adding emf proxy");
+
+ EntityManagerFactory emfProxy =
EmfProxyFactory.create(
+ context,
puAnn.unitName());
+ emfProxies.put(bean, emfProxy);
+ try {
+ method.invoke(bean,
getEmfProxy(method.getParameterTypes()[0], emfProxy));
+ } catch (Exception e) {
+ throw new
IllegalStateException("Error invoking method "
+ + method, e);
+ }
+ }
}
+ }
+ }
+
+ private List<Method> getPersistenceMethods(Class<?> c) {
+ List<Method> jpaAnnotated = new ArrayList<Method>();
+
+ List<Class<?>> managedJpaClasses = new ArrayList<Class<?>>();
+ managedJpaClasses.add(EntityManagerFactory.class);
+ managedJpaClasses.add(EntityManager.class);
+ managedJpaClasses.add(EmSupplier.class);
+
+ for (Method method : c.getDeclaredMethods()) {
+ if (method.getAnnotation(PersistenceContext.class) !=
null
+ ||
method.getAnnotation(PersistenceUnit.class) != null) {
+
+ Class<?>[] pType = method.getParameterTypes();
+ if (method.getName().startsWith("set") &&
pType.length == 1
+ &&
managedJpaClasses.contains(pType[0])) {
+ jpaAnnotated.add(method);
+ }
+ }
+ }
+ return jpaAnnotated;
+ }
+
+ private void managePersistenceFields(Object bean, String beanName,
+ BeanCreator beanCreator, BeanMetadata beanData) {
+ Class<?> c = bean.getClass();
+ List<Field> jpaAnnotated = getPersistenceFields(c);
+
+ for (Field field : jpaAnnotated) {
BundleContext context = FrameworkUtil.getBundle(c)
.getBundleContext();
field.setAccessible(true);
@@ -103,7 +200,7 @@ public class JpaBeanProcessor implements
pcAnn.unitName());
emProxies.put(bean, supplierProxy);
try {
- field.set(bean, getEmProxy(field,
supplierProxy));
+ field.set(bean,
getEmProxy(field.getType(), supplierProxy));
} catch (Exception e) {
throw new IllegalStateException("Error
setting field "
+ field, e);
@@ -120,7 +217,7 @@ public class JpaBeanProcessor implements
context,
puAnn.unitName());
emfProxies.put(bean, emfProxy);
try {
- field.set(bean,
getEmfProxy(field, emfProxy));
+ field.set(bean,
getEmfProxy(field.getType(), emfProxy));
} catch (Exception e) {
throw new
IllegalStateException("Error setting field "
+ field, e);
@@ -128,40 +225,18 @@ public class JpaBeanProcessor implements
}
}
}
- return bean;
}
- private Object getEmfProxy(Field field, EntityManagerFactory
supplierProxy) {
- if (field.getType() == EntityManagerFactory.class) {
- return supplierProxy;
- } else {
- throw new IllegalStateException(
- "Field with @PersistenceUnit is not of
type EntityManagerFactory "
- + field);
- }
- }
-
- private Object getEmProxy(Field field, EmSupplierProxy supplierProxy) {
- if (field.getType() == EmSupplier.class) {
- return supplierProxy;
- } else if (field.getType() == EntityManager.class) {
- return EmProxyFactory.create(supplierProxy);
- } else {
- throw new IllegalStateException(
- "Field with @PersistenceContext is not
of type EntityManager or EmSupplier "
- + field);
- }
- }
+ private List<Field> getPersistenceFields(Class<?> c) {
+ List<Field> jpaAnnotated = new ArrayList<Field>();
- private void getPersistenceFields(Class<?> c, List<Field> jpaAnnotated)
{
for (Field field : c.getDeclaredFields()) {
if (field.getAnnotation(PersistenceContext.class) !=
null
||
field.getAnnotation(PersistenceUnit.class) != null) {
- if (jpaAnnotated != null) {
- jpaAnnotated.add(field);
- }
+ jpaAnnotated.add(field);
}
}
+ return jpaAnnotated;
}
}