Modified: 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLDigesterTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLDigesterTest.java?rev=407424&r1=407423&r2=407424&view=diff
==============================================================================
--- 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLDigesterTest.java
 (original)
+++ 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLDigesterTest.java
 Wed May 17 18:16:30 2006
@@ -25,7 +25,6 @@
 
 import org.apache.commons.digester.Digester;
 import org.apache.commons.scxml.SCXMLTestHelper;
-import org.apache.commons.scxml.model.Hello;
 import org.apache.commons.scxml.model.SCXML;
 import org.apache.commons.scxml.model.Send;
 import org.apache.commons.scxml.model.State;
@@ -66,7 +65,7 @@
             getResource("org/apache/commons/scxml/transitions-01.xml");
         send01 = this.getClass().getClassLoader().
             getResource("org/apache/commons/scxml/send-01.xml");
-        digester = SCXMLDigester.newInstance(null, null);
+        digester = SCXMLDigester.newInstance();
     }
 
     /**
@@ -118,65 +117,6 @@
             + " an example.</prompt></foo>";
         assertFalse(scxmlAsString.indexOf(expectedFoo2Serialization) == -1);
         */
-    }
-
-    public void testAddGoodCustomAction01() {
-        try {
-            SCXMLDigester.addCustomAction(digester,
-                "http://my.actions.domain/CUSTOM";, "hello", Hello.class);
-        } catch (IllegalArgumentException iae) {
-            fail("Failed to add custom action &quot;Hello&quot;");
-        }
-    }
-
-    public void testAddBadCustomAction01() {
-        try {
-            SCXMLDigester.addCustomAction(digester,
-                null, "hello", Hello.class);
-            fail("Added custom action with illegal namespace");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
-    }
-
-    public void testAddBadCustomAction02() {
-        try {
-            SCXMLDigester.addCustomAction(digester,
-                "  ", "hello", Hello.class);
-            fail("Added custom action with illegal namespace");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
-    }
-
-    public void testAddBadCustomAction03() {
-        try {
-            SCXMLDigester.addCustomAction(digester,
-                "http://my.actions.domain/CUSTOM";, "", Hello.class);
-            fail("Added custom action with illegal local name");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
-    }
-
-    public void testAddBadCustomAction04() {
-        try {
-            SCXMLDigester.addCustomAction(digester,
-                "http://my.actions.domain/CUSTOM";, "  ", Hello.class);
-            fail("Added custom action with illegal local name");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
-    }
-
-    public void testAddBadCustomAction05() {
-        try {
-            SCXMLDigester.addCustomAction(digester,
-                "http://my.actions.domain/CUSTOM";, "foo", this.getClass());
-            fail("Added custom action which is not an Action class subtype");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
     }
 
     private String serialize(final SCXML scxml) {

Modified: 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/CustomActionTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/CustomActionTest.java?rev=407424&r1=407423&r2=407424&view=diff
==============================================================================
--- 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/CustomActionTest.java
 (original)
+++ 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/CustomActionTest.java
 Wed May 17 18:16:30 2006
@@ -16,6 +16,8 @@
 package org.apache.commons.scxml.model;
 
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -24,9 +26,6 @@
 import org.apache.commons.digester.Digester;
 import org.apache.commons.scxml.SCXMLExecutor;
 import org.apache.commons.scxml.SCXMLTestHelper;
-import org.apache.commons.scxml.io.SCXMLDigester;
-import org.apache.commons.scxml.model.SCXML;
-import org.apache.commons.scxml.model.State;
 
 public class CustomActionTest extends TestCase {
 
@@ -43,7 +42,7 @@
         junit.textui.TestRunner.main(testCaseName);
     }
 
-    private URL hello01, custom01;
+    private URL hello01, custom01, external01;
     private Digester digester;
     private SCXMLExecutor exec;
 
@@ -54,18 +53,77 @@
         hello01 = this.getClass().getClassLoader().
             getResource("org/apache/commons/scxml/hello-world.xml");
         custom01 = this.getClass().getClassLoader().
-            getResource("org/apache/commons/scxml/custom-hello-world.xml");
+            getResource("org/apache/commons/scxml/custom-hello-world-01.xml");
+        external01 = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/external-hello-world.xml");
     }
 
     /**
      * Tear down instance variables required by this test case.
      */
     public void tearDown() {
-        hello01 = custom01 = null;
+        hello01 = custom01 = external01 = null;
         digester = null;
         exec = null;
     }
 
+    public void testAddGoodCustomAction01() {
+        try {
+            new CustomAction("http://my.actions.domain/CUSTOM";, "hello",
+                Hello.class);
+        } catch (IllegalArgumentException iae) {
+            fail("Failed to add custom action &quot;Hello&quot;");
+        }
+    }
+
+    public void testAddBadCustomAction01() {
+        try {
+            new CustomAction(null, "hello", Hello.class);
+            fail("Added custom action with illegal namespace");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+    }
+
+    public void testAddBadCustomAction02() {
+        try {
+            new CustomAction("  ", "hello", Hello.class);
+            fail("Added custom action with illegal namespace");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+    }
+
+    public void testAddBadCustomAction03() {
+        try {
+            new CustomAction("http://my.actions.domain/CUSTOM";, "",
+                Hello.class);
+            fail("Added custom action with illegal local name");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+    }
+
+    public void testAddBadCustomAction04() {
+        try {
+            new CustomAction("http://my.actions.domain/CUSTOM";, "  ",
+                Hello.class);
+            fail("Added custom action with illegal local name");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+    }
+
+    public void testAddBadCustomAction05() {
+        try {
+            new CustomAction("http://my.actions.domain/CUSTOM";, "foo",
+                this.getClass());
+            fail("Added custom action which is not an Action class subtype");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+    }
+
     // Hello World example using the SCXML <log> action
     public void testHelloWorld() {
         // (1) Get a SCXMLExecutor
@@ -78,26 +136,52 @@
 
     // Hello World example using a custom <hello> action
     public void testCustomActionHelloWorld() {
-        // (1) Get Digester with "default" rules for parsing SCXML documents
-        digester = SCXMLDigester.newInstance(null, null);
-        // (2) Register the "custom" action(s)
-        SCXMLDigester.addCustomAction(digester,
-            "http://my.custom-actions.domain/CUSTOM";, "hello", Hello.class);
-        // (3) Parse the SCXML document containing the custom action(s)
-        SCXML scxml = null;
-        try {
-            scxml = (SCXML) digester.parse(custom01.toString());
-        } catch (Exception e) {
-            fail(e.getMessage());
-        }
-        // (4) Wire up the object model for the SCXMLExecutor
-        SCXMLDigester.updateSCXML(scxml);
-        // (5) Get a SCXMLExecutor
+        // (1) Form a list of custom actions defined in the SCXML
+        //     document (and any included documents via "src" attributes)
+        CustomAction ca1 =
+            new CustomAction("http://my.custom-actions.domain/CUSTOM1";,
+                             "hello", Hello.class);
+        // Register the same action under a different name, just to test
+        // multiple custom actions
+        CustomAction ca2 =
+            new CustomAction("http://my.custom-actions.domain/CUSTOM2";,
+                             "bar", Hello.class);
+        List customActions = new ArrayList();
+        customActions.add(ca1);
+        customActions.add(ca2);
+        // (2) Parse the document with a custom digester.
+        SCXML scxml = SCXMLTestHelper.digest(custom01, customActions);
+        // (3) Get a SCXMLExecutor
         exec = SCXMLTestHelper.getExecutor(scxml);
-        // (6) Fire events, proceed as usual
+        // (4) Single, final state
         assertEquals("custom", ((State) exec.getCurrentStatus().getStates().
                 iterator().next()).getId());
         assertTrue(exec.getCurrentStatus().isFinal());
+    }
+
+    // Hello World example using custom <my:hello> action
+    // as part of an external state source (src attribute)
+    public void testCustomActionExternalSrcHelloWorld() {
+        // (1) Form a list of custom actions defined in the SCXML
+        //     document (and any included documents via "src" attributes)
+        CustomAction ca =
+            new CustomAction("http://my.custom-actions.domain/CUSTOM";,
+                             "hello", Hello.class);
+        List customActions = new ArrayList();
+        customActions.add(ca);
+        // (2) Parse the document with a custom digester.
+        SCXML scxml = SCXMLTestHelper.digest(external01, customActions);
+        // (3) Get a SCXMLExecutor
+        exec = SCXMLTestHelper.getExecutor(scxml);
+        // (4) Single, final state
+        assertEquals("custom", ((State) exec.getCurrentStatus().getStates().
+            iterator().next()).getId());
+    }
+
+    // The custom action defined by Hello.class should be called
+    // to execute() exactly 4 times upto this point
+    public void testCustomActionCallbacks() {
+        assertEquals(4, Hello.callbacks);
     }
 
 }

Modified: 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/Hello.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/Hello.java?rev=407424&r1=407423&r2=407424&view=diff
==============================================================================
--- 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/Hello.java
 (original)
+++ 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/Hello.java
 Wed May 17 18:16:30 2006
@@ -31,6 +31,8 @@
 
     /** This is who we say hello to. */
     private String name;
+    /** We count callbacks to execute() as part of the test suite. */
+    public static int callbacks = 0;
 
     /** Public constructor is needed for the I in SCXML IO. */
     public Hello() {
@@ -65,6 +67,7 @@
         if (appLog.isInfoEnabled()) {
             appLog.info("Hello " + name);
         }
+        callbacks++;
     }
 }
 

Modified: 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/HistoryTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/HistoryTest.java?rev=407424&r1=407423&r2=407424&view=diff
==============================================================================
--- 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/HistoryTest.java
 (original)
+++ 
jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/HistoryTest.java
 Wed May 17 18:16:30 2006
@@ -15,12 +15,21 @@
  */
 package org.apache.commons.scxml.model;
 
+import java.net.URL;
+import java.util.Set;
+
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
-public class HistoryTest extends TestCase {
+import org.apache.commons.scxml.SCXMLExecutor;
+import org.apache.commons.scxml.SCXMLTestHelper;
 
+public class HistoryTest extends TestCase {
+    /**
+     * Construct a new instance of HistoryTest with
+     * the specified name
+     */
     public HistoryTest(String testName) {
         super(testName);
     }
@@ -33,13 +42,37 @@
         String[] testCaseName = { HistoryTest.class.getName()};
         junit.textui.TestRunner.main(testCaseName);
     }
-    
+
+    // Test data
     private History history;
-    
+    private URL shallow01, deep01, defaults01;
+    private SCXMLExecutor exec;
+
+    /**
+     * Set up instance variables required by this test case.
+     */   
     public void setUp() {
         history = new History();
+        shallow01 = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/history-shallow-01.xml");
+        deep01 = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/history-deep-01.xml");
+        defaults01 = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/history-default-01.xml");
     }
-    
+
+    /**
+     * Tear down instance variables required by this test case.
+     */
+    public void tearDown() {
+        history = null;
+        shallow01 = deep01 = defaults01 = null;
+        exec = null;
+    }
+
+    /**
+     * Test the implementation
+     */
     public void testSetTypeDeep() {
         history.setType("deep");
         
@@ -51,4 +84,70 @@
         
         assertFalse(history.isDeep());
     }
+
+    public void testShallowHistory01() {
+        exec = SCXMLTestHelper.getExecutor(shallow01);
+        runHistoryFlow();
+    }
+
+    public void testDeepHistory01() {
+        exec = SCXMLTestHelper.getExecutor(deep01);
+        runHistoryFlow();
+    }
+
+    public void testHistoryDefaults01() {
+        exec = SCXMLTestHelper.getExecutor(defaults01);
+        Set currentStates = exec.getCurrentStatus().getStates();
+        assertEquals(1, currentStates.size());
+        assertEquals("state11", ((State)currentStates.iterator().
+            next()).getId());
+        currentStates = SCXMLTestHelper.fireEvent(exec, "state.next");
+        assertEquals(1, currentStates.size());
+        assertEquals("state211", ((State)currentStates.iterator().
+            next()).getId());
+        currentStates = SCXMLTestHelper.fireEvent(exec, "state.next");
+        assertEquals(1, currentStates.size());
+        assertEquals("state31", ((State)currentStates.iterator().
+            next()).getId());
+    }
+
+    private void runHistoryFlow() {
+        Set currentStates = exec.getCurrentStatus().getStates();
+        assertEquals(1, currentStates.size());
+        assertEquals("phase1", ((State)currentStates.iterator().
+            next()).getId());
+        assertEquals("phase1", pauseAndResume());
+        assertEquals("phase2", nextPhase());
+        // pause and resume couple of times for good measure
+        assertEquals("phase2", pauseAndResume());
+        assertEquals("phase2", pauseAndResume());
+        assertEquals("phase3", nextPhase());
+        assertEquals("phase3", pauseAndResume());
+        try {
+            exec.reset();
+        } catch (ModelException me) {
+            fail(me.getMessage());
+        }
+        currentStates = exec.getCurrentStatus().getStates();
+        assertEquals(1, currentStates.size());
+        assertEquals("phase1", ((State)currentStates.iterator().
+            next()).getId());
+    }
+
+    private String pauseAndResume() {
+        Set currentStates = SCXMLTestHelper.fireEvent(exec, "flow.pause");
+        assertEquals(1, currentStates.size());
+        assertEquals("interrupted", ((State)currentStates.iterator().
+            next()).getId());
+        currentStates = SCXMLTestHelper.fireEvent(exec, "flow.resume");
+        assertEquals(1, currentStates.size());
+        return ((State)currentStates.iterator().next()).getId();
+    }
+
+    private String nextPhase() {
+        Set currentStates = SCXMLTestHelper.fireEvent(exec, "phase.done");
+        assertEquals(1, currentStates.size());
+        return ((State)currentStates.iterator().next()).getId();
+    }
+
 }

Modified: jakarta/commons/proper/scxml/trunk/xdocs/guide/core-digester.xml
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/xdocs/guide/core-digester.xml?rev=407424&r1=407423&r2=407424&view=diff
==============================================================================
--- jakarta/commons/proper/scxml/trunk/xdocs/guide/core-digester.xml (original)
+++ jakarta/commons/proper/scxml/trunk/xdocs/guide/core-digester.xml Wed May 17 
18:16:30 2006
@@ -38,6 +38,7 @@
         //import java.io.IOException;
         //import java.net.URL;
         //import org.apache.commons.scxml.io.SCXMLDigester;
+        //import org.apache.commons.scxml.model.ModelException;
         //import org.apache.commons.scxml.model.SCXML;
         //import org.xml.sax.ErrorHandler;
         //import org.xml.sax.SAXException;
@@ -50,6 +51,8 @@
           // IOException while parsing
         } catch (SAXException se) {
           // SAXException while parsing
+        } catch (ModelException me) {
+          // ModelException while parsing
         }
           
 

Modified: jakarta/commons/proper/scxml/trunk/xdocs/guide/custom-actions.xml
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/xdocs/guide/custom-actions.xml?rev=407424&r1=407423&r2=407424&view=diff
==============================================================================
--- jakarta/commons/proper/scxml/trunk/xdocs/guide/custom-actions.xml (original)
+++ jakarta/commons/proper/scxml/trunk/xdocs/guide/custom-actions.xml Wed May 
17 18:16:30 2006
@@ -118,28 +118,41 @@
 
    </subsection>
 
-   <subsection name="Registering the action with the digester">
+   <subsection name="Using a custom SCXML digester">
 
-    <p>With the custom action implemented, obtain a configured digester which
-       has the "default" ruleset required for reading (parsing) SCXML
-       documents, and then register the custom action like so:</p>
+    <p>With the custom action(s) implemented, the document may be
+    parsed using a custom SCXML digester that is aware of these actions
+    like so:</p>
 
     <pre>
-      // (1) Get Digester with "default" rules for parsing SCXML documents
-      Digester digester = SCXMLDigester.newInstance(null, null);
+      // (1) Create a list of custom actions, add as many as are needed
+      List customActions = new ArrayList();
+      CustomAction ca =
+            new CustomAction("http://my.custom-actions.domain/CUSTOM";,
+                             "hello", Hello.class);
+      customActions.add(ca);
 
-      // (2) Register the "custom" action(s)
-      SCXMLDigester.addCustomAction(digester,
-          "http://my.custom-actions.domain/CUSTOM";, "hello", Hello.class);
+      // (2) Parse the SCXML document containing the custom action(s)
+      SCXML scxml = null;
+      try {
+          scxml = SCXMLDigester.digest(url, errorHandler, customActions);
+          // Also see other methods in SCXMLDigester API
+          // "url" points to SCXML document
+          // "errorHandler" is SAX ErrorHandler
+      } catch (Exception e) {
+          // bad document, take necessary action
+      }
     </pre>
 
-    <p>This static addCustomAction() method can only be used if the custom
+    <p>This approach can only be used if the custom
        rule has no body content (child "tags") or if the custom action
        implements the
        <a 
href="../apidocs/org/apache/commons/scxml/model/ExternalContent.html">ExternalContent</a>
        interface, in which case, any body content gets read into a list
        of DOM nodes. For any other requirements, the digester rules
-       can be added by directly using the
+       can be added by directly by obtaining a Digester instance with the
+       "default" SCXML rules using the <code>newInstance()</code> methods
+       and further directly adding the necessary rules using the
        <a 
href="http://jakarta.apache.org/commons/digester/commons-digester-1.7/docs/api/";>digester
 API</a>
        .</p>
 
@@ -147,24 +160,6 @@
 
    <subsection name="Read in the 'custom' SCXML document">
 
-    <p>This involves parsing the document and making the resulting
-       SCXML object executor-ready (which allows us to detect any
-       "model inconsistencies" before feeding it to the
-       execution engine). That amounts to:</p>
-
-    <pre>
-      // (3) Parse the SCXML document containing the custom action(s)
-      SCXML scxml = null;
-      try {
-          scxml = (SCXML) digester.parse(&lt;String&gt;);
-          //String method as an example
-      } catch (Exception e) {
-          // bad document, take necessary action
-      }
-      // (4) Wire up the object model for the SCXMLExecutor
-      SCXMLDigester.updateSCXML(scxml);
-    </pre>
-
     <p>For documents without custom actions, the utility methods of the
        <a 
href="../apidocs/org/apache/commons/scxml/io/SCXMLDigester.html">SCXMLDigester</a>
        should be used. That section is
@@ -175,7 +170,7 @@
 
    <subsection name="Launching the engine">
 
-    <p>Having obtained the SCXML object beyond step (4) above,
+    <p>Having obtained the SCXML object beyond step (2) above,
        proceed as usual, see the section on the
        <a href="core-engine.html">Commons SCXML engine</a>
        for details.</p>



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

Reply via email to