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;
        }
 
 }


Reply via email to