Author: rahul
Date: Sat Dec 10 15:49:28 2005
New Revision: 355810

URL: http://svn.apache.org/viewcvs?rev=355810&view=rev
Log:
Start capturing arbitrary namespace nodes in SCXML documents (beginning with 
<send> element).

 * Make digester namespace aware.
 * Grab external namespace child nodes for <send>
 * Add test case for <send> parsing and serialization

Nudge by Mike Sparr.

Added:
    
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml
   (with props)
Modified:
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLDigester.java
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java
    
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLDigesterTest.java

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLDigester.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLDigester.java?rev=355810&r1=355809&r2=355810&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLDigester.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLDigester.java
 Sat Dec 10 15:49:28 2005
@@ -17,6 +17,8 @@
  */
 package org.apache.commons.scxml;
 
+import java.io.IOException;
+import java.io.StringWriter;
 import java.net.URL;
 import java.text.MessageFormat;
 import java.util.Iterator;
@@ -24,8 +26,11 @@
 import java.util.Map;
 import java.util.Set;
 
+import javax.xml.parsers.ParserConfigurationException;
+
 import org.apache.commons.digester.Digester;
 import org.apache.commons.digester.ExtendedBaseRules;
+import org.apache.commons.digester.NodeCreateRule;
 import org.apache.commons.digester.ObjectCreateRule;
 import org.apache.commons.digester.Rule;
 import org.apache.commons.digester.SetNextRule;
@@ -54,6 +59,11 @@
 import org.apache.commons.scxml.model.TransitionTarget;
 import org.apache.commons.scxml.model.Var;
 
+import org.apache.xml.serialize.XMLSerializer;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.InputSource;
@@ -340,7 +350,7 @@
      * This message may be rendered hence wrapped in a comment.
      */
     private static final String ERR_DOC_PARSE_FAIL = "<!-- Error parsing "
-        + "SCXML document for group: \"{0}\", with message: \"{1}\" -->\n";
+        + "SCXML document: \"{0}\", with message: \"{1}\" -->\n";
 
     /**
      * Error message when SCXML document specifies an illegal initial state.
@@ -393,6 +403,7 @@
             final PathResolver pr) {
 
         Digester digester = new Digester();
+        digester.setNamespaceAware(true);
         //Uncomment next line after SCXML DTD is available
         //digester.setValidating(true);
         digester.setRules(initRules(scxml, pr));
@@ -640,12 +651,32 @@
         addActionRulesTuple(xp + XP_ASN, scxmlRules, Assign.class);
         addActionRulesTuple(xp + XP_VAR, scxmlRules, Var.class);
         addActionRulesTuple(xp + XP_LOG, scxmlRules, Log.class);
-        addActionRulesTuple(xp + XP_SND, scxmlRules, Send.class);
+        addSendRulesTuple(xp + XP_SND, scxmlRules);
         addActionRulesTuple(xp + XP_CAN, scxmlRules, Cancel.class);
         addActionRulesTuple(xp + XP_EXT, scxmlRules, Exit.class);
     }
 
     /**
+     * Add Digester rules that are specific to the &lt;send&gt; action
+     * element.
+     *
+     * @param xp The Digester style XPath expression of &lt;send&gt; element
+     * @param scxmlRules The rule set to be used for digestion
+     * @param klass The class in the Java object model to be instantiated
+     *              in the ObjectCreateRule for this action
+     */
+    private static void addSendRulesTuple(final String xp,
+            final ExtendedBaseRules scxmlRules) {
+        addActionRulesTuple(xp, scxmlRules, Send.class);
+        try {
+            scxmlRules.add(xp, new ParseSendRule());
+        } catch (ParserConfigurationException pce) {
+            log.error("Error parsing <send> element content",
+                pce);
+        }
+    }
+
+    /**
      * Add Digester rules for all &lt;if&gt; elements.
      *
      * @param xp The Digester style XPath expression of the parent
@@ -1123,15 +1154,7 @@
                         .append(asn.getName()).append("\" expr=\"")
                         .append(asn.getExpr()).append("\"/>\n");
             } else if (a instanceof Send) {
-                Send s = (Send) a;
-                b.append(indent).append("<send sendid=\"")
-                    .append(s.getSendid()).append("\" target=\"")
-                    .append(s.getTarget()).append("\" targetType=\"")
-                    .append(s.getTargettype()).append("\" namelist=\"")
-                    .append(s.getNamelist()).append("\" delay=\"")
-                    .append(s.getDelay()).append("\" events=\"")
-                    .append(s.getEvent()).append("\" hints=\"")
-                    .append(s.getHints()).append("\"/>\n");
+                serializeSend(b, (Send) a, indent);
             } else if (a instanceof Cancel) {
                 Cancel c = (Cancel) a;
                 b.append(indent).append("<cancel sendid=\"")
@@ -1168,6 +1191,31 @@
     }
 
     /**
+     * Serialize this Send object.
+     *
+     * @param b The buffer to append the serialization to
+     * @param send The Send object to serialize
+     * @param indent The indent for this XML element
+     */
+    private static void serializeSend(final StringBuffer b,
+            final Send send, final String indent) {
+        b.append(indent).append("<send sendid=\"")
+            .append(send.getSendid()).append("\" target=\"")
+            .append(send.getTarget()).append("\" targetType=\"")
+            .append(send.getTargettype()).append("\" namelist=\"")
+            .append(send.getNamelist()).append("\" delay=\"")
+            .append(send.getDelay()).append("\" events=\"")
+            .append(send.getEvent()).append("\" hints=\"")
+            .append(send.getHints()).append("\">\n");
+        try {
+            b.append(send.getBodyContent());
+        } catch (IOException ioe) {
+            log.error("Failed to serialize external nodes for <send>", ioe);
+        }
+        b.append(indent).append("</send>\n");
+    }
+
+    /**
      * Serialize this If object.
      *
      * @param b The buffer to append the serialization to
@@ -1252,6 +1300,31 @@
                     child.setParent((Executable) ancestor);
                     return;
                 }
+            }
+        }
+    }
+
+    /**
+     * Custom digestion rule for setting Executable parent of Action elements.
+     *
+     */
+    public static class ParseSendRule extends NodeCreateRule {
+        /**
+         * Constructor
+         * @throws ParserConfigurationException
+         */
+        public ParseSendRule() throws ParserConfigurationException {
+            super();
+        }
+        /**
+         * @see Rule#end(String, String)
+         */
+        public final void end(final String namespace, final String name) {
+            Element sendElement = (Element) getDigester().pop();
+            NodeList childNodes = sendElement.getChildNodes();
+            Send send = (Send) getDigester().peek();
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                send.getExternalNodes().add(childNodes.item(i));
             }
         }
     }

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java?rev=355810&r1=355809&r2=355810&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java
 Sat Dec 10 15:49:28 2005
@@ -17,9 +17,15 @@
  */
 package org.apache.commons.scxml.model;
 
+import java.io.IOException;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.Element;
+
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;send&gt; SCXML element.
@@ -70,6 +76,15 @@
     private String event;
 
     /**
+     * OutputFormat used to serialize external nodes.
+     */
+    private static final OutputFormat format;
+    static {
+        format = new OutputFormat();
+        format.setOmitXMLDeclaration(true);
+    }
+
+    /**
      * Constructor.
      */
     public Send() {
@@ -187,6 +202,23 @@
      */
     public final String getEvent() {
         return event;
+    }
+
+    /**
+     * Return serialized external nodes.
+     *
+     * @throws IOException Serialization failed
+     */
+    public final String getBodyContent() throws IOException {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < externalNodes.size(); i++) {
+            StringWriter out = new StringWriter();
+            XMLSerializer output = new XMLSerializer(out, format);
+            output.setNamespaces(true);
+            output.serialize((Element) externalNodes.get(i));
+            buf.append(out.toString()).append("\n");
+        }
+        return buf.toString();
     }
 
 }

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLDigesterTest.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLDigesterTest.java?rev=355810&r1=355809&r2=355810&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLDigesterTest.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLDigesterTest.java
 Sat Dec 10 15:49:28 2005
@@ -16,6 +16,7 @@
 package org.apache.commons.scxml;
 
 import java.net.URL;
+import java.util.List;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -23,6 +24,9 @@
 import junit.textui.TestRunner;
 
 import org.apache.commons.scxml.model.SCXML;
+import org.apache.commons.scxml.model.Send;
+import org.apache.commons.scxml.model.State;
+import org.apache.commons.scxml.model.Transition;
 /**
  * Unit tests [EMAIL PROTECTED] org.apache.commons.scxml.SCXMLDigester}.
  */
@@ -42,7 +46,7 @@
     }
 
     // Test data
-    private URL microwave01, microwave02, transitions01;
+    private URL microwave01, microwave02, transitions01, send01;
     private SCXML scxml;
     private String scxmlAsString;
 
@@ -56,13 +60,15 @@
             getResource("org/apache/commons/scxml/microwave-02.xml");
         transitions01 = this.getClass().getClassLoader().
             getResource("org/apache/commons/scxml/transitions-01.xml");
+        send01 = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/send-01.xml");
     }
 
     /**
      * Tear down instance variables required by this test case.
      */
     public void tearDown() {
-        microwave01 = microwave02 = transitions01 = null;
+        microwave01 = microwave02 = transitions01 = send01 = null;
         scxml = null;
         scxmlAsString = null;
     }
@@ -83,6 +89,28 @@
     public void testSCXMLDigesterTransitions01Sample() {
         scxml = SCXMLTestHelper.digest(transitions01);
         scxmlAsString = serialize(scxml);
+    }
+
+    public void testSCXMLDigesterSend01Sample() {
+        // Digest
+        scxml = SCXMLTestHelper.digest(send01);
+        State ten = scxml.getInitialState();
+        assertEquals("ten", ten.getId());
+        List ten_done = ten.getTransitionsList("ten.done");
+        assertEquals(1, ten_done.size());
+        Transition ten2twenty = (Transition) ten_done.get(0);
+        List actions = ten2twenty.getActions();
+        assertEquals(1, actions.size());
+        Send send = (Send) actions.get(0);
+        assertEquals("send1", send.getSendid());
+        // Serialize
+        scxmlAsString = serialize(scxml);
+        assertNotNull(scxmlAsString);
+        String expectedFoo2Serialization =
+            "<foo xmlns=\"http://my.test.namespace\"; id=\"foo2\">"
+            + "<prompt xmlns=\"http://foo.bar.com/vxml3\";>This is just"
+            + " an example.</prompt></foo>";
+        assertFalse(scxmlAsString.indexOf(expectedFoo2Serialization) == -1);
     }
 
     private String serialize(final SCXML scxml) {

Added: 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml?rev=355810&view=auto
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml
 (added)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml
 Sat Dec 10 15:49:28 2005
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+   Copyright 2005 The Apache Software Foundation
+
+   Licensed 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.
+-->
+<scxml xmlns="http://www.w3.org/2005/07/SCXML";
+       version="1.0"
+       initialstate="ten">
+
+    <state id="ten">
+        <transition event="ten.done">
+            <send sendid="send1" delay="0"
+             target="http://localhost:8080/VXMLInterpreter"; targettype="v3"
+             xmlns:v3="http://foo.bar.com/vxml3";
+             xmlns:test="http://my.test.namespace";>
+                <v3:form id="Confirm">
+                    <v3:grammar type="boolean" />
+                    <v3:block>
+                        <v3:prompt>Say yes or no.</v3:prompt>
+                    </v3:block>
+                </v3:form>
+                <test:foo id="foo1">
+                    <test:bar id="bar1" />
+                </test:foo>
+                <test:foo id="foo2">
+                    <v3:prompt>This is just an example.</v3:prompt>
+                </test:foo>
+            </send>
+            <target next="twenty"/>
+        </transition>
+    </state>
+
+    <state id="twenty" final="true" />
+
+</scxml>
+

Propchange: 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/send-01.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



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

Reply via email to