Author: sergeyb
Date: Wed Mar 30 21:05:17 2011
New Revision: 1087071

URL: http://svn.apache.org/viewvc?rev=1087071&view=rev
Log:
[CXF-3338] Improving the way multiple namespaces and prefixes are handled in 
InTransformReader

Added:
    cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/
    
cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
   (with props)
Modified:
    
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
    
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/DelegatingNamespaceContext.java
    
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/InTransformReader.java
    
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/OutTransformWriter.java

Modified: 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java?rev=1087071&r1=1087070&r2=1087071&view=diff
==============================================================================
--- 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java 
(original)
+++ 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java 
Wed Mar 30 21:05:17 2011
@@ -464,6 +464,14 @@ public final class StaxUtils {
         copy(reader, writer);
     }
     
+    public static void copy(XMLStreamReader reader, OutputStream os)
+        throws XMLStreamException {
+        XMLStreamWriter xsw = StaxUtils.createXMLStreamWriter(os);
+        StaxUtils.copy(reader, xsw);
+        xsw.close();
+    }
+    
+    
     /**
      * Copies the reader to the writer. The start and end document methods must
      * be handled on the writer manually. TODO: if the namespace on the reader
@@ -519,9 +527,10 @@ public final class StaxUtils {
 
     private static void writeStartElement(XMLStreamReader reader, 
XMLStreamWriter writer)
         throws XMLStreamException {
-        String local = reader.getLocalName();
         String uri = reader.getNamespaceURI();
         String prefix = reader.getPrefix();
+        String local = reader.getLocalName();
+        
         if (prefix == null) {
             prefix = "";
         }
@@ -560,13 +569,14 @@ public final class StaxUtils {
             if (nsPrefix == null) {
                 nsPrefix = "";
             }
-
-            if (nsPrefix.length() == 0) {
-                writer.writeDefaultNamespace(nsURI);
-                writer.setDefaultNamespace(nsURI);
-            } else {
-                writer.writeNamespace(nsPrefix, nsURI);
-                writer.setPrefix(nsPrefix, nsURI);
+            if (nsURI.length() > 0) {
+                if (nsPrefix.length() == 0) {
+                    writer.writeDefaultNamespace(nsURI);
+                    writer.setDefaultNamespace(nsURI);
+                } else {
+                    writer.writeNamespace(nsPrefix, nsURI);
+                    writer.setPrefix(nsPrefix, nsURI);
+                }
             }
 
             if (nsURI.equals(uri) && nsPrefix.equals(prefix)) {

Modified: 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/DelegatingNamespaceContext.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/DelegatingNamespaceContext.java?rev=1087071&r1=1087070&r2=1087071&view=diff
==============================================================================
--- 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/DelegatingNamespaceContext.java
 (original)
+++ 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/DelegatingNamespaceContext.java
 Wed Mar 30 21:05:17 2011
@@ -18,6 +18,7 @@
  */
 package org.apache.cxf.staxutils.transform;
 
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -25,6 +26,7 @@ import javax.xml.namespace.NamespaceCont
 
 class DelegatingNamespaceContext implements NamespaceContext {
 
+    private Map<String, String> prefixes = new HashMap<String, String>();
     private NamespaceContext nc;
     private Map<String, String> nsMap;
     
@@ -33,16 +35,56 @@ class DelegatingNamespaceContext impleme
         this.nsMap = nsMap;
     }
     
+    public void addPrefix(String prefix, String namespace) {
+        prefixes.put(namespace, prefix);
+    }
+    
+    public String findUniquePrefix(String namespace) {
+        if (namespace.length() == 0) {
+            return null;
+        }
+        String existingPrefix = prefixes.get(namespace);
+        if (existingPrefix != null) {
+            return existingPrefix;
+        }
+        
+        int i = 0;
+        while (true) {
+            if (!prefixes.containsKey("ps" + ++i)) {
+                String prefix = "ps" + i;
+                addPrefix(prefix, namespace);
+                return prefix;
+            }
+        }
+    }
+    
     public String getNamespaceURI(String prefix) {
-        return nc.getNamespaceURI(prefix);
+        for (Map.Entry<String, String> entry : prefixes.entrySet()) {
+            if (entry.getValue().equals(prefix)) {
+                return entry.getKey();
+            }
+        }
+        String ns = nc.getNamespaceURI(prefix);
+        addPrefix(prefix, ns);
+        return ns;
     }
 
     public String getPrefix(String ns) {
+        if (ns.length() == 0) {
+            return null;
+        }
         String value = nsMap.get(ns);
         if (value != null && value.length() == 0) {
             return null;
         }
-        return value != null ? nc.getPrefix(value) : nc.getPrefix(ns);
+        
+        String actualNs = value == null ? ns : value;
+        if (prefixes.containsKey(actualNs)) {
+            return prefixes.get(actualNs);
+        }
+        String prefix = nc.getPrefix(actualNs);
+        addPrefix(prefix, actualNs);
+        return prefix;
     }
 
     public Iterator getPrefixes(String ns) {

Modified: 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/InTransformReader.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/InTransformReader.java?rev=1087071&r1=1087070&r2=1087071&view=diff
==============================================================================
--- 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/InTransformReader.java
 (original)
+++ 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/InTransformReader.java
 Wed Mar 30 21:05:17 2011
@@ -41,6 +41,7 @@ public class InTransformReader extends D
     private QName previousQName;
     private int previousDepth = -1;
     private boolean blockOriginalReader = true;
+    private DelegatingNamespaceContext namespaceContext;
     
     public InTransformReader(XMLStreamReader reader, 
                              Map<String, String> inMap,
@@ -51,6 +52,8 @@ public class InTransformReader extends D
         this.blockOriginalReader = blockOriginalReader;
         TransformUtils.convertToQNamesMap(inMap, inElementsMap, nsMap);
         TransformUtils.convertToMapOfQNames(appendMap, inAppendMap);
+        namespaceContext = new DelegatingNamespaceContext(
+            reader.getNamespaceContext(), nsMap);
     }
     
     @Override
@@ -100,9 +103,38 @@ public class InTransformReader extends D
     }
     
     public NamespaceContext getNamespaceContext() {
-        return new DelegatingNamespaceContext(super.getNamespaceContext(), 
nsMap);
+        return namespaceContext;
     }
 
+    public String getPrefix() {
+        QName name = readCurrentElement();
+        String prefix = name.getPrefix();
+        if (prefix.length() == 0) {
+            prefix = namespaceContext.findUniquePrefix(name.getNamespaceURI());
+        }
+        return prefix;
+    }
+     
+    public String getNamespaceURI(int index) {
+        String ns = super.getNamespaceURI(index);
+        String actualNs = nsMap.get(ns);
+        if (actualNs != null) {
+            return actualNs;
+        } else {
+            return ns;
+        }
+    }
+    
+    public String getNamespacePrefix(int index) {
+        String ns = super.getNamespaceURI(index);
+        String actualNs = nsMap.get(ns);
+        if (actualNs != null) {
+            return namespaceContext.findUniquePrefix(actualNs);
+        } else {
+            return namespaceContext.getPrefix(ns);
+        }
+    }
+    
     public String getNamespaceURI() {
      
         QName theName = readCurrentElement();
@@ -127,7 +159,8 @@ public class InTransformReader extends D
         }
         String ns = super.getNamespaceURI();
         String name = super.getLocalName();
-        return new QName(ns, name);
+        String prefix = super.getPrefix();
+        return new QName(ns, name, prefix == null ? "" : prefix);
     }
     
     public QName getName() { 

Modified: 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/OutTransformWriter.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/OutTransformWriter.java?rev=1087071&r1=1087070&r2=1087071&view=diff
==============================================================================
--- 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/OutTransformWriter.java
 (original)
+++ 
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/OutTransformWriter.java
 Wed Mar 30 21:05:17 2011
@@ -37,7 +37,6 @@ public class OutTransformWriter extends 
     private QNamesMap elementsMap;
     private Map<QName, QName> appendMap = new HashMap<QName, QName>(5);
     private Map<String, String> nsMap = new HashMap<String, String>(5);
-    private Set<String> prefixes = new HashSet<String>(2);
     private Set<String> writtenUris = new HashSet<String>(2);
     
     private Set<QName> dropElements;
@@ -46,6 +45,7 @@ public class OutTransformWriter extends 
     private List<Integer> appendedIndexes = new LinkedList<Integer>();
     private int currentDepth;
     private boolean attributesToElements;
+    private DelegatingNamespaceContext namespaceContext;
     
     public OutTransformWriter(XMLStreamWriter writer, 
                               Map<String, String> outMap,
@@ -58,6 +58,8 @@ public class OutTransformWriter extends 
         TransformUtils.convertToMapOfQNames(append, appendMap);
         dropElements = XMLUtils.convertStringsToQNames(dropEls);
         this.attributesToElements = attributesToElements;
+        namespaceContext = new DelegatingNamespaceContext(
+            writer.getNamespaceContext(), nsMap);
     }
 
     @Override
@@ -129,13 +131,13 @@ public class OutTransformWriter extends 
         String prefix = "";
         if (name.getNamespaceURI().length() > 0) {
             if (qname.getPrefix().length() == 0) {
-                prefix = findUniquePrefix();
+                prefix = 
namespaceContext.findUniquePrefix(name.getNamespaceURI());
                 writeNs = true;
             } else {
                 prefix = qname.getPrefix();
-                prefixes.add(prefix);
+                namespaceContext.addPrefix(prefix, qname.getNamespaceURI());   
 
             }
-            prefixes.add(prefix);
+            
         }
         super.writeStartElement(prefix, name.getLocalPart(), 
name.getNamespaceURI());
         if (writeNs) {
@@ -143,16 +145,6 @@ public class OutTransformWriter extends 
         }
     }
     
-    private String findUniquePrefix() {
-        
-        int i = 0;
-        while (true) {
-            if (!prefixes.contains("ps" + ++i)) {
-                return "ps" + i;
-            }
-        }
-    }
-    
     private boolean matchesDropped() {
         int size = droppingIndexes.size();
         if (size > 0 && droppingIndexes.get(size - 1) == currentDepth - 1) {
@@ -172,7 +164,7 @@ public class OutTransformWriter extends 
     
     @Override
     public NamespaceContext getNamespaceContext() {
-        return new DelegatingNamespaceContext(super.getNamespaceContext(), 
nsMap);
+        return namespaceContext; 
     }
     
     @Override

Added: 
cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java?rev=1087071&view=auto
==============================================================================
--- 
cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
 (added)
+++ 
cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
 Wed Mar 30 21:05:17 2011
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.cxf.staxutils.transform;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Collections;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.cxf.staxutils.StaxUtils;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InTransformReaderTest extends Assert {
+    @Test
+    public void testReadWithDefaultNamespace() throws Exception {
+        InputStream is = new ByteArrayInputStream("<test 
xmlns=\"http://bar\"/>".getBytes());
+        XMLStreamReader reader = StaxUtils.createXMLStreamReader(is);
+        reader = new InTransformReader(reader, 
+                                       
Collections.singletonMap("{http://bar}test";, "test2"),
+                                       null, false);
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
+        StaxUtils.copy(reader, bos);
+        String value = bos.toString();
+        assertTrue("<test2/>".equals(value)
+                   || "<test2></test2>".equals(value));        
+    }
+}

Propchange: 
cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to