Author: rahul
Date: Thu May 22 12:03:42 2008
New Revision: 659205
URL: http://svn.apache.org/viewvc?rev=659205&view=rev
Log:
Move towards eliminating the Xalan dependency.
Replace Xalan PrefixResolver with a NamespaceContext adapter for namespaces
supplied by current parser. Once the parser is rewritten to not use Commons
Digester, this adapter will no longer be necessary.
Modified:
commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java
Modified:
commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java
URL:
http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java?rev=659205&r1=659204&r2=659205&view=diff
==============================================================================
---
commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java
(original)
+++
commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java
Thu May 22 12:03:42 2008
@@ -17,18 +17,21 @@
package org.apache.commons.scxml;
import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.xml.transform.TransformerException;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.scxml.model.TransitionTarget;
-import org.apache.xml.utils.PrefixResolver;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathAPI;
-import org.apache.xpath.XPathContext;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -92,6 +95,7 @@
Node dataNode = (Node) data;
NodeList result = null;
try {
+ XPath xpath = XPathFactory.newInstance().newXPath();
if (namespaces == null || namespaces.size() == 0) {
Log log = LogFactory.getLog(Builtin.class);
if (log.isDebugEnabled()) {
@@ -99,20 +103,14 @@
+ "no namespace information is available for path: "
+ path);
}
- result = XPathAPI.selectNodeList(dataNode, path);
} else {
- XPathContext xpathSupport = new XPathContext();
- PrefixResolver prefixResolver =
- new DataPrefixResolver(namespaces);
- XPath xpath = new XPath(path, null, prefixResolver,
- XPath.SELECT);
- int ctxtNode = xpathSupport.getDTMHandleFromNode(dataNode);
- result = xpath.execute(xpathSupport, ctxtNode,
- prefixResolver).nodelist();
+ xpath.setNamespaceContext(new ExpressionNSContext(namespaces));
}
- } catch (TransformerException te) {
+ result = (NodeList) xpath.evaluate(path, dataNode,
+ XPathConstants.NODESET);
+ } catch (XPathExpressionException xee) {
Log log = LogFactory.getLog(Builtin.class);
- log.error(te.getMessage(), te);
+ log.error(xee.getMessage(), xee);
return null;
}
int length = result.getLength();
@@ -169,40 +167,86 @@
}
/**
- * Prefix resolver for XPaths pointing to <data> nodes.
+ * XPath [EMAIL PROTECTED] NamespaceContext} for Commons SCXML expressions.
*/
- private static class DataPrefixResolver implements PrefixResolver {
+ private static final class ExpressionNSContext
+ implements Serializable, NamespaceContext {
- /** Cached namespaces. */
- private Map<String, String> namespaces;
+ /** Serial version UID. */
+ private static final long serialVersionUID = 8620558582288851315L;
+ /** Map supplied by digester. */
+ private final Map<String, String> namespaces;
/**
* Constructor.
- * @param namespaces The prefix to namespace URI map.
+ *
+ * @param namespaces The current namespace map.
*/
- private DataPrefixResolver(final Map<String, String> namespaces) {
+ ExpressionNSContext(final Map<String, String> namespaces) {
this.namespaces = namespaces;
}
- /** [EMAIL PROTECTED] */
- public String getNamespaceForPrefix(final String prefix) {
+ /**
+ * @see NamespaceContext#getNamespaceURI(String)
+ */
+ @Override
+ public String getNamespaceURI(final String prefix) {
return namespaces.get(prefix);
}
- /** [EMAIL PROTECTED] */
- public String getNamespaceForPrefix(final String prefix,
- final Node nsContext) {
- return namespaces.get(prefix);
+ /**
+ * @see NamespaceContext#getPrefix(String)
+ *
+ * First matching key in iteration order is returned, and the
+ * iteration order depends on the underlying <code>namespaces</code>
+ * [EMAIL PROTECTED] Map} implementation.
+ */
+ @Override
+ public String getPrefix(final String namespaceURI) {
+ return (String) getKeys(namespaceURI, true);
}
- /** [EMAIL PROTECTED] */
- public String getBaseIdentifier() {
- return null;
+ /**
+ * @see NamespaceContext#getPrefixes(String)
+ *
+ * The iteration order depends on the underlying
<code>namespaces</code>
+ * [EMAIL PROTECTED] Map} implementation.
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public Iterator<String> getPrefixes(final String namespaceURI) {
+ return (Iterator<String>) getKeys(namespaceURI, false);
}
- /** [EMAIL PROTECTED] */
- public boolean handlesNullPrefixes() {
- return false;
+ /**
+ * Get prefix key(s) for given namespaceURI value.
+ *
+ * If <code>one</code>, first matching key in iteration order is
+ * returned, and the iteration order depends on the underlying
+ * <code>namespaces</code> [EMAIL PROTECTED] Map} implementation.
+ * Otherwise, an iterator to all matching keys is returned.
+ *
+ * @param value The value whose key is required
+ * @param one At most one matching key is returned
+ * @return The required prefix key(s)
+ */
+ private Object getKeys(final String value, final boolean one) {
+ List<String> prefixes = new LinkedList<String>();
+ if (namespaces.containsValue(value)) {
+ for (Map.Entry<String, String> entry : namespaces.entrySet()) {
+ String v = entry.getValue();
+ if ((value == null && v == null) ||
+ (value != null && value.equals(v))) {
+ String prefix = entry.getKey();
+ if (one) {
+ return prefix;
+ } else {
+ prefixes.add(prefix);
+ }
+ }
+ }
+ }
+ return one ? null : prefixes.iterator();
}
}