You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cm...@apache.org on 2009/12/05 00:12:01 UTC

svn commit: r887437 - in /activemq/sandbox/activemq-apollo-actor/activemq-dispatcher: ./ src/main/java/org/apache/activemq/actor/ src/test/java/org/apache/activemq/actor/

Author: cmacnaug
Date: Fri Dec  4 23:12:00 2009
New Revision: 887437

URL: http://svn.apache.org/viewvc?rev=887437&view=rev
Log:
Adding Actor class which facilitates create wrappers around Actor classes to perform method execution on a DispatchQueue

Added:
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Actor.java   (with props)
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Message.java   (with props)
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/ActorTest.java   (with props)
Modified:
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/pom.xml

Modified: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/pom.xml
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/pom.xml?rev=887437&r1=887436&r2=887437&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/pom.xml (original)
+++ activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/pom.xml Fri Dec  4 23:12:00 2009
@@ -49,6 +49,11 @@
       <artifactId>log4j</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+    	<groupId>cglib</groupId>
+    	<artifactId>cglib</artifactId>
+    	<version>2.2</version>
+    </dependency>
     
   </dependencies>
 

Added: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Actor.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Actor.java?rev=887437&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Actor.java (added)
+++ activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Actor.java Fri Dec  4 23:12:00 2009
@@ -0,0 +1,98 @@
+/**************************************************************************************
+ * Copyright (C) 2009 Progress Software, Inc. All rights reserved.                    *
+ * http://fusesource.com                                                              *
+ * ---------------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the AGPL license      *
+ * a copy of which has been included with this distribution in the license.txt file.  *
+ **************************************************************************************/
+package org.apache.activemq.actor;
+
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import org.apache.activemq.dispatch.DispatchQueue;
+
+/**
+ * Allows creation of wrapper objects that intercept {@link Message} annotated
+ * methods and dispatch them asynchronously on a given {@link DispatchQueue}.
+ * 
+ * @author cmacnaug
+ * @version 1.0
+ */
+public class Actor {
+
+    public static <T> T create(T target, DispatchQueue queue, Class<?>... interfaces) {
+
+        validateMessageMethods(target);
+        Enhancer e = new Enhancer();
+        e.setSuperclass(target.getClass());
+        e.setInterfaces(interfaces);
+        e.setCallback(new ActorMethodInterceptor(queue));
+        return (T) e.create();
+    }
+
+    private static final <T> void validateMessageMethods(T target) throws IllegalArgumentException {
+        for (Method m : target.getClass().getDeclaredMethods()) {
+            if (isMessage(m)) {
+                if (m.getReturnType() == null) {
+                    throw new IllegalArgumentException("Illegal method declaration: " + m + ". Actor methods must return void");
+                }
+                if (m.getExceptionTypes().length > 0) {
+                    throw new IllegalArgumentException("Illegal method declaration: " + m + ". Actor methods must not throw exceptions");
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests if a given method has a Message annotation
+     * 
+     * @param method The mehod.
+     */
+    private static boolean isMessage(Method method) {
+        if (method.isAnnotationPresent(Message.class)) {
+            return true;
+        }
+        if (method.getDeclaringClass().isAnnotationPresent(Message.class)) {
+            return true;
+        }
+        return false;
+    }
+
+    private static class ActorMethodInterceptor implements MethodInterceptor {
+
+        private final DispatchQueue queue;
+
+        ActorMethodInterceptor(DispatchQueue queue) {
+            this.queue = queue;
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object,
+         * java.lang.reflect.Method, java.lang.Object[],
+         * net.sf.cglib.proxy.MethodProxy)
+         */
+        public Object intercept(final Object obj, Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
+            if (isMessage(method)) {
+                queue.dispatchAsync(new Runnable() {
+                    public void run() {
+                        try {
+                            proxy.invokeSuper(obj, args);
+                        } catch (Throwable thrown) {
+                            throw new IllegalStateException(thrown);
+                        }
+                    }
+                });
+                return null;
+            } else {
+                return proxy.invokeSuper(obj, args);
+            }
+        }
+    }
+
+}

Propchange: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Actor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Message.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Message.java?rev=887437&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Message.java (added)
+++ activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Message.java Fri Dec  4 23:12:00 2009
@@ -0,0 +1,25 @@
+/**************************************************************************************
+ * Copyright (C) 2009 Progress Software, Inc. All rights reserved.                    *
+ * http://fusesource.com                                                              *
+ * ---------------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the AGPL license      *
+ * a copy of which has been included with this distribution in the license.txt file.  *
+ **************************************************************************************/
+package org.apache.activemq.actor;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ * Indicates that a given method, class or interface should be treated as an actor. 
+ * 
+ * @author cmacnaug 
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target( { java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE })
+public @interface Message {
+
+}

Propchange: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/Message.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/ActorTest.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/ActorTest.java?rev=887437&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/ActorTest.java (added)
+++ activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/ActorTest.java Fri Dec  4 23:12:00 2009
@@ -0,0 +1,67 @@
+/**************************************************************************************
+ * Copyright (C) 2009 Progress Software, Inc. All rights reserved.                    *
+ * http://fusesource.com                                                              *
+ * ---------------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the AGPL license      *
+ * a copy of which has been included with this distribution in the license.txt file.  *
+ **************************************************************************************/
+package org.apache.activemq.actor;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.TestCase;
+
+import org.apache.activemq.dispatch.DispatchQueue;
+import org.apache.activemq.dispatch.DispatchSPI;
+import org.apache.activemq.dispatch.internal.advanced.AdvancedDispatchSPI;
+
+
+/** 
+ * ActorTest
+ * <p>
+ * Description:
+ * </p>
+ * @author cmacnaug
+ * @version 1.0
+ */
+public class ActorTest extends TestCase {
+
+    
+    public static class ActorTestObject
+    {
+        @Message
+        public void actorInvocation(CountDownLatch latch)
+        {
+            latch.countDown();
+        }
+        
+        public void straightThrough(CountDownLatch latch)
+        {
+            latch.countDown();
+        }
+        
+    }
+    
+    public void testActorInvocation() throws Exception
+    {
+        DispatchSPI advancedSystem = new AdvancedDispatchSPI(Runtime.getRuntime().availableProcessors(), 3);
+        advancedSystem.start();
+        
+        DispatchQueue queue = advancedSystem.createQueue("test");
+        ActorTestObject testObject = Actor.create(new ActorTestObject(), queue);
+        
+        CountDownLatch latch = new CountDownLatch(1);
+        testObject.actorInvocation(latch);
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+        
+        latch = new CountDownLatch(1);
+        queue.suspend();
+        assertFalse(latch.await(2, TimeUnit.SECONDS));
+        
+        queue.resume();
+        assertTrue(latch.await(2, TimeUnit.SECONDS));
+        
+    }
+    
+}

Propchange: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/ActorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native