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 <send> action + * element. + * + * @param xp The Digester style XPath expression of <send> 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 <if> 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 * <send> 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]