You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ay...@apache.org on 2012/01/05 17:49:56 UTC

svn commit: r1227691 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/staxutils/transform/ common/common/src/test/java/org/apache/cxf/staxutils/transform/ rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/

Author: ay
Date: Thu Jan  5 16:49:56 2012
New Revision: 1227691

URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
Log:
[CXF-4013] Enhancing the element-append and drop options of OutTransformWriter

Added:
    cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/ParsingEvent.java   (with props)
    cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/TransformTestUtils.java   (with props)
Modified:
    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
    cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/TransformUtils.java
    cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java
    cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/OutTransformWriterTest.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JAXBElementProviderTest.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java

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=1227691&r1=1227690&r2=1227691&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 Thu Jan  5 16:49:56 2012
@@ -50,8 +50,7 @@ public class InTransformReader extends D
     private Set<QName> inDropSet = new HashSet<QName>(5);
     private Map<String, String> nsMap = new HashMap<String, String>(5);
     private Stack<ParsingEvent> pushedBackEvents = new Stack<ParsingEvent>();
-    private Map<EndEventMarker, List<ParsingEvent>> pushedAheadEvents = 
-        new HashMap<EndEventMarker, List<ParsingEvent>>();
+    private Stack<List<ParsingEvent>> pushedAheadEvents = new Stack<List<ParsingEvent>>();
     private String replaceText;
     private ParsingEvent currentEvent;
     private List<Integer> attributesIndexes = new ArrayList<Integer>(); 
@@ -102,7 +101,7 @@ public class InTransformReader extends D
             if (doDebug) {
                 LOG.fine("pushed event available: " + currentEvent);
             }
-            return currentEvent.event;
+            return currentEvent.getEvent();
         } else {
             if (doDebug) {
                 LOG.fine("no pushed event");
@@ -133,15 +132,15 @@ public class InTransformReader extends D
                 if (doDebug) {
                     LOG.fine("replacing content with " + replaceText);    
                 }
-                
-                currentEvent = createStartElementEvent(expected);
+                currentEvent = TransformUtils.createStartElementEvent(expected);
+                pushedAheadEvents.push(null);
             } else if (dropped) {
                 if (doDebug) {
                     LOG.fine("shallow-dropping start " + expected);
                 }
                 // unwrap the current element (shallow drop)
                 event = next();
-            } else if (isEmptyQName(expected)) {
+            } else if (TransformUtils.isEmptyQName(expected)) {
                 // skip the current element (deep drop)
                 if (doDebug) {
                     LOG.fine("deep-dropping " + theName);
@@ -159,15 +158,14 @@ public class InTransformReader extends D
             
             final boolean dropped = inDropSet.contains(theName);
             if (!dropped) {
-                EndEventMarker em = new EndEventMarker(theName, getDepth() + 1);
-                List<ParsingEvent> pe = pushedAheadEvents.remove(em);
+                List<ParsingEvent> pe = pushedAheadEvents.pop();
                 if (null != pe) {
                     if (doDebug) {
                         LOG.fine("pushed event found");    
                     }
                     pushedBackEvents.addAll(pe);
                     currentEvent = pushedBackEvents.pop();
-                    event = currentEvent.event;
+                    event = currentEvent.getEvent();
                 } else {
                     if (doDebug) {
                         LOG.fine("no pushed event found");    
@@ -191,73 +189,61 @@ public class InTransformReader extends D
     
     private void handleAppendMode(QName name, QName expected, ElementProperty appendProp) {
         final boolean doDebug = LOG.isLoggable(Level.FINE);
-
         if (appendProp.isChild()) {
+            // ap-post-*
             if (null == appendProp.getText()) {
                 // ap-post-wrap
-                pushedBackEvents.push(createStartElementEvent(appendProp.getName()));
-                currentEvent = createStartElementEvent(expected);
-                EndEventMarker em = new EndEventMarker(name, getDepth());
-                if (doDebug) {
-                    LOG.fine("ap-post-wrap " + appendProp.getName() + ", " + em);    
-                }
+                pushedBackEvents.push(TransformUtils.createStartElementEvent(appendProp.getName()));
+                currentEvent = TransformUtils.createStartElementEvent(expected);
 
                 List<ParsingEvent> pe = new ArrayList<ParsingEvent>(2);
-                pe.add(createEndElementEvent(expected));
-                pe.add(createEndElementEvent(appendProp.getName()));
-                pushedAheadEvents.put(em, pe);
+                pe.add(TransformUtils.createEndElementEvent(expected));
+                pe.add(TransformUtils.createEndElementEvent(appendProp.getName()));
+                pushedAheadEvents.push(pe);
             } else {
                 // ap-post-incl
-                currentEvent = createStartElementEvent(expected);
-                EndEventMarker em = new EndEventMarker(name, getDepth());
-                if (doDebug) {
-                    LOG.fine("ap-pre-incl " + appendProp.getName() + "=" + appendProp.getText() + ", " + em);
-                }
+                currentEvent = TransformUtils.createStartElementEvent(expected);
 
                 List<ParsingEvent> pe = new ArrayList<ParsingEvent>();
-                pe.add(createEndElementEvent(expected));
-                pe.add(createEndElementEvent(appendProp.getName()));
-                pe.add(createCharactersEvent(appendProp.getText()));
-                pe.add(createStartElementEvent(appendProp.getName()));
-                pushedAheadEvents.put(em, pe);
+                pe.add(TransformUtils.createEndElementEvent(expected));
+                pe.add(TransformUtils.createEndElementEvent(appendProp.getName()));
+                pe.add(TransformUtils.createCharactersEvent(appendProp.getText()));
+                pe.add(TransformUtils.createStartElementEvent(appendProp.getName()));
+                pushedAheadEvents.push(pe);
             }
         } else { 
+            // ap-pre-*
             if (null == appendProp.getText()) {
                 // ap-pre-wrap
-                pushedBackEvents.push(createStartElementEvent(expected));
-                currentEvent = createStartElementEvent(appendProp.getName());
-                EndEventMarker em = new EndEventMarker(name, getDepth());
-                if (doDebug) {
-                    LOG.fine("ap-pre-wrap " + appendProp.getName() + ", " + em);
-                }
+                pushedBackEvents.push(TransformUtils.createStartElementEvent(expected));
+                currentEvent = TransformUtils.createStartElementEvent(appendProp.getName());
 
                 List<ParsingEvent> pe = new ArrayList<ParsingEvent>();
-                pe.add(createEndElementEvent(appendProp.getName()));
-                pe.add(createEndElementEvent(expected));
-                pushedAheadEvents.put(em, pe);
+                pe.add(TransformUtils.createEndElementEvent(appendProp.getName()));
+                pe.add(TransformUtils.createEndElementEvent(expected));
+                pushedAheadEvents.push(pe);
             } else {
                 // ap-pre-incl
-                pushedBackEvents.push(createStartElementEvent(expected));
-                pushedBackEvents.push(createEndElementEvent(appendProp.getName()));
-                pushedBackEvents.push(createCharactersEvent(appendProp.getText()));
-                currentEvent = createStartElementEvent(appendProp.getName());
+                pushedBackEvents.push(TransformUtils.createStartElementEvent(expected));
+                pushedBackEvents.push(TransformUtils.createEndElementEvent(appendProp.getName()));
+                pushedBackEvents.push(TransformUtils.createCharactersEvent(appendProp.getText()));
+                currentEvent = TransformUtils.createStartElementEvent(appendProp.getName());
                 if (doDebug) {
                     LOG.fine("ap-pre-incl " + appendProp.getName() + "=" + appendProp.getText());
                 }
+                pushedAheadEvents.push(null);
             }
         }
     }
     
     private void handleDefaultMode(QName name, QName expected) {
-        currentEvent = createStartElementEvent(expected);
+        currentEvent = TransformUtils.createStartElementEvent(expected);
         if (!name.equals(expected)) {
-            EndEventMarker em = new EndEventMarker(name, getDepth());
-            if (LOG.isLoggable(Level.FINE)) {
-                LOG.fine("default " + name + "->" + expected + ", " + em);
-            }
             List<ParsingEvent> pe = new ArrayList<ParsingEvent>(1);
-            pe.add(createEndElementEvent(expected));
-            pushedAheadEvents.put(em, pe);
+            pe.add(TransformUtils.createEndElementEvent(expected));
+            pushedAheadEvents.push(pe);
+        } else {
+            pushedAheadEvents.push(null);
         }
     }
     
@@ -278,7 +264,7 @@ public class InTransformReader extends D
 
     public String getLocalName() {
         if (currentEvent != null) {
-            return currentEvent.name.getLocalPart();    
+            return currentEvent.getName().getLocalPart();    
         } else {
             return super.getLocalName();
         }
@@ -320,7 +306,7 @@ public class InTransformReader extends D
     
     public String getNamespaceURI() {
         if (currentEvent != null) {
-            return currentEvent.name.getNamespaceURI();
+            return currentEvent.getName().getNamespaceURI();
         } else {
             return super.getNamespaceURI();
         }
@@ -328,7 +314,7 @@ public class InTransformReader extends D
 
     private QName readCurrentElement() {
         if (currentEvent != null) {
-            return currentEvent.name;
+            return currentEvent.getName();
         }
         String ns = super.getNamespaceURI();
         String name = super.getLocalName();
@@ -423,7 +409,7 @@ public class InTransformReader extends D
 
     public String getText() {
         if (currentEvent != null) {
-            return currentEvent.value;
+            return currentEvent.getValue();
         }
         String superText = super.getText();
         if (replaceText != null) {
@@ -435,7 +421,7 @@ public class InTransformReader extends D
 
     public char[] getTextCharacters() {
         if (currentEvent != null && currentEvent != null) {
-            return currentEvent.value.toCharArray();
+            return currentEvent.getValue().toCharArray();
         }
         char[] superChars = super.getTextCharacters();
         if (replaceText != null) {
@@ -448,11 +434,11 @@ public class InTransformReader extends D
     public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
         throws XMLStreamException {
         if (currentEvent != null && currentEvent != null) {
-            int len = currentEvent.value.length() - sourceStart;
+            int len = currentEvent.getValue().length() - sourceStart;
             if (len > length) {
                 len = length;
             }
-            currentEvent.value.getChars(sourceStart, sourceStart + len, target, targetStart);
+            currentEvent.getValue().getChars(sourceStart, sourceStart + len, target, targetStart);
             return len;
         }
 
@@ -460,8 +446,8 @@ public class InTransformReader extends D
     }
 
     public int getTextLength() {
-        if (currentEvent != null && currentEvent.value != null) {
-            return currentEvent.value.length();
+        if (currentEvent != null && currentEvent.getValue() != null) {
+            return currentEvent.getValue().length();
         }
         return super.getTextLength();
     }
@@ -479,7 +465,7 @@ public class InTransformReader extends D
             for (int i = 0; i < c; i++) {
                 QName aname = super.getAttributeName(i);
                 QName expected = inAttributesMap.get(aname);
-                if (expected == null || !isEmptyQName(expected)) {
+                if (expected == null || !TransformUtils.isEmptyQName(expected)) {
                     attributesIndexes.add(i);
                 }
             }
@@ -490,74 +476,9 @@ public class InTransformReader extends D
         }
     }
 
-    private static boolean isEmptyQName(QName qname) {
-        return XMLConstants.NULL_NS_URI.equals(qname.getNamespaceURI()) && "".equals(qname.getLocalPart());
-    }
-
     private void throwIndexException(int index, int size) {
         throw new IllegalArgumentException("Invalid index " + index 
                                            + "; current element has only " + size + " attributes");
     }
 
-    private static ParsingEvent createStartElementEvent(QName name) {
-        return new ParsingEvent(XMLStreamConstants.START_ELEMENT, name, null);
-    }
-
-    private static ParsingEvent createEndElementEvent(QName name) {
-        return new ParsingEvent(XMLStreamConstants.END_ELEMENT, name, null);
-    }
-
-    private static ParsingEvent createCharactersEvent(String value) {
-        return new ParsingEvent(XMLStreamConstants.CHARACTERS, null, value);
-    }
-    
-    private static class ParsingEvent {
-        private int event;
-        private QName name;
-        private String value;
-        
-        public ParsingEvent(int event, QName name, String value) {
-            this.event = event;
-            this.name = name;
-            this.value = value;
-        }
-        
-        public String toString() {
-            return new StringBuffer().append("Event(").
-                append(event).append(", ").append(name).append(", ").append(value).append(")").
-                toString();
-        }
-    }
-    
-    private static class EndEventMarker {
-        private QName name;
-        private int level;
-        
-        public EndEventMarker(QName name, int level) {
-            this.name = name;
-            this.level = level;
-        }
-
-        /** {@inheritDoc}*/
-        @Override
-        public int hashCode() {
-            return name.hashCode() ^ level;
-        }
-
-        /** {@inheritDoc}*/
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof EndEventMarker) {
-                EndEventMarker e = (EndEventMarker)obj;
-                return name.equals(e.name) && level == e.level;
-            }
-            return false;
-        }
-        
-        public String toString() {
-            return new StringBuffer().append("Marker(").
-                append(name).append(", ").append(level).append(")").
-                toString();
-        }
-    }
 }

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=1227691&r1=1227690&r2=1227691&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 Thu Jan  5 16:49:56 2012
@@ -18,15 +18,19 @@
  */
 package org.apache.cxf.staxutils.transform;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Stack;
 
+import javax.xml.XMLConstants;
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
@@ -36,28 +40,43 @@ import org.apache.cxf.staxutils.Delegati
 public class OutTransformWriter extends DelegatingXMLStreamWriter {
     private String defaultNamespace;
     private QNamesMap elementsMap;
-    private Map<QName, QName> appendMap = new HashMap<QName, QName>(5);
+    private QNamesMap attributesMap;
+    private Map<QName, ElementProperty> appendMap = new HashMap<QName, ElementProperty>(5);
     private Map<String, String> nsMap = new HashMap<String, String>(5);
     private List<Set<String>> writtenUris = new LinkedList<Set<String>>();
     
     private Set<QName> dropElements;
-    private List<Integer> droppingIndexes = new LinkedList<Integer>();
-    private List<QName> appendedElements = new LinkedList<QName>();
-    private List<Integer> appendedIndexes = new LinkedList<Integer>();
+    private Stack<List<ParsingEvent>> pushedAheadEvents = new Stack<List<ParsingEvent>>();
+    private Stack<QName> elementsStack = new Stack<QName>();
+    private String replaceText;
     private int currentDepth;
+    private int dropDepth;
     private boolean attributesToElements;
     private DelegatingNamespaceContext namespaceContext;
-    
+
     public OutTransformWriter(XMLStreamWriter writer, 
                               Map<String, String> outMap,
                               Map<String, String> append,
                               List<String> dropEls,
                               boolean attributesToElements,
                               String defaultNamespace) {
+        this(writer, outMap, append, dropEls, null, attributesToElements, defaultNamespace);
+    }
+    
+    public OutTransformWriter(XMLStreamWriter writer, 
+                              Map<String, String> outEMap,
+                              Map<String, String> append,
+                              List<String> dropEls,
+                              Map<String, String> outAMap,
+                              boolean attributesToElements,
+                              String defaultNamespace) {
         super(writer);
-        elementsMap = new QNamesMap(outMap == null ? 0 : outMap.size());
-        TransformUtils.convertToQNamesMap(outMap, elementsMap, nsMap);
-        TransformUtils.convertToMapOfQNames(append, appendMap);
+        elementsMap = new QNamesMap(outEMap == null ? 0 : outEMap.size());
+        attributesMap = new QNamesMap(outAMap == null ? 0 : outAMap.size());
+        TransformUtils.convertToQNamesMap(outEMap, elementsMap, nsMap);
+        TransformUtils.convertToQNamesMap(outAMap, attributesMap, null);
+
+        TransformUtils.convertToMapOfElementProperties(append, appendMap);
         dropElements = XMLUtils.convertStringsToQNames(dropEls);
         this.attributesToElements = attributesToElements;
         namespaceContext = new DelegatingNamespaceContext(
@@ -67,7 +86,7 @@ public class OutTransformWriter extends 
 
     @Override
     public void writeNamespace(String prefix, String uri) throws XMLStreamException {
-        if (matchesDropped()) {
+        if (matchesDropped(true)) {
             return;
         }
         String value = nsMap.get(uri);
@@ -95,6 +114,9 @@ public class OutTransformWriter extends 
     @Override
     public void writeStartElement(String prefix, String local, String uri) throws XMLStreamException {
         currentDepth++;
+        if (matchesDropped(false)) {
+            return;
+        }
         Set<String> s;
         if (writtenUris.isEmpty()) {
             s = new HashSet<String>();
@@ -102,93 +124,199 @@ public class OutTransformWriter extends 
             s = new HashSet<String>(writtenUris.get(0));
         }
         writtenUris.add(0, s);
-        QName currentQName = new QName(uri, local);
         
-        QName appendQName = appendMap.get(currentQName);
-        if (appendQName != null && !appendedElements.contains(appendQName)) {
-            currentDepth++;
-            String theprefix = uri.equals(appendQName.getNamespaceURI()) ? prefix : "";
-            write(new QName(appendQName.getNamespaceURI(), appendQName.getLocalPart(), theprefix));
-            if (theprefix.length() > 0) {
-                this.writeNamespace(theprefix, uri);
-            }
-            appendedElements.add(appendQName);
-            appendedIndexes.add(currentDepth - 1);
+        final QName theName = new QName(uri, local, prefix);
+        final ElementProperty appendProp = appendMap.remove(theName);
+        final boolean replaceContent = appendProp != null && theName.equals(appendProp.getName());
+
+        final boolean dropped = dropElements.contains(theName);
+        QName expected = elementsMap.get(theName);
+        if (expected == null) {
+            expected = theName;
+        } else {
+            expected = new QName(expected.getNamespaceURI(), expected.getLocalPart(), prefix);
         }
-        
-        if (dropElements.contains(currentQName)) {
-            droppingIndexes.add(currentDepth - 1);
+        List<ParsingEvent> pe = null;
+        if (appendProp != null && !replaceContent) {
+            if (!appendProp.isChild()) {
+                // ap-pre-*
+                QName appendQName = appendProp.getName();
+                String theprefix = namespaceContext.getPrefix(appendQName.getNamespaceURI()); 
+                boolean nsadded = false;
+                if (theprefix == null) {
+                    nsadded = true;
+                    theprefix = getPrefix(appendQName.getNamespaceURI());
+                    if (theprefix == null 
+                        && (appendQName.getNamespaceURI().equals(expected.getNamespaceURI()) 
+                            && expected.getPrefix().length() > 0)) {
+                        theprefix = expected.getPrefix();
+                    } else if (theprefix == null) {
+                        theprefix = namespaceContext.findUniquePrefix(appendQName.getNamespaceURI());
+                    }
+                    if (theprefix == null) {
+                        theprefix = "";
+                    }
+                }
+                write(new QName(appendQName.getNamespaceURI(), appendQName.getLocalPart(), theprefix));
+                if (nsadded && theprefix.length() > 0) {
+                    writeNamespace(theprefix, appendQName.getNamespaceURI());
+                }
+                if (appendProp.getText() == null) {
+                    // ap-pre-wrap
+                    currentDepth++;
+                    pe = new ArrayList<ParsingEvent>();
+                    pe.add(TransformUtils.createEndElementEvent(expected));
+                    pe.add(TransformUtils.createEndElementEvent(appendProp.getName()));
+                    pushedAheadEvents.push(null);
+                    elementsStack.push(appendQName);
+                } else {
+                    // ap-pre-incl
+                    super.writeCharacters(appendProp.getText());
+                    super.writeEndElement();
+                }
+            }
+        } else if (replaceContent) {
+            //
+            replaceText = appendProp.getText();
+        } else if (dropped) {
+            // unwrap the current element (shallow drop)
+            elementsStack.push(theName);
+            return;
+        } else if (TransformUtils.isEmptyQName(expected)) {
+            // skip the current element (deep drop));
+            dropDepth = currentDepth - 1;
             return;
         }
-        write(new QName(uri, local, prefix));
+        write(expected);
+        pushedAheadEvents.push(pe);
+        elementsStack.push(expected);
+
+        if (appendProp != null && !replaceContent && appendProp.isChild()) {
+            // ap-post-*
+            QName appendQName = appendProp.getName();
+            String theprefix = getPrefix(appendQName.getNamespaceURI());
+                
+            if (appendProp.getText() == null) {
+                // ap-post-wrap
+                write(new QName(appendQName.getNamespaceURI(), appendQName.getLocalPart(), 
+                                theprefix == null ? "" : theprefix));
+                if (getNamespaceContext().getPrefix(appendQName.getNamespaceURI()) == null) {
+                    this.writeNamespace(theprefix, uri);
+                }
+                currentDepth++;
+                pe = new ArrayList<ParsingEvent>();
+                pe.add(TransformUtils.createEndElementEvent(appendProp.getName()));
+                pe.add(TransformUtils.createEndElementEvent(expected));
+                pushedAheadEvents.push(pe);
+                elementsStack.push(appendQName);
+            } else {
+                // ap-post-incl
+                pushedAheadEvents.pop();
+                pe = new ArrayList<ParsingEvent>();
+                pe.add(TransformUtils.createStartElementEvent(appendProp.getName()));
+                pe.add(TransformUtils.createCharactersEvent(appendProp.getText()));
+                pe.add(TransformUtils.createEndElementEvent(appendProp.getName()));
+                pe.add(TransformUtils.createEndElementEvent(expected));
+                pushedAheadEvents.push(pe);
+            }
+        }
     }
+
     
     @Override
+    public void writeStartElement(String uri, String local) throws XMLStreamException {
+        pushedAheadEvents.push(null);
+        elementsStack.push(new QName(uri, local));
+        super.writeStartElement(uri, local);
+    }
+
+    @Override
+    public void writeStartElement(String local) throws XMLStreamException {
+        writeStartElement("", local, "");
+    }
+
+    @Override
     public void writeEndElement() throws XMLStreamException {
-        if (!writtenUris.isEmpty()) {
-            writtenUris.remove(0);
-        }
         --currentDepth;
-        if (indexRemoved(droppingIndexes)) {
+        if (matchesDropped(false)) {
             return;
+        } else if (dropDepth > 0) {
+            dropDepth = 0;
         }
-        super.writeEndElement();
-        if (indexRemoved(appendedIndexes)) {
-            super.writeEndElement();
+        if (!writtenUris.isEmpty()) {
+            writtenUris.remove(0);
+        }
+        QName theName = elementsStack.pop();
+        final boolean dropped = dropElements.contains(theName);
+        if (!dropped) {
+            List<ParsingEvent> pes = pushedAheadEvents.pop();
+            if (null != pes) {
+                for (ParsingEvent pe : pes) {
+                    switch (pe.getEvent()) {
+                    case XMLStreamConstants.START_ELEMENT:
+                        write(pe.getName());
+                        break;
+                    case XMLStreamConstants.END_ELEMENT:
+                        super.writeEndElement();
+                        break;
+                    case XMLStreamConstants.CHARACTERS:
+                        super.writeCharacters(pe.getValue());
+                        break;
+                    default:
+                    }
+                }
+            } else {
+                super.writeEndElement();
+            }
         }
     }
     
     @Override
     public void writeCharacters(String text) throws XMLStreamException {
-        if (matchesDropped()) {
+        if (matchesDropped(false)) {
             return;
         }
+        if (replaceText != null) {
+            text = replaceText;
+            replaceText = null;
+        }
         super.writeCharacters(text);
     }
     
     private void write(QName qname) throws XMLStreamException {
-        QName name = elementsMap.get(qname);
-        if (name == null) {
-            name = qname;
-        }
         boolean writeNs = false;
         String prefix = "";
-        if (name.getNamespaceURI().length() > 0) {
+        if (qname.getNamespaceURI().length() > 0) {
             if (qname.getPrefix().length() == 0) {
-                prefix = namespaceContext.findUniquePrefix(name.getNamespaceURI());
-                writeNs = true;
+                prefix = getPrefix(qname.getNamespaceURI());
+                if (prefix == null) {
+                    prefix = namespaceContext.findUniquePrefix(qname.getNamespaceURI());
+                    writeNs = true;
+                }
             } else {
                 prefix = qname.getPrefix();
                 namespaceContext.addPrefix(prefix, qname.getNamespaceURI());    
             }
             
         }
-        if (defaultNamespace != null && defaultNamespace.equals(name.getNamespaceURI())) {
+        if (defaultNamespace != null && defaultNamespace.equals(qname.getNamespaceURI())) {
             prefix = "";
         }
         
-        super.writeStartElement(prefix, name.getLocalPart(), name.getNamespaceURI());
+        super.writeStartElement(prefix, qname.getLocalPart(), qname.getNamespaceURI());
         if (writeNs) {
-            this.writeNamespace(prefix, name.getNamespaceURI());
+            this.writeNamespace(prefix, qname.getNamespaceURI());
         }
     }
     
-    private boolean matchesDropped() {
-        int size = droppingIndexes.size();
-        if (size > 0 && droppingIndexes.get(size - 1) == currentDepth - 1) {
+    private boolean matchesDropped(boolean shallow) {
+        if ((dropDepth > 0 && dropDepth <= currentDepth) 
+            || (shallow && (elementsStack.size() > 0 && dropElements.contains(elementsStack.peek())))) {
             return true;
         }
         return false;
     }
     
-    private boolean indexRemoved(List<Integer> indexes) {
-        int size = indexes.size();
-        if (size > 0 && indexes.get(size - 1) == currentDepth) {
-            indexes.remove(size - 1);
-            return true;
-        }
-        return false;
-    }
     
     @Override
     public NamespaceContext getNamespaceContext() {
@@ -196,9 +324,18 @@ public class OutTransformWriter extends 
     }
     
     @Override
-    public void writeAttribute(String uri, String local, String value) throws XMLStreamException {
+    public void writeAttribute(String prefix, String uri, String local, String value) 
+        throws XMLStreamException {
+        QName expected = attributesMap.get(new QName(uri, local, prefix));
+        if (expected != null) {
+            if (TransformUtils.isEmptyQName(expected)) {
+                return;
+            }
+            uri = expected.getNamespaceURI();
+            local = expected.getLocalPart();
+        }
         if (!attributesToElements) {
-            super.writeAttribute(uri, local, value);
+            super.writeAttribute(prefix, uri, local, value);
         } else {
             writeAttributeAsElement(uri, local, value);
         }
@@ -206,10 +343,23 @@ public class OutTransformWriter extends 
 
     @Override
     public void writeAttribute(String local, String value) throws XMLStreamException {
+        String uri = XMLConstants.NULL_NS_URI;
+        QName expected = attributesMap.get(new QName("", local));
+        if (expected != null) {
+            if (TransformUtils.isEmptyQName(expected)) {
+                return;
+            }
+            uri = expected.getNamespaceURI();
+            local = expected.getLocalPart();
+        }
         if (!attributesToElements) {
-            super.writeAttribute(local, value);
+            if (uri.length() > 0) {
+                super.writeAttribute(uri, local, value);
+            } else {
+                super.writeAttribute(local, value);                
+            }
         } else {
-            writeAttributeAsElement("", local, value);
+            writeAttributeAsElement(uri, local, value);
         }
     }
     

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/ParsingEvent.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/ParsingEvent.java?rev=1227691&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/ParsingEvent.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/ParsingEvent.java Thu Jan  5 16:49:56 2012
@@ -0,0 +1,65 @@
+/**
+ * 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 javax.xml.namespace.QName;
+
+/**
+ * 
+ */
+class ParsingEvent {
+    private int event;
+    private QName name;
+    private String value;
+        
+    public ParsingEvent(int event, QName name, String value) {
+        this.event = event;
+        this.name = name;
+        this.value = value;
+    }
+        
+    public String toString() {
+        return new StringBuffer().append("Event(").
+            append(event).append(", ").append(name).append(", ").append(value).append(")").
+            toString();
+    }
+
+    /**
+     * @return Returns the event.
+     */
+    public int getEvent() {
+        return event;
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public QName getName() {
+        return name;
+    }
+
+    /**
+     * @return Returns the value.
+     */
+    public String getValue() {
+        return value;
+    }
+
+}

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/ParsingEvent.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/TransformUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/TransformUtils.java?rev=1227691&r1=1227690&r2=1227691&view=diff
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/TransformUtils.java (original)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/transform/TransformUtils.java Thu Jan  5 16:49:56 2012
@@ -24,7 +24,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 
@@ -95,7 +97,7 @@ public final class TransformUtils {
                 QName lname = XMLUtils.convertStringToQName(entry.getKey());
                 QName rname = XMLUtils.convertStringToQName(entry.getValue());
                 elementsMap.put(lname, rname);
-                if (nsMap != null) {
+                if (nsMap != null && !isEmptyQName(rname)) {
                     nsMap.put(lname.getNamespaceURI(), rname.getNamespaceURI());
                 }
             }
@@ -156,4 +158,21 @@ public final class TransformUtils {
             }
         }
     }
+    
+    static boolean isEmptyQName(QName qname) {
+        return XMLConstants.NULL_NS_URI.equals(qname.getNamespaceURI()) && "".equals(qname.getLocalPart());
+    }
+
+    static ParsingEvent createStartElementEvent(QName name) {
+        return new ParsingEvent(XMLStreamConstants.START_ELEMENT, name, null);
+    }
+
+    static ParsingEvent createEndElementEvent(QName name) {
+        return new ParsingEvent(XMLStreamConstants.END_ELEMENT, name, null);
+    }
+
+    static ParsingEvent createCharactersEvent(String value) {
+        return new ParsingEvent(XMLStreamConstants.CHARACTERS, null, value);
+    }
+
 }

Modified: 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=1227691&r1=1227690&r2=1227691&view=diff
==============================================================================
--- cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java (original)
+++ cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/InTransformReaderTest.java Thu Jan  5 16:49:56 2012
@@ -26,14 +26,10 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.logging.Logger;
 
 import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.staxutils.PartialXMLStreamReader;
 import org.apache.cxf.staxutils.StaxUtils;
 
@@ -41,7 +37,6 @@ import org.junit.Assert;
 import org.junit.Test;
 
 public class InTransformReaderTest extends Assert {
-    private static final Logger LOG = LogUtils.getLogger(InTransformReaderTest.class);
 
     @Test
     public void testReadWithDefaultNamespace() throws Exception {
@@ -107,6 +102,8 @@ public class InTransformReaderTest exten
         assertEquals("<ps1:test xmlns:ps1=\"http://bar\"><subtest xmlns=\"\"/></ps1:test>",
                      value);        
     }
+    
+    // additional test cases
     @Test
     public void testReadWithComplexRequestSameNamespace() throws Exception {
         XMLStreamReader reader = 
@@ -123,7 +120,7 @@ public class InTransformReaderTest exten
         XMLStreamReader reader2 = 
             StaxUtils.createXMLStreamReader(
                 InTransformReader.class.getResourceAsStream("../resources/complexReq1.xml"));
-        verifyReaders(reader, reader2, true);
+        TransformTestUtils.verifyReaders(reader2, reader, true);
     }
     
     @Test
@@ -145,7 +142,7 @@ public class InTransformReaderTest exten
         XMLStreamReader reader2 = 
             StaxUtils.createXMLStreamReader(
                 InTransformReader.class.getResourceAsStream("../resources/complexReq2.xml"));        
-        verifyReaders(reader, reader2, true);
+        TransformTestUtils.verifyReaders(reader2, reader, true);
     }
     
     @Test
@@ -169,7 +166,7 @@ public class InTransformReaderTest exten
         XMLStreamReader reader2 = 
             StaxUtils.createXMLStreamReader(
                 InTransformReader.class.getResourceAsStream("../resources/complexReq3.xml"));        
-        verifyReaders(reader, reader2, true);
+        TransformTestUtils.verifyReaders(reader2, reader, true);
     }
 
     @Test
@@ -191,7 +188,7 @@ public class InTransformReaderTest exten
         XMLStreamReader reader2 = 
             StaxUtils.createXMLStreamReader(
                 InTransformReader.class.getResourceAsStream("../resources/complexReq1partial.xml"));        
-        verifyReaders(filteredReader, reader2, false);
+        TransformTestUtils.verifyReaders(reader2, filteredReader, false);
     }
     
     @Test
@@ -216,7 +213,7 @@ public class InTransformReaderTest exten
         XMLStreamReader reader2 = 
             StaxUtils.createXMLStreamReader(
                 InTransformReader.class.getResourceAsStream("../resources/complexReq2partial.xml"));        
-        verifyReaders(filteredReader, reader2, false);
+        TransformTestUtils.verifyReaders(reader2, filteredReader, false);
     }
     
     @Test
@@ -244,7 +241,7 @@ public class InTransformReaderTest exten
         XMLStreamReader reader2 = 
             StaxUtils.createXMLStreamReader(
                   InTransformReader.class.getResourceAsStream("../resources/complexReq3partial.xml"));        
-        verifyReaders(filteredReader, reader2, false);
+        TransformTestUtils.verifyReaders(reader2, filteredReader, false);
     }
     
     
@@ -258,7 +255,8 @@ public class InTransformReaderTest exten
         appendElements.put("requestValue",
                            "{http://cxf.apache.org/hello_world_soap_http/types}greetMe");
 
-        transformStreamAndCompare("../resources/greetMeReqIn1.xml", "../resources/greetMeReq.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/greetMeReqIn1.xml", 
+                                                     "../resources/greetMeReq.xml",
                                   transformElements, appendElements, null, null, null);
     }
 
@@ -281,7 +279,8 @@ public class InTransformReaderTest exten
         transformAttributes.put("num", "");
         transformAttributes.put("nombre", "{http://cxf.apache.org/hello_world_soap_http/types}name");
         
-        transformStreamAndCompare("../resources/greetMeReqIn2.xml", "../resources/greetMeReq.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/greetMeReqIn2.xml", 
+                                                     "../resources/greetMeReq.xml",
                                   transformElements, appendElements, dropElements, 
                                   transformAttributes, null);
     }
@@ -292,7 +291,8 @@ public class InTransformReaderTest exten
         transformElements.put("*",
                               "{http://cxf.apache.org/hello_world_soap_http/types}*");
 
-        transformStreamAndCompare("../resources/greetMeReqIn3.xml", "../resources/greetMeReq.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/greetMeReqIn3.xml", 
+                                                     "../resources/greetMeReq.xml",
                                   transformElements, null, null, null, null);
     }
 
@@ -302,7 +302,8 @@ public class InTransformReaderTest exten
         transformAttributes.put("{http://www.w3.org/2001/XMLSchema-instance}type",
                                 "");
 
-        transformStreamAndCompare("../resources/greetMeReqIn4.xml", "../resources/greetMeReq.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/greetMeReqIn4.xml", 
+                                                     "../resources/greetMeReq.xml",
                                   null, null, null, transformAttributes, null);
     }
     
@@ -311,7 +312,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId",
                            "{http://xml.amazon.com/AWSECommerceService/2004-08-01}IdType=ASIN");
-        transformStreamAndCompare("../resources/amazonIn1.xml", "../resources/amazon.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/amazonIn1.xml", 
+                                                     "../resources/amazon.xml",
                                   null, appendElements, null, null, null);
         
     }
@@ -321,7 +323,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId",
                            "{http://xml.amazon.com/AWSECommerceService/2004-08-01}IdType=ASIN");
-        transformStreamAndCompare("../resources/amazonIn1nospace.xml", "../resources/amazon.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/amazonIn1nospace.xml", 
+                                                     "../resources/amazon.xml",
                                   null, appendElements, null, null, null);
         
     }
@@ -334,7 +337,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://apache.org/cxf/calculator/types}add",
                            "{http://www.w3.org/2003/05/soap-envelope}Body");
-        transformStreamAndCompare("../resources/AddRequestIn2.xml", "../resources/AddRequest.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/AddRequestIn2.xml", 
+                                                     "../resources/AddRequest.xml",
                                   transformElements, appendElements, null, null, null);
     }
 
@@ -346,7 +350,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://apache.org/cxf/calculator/types}add",
                            "{http://www.w3.org/2003/05/soap-envelope}Body");
-        transformStreamAndCompare("../resources/AddRequestIn2nospace.xml", "../resources/AddRequest.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/AddRequestIn2nospace.xml", 
+                                                     "../resources/AddRequest.xml",
                                   transformElements, appendElements, null, null, null);
     }
 
@@ -355,7 +360,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}Request/",
                            "{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId=0486411214");
-        transformStreamAndCompare("../resources/amazonIn2.xml", "../resources/amazon.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/amazonIn2.xml", 
+                                                     "../resources/amazon.xml",
                                   null, appendElements, null, null, null);
         
     }
@@ -365,7 +371,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}Request/",
                            "{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId=0486411214");
-        transformStreamAndCompare("../resources/amazonIn2nospace.xml", "../resources/amazon.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/amazonIn2nospace.xml", 
+                                                     "../resources/amazon.xml",
                                   null, appendElements, null, null, null);
         
     }
@@ -375,7 +382,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://www.w3.org/2003/05/soap-envelope}Body/",
                            "{http://apache.org/cxf/calculator/types}add");
-        transformStreamAndCompare("../resources/AddRequestIn1.xml", "../resources/AddRequest.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/AddRequestIn1.xml", 
+                                                     "../resources/AddRequest.xml",
                                   null, appendElements, null, null, null);
         
     }
@@ -385,7 +393,8 @@ public class InTransformReaderTest exten
         Map<String, String> appendElements = new HashMap<String, String>();
         appendElements.put("{http://www.w3.org/2003/05/soap-envelope}Body/",
                            "{http://apache.org/cxf/calculator/types}add");
-        transformStreamAndCompare("../resources/AddRequestIn1nospace.xml", "../resources/AddRequest.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/AddRequestIn1nospace.xml", 
+                                                     "../resources/AddRequest.xml",
                                   null, appendElements, null, null, null);
         
     }
@@ -409,119 +418,10 @@ public class InTransformReaderTest exten
         List<String> dropElements = new ArrayList<String>();
         dropElements.add("param");
 
-        transformStreamAndCompare("../resources/AddRequestIn3.xml", "../resources/AddRequest.xml",
+        TransformTestUtils.transformInStreamAndCompare("../resources/AddRequestIn3.xml", 
+                                                     "../resources/AddRequest.xml",
                                   transformElements, appendElements, dropElements, null, null);
         
     }
 
-    // test utilities methods 
-    
-    private void transformStreamAndCompare(String inname, String outname, 
-                                           Map<String, String> transformElements,
-                                           Map<String, String> appendElements,
-                                           List<String> dropElements,
-                                           Map<String, String> transformAttributes,
-                                           Map<String, String> appendAttributes) 
-        throws XMLStreamException {
-        
-        XMLStreamReader reader = 
-            StaxUtils.createXMLStreamReader(
-                      InTransformReader.class.getResourceAsStream(inname));
-
-        reader = new InTransformReader(reader,
-                                        transformElements, appendElements, dropElements, 
-                                        transformAttributes, false);
-
-        XMLStreamReader teacher = 
-            StaxUtils.createXMLStreamReader(
-                      InTransformReader.class.getResourceAsStream(outname));
-        
-        verifyReaders(reader, teacher, false);
-    }
-
-    /**
-     * Verifies the two stream events are equivalent and throws an assertion 
-     * exception at the first mismatch.
-     * @param reader
-     * @param teacher
-     * @param eec
-     * @throws XMLStreamException
-     */
-    private void verifyReaders(XMLStreamReader reader, XMLStreamReader teacher, 
-                               boolean eec) throws XMLStreamException {
-        // compare the elements and attributes while ignoring comments, line breaks, etc
-        for (;;) {
-            int revent = getNextEvent(reader);
-            int tevent = getNextEvent(teacher);
-            
-            if (revent == -1 && tevent == -1) {
-                break;
-            }
-            LOG.fine("Event: " + tevent + " ? " + revent);
-            assertEquals(tevent, revent);
-
-            switch (revent) {
-            case XMLStreamConstants.START_ELEMENT:
-                LOG.fine("Start Element " + teacher.getName() + " ? " + reader.getName());
-                assertEquals(teacher.getName(), reader.getName());
-                verifyAttributes(reader, teacher);
-                break;
-            case XMLStreamConstants.END_ELEMENT:
-                LOG.fine("End Element " + teacher.getName() + " ? " + reader.getName());
-                if (eec) {
-                    // perform end-element-check
-                    assertEquals(teacher.getName(), reader.getName());
-                }
-                break;
-            case XMLStreamConstants.CHARACTERS:
-                LOG.fine("Characters " + teacher.getText() + " ? " + reader.getText());
-                assertEquals(teacher.getText(), reader.getText());
-                break;
-            default:
-            }
-        }
-    }
-
-    private void verifyAttributes(XMLStreamReader reader, XMLStreamReader teacher) {
-        int acount = teacher.getAttributeCount();
-        assertEquals(acount, reader.getAttributeCount());
-        Map<QName, String> attributesMap = new HashMap<QName, String>();
-        // temporarily store all the attributes
-        for (int i = 0; i < acount; i++) {
-            attributesMap.put(reader.getAttributeName(i), reader.getAttributeValue(i));
-        }
-        // compares each attribute
-        for (int i = 0; i < acount; i++) {
-            String avalue = attributesMap.remove(teacher.getAttributeName(i));
-            assertEquals(avalue, teacher.getAttributeValue(i));
-        }
-        // attributes must be exhausted
-        assertTrue(attributesMap.isEmpty());
-    }
-
-    /**
-     * Returns the next relevant reader event.
-     *  
-     * @param reader
-     * @return
-     * @throws XMLStreamException
-     */
-    private int getNextEvent(XMLStreamReader reader) throws XMLStreamException {
-        while (reader.hasNext()) {
-            int e = reader.next();
-            if (e == XMLStreamConstants.END_DOCUMENT) {
-                return e;
-            }
-            if (e == XMLStreamConstants.START_ELEMENT || e == XMLStreamConstants.END_ELEMENT) {
-                return e;
-            } else if (e == XMLStreamConstants.CHARACTERS) {
-                String text = reader.getText();
-                if (text.trim().length() == 0) {
-                    continue;
-                }
-                return e;
-            }
-        }
-        return -1;
-    }
 }

Modified: cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/OutTransformWriterTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/OutTransformWriterTest.java?rev=1227691&r1=1227690&r2=1227691&view=diff
==============================================================================
--- cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/OutTransformWriterTest.java (original)
+++ cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/OutTransformWriterTest.java Thu Jan  5 16:49:56 2012
@@ -18,16 +18,22 @@
  */
 package org.apache.cxf.staxutils.transform;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
 
 import org.apache.cxf.staxutils.StaxUtils;
 import org.junit.Assert;
@@ -133,4 +139,261 @@ public class OutTransformWriterTest exte
     
     private static class TestBean2 {
     }
+    
+    // additional test cases
+    @Test
+    public void testReplaceSimpleElement() throws Exception {
+        InputStream is = new ByteArrayInputStream(
+                "<ns:test xmlns:ns=\"http://bar\"><ns:a>1</ns:a></ns:test>".getBytes());
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        XMLStreamWriter writer = 
+            new OutTransformWriter(StaxUtils.createXMLStreamWriter(os, "UTF-8"), 
+                                   null, Collections.singletonMap("{http://bar}a", "{http://bar}a=1 2 3"),
+                                   null, null, false, null);
+        StaxUtils.copy(new StreamSource(is), writer);
+        writer.flush();
+
+        XMLStreamReader reader = StaxUtils.createXMLStreamReader(new ByteArrayInputStream(os.toByteArray()));
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
+        StaxUtils.copy(reader, bos);
+        String value = bos.toString();
+        assertEquals("<ns:test xmlns:ns=\"http://bar\"><ns:a>1 2 3</ns:a></ns:test>", value);        
+    }
+
+    @Test
+    public void testReadWithComplexRequestSameNamespace() throws Exception {
+        Map<String, String> inMap = new HashMap<String, String>();
+        inMap.put("{http://cxf.apache.org/transform/header/element}*", 
+                "{http://cxf.apache.org/transform/header/element}*");
+        
+        XMLStreamReader reader = 
+            TransformTestUtils.createOutTransformedStreamReader("../resources/complexReqIn1.xml", 
+                                                                inMap, null, null, null, false, null);
+        
+        XMLStreamReader reader2 = 
+            StaxUtils.createXMLStreamReader(
+                OutTransformWriter.class.getResourceAsStream("../resources/complexReq1.xml"));
+        TransformTestUtils.verifyReaders(reader2, reader, true);
+    }
+    
+    @Test
+    public void testReadWithComplexRequestMultipleNamespace() throws Exception {
+        Map<String, String> inMap = new HashMap<String, String>();
+        inMap.put("{http://cxf.apache.org/transform/header/element}*", 
+                "{http://cxf.apache.org/transform/header/otherelement}*");
+        inMap.put("{http://cxf.apache.org/transform/test}*", 
+                "{http://cxf.apache.org/transform/othertest}*");
+        
+        XMLStreamReader reader = 
+            TransformTestUtils.createOutTransformedStreamReader("../resources/complexReqIn2.xml", 
+                                                                inMap, null, null, null, false, null);
+        
+        XMLStreamReader reader2 = 
+            StaxUtils.createXMLStreamReader(
+                InTransformReader.class.getResourceAsStream("../resources/complexReq2.xml"));        
+        TransformTestUtils.verifyReaders(reader2, reader, true);
+    }
+    
+    @Test
+    public void testReadWithComplexTransformationNamespace() throws Exception {
+        Map<String, String> inMap = new HashMap<String, String>();
+        inMap.put("{http://cxf.apache.org/transform/header/element}*", 
+                "{http://cxf.apache.org/transform/header/otherelement}*");
+        inMap.put("{http://cxf.apache.org/transform/test}*", 
+                "{http://cxf.apache.org/transform/othertest}*");
+        inMap.put("{http://schemas.xmlsoap.org/soap/envelope/}Envelope", 
+                "{http://schemas.xmlsoap.org/soap/envelope/}TheEnvelope");
+        
+        // set the block original reader flag to true
+        XMLStreamReader reader = 
+            TransformTestUtils.createOutTransformedStreamReader("../resources/complexReqIn3.xml", 
+                                                                inMap, null, null, null, false, null);
+
+        XMLStreamReader reader2 = 
+            StaxUtils.createXMLStreamReader(
+                InTransformReader.class.getResourceAsStream("../resources/complexReq3.xml"));        
+        TransformTestUtils.verifyReaders(reader2, reader, true);
+    }
+
+    @Test
+    public void testReadWithReplaceAppend() throws Exception {
+        Map<String, String> transformElements = new HashMap<String, String>();
+        transformElements.put("requestValue",
+                              "{http://cxf.apache.org/hello_world_soap_http/types}requestType");
+        
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("requestValue",
+                           "{http://cxf.apache.org/hello_world_soap_http/types}greetMe");
+
+        TransformTestUtils.transformOutStreamAndCompare("../resources/greetMeReqIn1.xml", 
+                                                     "../resources/greetMeReq.xml",
+                                  transformElements, appendElements, null, null, null);
+    }
+
+    @Test
+    public void testReadWithReplaceAppendDelete() throws Exception {
+        Map<String, String> transformElements = new HashMap<String, String>();
+        transformElements.put("requestValue",
+                              "{http://cxf.apache.org/hello_world_soap_http/types}requestType");
+        transformElements.put("{http://cxf.apache.org/hello_world_soap_http/types}requestDate",
+                              "");
+        
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("requestValue",
+                           "{http://cxf.apache.org/hello_world_soap_http/types}greetMe");
+        
+        List<String> dropElements = new ArrayList<String>();
+        dropElements.add("value");
+        
+        Map<String, String> transformAttributes = new HashMap<String, String>();
+        transformAttributes.put("num", "");
+        transformAttributes.put("nombre", "{http://cxf.apache.org/hello_world_soap_http/types}name");
+        
+        TransformTestUtils.transformOutStreamAndCompare("../resources/greetMeReqIn2.xml", 
+                                                     "../resources/greetMeReq.xml",
+                                  transformElements, appendElements, dropElements, 
+                                  transformAttributes, null);
+    }
+
+    @Test
+    public void testReadWithChangeNamespaces() throws Exception {
+        Map<String, String> transformElements = new HashMap<String, String>();
+        transformElements.put("*",
+                              "{http://cxf.apache.org/hello_world_soap_http/types}*");
+
+        TransformTestUtils.transformOutStreamAndCompare("../resources/greetMeReqIn3.xml", 
+                                                     "../resources/greetMeReq.xml",
+                                  transformElements, null, null, null, null);
+    }
+
+    @Test
+    public void testReadWithDeleteAttributes() throws Exception {
+        Map<String, String> transformAttributes = new HashMap<String, String>();
+        transformAttributes.put("{http://www.w3.org/2001/XMLSchema-instance}type",
+                                "");
+
+        TransformTestUtils.transformOutStreamAndCompare("../resources/greetMeReqIn4.xml", 
+                                                     "../resources/greetMeReq.xml",
+                                  null, null, null, transformAttributes, null);
+    }
+    
+    @Test
+    public void testReadWithAppendPreInclude1() throws Exception {
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId",
+                           "{http://xml.amazon.com/AWSECommerceService/2004-08-01}IdType=ASIN");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/amazonIn1.xml", 
+                                                     "../resources/amazon.xml",
+                                  null, appendElements, null, null, null);
+        
+    }
+
+    @Test
+    public void testReadWithAppendPreInclude2() throws Exception {
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId",
+                           "{http://xml.amazon.com/AWSECommerceService/2004-08-01}IdType=ASIN");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/amazonIn1nospace.xml", 
+                                                     "../resources/amazon.xml",
+                                  null, appendElements, null, null, null);
+        
+    }
+
+    @Test
+    public void testReadWithAppendPreWrap1() throws Exception {
+        Map<String, String> transformElements = new HashMap<String, String>();
+        transformElements.put("payload",
+                              "{http://www.w3.org/2003/05/soap-envelope}Envelope");
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://apache.org/cxf/calculator/types}add",
+                           "{http://www.w3.org/2003/05/soap-envelope}Body");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/AddRequestIn2.xml", 
+                                                     "../resources/AddRequest.xml",
+                                  transformElements, appendElements, null, null, null);
+    }
+
+    @Test
+    public void testReadWithAppendPreWrap2() throws Exception {
+        Map<String, String> transformElements = new HashMap<String, String>();
+        transformElements.put("payload",
+                              "{http://www.w3.org/2003/05/soap-envelope}Envelope");
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://apache.org/cxf/calculator/types}add",
+                           "{http://www.w3.org/2003/05/soap-envelope}Body");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/AddRequestIn2nospace.xml", 
+                                                     "../resources/AddRequest.xml",
+                                  transformElements, appendElements, null, null, null);
+    }
+
+    @Test
+    public void testReadWithAppendPostInclude1() throws Exception {
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}Request/",
+                           "{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId=0486411214");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/amazonIn2.xml", 
+                                                     "../resources/amazon.xml",
+                                  null, appendElements, null, null, null);
+        
+    }
+
+    @Test
+    public void testReadWithAppendPostInclude2() throws Exception {
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://xml.amazon.com/AWSECommerceService/2004-08-01}Request/",
+                           "{http://xml.amazon.com/AWSECommerceService/2004-08-01}ItemId=0486411214");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/amazonIn2nospace.xml", 
+                                                     "../resources/amazon.xml",
+                                  null, appendElements, null, null, null);
+        
+    }
+
+    @Test
+    public void testReadWithAppendPostWrap1() throws Exception {
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://www.w3.org/2003/05/soap-envelope}Body/",
+                           "{http://apache.org/cxf/calculator/types}add");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/AddRequestIn1.xml", 
+                                                     "../resources/AddRequest.xml",
+                                  null, appendElements, null, null, null);
+        
+    }
+
+    @Test
+    public void testReadWithAppendPostWrap2() throws Exception {
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("{http://www.w3.org/2003/05/soap-envelope}Body/",
+                           "{http://apache.org/cxf/calculator/types}add");
+        TransformTestUtils.transformOutStreamAndCompare("../resources/AddRequestIn1nospace.xml", 
+                                                     "../resources/AddRequest.xml",
+                                  null, appendElements, null, null, null);
+        
+    }
+
+    @Test
+    public void testReadWithAppendPostWrapReplaceDrop() throws Exception {
+        Map<String, String> transformElements = new HashMap<String, String>();
+        transformElements.put("payload",
+                              "{http://www.w3.org/2003/05/soap-envelope}Envelope");
+        transformElements.put("params",
+                              "{http://apache.org/cxf/calculator/types}add");
+        transformElements.put("i1",
+                              "{http://apache.org/cxf/calculator/types}arg0");
+        transformElements.put("i2",
+                              "{http://apache.org/cxf/calculator/types}arg1");
+        transformElements.put("i3",
+                              "");
+        Map<String, String> appendElements = new HashMap<String, String>();
+        appendElements.put("payload/",
+                           "{http://www.w3.org/2003/05/soap-envelope}Body");
+        List<String> dropElements = new ArrayList<String>();
+        dropElements.add("param");
+
+        TransformTestUtils.transformOutStreamAndCompare("../resources/AddRequestIn3.xml", 
+                                                     "../resources/AddRequest.xml",
+                                  transformElements, appendElements, dropElements, null, null);
+        
+    }
+    
 }

Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/TransformTestUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/TransformTestUtils.java?rev=1227691&view=auto
==============================================================================
--- cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/TransformTestUtils.java (added)
+++ cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/TransformTestUtils.java Thu Jan  5 16:49:56 2012
@@ -0,0 +1,208 @@
+/**
+ * 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.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.staxutils.StaxUtils;
+
+import org.junit.Assert;
+
+/**
+ * 
+ */
+public final class TransformTestUtils {
+    private static final Logger LOG = LogUtils.getLogger(TransformTestUtils.class);
+
+    private TransformTestUtils() {
+    }
+    
+    // test utilities methods 
+    
+    static void transformInStreamAndCompare(String inname, String outname, 
+                                           Map<String, String> transformElements,
+                                           Map<String, String> appendElements,
+                                           List<String> dropElements,
+                                           Map<String, String> transformAttributes,
+                                           Map<String, String> appendAttributes) 
+        throws XMLStreamException {
+        
+        XMLStreamReader reader = createInTransformedStreamReader(inname,
+                                                                 transformElements,
+                                                                 appendElements,
+                                                                 dropElements,
+                                                                 transformAttributes);
+        
+        XMLStreamReader teacher = 
+            StaxUtils.createXMLStreamReader(
+                      TransformTestUtils.class.getResourceAsStream(outname));
+        
+        verifyReaders(teacher, reader, false);
+    }
+
+    static void transformOutStreamAndCompare(String inname, String outname, 
+                                           Map<String, String> transformElements,
+                                           Map<String, String> appendElements,
+                                           List<String> dropElements,
+                                           Map<String, String> transformAttributes,
+                                           Map<String, String> appendAttributes) 
+        throws XMLStreamException {
+        
+        XMLStreamReader reader = createOutTransformedStreamReader(inname, 
+                                                                  transformElements, appendElements, 
+                                                                  dropElements, transformAttributes, 
+                                                                  false, null);
+        XMLStreamReader teacher = 
+            StaxUtils.createXMLStreamReader(
+                      TransformTestUtils.class.getResourceAsStream(outname));
+        
+        verifyReaders(teacher, reader, false);
+    }
+
+    static XMLStreamReader createInTransformedStreamReader(
+        String file,
+        Map<String, String> emap, 
+        Map<String, String> eappend,
+        List<String> dropEls,
+        Map<String, String> amap) throws XMLStreamException {
+
+        return new InTransformReader(StaxUtils.createXMLStreamReader(
+            TransformTestUtils.class.getResourceAsStream(file)),
+            emap, eappend, dropEls, amap, false);
+    }
+    
+    static XMLStreamReader createOutTransformedStreamReader(
+        String file,
+        Map<String, String> emap, 
+        Map<String, String> append,
+        List<String> dropEls,
+        Map<String, String> amap,
+        boolean attributesToElements,
+        String defaultNamespace) throws XMLStreamException {
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        XMLStreamWriter writer = 
+            new OutTransformWriter(StaxUtils.createXMLStreamWriter(os, "UTF-8"), 
+                                   emap, append, dropEls, amap, attributesToElements, defaultNamespace);
+        StaxUtils.copy(new StreamSource(TransformTestUtils.class.getResourceAsStream(file)), writer);
+        writer.flush();
+
+        return StaxUtils.createXMLStreamReader(new ByteArrayInputStream(os.toByteArray()));
+    }
+
+    /**
+     * Verifies the two stream events are equivalent and throws an assertion 
+     * exception at the first mismatch.
+     * @param teacher
+     * @param reader
+     * @param eec
+     * @throws XMLStreamException
+     */
+    static void verifyReaders(XMLStreamReader teacher, XMLStreamReader reader, 
+                               boolean eec) throws XMLStreamException {
+        // compare the elements and attributes while ignoring comments, line breaks, etc
+        for (;;) {
+            int revent = getNextEvent(reader);
+            int tevent = getNextEvent(teacher);
+            
+            if (revent == -1 && tevent == -1) {
+                break;
+            }
+            LOG.fine("Event: " + tevent + " ? " + revent);
+            Assert.assertEquals(tevent, revent);
+
+            switch (revent) {
+            case XMLStreamConstants.START_ELEMENT:
+                LOG.fine("Start Element " + teacher.getName() + " ? " + reader.getName());
+                Assert.assertEquals(teacher.getName(), reader.getName());
+                verifyAttributes(teacher, reader);
+                break;
+            case XMLStreamConstants.END_ELEMENT:
+                LOG.fine("End Element " + teacher.getName() + " ? " + reader.getName());
+                if (eec) {
+                    // perform end-element-check
+                    Assert.assertEquals(teacher.getName(), reader.getName());
+                }
+                break;
+            case XMLStreamConstants.CHARACTERS:
+                LOG.fine("Characters " + teacher.getText() + " ? " + reader.getText());
+                Assert.assertEquals(teacher.getText(), reader.getText());
+                break;
+            default:
+            }
+        }
+    }
+
+    private static void verifyAttributes(XMLStreamReader teacher, XMLStreamReader reader) {
+        int acount = teacher.getAttributeCount();
+        Assert.assertEquals(acount, reader.getAttributeCount());
+        Map<QName, String> attributesMap = new HashMap<QName, String>();
+        // temporarily store all the attributes
+        for (int i = 0; i < acount; i++) {
+            attributesMap.put(reader.getAttributeName(i), reader.getAttributeValue(i));
+        }
+        // compares each attribute
+        for (int i = 0; i < acount; i++) {
+            String avalue = attributesMap.remove(teacher.getAttributeName(i));
+            Assert.assertEquals(avalue, teacher.getAttributeValue(i));
+        }
+        // attributes must be exhausted
+        Assert.assertTrue(attributesMap.isEmpty());
+    }
+
+    /**
+     * Returns the next relevant reader event.
+     *  
+     * @param reader
+     * @return
+     * @throws XMLStreamException
+     */
+    private static int getNextEvent(XMLStreamReader reader) throws XMLStreamException {
+        while (reader.hasNext()) {
+            int e = reader.next();
+            if (e == XMLStreamConstants.END_DOCUMENT) {
+                return e;
+            }
+            if (e == XMLStreamConstants.START_ELEMENT || e == XMLStreamConstants.END_ELEMENT) {
+                return e;
+            } else if (e == XMLStreamConstants.CHARACTERS) {
+                String text = reader.getText();
+                if (text.trim().length() == 0) {
+                    continue;
+                }
+                return e;
+            }
+        }
+        return -1;
+    }
+}

Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/staxutils/transform/TransformTestUtils.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JAXBElementProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JAXBElementProviderTest.java?rev=1227691&r1=1227690&r2=1227691&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JAXBElementProviderTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JAXBElementProviderTest.java Thu Jan  5 16:49:56 2012
@@ -471,7 +471,6 @@ public class JAXBElementProviderTest ext
                          new MetadataMap<String, Object>(), bos);
         assertTrue(bos.toString().contains("thebook2"));
         assertTrue(bos.toString().contains("http://superbooks"));
-        System.out.println(bos.toString());
         ByteArrayInputStream is = new ByteArrayInputStream(bos.toByteArray());
         Book2 book2 = 
             (Book2)provider.readFrom(
@@ -1005,8 +1004,10 @@ public class JAXBElementProviderTest ext
         JAXBElementProvider provider = new JAXBElementProvider();
         List<String> list = new ArrayList<String>();
         list.add("{http://tags}thetag");
-        list.add("name");
         provider.setOutDropElements(list);
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("name", "");
+        provider.setOutTransformElements(map);
         TagVO2 tag = new TagVO2("A", "B");
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         provider.writeTo(tag, TagVO2.class, TagVO2.class,

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java?rev=1227691&r1=1227690&r2=1227691&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java Thu Jan  5 16:49:56 2012
@@ -967,8 +967,10 @@ public class JSONProviderTest extends As
         JSONProvider provider = new JSONProvider();
         List<String> list = new ArrayList<String>();
         list.add("{http://tags}thetag");
-        list.add("name");
         provider.setOutDropElements(list);
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("name", "");
+        provider.setOutTransformElements(map);
         TagVO2 tag = new TagVO2("A", "B");
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         provider.writeTo(tag, TagVO2.class, TagVO2.class,



Re: Transform Feature Improvements (Was: Re: svn commit: r1227691)

Posted by Aki Yoshida <el...@googlemail.com>.
2012/1/26 Sergey Beryozkin <sb...@gmail.com>:
> Hi,
>
>
> On 26/01/12 09:52, Aki Yoshida wrote:
>>
>> 2012/1/25 Sergey Beryozkin<sb...@gmail.com>:
>>>
>>> Hi Aki
>>>
>>> I've changed the subject, hope you are ok with it
>>>
>>> On 25/01/12 10:04, Aki Yoshida wrote:
>>>>
>>>>
>>>> 2012/1/24 Sergey Beryozkin<sb...@gmail.com>:
>>>>>
>>>>>
>>>>> Hi Aki
>>>>>
>>>>> On 05/01/12 16:49, ay@apache.org wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> Author: ay
>>>>>> Date: Thu Jan  5 16:49:56 2012
>>>>>> New Revision: 1227691
>>>>>>
>>>>>> URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
>>>>>> Log:
>>>>>> [CXF-4013] Enhancing the element-append and drop options of
>>>>>> OutTransformWriter
>>>>>>
>>>>>
>>>>> I've finally updated the documentation [1] to take note of your
>>>>> enhancement,
>>>>> thanks for this fine effort.
>>>>>
>>>>> It's quite complete now, this feature, may be we can offer some basic
>>>>> conditional transformation support in time too :-)
>>>>>
>>>>
>>>> Hi Sergey,
>>>>
>>>> Thanks for the documentation update. We have now the inbound and
>>>> outbound transformation features aligned.
>>>>
>>>> Yes, we can add a few things along this transformation model. Allowing
>>>> a simple node path rather than just its node name to pick the node is
>>>> a useful extension. This will be easy. Providing some conditional
>>>> transformation is also useful one. If we can limit its functionality
>>>> and complexity in some reasonably level, that will be good.
>>>>
>>>
>>> I thought briefly about it, supporting node paths and simple conditions
>>> can
>>> probably be handled at the same time.
>>> As far as the condition is concerned, it should probably be
>>> straightforward
>>> conditions such as:
>>>
>>> /a:bar/a:foo = "text"
>>> /a:bar/a:foo/@baz = "text"
>>>
>>> and say inTransformMap:
>>> /a:bar/a:foo : {myns2}foo
>>>
>>> I recall you had an idea how to specify prefixes, may be we can also set
>>> a
>>> custom namespaceToPrefixes map so that we can say:
>>> /a:bar/a:foo : {b}foo
>>>
>>> at any moment of time we can get String or some stack pointing to the
>>> current simple element or attribute.
>>>
>>> If no conditions are there then as soon as we get a matching path we
>>> apply
>>> the transfpormation, otherwise we additionally check that the simple
>>> conditions are met
>>>
>>> I guess we can do something not too over-complex indeed, in many cases
>>> it's
>>> probably simple logic or path that can be applied
>>
>>
>> Hi Sergey,
>>
>> If the conditions can be evaluated at the time of parsing, we can keep
>> the mechanism simple. So, we should assume this restriction.
>>
>> Regarding how to specify the fixed namespace prefixes, for the plain
>> bean property based configuration, we could provide a namespace-prefix
>> mapping table. But this is kind of redundant because the namespace
>> prefix binding is in the parsing context. I wonder if there is a
>> simple way to get to the underlining namespace context without
>> introducing a spring/BP namespace handler for this feature. If not, we
>> can start with the mapping table approach.
>>
>
> I was not thinking of introducing a spring or BP handler, but rather
> optionally providing a namespace mapping table to the in/out writers.
> I'm not sure that the prefix that JAXB will provide at a given time will
> always match the one specified in the path/condition.
>
> May be the first step, before even trying to deal with paths or conditions,
> is to start supporting transform maps such as:
>
> "a:b" to "a1:b"
>
> as an alternative to
>
> "{http://myns/1}b" to "{http://myns/2}:b"
>
> which will be possible if the additional table is available with
> http://myns/1: a
> http://myns/2: a1
>
> values...
>
>
> I may give it a try a bit later on if you agree it makes sense

Sounds good. That will be fine with me. So I suppose, we will have
something like

    <property name="outTransformElements">
       <map>
         <entry key="a:b" value="a1:b"/>
         ...
       </map>
    </property>
    <property name="namespaces" >
         <map>
              <entry key="a" value="http://myns/1"/>
              <entry key="a1" value="http://myns/2"/>
         </map>
    </property>

regards, aki

>
> Cheers, Sergey
>
>
>
>> regards, aki
>>
>>>
>>> Cheers, Sergey
>>>
>>>> Regards, aki
>>>>
>>>>> Cheers
>>>>> Sergey
>>>>>
>>>>>
>>>>> [1]
>>>>>
>>>>>
>>>>> https://cwiki.apache.org/confluence/display/CXF20DOC/TransformationFeature
>>>
>>>
>>>
>>>
>>> --
>>> Sergey Beryozkin
>>>
>>> Talend Community Coders
>>> http://coders.talend.com/
>>>
>>> Blog: http://sberyozkin.blogspot.com

Re: Transform Feature Improvements (Was: Re: svn commit: r1227691)

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi,

On 26/01/12 09:52, Aki Yoshida wrote:
> 2012/1/25 Sergey Beryozkin<sb...@gmail.com>:
>> Hi Aki
>>
>> I've changed the subject, hope you are ok with it
>>
>> On 25/01/12 10:04, Aki Yoshida wrote:
>>>
>>> 2012/1/24 Sergey Beryozkin<sb...@gmail.com>:
>>>>
>>>> Hi Aki
>>>>
>>>> On 05/01/12 16:49, ay@apache.org wrote:
>>>>>
>>>>>
>>>>> Author: ay
>>>>> Date: Thu Jan  5 16:49:56 2012
>>>>> New Revision: 1227691
>>>>>
>>>>> URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
>>>>> Log:
>>>>> [CXF-4013] Enhancing the element-append and drop options of
>>>>> OutTransformWriter
>>>>>
>>>>
>>>> I've finally updated the documentation [1] to take note of your
>>>> enhancement,
>>>> thanks for this fine effort.
>>>>
>>>> It's quite complete now, this feature, may be we can offer some basic
>>>> conditional transformation support in time too :-)
>>>>
>>>
>>> Hi Sergey,
>>>
>>> Thanks for the documentation update. We have now the inbound and
>>> outbound transformation features aligned.
>>>
>>> Yes, we can add a few things along this transformation model. Allowing
>>> a simple node path rather than just its node name to pick the node is
>>> a useful extension. This will be easy. Providing some conditional
>>> transformation is also useful one. If we can limit its functionality
>>> and complexity in some reasonably level, that will be good.
>>>
>>
>> I thought briefly about it, supporting node paths and simple conditions can
>> probably be handled at the same time.
>> As far as the condition is concerned, it should probably be straightforward
>> conditions such as:
>>
>> /a:bar/a:foo = "text"
>> /a:bar/a:foo/@baz = "text"
>>
>> and say inTransformMap:
>> /a:bar/a:foo : {myns2}foo
>>
>> I recall you had an idea how to specify prefixes, may be we can also set a
>> custom namespaceToPrefixes map so that we can say:
>> /a:bar/a:foo : {b}foo
>>
>> at any moment of time we can get String or some stack pointing to the
>> current simple element or attribute.
>>
>> If no conditions are there then as soon as we get a matching path we apply
>> the transfpormation, otherwise we additionally check that the simple
>> conditions are met
>>
>> I guess we can do something not too over-complex indeed, in many cases it's
>> probably simple logic or path that can be applied
>
> Hi Sergey,
>
> If the conditions can be evaluated at the time of parsing, we can keep
> the mechanism simple. So, we should assume this restriction.
>
> Regarding how to specify the fixed namespace prefixes, for the plain
> bean property based configuration, we could provide a namespace-prefix
> mapping table. But this is kind of redundant because the namespace
> prefix binding is in the parsing context. I wonder if there is a
> simple way to get to the underlining namespace context without
> introducing a spring/BP namespace handler for this feature. If not, we
> can start with the mapping table approach.
>

I was not thinking of introducing a spring or BP handler, but rather 
optionally providing a namespace mapping table to the in/out writers.
I'm not sure that the prefix that JAXB will provide at a given time will 
always match the one specified in the path/condition.

May be the first step, before even trying to deal with paths or 
conditions, is to start supporting transform maps such as:

"a:b" to "a1:b"

as an alternative to

"{http://myns/1}b" to "{http://myns/2}:b"

which will be possible if the additional table is available with
http://myns/1: a
http://myns/2: a1

values...


I may give it a try a bit later on if you agree it makes sense

Cheers, Sergey


> regards, aki
>
>>
>> Cheers, Sergey
>>
>>> Regards, aki
>>>
>>>> Cheers
>>>> Sergey
>>>>
>>>>
>>>> [1]
>>>>
>>>> https://cwiki.apache.org/confluence/display/CXF20DOC/TransformationFeature
>>
>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com

Re: Transform Feature Improvements (Was: Re: svn commit: r1227691)

Posted by Aki Yoshida <el...@googlemail.com>.
2012/1/25 Sergey Beryozkin <sb...@gmail.com>:
> Hi Aki
>
> I've changed the subject, hope you are ok with it
>
> On 25/01/12 10:04, Aki Yoshida wrote:
>>
>> 2012/1/24 Sergey Beryozkin<sb...@gmail.com>:
>>>
>>> Hi Aki
>>>
>>> On 05/01/12 16:49, ay@apache.org wrote:
>>>>
>>>>
>>>> Author: ay
>>>> Date: Thu Jan  5 16:49:56 2012
>>>> New Revision: 1227691
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
>>>> Log:
>>>> [CXF-4013] Enhancing the element-append and drop options of
>>>> OutTransformWriter
>>>>
>>>
>>> I've finally updated the documentation [1] to take note of your
>>> enhancement,
>>> thanks for this fine effort.
>>>
>>> It's quite complete now, this feature, may be we can offer some basic
>>> conditional transformation support in time too :-)
>>>
>>
>> Hi Sergey,
>>
>> Thanks for the documentation update. We have now the inbound and
>> outbound transformation features aligned.
>>
>> Yes, we can add a few things along this transformation model. Allowing
>> a simple node path rather than just its node name to pick the node is
>> a useful extension. This will be easy. Providing some conditional
>> transformation is also useful one. If we can limit its functionality
>> and complexity in some reasonably level, that will be good.
>>
>
> I thought briefly about it, supporting node paths and simple conditions can
> probably be handled at the same time.
> As far as the condition is concerned, it should probably be straightforward
> conditions such as:
>
> /a:bar/a:foo = "text"
> /a:bar/a:foo/@baz = "text"
>
> and say inTransformMap:
> /a:bar/a:foo : {myns2}foo
>
> I recall you had an idea how to specify prefixes, may be we can also set a
> custom namespaceToPrefixes map so that we can say:
> /a:bar/a:foo : {b}foo
>
> at any moment of time we can get String or some stack pointing to the
> current simple element or attribute.
>
> If no conditions are there then as soon as we get a matching path we apply
> the transfpormation, otherwise we additionally check that the simple
> conditions are met
>
> I guess we can do something not too over-complex indeed, in many cases it's
> probably simple logic or path that can be applied

Hi Sergey,

If the conditions can be evaluated at the time of parsing, we can keep
the mechanism simple. So, we should assume this restriction.

Regarding how to specify the fixed namespace prefixes, for the plain
bean property based configuration, we could provide a namespace-prefix
mapping table. But this is kind of redundant because the namespace
prefix binding is in the parsing context. I wonder if there is a
simple way to get to the underlining namespace context without
introducing a spring/BP namespace handler for this feature. If not, we
can start with the mapping table approach.

regards, aki

>
> Cheers, Sergey
>
>> Regards, aki
>>
>>> Cheers
>>> Sergey
>>>
>>>
>>> [1]
>>>
>>> https://cwiki.apache.org/confluence/display/CXF20DOC/TransformationFeature
>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com

Transform Feature Improvements (Was: Re: svn commit: r1227691)

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Aki

I've changed the subject, hope you are ok with it

On 25/01/12 10:04, Aki Yoshida wrote:
> 2012/1/24 Sergey Beryozkin<sb...@gmail.com>:
>> Hi Aki
>>
>> On 05/01/12 16:49, ay@apache.org wrote:
>>>
>>> Author: ay
>>> Date: Thu Jan  5 16:49:56 2012
>>> New Revision: 1227691
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
>>> Log:
>>> [CXF-4013] Enhancing the element-append and drop options of
>>> OutTransformWriter
>>>
>>
>> I've finally updated the documentation [1] to take note of your enhancement,
>> thanks for this fine effort.
>>
>> It's quite complete now, this feature, may be we can offer some basic
>> conditional transformation support in time too :-)
>>
>
> Hi Sergey,
>
> Thanks for the documentation update. We have now the inbound and
> outbound transformation features aligned.
>
> Yes, we can add a few things along this transformation model. Allowing
> a simple node path rather than just its node name to pick the node is
> a useful extension. This will be easy. Providing some conditional
> transformation is also useful one. If we can limit its functionality
> and complexity in some reasonably level, that will be good.
>

I thought briefly about it, supporting node paths and simple conditions 
can probably be handled at the same time.
As far as the condition is concerned, it should probably be 
straightforward conditions such as:

/a:bar/a:foo = "text"
/a:bar/a:foo/@baz = "text"

and say inTransformMap:
/a:bar/a:foo : {myns2}foo

I recall you had an idea how to specify prefixes, may be we can also set 
a custom namespaceToPrefixes map so that we can say:
/a:bar/a:foo : {b}foo

at any moment of time we can get String or some stack pointing to the 
current simple element or attribute.

If no conditions are there then as soon as we get a matching path we 
apply the transfpormation, otherwise we additionally check that the 
simple conditions are met

I guess we can do something not too over-complex indeed, in many cases 
it's probably simple logic or path that can be applied

Cheers, Sergey

> Regards, aki
>
>> Cheers
>> Sergey
>>
>>
>> [1]
>> https://cwiki.apache.org/confluence/display/CXF20DOC/TransformationFeature


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: svn commit: r1227691

Posted by Aki Yoshida <el...@googlemail.com>.
2012/1/24 Sergey Beryozkin <sb...@gmail.com>:
> Hi Aki
>
> On 05/01/12 16:49, ay@apache.org wrote:
>>
>> Author: ay
>> Date: Thu Jan  5 16:49:56 2012
>> New Revision: 1227691
>>
>> URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
>> Log:
>> [CXF-4013] Enhancing the element-append and drop options of
>> OutTransformWriter
>>
>
> I've finally updated the documentation [1] to take note of your enhancement,
> thanks for this fine effort.
>
> It's quite complete now, this feature, may be we can offer some basic
> conditional transformation support in time too :-)
>

Hi Sergey,

Thanks for the documentation update. We have now the inbound and
outbound transformation features aligned.

Yes, we can add a few things along this transformation model. Allowing
a simple node path rather than just its node name to pick the node is
a useful extension. This will be easy. Providing some conditional
transformation is also useful one. If we can limit its functionality
and complexity in some reasonably level, that will be good.

Regards, aki

> Cheers
> Sergey
>
>
> [1]
> https://cwiki.apache.org/confluence/display/CXF20DOC/TransformationFeature

Re: svn commit: r1227691

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Aki

On 05/01/12 16:49, ay@apache.org wrote:
> Author: ay
> Date: Thu Jan  5 16:49:56 2012
> New Revision: 1227691
>
> URL: http://svn.apache.org/viewvc?rev=1227691&view=rev
> Log:
> [CXF-4013] Enhancing the element-append and drop options of OutTransformWriter
>

I've finally updated the documentation [1] to take note of your 
enhancement, thanks for this fine effort.

It's quite complete now, this feature, may be we can offer some basic 
conditional transformation support in time too :-)

Cheers
Sergey


[1] 
https://cwiki.apache.org/confluence/display/CXF20DOC/TransformationFeature