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]

Reply via email to