Author: rahul
Date: Fri Nov 21 12:57:08 2008
New Revision: 719709
URL: http://svn.apache.org/viewvc?rev=719709&view=rev
Log:
SCXMLSerializer does not serialize custom namespace declarations.
Partial fix, with assumptions / limitations added to class Javadoc.
SCXML-88
Modified:
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLParser.java
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/SCXML.java
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLSerializerTest.java
Modified:
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLParser.java
URL:
http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLParser.java?rev=719709&r1=719708&r2=719709&view=diff
==============================================================================
---
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLParser.java
(original)
+++
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLParser.java
Fri Nov 21 12:57:08 2008
@@ -728,6 +728,7 @@
//// SCXML
scxmlRules.add(XP_SM, new ObjectCreateRule(SCXML.class));
scxmlRules.add(XP_SM, new SetPropertiesRule());
+ scxmlRules.add(XP_SM, new SetCurrentNamespacesRule());
//// Datamodel at document root i.e. <scxml> datamodel
addDatamodelRules(XP_SM + XPF_DM, scxmlRules, scxml, pr);
Modified:
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java
URL:
http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java?rev=719709&r1=719708&r2=719709&view=diff
==============================================================================
---
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java
(original)
+++
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java
Fri Nov 21 12:57:08 2008
@@ -49,6 +49,7 @@
import org.apache.commons.scxml.model.Initial;
import org.apache.commons.scxml.model.Invoke;
import org.apache.commons.scxml.model.Log;
+import org.apache.commons.scxml.model.NamespacePrefixesHolder;
import org.apache.commons.scxml.model.OnEntry;
import org.apache.commons.scxml.model.OnExit;
import org.apache.commons.scxml.model.Parallel;
@@ -62,11 +63,22 @@
import org.w3c.dom.Node;
/**
- * Utility class for serializing the Commons SCXML Java object
+ * <p>Utility class for serializing the Commons SCXML Java object
* model. Class uses the visitor pattern to trace through the
* object heirarchy. Used primarily for testing, debugging and
- * visual verification.
+ * visual verification.</p>
*
+ * <b>NOTE:</b> This serializer makes the following assumptions about the
+ * original SCXML document(s) parsed to create the object model:
+ * <ul>
+ * <li>The default document namespace is the SCXML namespace:
+ * <i>http://www.w3.org/2005/07/scxml</i></li>
+ * <li>The Commons SCXML namespace
+ * ( <i>http://commons.apache.org/scxml</i> ), if needed, uses the
+ * "<i>cs</i>" prefix</li>
+ * <li>All namespace prefixes needed throughout the document are
+ * declared on the document root element (<scxml>)</li>
+ * </ul>
*/
public class SCXMLSerializer {
@@ -92,8 +104,8 @@
StringBuffer b =
new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n").
append("<scxml xmlns=\"").append(NAMESPACE_SCXML).
- append("\" xmlns:cs=\"").append(NAMESPACE_COMMONS_SCXML).
- append("\" version=\"").append(scxml.getVersion()).
+ append("\"").append(serializeNamespaceDeclarations(scxml)).
+ append(" version=\"").append(scxml.getVersion()).
append("\" initial=\"").append(scxml.getInitial()).
append("\">\n");
if (XFORMER == null) {
@@ -103,6 +115,7 @@
+ " the document will be skipped since a suitable"
+ " JAXP Transformer could not be instantiated.");
}
+ b.append(INDENT).append("<!-- http://commons.apache.org/scxml -->\n");
Datamodel dm = scxml.getDatamodel();
if (dm != null) {
serializeDatamodel(b, dm, INDENT);
@@ -585,6 +598,43 @@
}
/**
+ * Serialize namespace declarations for the root SCXML element.
+ *
+ * @param holder The [EMAIL PROTECTED] NamespacePrefixesHolder} object
+ */
+ private static String serializeNamespaceDeclarations(
+ final NamespacePrefixesHolder holder) {
+ Map ns = holder.getNamespaces();
+ StringBuffer b = new StringBuffer();
+ if (ns != null) {
+ Iterator iter = ns.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String prefix = (String) entry.getKey();
+ String nsURI = (String) entry.getValue();
+ if (prefix.length() == 0 && !nsURI.equals(NAMESPACE_SCXML)) {
+ org.apache.commons.logging.Log log = LogFactory.
+ getLog(SCXMLSerializer.class);
+ log.warn("When using the SCXMLSerializer, the default " +
+ "namespace must be the SCXML namespace:" +
+ NAMESPACE_SCXML);
+ } if (prefix.equals("cs") &&
+ !nsURI.equals(NAMESPACE_COMMONS_SCXML)) {
+ org.apache.commons.logging.Log log = LogFactory.
+ getLog(SCXMLSerializer.class);
+ log.warn("When using the SCXMLSerializer, the namespace" +
+ "prefix \"cs\" must bind to the Commons SCXML " +
+ "namespace:" + NAMESPACE_COMMONS_SCXML);
+ } else if (prefix.length() > 0) {
+ b.append(" xmlns:").append(prefix).append("=\"").
+ append(nsURI).append("\"");
+ }
+ }
+ }
+ return b.toString();
+ }
+
+ /**
* Get a <code>Transformer</code> instance.
*
* @return Transformer The <code>Transformer</code> instance.
Modified:
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/SCXML.java
URL:
http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/SCXML.java?rev=719709&r1=719708&r2=719709&view=diff
==============================================================================
---
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/SCXML.java
(original)
+++
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/SCXML.java
Fri Nov 21 12:57:08 2008
@@ -29,7 +29,7 @@
* root".
*
*/
-public class SCXML implements Serializable {
+public class SCXML implements Serializable, NamespacePrefixesHolder {
/**
* Serial version UID.
@@ -81,6 +81,12 @@
private Map targets;
/**
+ * The XML namespaces defined on the SCXML document root node,
+ * preserved primarily for serialization.
+ */
+ private Map namespaces;
+
+ /**
* Indicates whether the legacy parser
* ([EMAIL PROTECTED] org.apache.commons.scxml.io.SCXMLDigester}) was used.
*/
@@ -264,6 +270,27 @@
}
/**
+ * Get the namespace definitions specified on the SCXML element.
+ * May be <code>null</code>.
+ *
+ * @return The namespace definitions specified on the SCXML element,
+ * may be <code>null</code>.
+ */
+ public final Map getNamespaces() {
+ return namespaces;
+ }
+
+ /**
+ * Set the namespace definitions specified on the SCXML element.
+ *
+ * @param namespaces The namespace definitions specified on the
+ * SCXML element.
+ */
+ public final void setNamespaces(final Map namespaces) {
+ this.namespaces = namespaces;
+ }
+
+ /**
* Get the ID of the initial state.
*
* @return String Returns the initial state ID (used by XML Digester only).
Modified:
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLSerializerTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLSerializerTest.java?rev=719709&r1=719708&r2=719709&view=diff
==============================================================================
---
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLSerializerTest.java
(original)
+++
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/io/SCXMLSerializerTest.java
Fri Nov 21 12:57:08 2008
@@ -17,7 +17,9 @@
package org.apache.commons.scxml.io;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import junit.framework.Test;
import junit.framework.TestCase;
@@ -57,13 +59,21 @@
public void testSerializeSCXMLNoStates() {
SCXML scxml = new SCXML();
+ Map namespaces = new LinkedHashMap();
+ namespaces.put("", "http://www.w3.org/2005/07/scxml");
+ namespaces.put("cs", "http://commons.apache.org/scxml");
+ namespaces.put("foo", "http://f.o.o");
+ namespaces.put("bar", "http://b.a.r");
+ scxml.setNamespaces(namespaces);
scxml.setVersion("version1");
scxml.setInitial("off");
scxml.addChild(new State());
String assertValue = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\"
xmlns:cs=\"http://commons.apache.org/scxml\" "
- + "version=\"version1\" initial=\"off\">\n <state>\n
</state>\n</scxml>\n";
+ + "xmlns:foo=\"http://f.o.o\" xmlns:bar=\"http://b.a.r\" "
+ + "version=\"version1\" initial=\"off\">\n <!--
http://commons.apache.org/scxml -->\n <state>\n "
+ + "</state>\n</scxml>\n";
assertEquals(assertValue, SCXMLSerializer.serialize(scxml));
}
@@ -327,8 +337,9 @@
scxml.addChild(s1);
String assertValue = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\"
xmlns:cs=\"http://commons.apache.org/scxml\" "
- + "version=\"1.0\" initial=\"S1\">\n <state id=\"S1\">\n
</state>\n</scxml>\n";
+ + "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\" "
+ + "version=\"1.0\" initial=\"S1\">\n <!--
http://commons.apache.org/scxml -->\n"
+ + " <state id=\"S1\">\n </state>\n</scxml>\n";
assertEquals(assertValue, SCXMLSerializer.serialize(scxml));
}
@@ -364,8 +375,9 @@
scxml.addChild(par);
String assertValue = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\"
xmlns:cs=\"http://commons.apache.org/scxml\" "
+ + "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\" "
+ "version=\"1.0\" initial=\"par\">\n"
+ + " <!-- http://commons.apache.org/scxml -->\n"
+ " <parallel id=\"par\">\n"
+ " <state id=\"S1\">\n"
+ " <state id=\"S11\">\n"