Author: mbenson Date: Wed Jul 25 12:49:33 2007 New Revision: 559574 URL: http://svn.apache.org/viewvc?view=rev&rev=559574 Log: [JXPATH-97] handle createPathAndSetValue() for externally registered namespaced attributes
Modified: jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/NamespaceResolver.java jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMAttributeIterator.java jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMAttributeIterator.java jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java jakarta/commons/proper/jxpath/trunk/src/test/org/apache/commons/jxpath/ri/model/ExternalXMLNamespaceTest.java Modified: jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/NamespaceResolver.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/NamespaceResolver.java?view=diff&rev=559574&r1=559573&r2=559574 ============================================================================== --- jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/NamespaceResolver.java (original) +++ jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/NamespaceResolver.java Wed Jul 25 12:49:33 2007 @@ -38,6 +38,32 @@ private boolean sealed; /** + * Find the namespace prefix for the specified namespace URI and NodePointer. + * @param pointer + * @param namespaceURI + * @return prefix if found + * @since JXPath 1.3 + */ + protected static String getPrefix(NodePointer pointer, String namespaceURI) { + NodePointer currentPointer = pointer; + while (currentPointer != null) { + NodeIterator ni = currentPointer.namespaceIterator(); + for (int position = 1; ni != null && ni.setPosition(position); position++) { + NodePointer nsPointer = ni.getNodePointer(); + String uri = nsPointer.getNamespaceURI(); + if (uri.equals(namespaceURI)) { + String prefix = nsPointer.getName().getName(); + if (!"".equals(prefix)) { + return prefix; + } + } + } + currentPointer = pointer.getParent(); + } + return null; + } + + /** * Create a new NamespaceResolver. */ public NamespaceResolver() { @@ -60,7 +86,8 @@ */ public synchronized void registerNamespace(String prefix, String namespaceURI) { if (isSealed()) { - throw new IllegalStateException("Cannot register namespaces on a sealed NamespaceResolver"); + throw new IllegalStateException( + "Cannot register namespaces on a sealed NamespaceResolver"); } namespaceMap.put(prefix, namespaceURI); reverseMap = null; @@ -96,14 +123,23 @@ * @return namespace URI or null if the prefix is undefined. */ public synchronized String getNamespaceURI(String prefix) { + String uri = getExternallyRegisteredNamespaceURI(prefix); + return uri == null && pointer != null ? pointer.getNamespaceURI(prefix) + : uri; + } + + /** + * Given a prefix, returns an externally registered namespace URI. + * + * @param prefix The namespace prefix to look up + * @return namespace URI or null if the prefix is undefined. + * @since JXPath 1.3 + */ + protected synchronized String getExternallyRegisteredNamespaceURI( + String prefix) { String uri = (String) namespaceMap.get(prefix); - if (uri == null && pointer != null) { - uri = pointer.getNamespaceURI(prefix); - } - if (uri == null && parent != null) { - return parent.getNamespaceURI(prefix); - } - return uri; + return uri == null && parent != null ? parent + .getExternallyRegisteredNamespaceURI(prefix) : uri; } /** @@ -112,19 +148,20 @@ * @return String prefix */ public synchronized String getPrefix(String namespaceURI) { + String prefix = getExternallyRegisteredPrefix(namespaceURI); + return prefix == null && pointer != null ? getPrefix(pointer, + namespaceURI) : prefix; + } + + /** + * Get the nearest prefix found that matches an externally-registered namespace. + * @param namespaceURI + * @return String prefix if found. + * @since JXPath 1.3 + */ + protected synchronized String getExternallyRegisteredPrefix(String namespaceURI) { if (reverseMap == null) { reverseMap = new HashMap(); - NodeIterator ni = pointer.namespaceIterator(); - if (ni != null) { - for (int position = 1; ni.setPosition(position); position++) { - NodePointer nsPointer = ni.getNodePointer(); - String uri = nsPointer.getNamespaceURI(); - String prefix = nsPointer.getName().getName(); - if (!"".equals(prefix)) { - reverseMap.put(uri, prefix); - } - } - } Iterator it = namespaceMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); @@ -132,10 +169,8 @@ } } String prefix = (String) reverseMap.get(namespaceURI); - if (prefix == null && parent != null) { - return parent.getPrefix(namespaceURI); - } - return prefix; + return prefix == null && parent != null ? parent + .getExternallyRegisteredPrefix(namespaceURI) : prefix; } /** Modified: jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMAttributeIterator.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMAttributeIterator.java?view=diff&rev=559574&r1=559573&r2=559574 ============================================================================== --- jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMAttributeIterator.java (original) +++ jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMAttributeIterator.java Wed Jul 25 12:49:33 2007 @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.commons.jxpath.ri.NamespaceResolver; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.model.NodeIterator; import org.apache.commons.jxpath.ri.model.NodePointer; @@ -109,9 +108,7 @@ String testNS = null; if (testPrefix != null) { - NamespaceResolver nsr = parent.getNamespaceResolver(); - testNS = nsr == null ? null : nsr.getNamespaceURI(testPrefix); - testNS = testNS == null ? parent.getNamespaceURI(testPrefix) : testNS; + testNS = parent.getNamespaceResolver().getNamespaceURI(testPrefix); } if (testNS != null) { Modified: jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java?view=diff&rev=559574&r1=559573&r2=559574 ============================================================================== --- jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java (original) +++ jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java Wed Jul 25 12:49:33 2007 @@ -26,6 +26,7 @@ import org.apache.commons.jxpath.JXPathException; import org.apache.commons.jxpath.Pointer; import org.apache.commons.jxpath.ri.Compiler; +import org.apache.commons.jxpath.ri.NamespaceResolver; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.compiler.NodeNameTest; import org.apache.commons.jxpath.ri.compiler.NodeTest; @@ -58,6 +59,7 @@ private Map namespaces; private String defaultNamespace; private String id; + private NamespaceResolver localNamespaceResolver; public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace"; @@ -183,6 +185,17 @@ return new DOMNamespaceIterator(this); } + /* (non-Javadoc) + * @see org.apache.commons.jxpath.ri.model.NodePointer#getNamespaceResolver() + */ + public synchronized NamespaceResolver getNamespaceResolver() { + if (localNamespaceResolver == null) { + localNamespaceResolver = new NamespaceResolver(super.getNamespaceResolver()); + localNamespaceResolver.setNamespaceContextPointer(this); + } + return localNamespaceResolver; + } + public String getNamespaceURI(String prefix) { if (prefix == null || prefix.equals("")) { return getDefaultNamespaceURI(); @@ -408,7 +421,11 @@ Element element = (Element) node; String prefix = name.getPrefix(); if (prefix != null) { - String ns = getNamespaceURI(prefix); + String ns = null; + NamespaceResolver nsr = getNamespaceResolver(); + if (nsr != null) { + ns = nsr.getNamespaceURI(prefix); + } if (ns == null) { throw new JXPathException( "Unknown namespace prefix: " + prefix); Modified: jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMAttributeIterator.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMAttributeIterator.java?view=diff&rev=559574&r1=559573&r2=559574 ============================================================================== --- jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMAttributeIterator.java (original) +++ jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMAttributeIterator.java Wed Jul 25 12:49:33 2007 @@ -20,7 +20,6 @@ import java.util.Collections; import java.util.List; -import org.apache.commons.jxpath.ri.NamespaceResolver; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.model.NodeIterator; import org.apache.commons.jxpath.ri.model.NodePointer; @@ -50,20 +49,14 @@ ns = Namespace.XML_NAMESPACE; } else { - NamespaceResolver nsr = parent.getNamespaceResolver(); - if (nsr != null) { - String uri = nsr.getNamespaceURI(prefix); - if (uri != null) { - ns = Namespace.getNamespace(prefix, uri); - } + String uri = parent.getNamespaceResolver().getNamespaceURI(prefix); + if (uri != null) { + ns = Namespace.getNamespace(prefix, uri); } if (ns == null) { - ns = element.getNamespace(prefix); - if (ns == null) { - // TBD: no attributes - attributes = Collections.EMPTY_LIST; - return; - } + // TBD: no attributes + attributes = Collections.EMPTY_LIST; + return; } } } Modified: jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java?view=diff&rev=559574&r1=559573&r2=559574 ============================================================================== --- jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java (original) +++ jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java Wed Jul 25 12:49:33 2007 @@ -24,6 +24,7 @@ import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.JXPathException; import org.apache.commons.jxpath.ri.Compiler; +import org.apache.commons.jxpath.ri.NamespaceResolver; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.compiler.NodeNameTest; import org.apache.commons.jxpath.ri.compiler.NodeTest; @@ -52,6 +53,7 @@ private Object node; private String id; + private NamespaceResolver localNamespaceResolver; public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace"; @@ -110,22 +112,33 @@ return null; } + /* (non-Javadoc) + * @see org.apache.commons.jxpath.ri.model.NodePointer#getNamespaceResolver() + */ + public synchronized NamespaceResolver getNamespaceResolver() { + if (localNamespaceResolver == null) { + localNamespaceResolver = new NamespaceResolver(super.getNamespaceResolver()); + localNamespaceResolver.setNamespaceContextPointer(this); + } + return localNamespaceResolver; + } + public String getNamespaceURI(String prefix) { + if (prefix.equals("xml")) { + return Namespace.XML_NAMESPACE.getURI(); + } + Element element = null; if (node instanceof Document) { - Element element = ((Document)node).getRootElement(); - Namespace ns = element.getNamespace(prefix); - if (ns != null) { - return ns.getURI(); - } - } - else if (node instanceof Element) { - Element element = (Element) node; - Namespace ns = element.getNamespace(prefix); - if (ns != null) { - return ns.getURI(); - } + element = ((Document) node).getRootElement(); } - return null; + if (node instanceof Element) { + element = (Element) node; + } + if (element == null) { + return null; + } + Namespace ns = element.getNamespace(prefix); + return ns == null ? null : ns.getURI(); } public int compareChildNodePointers( @@ -521,11 +534,12 @@ Element element = (Element) node; String prefix = name.getPrefix(); if (prefix != null) { - Namespace ns = element.getNamespace(prefix); - if (ns == null) { + String namespaceUri = getNamespaceResolver().getNamespaceURI(prefix); + if (namespaceUri == null) { throw new JXPathException( "Unknown namespace prefix: " + prefix); } + Namespace ns = Namespace.getNamespace(prefix, namespaceUri); Attribute attr = element.getAttribute(name.getName(), ns); if (attr == null) { element.setAttribute(name.getName(), "", ns); Modified: jakarta/commons/proper/jxpath/trunk/src/test/org/apache/commons/jxpath/ri/model/ExternalXMLNamespaceTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/test/org/apache/commons/jxpath/ri/model/ExternalXMLNamespaceTest.java?view=diff&rev=559574&r1=559573&r2=559574 ============================================================================== --- jakarta/commons/proper/jxpath/trunk/src/test/org/apache/commons/jxpath/ri/model/ExternalXMLNamespaceTest.java (original) +++ jakarta/commons/proper/jxpath/trunk/src/test/org/apache/commons/jxpath/ri/model/ExternalXMLNamespaceTest.java Wed Jul 25 12:49:33 2007 @@ -41,17 +41,21 @@ protected DocumentContainer createDocumentContainer(String model) { DocumentContainer result = new DocumentContainer(JXPathTestCase.class .getResource("ExternalNS.xml"), model); - //this setting only works for DOM, so no JDOM tests :| + // this setting only works for DOM, so no JDOM tests :| result.setNamespaceAware(false); return result; } - protected void doTest(String xpath, String model, String expected) { + protected JXPathContext createContext(String model) { JXPathContext context = JXPathContext .newContext(createDocumentContainer(model)); context.registerNamespace("A", "foo"); context.registerNamespace("B", "bar"); - assertXPathValue(context, xpath, expected); + return context; + } + + protected void doTest(String xpath, String model, String expected) { + assertXPathValue(createContext(model), xpath, expected); } protected void doTestAttribute(String model) { @@ -59,7 +63,12 @@ } protected void doTestElement(String model) { - doTest("/ElementA/B:ElementB", model, "MY VALUE"); + doTest("/ElementA/B:ElementB", model, "MY VALUE"); + } + + protected void doTestCreateAndSetAttribute(String model) { + assertXPathCreatePathAndSetValue(createContext(model), + "/ElementA/@A:newAttr", "newValue", "/ElementA[1]/@A:newAttr"); } public void testAttributeDOM() { @@ -68,6 +77,10 @@ public void testElementDOM() { doTestElement(DocumentContainer.MODEL_DOM); + } + + public void testCreateAndSetAttributeDOM() { + doTestCreateAndSetAttribute(DocumentContainer.MODEL_DOM); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]