Author: kohsuke
Date: Sun Jul 31 11:49:52 2005
New Revision: 226678

URL: http://svn.apache.org/viewcvs?rev=226678&view=rev
Log:
modified to use Runnable to start an execution instead of reflection.
this allows us to eliminate MethodLookup.
Since this change removes the last property from ContinuationContext,
we can now take any class as a context.
Also improved javadoc of Continuation a bit.

Removed:
    
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/ContinuationContext.java
    
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/MethodLookup.java
Modified:
    
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
    
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/ContinuationTests.java
    
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java
    
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTests.java
    
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Calculator.java
    
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java?rev=226678&r1=226677&r2=226678&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
 Sun Jul 31 11:49:52 2005
@@ -16,40 +16,48 @@
 package org.apache.commons.javaflow;
 
 import java.io.Serializable;
-import java.lang.reflect.Method;
 
 import org.apache.commons.javaflow.bytecode.Stack;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
- * Continations object to store the current execution. The continuation
- * object can only used once. 
+ * Snapshot of a thread execution state.
+ *
+ * <p>
+ * A [EMAIL PROTECTED] Continuation} object is an immutable object that 
captures everything in
+ * the Java stack. This includes
+ * (1) current instruction pointer,
+ * (2) return addresses, and
+ * (3) local variables.
+ *
+ * <p>
+ * <tt>Continuation</tt> objects are used to restore the captured execution 
states
+ * later.
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
  * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a>
  * @version CVS $Id$
  */
-public class Continuation implements Serializable {
+public final class Continuation implements Serializable {
 
     private final static Log log = LogFactory.getLog(Continuation.class);
     
     private final static ThreadLocal continuationsMap = new ThreadLocal();
-    private transient ContinuationContext context;
+    private transient Object context;
 
     private transient boolean restoring = false;
     private transient boolean capturing = false;
 
-    private transient Method method;
-    private transient Object instance;
-    
-    private String methodName;
+    private final Runnable target;
+
     private final Stack stack;
     private final Continuation root;
 
     
-    private Continuation() {
+    private Continuation(Runnable target) {
         stack = new Stack();
+        this.target = target;
         root = this;
     }
 
@@ -58,9 +66,7 @@
      */
     private Continuation( final Continuation parent ) {
         stack = new Stack(parent.stack);
-        methodName = parent.methodName;
-        method = parent.method;
-        instance = parent.instance;
+        target = parent.target;
         root = parent.root;
     }
 
@@ -69,28 +75,75 @@
      * get the current context.
      *
      * <p>
-     * This method returns the same context object given to [EMAIL PROTECTED] 
#startWith(String, ContinuationContext)}
-     * or [EMAIL PROTECTED] #continueWith(Continuation, ContinuationContext)}.
+     * This method returns the same context object given to [EMAIL PROTECTED] 
#startWith(Runnable, Object)}
+     * or [EMAIL PROTECTED] #continueWith(Continuation, Object)}.
+     *
+     * <p>
+     * A different context can be used for each run of a continuation, so
+     * this mechanism can be used to associate some state with each execution.
      *
      * @return
-     *      null if this method is invoked outside [EMAIL PROTECTED] 
#startWith(String, ContinuationContext)}
-     *      or [EMAIL PROTECTED] #continueWith(Continuation, 
ContinuationContext)} .
+     *      null if this method is invoked outside [EMAIL PROTECTED] 
#startWith(Runnable, Object)}
+     *      or [EMAIL PROTECTED] #continueWith(Continuation, Object)} .
      */
-    public ContinuationContext getContext() {
+    public Object getContext() {
         return context;
     }
-    
-    public static Continuation startWith( final String methodName, final 
ContinuationContext context ) {
 
-        final Continuation newContinuation = new Continuation();
+    /**
+     * Starts executing the specified [EMAIL PROTECTED] Runnable} object in an 
environment
+     * that allows [EMAIL PROTECTED] Continuation#suspend()}.
+     *
+     * <p>
+     * This is a short hand for <tt>startWith(target,null)</tt>.
+     *
+     * @see #startWith(Runnable, Object).
+     */
+    public static Continuation startWith( final Runnable target ) {
+        return startWith(target,null);
+    }
+
+    /**
+     * Starts executing the specified [EMAIL PROTECTED] Runnable} object in an 
environment
+     * that allows [EMAIL PROTECTED] Continuation#suspend()}.
+     *
+     * This method blocks until the continuation suspends or completes.
+     *
+     * @param target
+     *      The object whose <tt>run</tt> method will be executed.
+     * @param context
+     *      This value can be obtained from [EMAIL PROTECTED] #getContext()} 
until this method returns.
+     *      Can be null.
+     * @return
+     *      If the execution completes and there's nothing more to continue, 
return null.
+     *      Otherwise, the execution has been [EMAIL PROTECTED] #suspend() 
suspended}, in which case
+     *      a new non-null continuation is returned.
+     * @see #getContext()
+     */
+    public static Continuation startWith( final Runnable target, final Object 
context ) {
+        if(target==null) {
+            throw new IllegalArgumentException("target is null");
+        }
+
+        final Continuation newContinuation = new Continuation(target);
 
-        newContinuation.methodName = methodName;
+        log.debug("starting new flow from " + target);
 
-        log.debug("starting new flow from " + methodName);
+        return newContinuation.execute(context);
+    }
 
-        return execute(newContinuation, context);
+    /**
+     * Resumes the execution of the specified continuation from where it's 
left off.
+     *
+     * <p>
+     * This is a short hand for <tt>continueWith(resumed,null)</tt>.
+     *
+     * @see #continueWith(Continuation, Object)
+     */
+    public static Continuation continueWith(final Continuation resumed) {
+        return continueWith(resumed,null);
     }
-    
+
     /**
      * Resumes the execution of the specified continuation from where it's 
left off.
      *
@@ -100,13 +153,17 @@
      *      The resumed continuation to be executed. Must not be null.
      * @param context
      *      This value can be obtained from [EMAIL PROTECTED] #getContext()} 
until this method returns.
-     *      <!-- Can be null. -->
+     *      Can be null.
      * @return
      *      If the execution completes and there's nothing more to continue, 
return null.
      *      Otherwise, the execution has been [EMAIL PROTECTED] #suspend() 
suspended}, in which case
      *      a new non-null continuation is returned.
+     * @see #getContext()
      */
-    public static Continuation continueWith(final Continuation resumed, final 
ContinuationContext context) {
+    public static Continuation continueWith(final Continuation resumed, final 
Object context) {
+        if(resumed==null) {
+            throw new IllegalArgumentException("continuation parameter must 
not be null.");
+        }
 
         log.debug("continueing with continuation " + resumed);
 
@@ -114,59 +171,34 @@
 
         newContinuation.restoring = true;
         
-        return execute(newContinuation, context);
+        return newContinuation.execute(context);
     }
 
-    private static Continuation execute(final Continuation continuation, final 
ContinuationContext context) {
+    private Continuation execute(final Object context) {
         boolean completed = false;
 
-        final Continuation runningContinuation = continuation.registerThread();
+        final Continuation runningContinuation = registerThread();
         try {
-            // REVISIT: use instance from root continuation
-            
-            if (continuation.method == null) {
-                log.debug("looking up method " + continuation.methodName);
-                final MethodLookup lookup = context.getMethodLookup();
-                continuation.method = 
lookup.getMethod(continuation.methodName);
-                log.debug("found method " + continuation.method + " in " +
-                        
continuation.method.getDeclaringClass().getClassLoader()
-                        );
-            }
-
-            if (continuation.instance == null) {
-                log.debug("creating instance " + 
continuation.method.getDeclaringClass().getName());
-                continuation.instance = 
continuation.method.getDeclaringClass().newInstance();
-                log.debug("created instance " +
-                        continuation.instance.getClass().getName() + "@" + 
continuation.instance.hashCode() + 
-                        "-" +
-                        continuation.instance.getClass().getClassLoader()
-                        );
-            }
-
-            continuation.context = context;
-
-            continuation.method.invoke(continuation.instance, new Object[0]);
-
-        } catch (final Exception e) {
-            log.error("could not execute " + continuation, e);       
+            this.context = context;
+            target.run();
         } finally {
-            if (continuation.capturing) {
-                if (continuation.stack.hasReference()) {
-                    continuation.stack.popReference();
+            if (capturing) {
+                if (stack.hasReference()) {
+                    stack.popReference();
                 }
             } else {
                 completed = true;
             }
 
-            continuation.context = null;
+            this.context = null;
             
-            continuation.deregisterThread(runningContinuation);
+            deregisterThread(runningContinuation);
         }
 
         if(completed) {
             return null;
         } else {
-            return continuation;
+            return this;
         }
     }
     

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/ContinuationTests.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/ContinuationTests.java?rev=226678&r1=226677&r2=226678&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/ContinuationTests.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/ContinuationTests.java
 Sun Jul 31 11:49:52 2005
@@ -33,41 +33,18 @@
     
     private final static Log log = LogFactory.getLog(ContinuationTests.class);
 
-    private ContinuationContext createContinuationContext() {
-
-        final Map methods = ReflectionUtils.discoverMethods(Calculator.class);
-        TestCase.assertNotNull(methods);
-        TestCase.assertTrue(methods.size() > 0);
-        
-        final MethodLookup lookup = new MethodLookup() {
-            public Method getMethod(final String methodName) {
-                final Method method = (Method) methods.get(methodName);
-                if (method == null) {
-                    throw new NullPointerException("method " + methodName + " 
could not be found");
-                }
-                return method;
-            }            
-        };
-        
-        final ContinuationContext context = new ContinuationContext();
-        context.setMethodLookup(lookup);
-        
-        return context;
-    }  
-    
     public void testHierarchy() throws Exception {
                 
         log.debug("Testing hierarchy...");
         
         Continuation continuation = null;
-        ContinuationContext context = createContinuationContext();
-        
+
         TestCase.assertTrue(
                 Calculator.global == 0 &&
                 Calculator.local == 0
                 );                
 
-        continuation = Continuation.startWith("main", context);
+        continuation = Continuation.startWith(new Calculator());
         TestCase.assertTrue(
                 Calculator.global == 1 &&
                 Calculator.local == 1
@@ -75,15 +52,13 @@
         
         final Continuation parent = continuation;
 
-        context = createContinuationContext();
-
-        final Continuation continuation11 = Continuation.continueWith(parent, 
context);
+        final Continuation continuation11 = Continuation.continueWith(parent);
         TestCase.assertTrue(
                 Calculator.global == 2 &&
                 Calculator.local == 2
                 );                
         
-        final Continuation continuation12 = Continuation.continueWith(parent, 
context);
+        final Continuation continuation12 = Continuation.continueWith(parent);
         TestCase.assertTrue(
                 Calculator.global == 3 &&
                 Calculator.local == 2
@@ -99,7 +74,7 @@
         
         try {
             final Calculator c = new Calculator();
-            c.main();
+            c.run();
         } catch (final Exception e) {
             log.debug("Catching a " + e);
             TestCase.assertTrue(e instanceof IllegalStateException);

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java?rev=226678&r1=226677&r2=226678&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java
 Sun Jul 31 11:49:52 2005
@@ -15,6 +15,7 @@
  */
 package org.apache.commons.javaflow;
 
+import junit.textui.TestRunner;
 
 
 /**
@@ -26,7 +27,11 @@
     public SerializationTestCase() {
         super("org.apache.commons.javaflow.SerializationTests");
     }
-    
+
+    public static void main(String[] args) {
+        TestRunner.run(SerializationTestCase.class);
+    }
+
     public void testStart() throws Exception {
         call("testStart");
     }

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTests.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTests.java?rev=226678&r1=226677&r2=226678&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTests.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTests.java
 Sun Jul 31 11:49:52 2005
@@ -40,39 +40,14 @@
     private final static Log log = LogFactory.getLog(SerializationTests.class);
 
     
-    private ContinuationContext createContinuationContext() {
-
-        final Map methods = ReflectionUtils.discoverMethods(Calculator.class);
-        TestCase.assertNotNull(methods);
-        TestCase.assertTrue(methods.size() > 0);
-        
-        final MethodLookup lookup = new MethodLookup() {
-            public Method getMethod(final String methodName) {
-                final Method method = (Method) methods.get(methodName);
-                if (method == null) {
-                    throw new NullPointerException("method " + methodName + " 
could not be found");
-                }
-                return method;
-            }            
-        };
-        
-        final ContinuationContext context = new ContinuationContext();
-        context.setMethodLookup(lookup);
-        
-        return context;
-    }
-    
-    
     public void testStart() throws Exception {
                 
-        final ContinuationContext context = createContinuationContext();
-
         TestCase.assertTrue(
                 Calculator.global == 0 &&
                 Calculator.local == 0
                 );                
         
-        final Continuation continuation = Continuation.startWith("main", 
context);
+        final Continuation continuation = Continuation.startWith(new 
Calculator());
 
         log.debug("back from contination " + continuation);
         
@@ -92,8 +67,6 @@
 
     public void testResume() throws Exception {
 
-        final ContinuationContext context = createContinuationContext();
-
         final String xml = FileUtils.readFully(new 
FileReader("continuation.xml"));
         final XStream xstream = new XStream(new DomDriver());
         final Object o = xstream.fromXML(xml);
@@ -102,7 +75,7 @@
         
         log.debug("continuation restored " + parent);
         
-        final Continuation continuation = Continuation.continueWith(parent, 
context);
+        final Continuation continuation = Continuation.continueWith(parent);
 
         log.debug("back from contination " + continuation);
 

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Calculator.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Calculator.java?rev=226678&r1=226677&r2=226678&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Calculator.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Calculator.java
 Sun Jul 31 11:49:52 2005
@@ -26,14 +26,16 @@
  * @author tcurdt
  *
  */
-public final class Calculator implements Continuable, Serializable {
+public final class Calculator implements Continuable, Serializable, Runnable {
     
     private static final Log log = LogFactory.getLog(Calculator.class);
 
     public static transient int global;
     public static transient int local;
-    
-    public void main() {
+
+    public int field = 5;
+
+    public void run() {
 
         global = 0;
         local = 0;
@@ -48,9 +50,13 @@
         local = ++l;
 
         log.debug("Calculator@" + hashCode() + " Step 1: g=" + global + " l=" 
+ l);
-        
+
+        field = 6;
+
         Continuation.suspend();
-        
+
+        System.out.println(field);
+
         log.debug("Calculator@" + hashCode() + " Step 2: g=" + global + " l=" 
+ l);
 
         global++;

Modified: 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java?rev=226678&r1=226677&r2=226678&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java
 (original)
+++ 
jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java
 Sun Jul 31 11:49:52 2005
@@ -4,59 +4,19 @@
 import java.util.Map;
 import junit.framework.TestCase;
 import org.apache.commons.javaflow.Continuation;
-import org.apache.commons.javaflow.ContinuationContext;
-import org.apache.commons.javaflow.MethodLookup;
 import org.apache.commons.javaflow.utils.ReflectionUtils;
 
 public class Test implements Runnable {
-
-    public final class MapMethodLookup implements MethodLookup {
-
-        private final Map methods;
-
-
-        public MapMethodLookup(Map methods) {
-            super();
-            this.methods = methods;
-        }
-
-
-        public Method getMethod(final String methodName) {
-            final Method method = (Method) methods.get(methodName);
-            if (method == null) {
-                throw new NullPointerException("method " + methodName + " 
could not be found");
-            }
-            return method;
-        }
-    }
-
-    private ContinuationContext createContinuationContext(final Class clazz) {
-
-        final Map methods = ReflectionUtils.discoverMethods(clazz);
-        TestCase.assertNotNull(methods);
-        TestCase.assertTrue(methods.size() > 0);
-        
-        final MethodLookup lookup = new MapMethodLookup(methods);
-        
-        final ContinuationContext context = new ContinuationContext();
-        context.setMethodLookup(lookup);
-        
-        return context;
-    }
-
     public void run() {
         System.out.println("running in " + 
this.getClass().getClassLoader().hashCode());
         
-        final ContinuationContext context = 
createContinuationContext(this.getClass());
-        
-        final Continuation continuation = Continuation.startWith("main", 
context);
+        final Continuation continuation = Continuation.startWith(new 
Runnable() {
+            public void run() {
+                Continuation.suspend();
+            }
+        });
         
         System.out.println("finished in " + 
this.getClass().getClassLoader().hashCode());
     }
 
-    public void main() {
-        
-        Continuation.suspend();
-
-    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to