activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jstrac...@apache.org
Subject svn commit: r525236 - in /activemq/camel/trunk: camel-core/src/main/java/org/apache/camel/impl/converter/ camel-core/src/main/java/org/apache/camel/util/ camel-jpa/src/main/java/org/apache/camel/component/jpa/ camel-jpa/src/test/java/org/apache/camel/c...
Date Tue, 03 Apr 2007 18:33:12 GMT
Author: jstrachan
Date: Tue Apr  3 11:33:10 2007
New Revision: 525236

URL: http://svn.apache.org/viewvc?view=rev&rev=525236
Log:
Added a test case showing how to use a named query with JPA along with using an annotation
to mark the @Consumed method; so POJO developers can write a method to be invoked on a consume
(to set a flag or update a step to the next state etc). Also performed a minor refactor to
move more reusable code into the core module (for dealing with exception handling of reflection
calls).

Added:
    activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
  (with props)
Modified:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
    activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
    activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
    activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/examples/MultiSteps.java

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java?view=diff&rev=525236&r1=525235&r2=525236
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java
Tue Apr  3 11:33:10 2007
@@ -19,6 +19,7 @@
 
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.TypeConverter;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.impl.CachingInjector;
 
 import java.lang.reflect.InvocationTargetException;
@@ -49,14 +50,6 @@
         if (instance == null) {
             throw new RuntimeCamelException("Could not instantiate aninstance of: " + type.getName());
         }
-        try {
-            return (T) method.invoke(instance, value);
-        }
-        catch (IllegalAccessException e) {
-            throw new RuntimeCamelException(e);
-        }
-        catch (InvocationTargetException e) {
-            throw new RuntimeCamelException(e.getCause());
-        }
+        return (T) ObjectHelper.invokeMethod(method, instance, value);
     }
 }

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java?view=diff&rev=525236&r1=525235&r2=525236
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java
Tue Apr  3 11:33:10 2007
@@ -19,6 +19,7 @@
 
 import org.apache.camel.TypeConverter;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -43,14 +44,6 @@
     }
 
     public <T> T convertTo(Class<T> type, Object value) {
-        try {
-            return (T) method.invoke(null, value);
-        }
-        catch (IllegalAccessException e) {
-            throw new RuntimeCamelException(e);
-        }
-        catch (InvocationTargetException e) {
-            throw new RuntimeCamelException(e.getCause());
-        }
+        return (T) ObjectHelper.invokeMethod(method, null, value);
     }
 }

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java?view=diff&rev=525236&r1=525235&r2=525236
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
Tue Apr  3 11:33:10 2007
@@ -16,12 +16,18 @@
  */
 package org.apache.camel.util;
 
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.converter.ObjectConverter;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 /**
  * @version $Revision$
@@ -67,27 +73,26 @@
         }
     }
 
-
     public static void notNull(Object value, String name) {
         if (value == null) {
             throw new NullPointerException("No " + name + " specified");
         }
     }
-    
+
     public static String[] splitOnCharacter(String value, String needle, int count) {
-    	String rc [] = new String[count];
-    	rc[0] = value;
-    	for ( int i=1; i < count; i++ ) {
-    		String v = rc[i-1];
-			int p = v.indexOf(needle);
-			if( p < 0 ) {
-				return rc;
-			} 
-			rc[i-1] = v.substring(0,p);
-			rc[i] = v.substring(p+1);
-    	}
-    	return rc;
-	}
+        String rc[] = new String[count];
+        rc[0] = value;
+        for (int i = 1; i < count; i++) {
+            String v = rc[i - 1];
+            int p = v.indexOf(needle);
+            if (p < 0) {
+                return rc;
+            }
+            rc[i - 1] = v.substring(0, p);
+            rc[i] = v.substring(p + 1);
+        }
+        return rc;
+    }
 
     /**
      * Returns true if the collection contains the specified value
@@ -115,7 +120,7 @@
     /**
      * A helper method to access a system property, catching any security exceptions
      *
-     * @param name the name of the system property required
+     * @param name         the name of the system property required
      * @param defaultValue the default value to use if the property is not available or a
security exception prevents access
      * @return the system property value or the default value if the property is not available
or security does not allow its access
      */
@@ -148,11 +153,11 @@
     public static Class<?> loadClass(String name) {
         return loadClass(name, ObjectHelper.class.getClassLoader());
     }
-    
+
     /**
      * Attempts to load the given class name using the thread context class loader or the
given class loader
      *
-     * @param name the name of the class to load
+     * @param name   the name of the class to load
      * @param loader the class loader to use after the thread context class loader
      * @return the class or null if it could not be loaded
      */
@@ -172,5 +177,48 @@
             }
         }
         return null;
+    }
+
+    /**
+     * A helper method to invoke a method via reflection and wrap any exceptions
+     * as {@link RuntimeCamelException} instances
+     *
+     * @param method     the method to invoke
+     * @param instance   the object instance (or null for static methods)
+     * @param parameters the parameters to the method
+     * @return the result of the method invocation
+     */
+    public static Object invokeMethod(Method method, Object instance, Object... parameters)
{
+        try {
+            return method.invoke(instance, parameters);
+        }
+        catch (IllegalAccessException e) {
+            throw new RuntimeCamelException(e);
+        }
+        catch (InvocationTargetException e) {
+            throw new RuntimeCamelException(e.getCause());
+        }
+    }
+
+    /**
+     * Returns a list of methods which are annotated with the given annotation
+     *
+     * @param type           the type to reflect on
+     * @param annotationType the annotation type
+     * @return a list of the methods found
+     */
+    public static List<Method> findMethodsWithAnnotation(Class<?> type, Class<?
extends Annotation> annotationType) {
+        List<Method> answer = new ArrayList<Method>();
+        do {
+            Method[] methods = type.getDeclaredMethods();
+            for (Method method : methods) {
+                if (method.getAnnotation(annotationType) != null) {
+                    answer.add(method);
+                }
+            }
+            type = type.getSuperclass();
+        }
+        while (type != null);
+        return answer;
     }
 }

Added: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java?view=auto&rev=525236
==============================================================================
--- activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
(added)
+++ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
Tue Apr  3 11:33:10 2007
@@ -0,0 +1,19 @@
+package org.apache.camel.component.jpa;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * An annotation to mark a method to be invoked when an entity bean has been succesfully
processed
+ * by a Camel consumer, so that it can be updated in some way to remove it from the query
set.
+ *
+ * For example a method may be marked to set an active flag to false or to update some status
value to the next step in a workflow
+ *
+ * @version $Revision$
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Consumed {
+}

Propchange: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java?view=diff&rev=525236&r1=525235&r2=525236
==============================================================================
--- activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
(original)
+++ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
Tue Apr  3 11:33:10 2007
@@ -20,6 +20,7 @@
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.impl.PollingConsumer;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.orm.jpa.JpaCallback;
@@ -28,6 +29,7 @@
 import javax.persistence.LockModeType;
 import javax.persistence.PersistenceException;
 import javax.persistence.Query;
+import java.lang.reflect.Method;
 import java.util.List;
 
 /**
@@ -67,6 +69,7 @@
                         getDeleteHandler().deleteObject(entityManager, result);
                     }
                 }
+                entityManager.flush();
                 return null;
             }
         });
@@ -176,7 +179,22 @@
 
     protected DeleteHandler<Object> createDeleteHandler() {
         // TODO auto-discover an annotation in the entity bean to indicate the process completed
method call?
-
+        Class<?> entityType = getEndpoint().getEntityType();
+        if (entityType != null) {
+            List<Method> methods = ObjectHelper.findMethodsWithAnnotation(entityType,
Consumed.class);
+            if (methods.size() > 1) {
+                throw new IllegalArgumentException("Only one method can be annotated with
the @Consumed annotation but found: " + methods);
+            }
+            else if (methods.size() == 1) {
+                final Method method = methods.get(0);
+
+                return new DeleteHandler<Object>() {
+                    public void deleteObject(EntityManager entityManager, Object entityBean)
{
+                        ObjectHelper.invokeMethod(method, entityBean);
+                    }
+                };
+            }
+        }
         return new DeleteHandler<Object>() {
             public void deleteObject(EntityManager entityManager, Object entityBean) {
                 entityManager.remove(entityBean);

Modified: activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java?view=diff&rev=525236&r1=525235&r2=525236
==============================================================================
--- activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
(original)
+++ activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
Tue Apr  3 11:33:10 2007
@@ -18,26 +18,25 @@
 package org.apache.camel.component.jpa;
 
 import junit.framework.TestCase;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
 import org.apache.camel.Consumer;
-import org.apache.camel.Processor;
 import org.apache.camel.Endpoint;
-import org.apache.camel.examples.SendEmail;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
 import org.apache.camel.examples.MultiSteps;
+import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.util.CamelClient;
 import org.apache.camel.util.ServiceHelper;
-import org.apache.camel.impl.DefaultCamelContext;
-import org.springframework.orm.jpa.JpaTemplate;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.springframework.orm.jpa.JpaCallback;
+import org.springframework.orm.jpa.JpaTemplate;
 
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceException;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.List;
 
 /**
  * @version $Revision$
@@ -101,6 +100,36 @@
         MultiSteps result = receivedExchange.getIn().getBody(MultiSteps.class);
         assertNotNull("Received a POJO", result);
         assertEquals("address property", "foo@bar.com", result.getAddress());
+
+
+        // lets now test that the database is updated
+        // TODO we need to sleep as we will be invoked from inside the transaction!
+        Thread.sleep(1000);
+        
+        transactionStrategy.execute(new JpaCallback() {
+            public Object doInJpa(EntityManager entityManager) throws PersistenceException
{
+
+                // now lets assert that there are still 2 entities left
+                List<MultiSteps> rows = entityManager.createQuery("select x from MultiSteps
x").getResultList();
+                assertEquals("Number of entities: " + rows, 2, rows.size());
+
+                int counter = 1;
+                for (MultiSteps row : rows) {
+                    log.info("entity: " + counter++ + " = " + row);
+
+                    if (row.getAddress().equals("foo@bar.com")) {
+                        log.info("Found updated row: " + row);
+
+                        assertEquals("Updated row step for: " + row, 2, row.getStep());
+                    }
+                    else {
+                        // dummy row
+                        assertEquals("dummy row step for: " + row, 4, row.getStep());
+                    }
+                }
+                return null;
+            }
+        });
     }
 
     @Override

Modified: activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/examples/MultiSteps.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/examples/MultiSteps.java?view=diff&rev=525236&r1=525235&r2=525236
==============================================================================
--- activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/examples/MultiSteps.java
(original)
+++ activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/examples/MultiSteps.java
Tue Apr  3 11:33:10 2007
@@ -17,6 +17,10 @@
  */
 package org.apache.camel.examples;
 
+import org.apache.camel.component.jpa.Consumed;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.GeneratedValue;
@@ -24,12 +28,16 @@
 
 /**
  * Represents a task which has multiple steps so that it can move from stage to stage
+ * with the method annotated with {@link @Consumed} being invoked when the Camel consumer
+ * has processed the entity bean
  *
  * @version $Revision$
  */
 @Entity
 @NamedQuery(name = "step1", query="select x from MultiSteps x where x.step = 1")
 public class MultiSteps {
+    private static final transient Log log = LogFactory.getLog(MultiSteps.class);
+    
     private Long id;
     private String address;
     private int step;
@@ -71,5 +79,15 @@
 
     public void setStep(int step) {
         this.step = step;
+    }
+
+    /**
+     * This method is invoked after the entity bean is processed successfully by a Camel
endpoint
+     */
+    @Consumed
+    public void goToNextStep() {
+        setStep(getStep() + 1);
+
+        log.info("Invoked the completion complete method. Now updated the step to: " + getStep());
     }
 }



Mime
View raw message