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 2013/09/30 19:46:45 UTC

svn commit: r1527683 - in /cxf/branches/2.7.x-fixes: api/src/main/java/org/apache/cxf/common/jaxb/ api/src/main/java/org/apache/cxf/common/util/ api/src/main/java/org/apache/cxf/databinding/ rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/ rt/...

Author: ay
Date: Mon Sep 30 17:46:44 2013
New Revision: 1527683

URL: http://svn.apache.org/r1527683
Log:
Merged revisions 1524470 via  git cherry-pick from
https://svn.apache.org/repos/asf/cxf/trunk

........
  r1524470 | ay | 2013-09-18 18:04:52 +0200 (Wed, 18 Sep 2013) | 2 lines

  [CXF-5290] jaxb's databinding to support an option to not include specific namespace declarations when marshalling

........

Modified:
    cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
    cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/NamespaceMapper.java
    cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/util/ASMHelper.java
    cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/databinding/AbstractDataBinding.java
    cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
    cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
    cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/io/XMLStreamDataWriterTest.java

Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java (original)
+++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java Mon Sep 30 17:46:44 2013
@@ -1021,17 +1021,22 @@ public final class JAXBUtils {
             return null;
         }
     }
+    
+    //CHECKSTYLE:OFF
     private static Class<?> createNamespaceWrapperInternal(ASMHelper helper, ClassWriter cw, 
                                                            String postFix, Class<?> ref) {
         String className = "org.apache.cxf.jaxb.NamespaceMapper" + postFix;
         String superName = "com/sun/xml/" 
             + ("RI".equals(postFix) ? "" : "internal/") 
             + "bind/marshaller/NamespacePrefixMapper";
+        String postFixedName = "org/apache/cxf/jaxb/NamespaceMapper" + postFix;
+        
         FieldVisitor fv;
         MethodVisitor mv;
-        cw.visit(Opcodes.V1_5, 
+
+        cw.visit(Opcodes.V1_6,
                  Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
-                 "org/apache/cxf/jaxb/NamespaceMapper" + postFix, null,
+                 postFixedName, null,
                  superName, null);
 
         cw.visitSource("NamespaceMapper.java", null);
@@ -1040,34 +1045,57 @@ public final class JAXBUtils {
                            "nspref", "Ljava/util/Map;",
                            "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", null);
         fv.visitEnd();
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, 
+                           "EMPTY_STRING", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
         
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", 
-                            "(Ljava/util/Map;)V", 
-                            "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+        mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
         mv.visitCode();
         Label l0 = helper.createLabel();
         mv.visitLabel(l0);
         mv.visitLineNumber(30, l0);
+        mv.visitInsn(Opcodes.ICONST_0);
+        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
+        mv.visitFieldInsn(Opcodes.PUTSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.RETURN);
+        mv.visitMaxs(1, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
+                            "(Ljava/util/Map;)V",
+                            "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(32, l0);
         mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                           superName, "<init>", "()V");
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", "()V");
         Label l1 = helper.createLabel();
         mv.visitLabel(l1);
-        mv.visitLineNumber(31, l1);
+        mv.visitLineNumber(29, l1);
         mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitFieldInsn(Opcodes.PUTFIELD, "org/apache/cxf/jaxb/NamespaceMapper" + postFix,
-                          "nspref", "Ljava/util/Map;");
+        mv.visitFieldInsn(Opcodes.GETSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
         Label l2 = helper.createLabel();
         mv.visitLabel(l2);
-        mv.visitLineNumber(32, l2);
-        mv.visitInsn(Opcodes.RETURN);
+        mv.visitLineNumber(33, l2);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nspref", "Ljava/util/Map;");
         Label l3 = helper.createLabel();
         mv.visitLabel(l3);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/jaxb/NamespaceMapper" + postFix + ";", null, l0, l3, 0);
-        mv.visitLocalVariable("nspref", "Ljava/util/Map;",
-                              "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", 
-                              l0, l3, 1);
+        mv.visitLineNumber(34, l3);
+        mv.visitInsn(Opcodes.RETURN);
+        Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+        mv.visitLocalVariable("nspref", 
+                              "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", 
+                              l0, l4, 1);
         mv.visitMaxs(2, 2);
         mv.visitEnd();
 
@@ -1077,11 +1105,9 @@ public final class JAXBUtils {
         mv.visitCode();
         l0 = helper.createLabel();
         mv.visitLabel(l0);
-        mv.visitLineNumber(38, l0);
+        mv.visitLineNumber(39, l0);
         mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, 
-                          "org/apache/cxf/jaxb/NamespaceMapper" + postFix, 
-                          "nspref", "Ljava/util/Map;");
+        mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nspref", "Ljava/util/Map;");
         mv.visitVarInsn(Opcodes.ALOAD, 1);
         mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", 
                            "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
@@ -1089,34 +1115,72 @@ public final class JAXBUtils {
         mv.visitVarInsn(Opcodes.ASTORE, 4);
         l1 = helper.createLabel();
         mv.visitLabel(l1);
-        mv.visitLineNumber(39, l1);
+        mv.visitLineNumber(40, l1);
         mv.visitVarInsn(Opcodes.ALOAD, 4);
         l2 = helper.createLabel();
         mv.visitJumpInsn(Opcodes.IFNULL, l2);
         l3 = helper.createLabel();
         mv.visitLabel(l3);
-        mv.visitLineNumber(40, l3);
+        mv.visitLineNumber(41, l3);
         mv.visitVarInsn(Opcodes.ALOAD, 4);
         mv.visitInsn(Opcodes.ARETURN);
         mv.visitLabel(l2);
-        mv.visitLineNumber(42, l2);
+        mv.visitLineNumber(43, l2);
+        mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
         mv.visitVarInsn(Opcodes.ALOAD, 2);
         mv.visitInsn(Opcodes.ARETURN);
-        Label l4 = helper.createLabel();
+        l4 = helper.createLabel();
         mv.visitLabel(l4);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/jaxb/NamespaceMapper" + postFix + ";", null, l0, l4, 0);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
         mv.visitLocalVariable("namespaceUri", "Ljava/lang/String;", null, l0, l4, 1);
         mv.visitLocalVariable("suggestion", "Ljava/lang/String;", null, l0, l4, 2);
         mv.visitLocalVariable("requirePrefix", "Z", null, l0, l4, 3);
         mv.visitLocalVariable("prefix", "Ljava/lang/String;", null, l1, l4, 4);
         mv.visitMaxs(2, 5);
         mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(47, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(48, l1);
+        mv.visitInsn(Opcodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l2, 0);
+        mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+        mv.visitMaxs(2, 2);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(51, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARETURN);
+        l1 = helper.createLabel();
+
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l1, 0);
+        
+        mv.visitMaxs(1, 1);
+        mv.visitEnd();
+
         cw.visitEnd();
 
         byte bts[] = cw.toByteArray();
         return helper.loadClass(className,
                                 ref, bts);
     }
+    //CHECKSTYLE:ON
     
     public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx) {
         return createJAXBContextProxy(ctx, null, null);

Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/NamespaceMapper.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/NamespaceMapper.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/NamespaceMapper.java (original)
+++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/jaxb/NamespaceMapper.java Mon Sep 30 17:46:44 2013
@@ -25,7 +25,10 @@ import com.sun.xml.bind.marshaller.Names
 
 
 public final class NamespaceMapper extends NamespacePrefixMapper {
+    private static final String[] EMPTY_STRING = new String[0];
+
     private final Map<String, String> nspref;
+    private String[] nsctxt = EMPTY_STRING;
 
     public NamespaceMapper(Map<String, String> nspref) {
         this.nspref = nspref;
@@ -40,4 +43,14 @@ public final class NamespaceMapper exten
         }
         return suggestion;
     }
+
+    public void setContextualNamespace(String[] contextualNamespaceDecls) {
+        this.nsctxt = contextualNamespaceDecls;
+    }
+
+    public String[] getContextualNamespaceDecls() {
+        return nsctxt;
+    }
+    
+    
 }
\ No newline at end of file

Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/util/ASMHelper.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/util/ASMHelper.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/util/ASMHelper.java (original)
+++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/common/util/ASMHelper.java Mon Sep 30 17:46:44 2013
@@ -127,6 +127,7 @@ public class ASMHelper {
         public static int ILOAD = 0;
         public static int IRETURN = 0;
         public static int NEW = 0;
+        public static int ANEWARRAY = 0;
         public static int DUP = 0;
         public static int ATHROW = 0;
         public static int INVOKEVIRTUAL = 0;

Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/databinding/AbstractDataBinding.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/databinding/AbstractDataBinding.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/databinding/AbstractDataBinding.java (original)
+++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/databinding/AbstractDataBinding.java Mon Sep 30 17:46:44 2013
@@ -62,6 +62,7 @@ public abstract class AbstractDataBindin
     private Bus bus;
     private Collection<DOMSource> schemas;
     private Map<String, String> namespaceMap;
+    private Map<String, String> contextualNamespaceMap;
     private boolean hackAroundEmptyNamespaceIssue;
 
     protected Bus getBus() {
@@ -267,6 +268,14 @@ public abstract class AbstractDataBindin
         this.namespaceMap = namespaceMap;
     }
 
+    public Map<String, String> getContextualNamespaceMap() {
+        return contextualNamespaceMap;
+    }
+
+    public void setContextualNamespaceMap(Map<String, String> contextualNamespaceMap) {
+        this.contextualNamespaceMap = contextualNamespaceMap;
+    }
+
     /**
      * Provide explicit mappings to ReflectionServiceFactory. {@inheritDoc}
      */

Modified: cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java (original)
+++ cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java Mon Sep 30 17:46:44 2013
@@ -22,8 +22,10 @@ package org.apache.cxf.jaxb.io;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
+import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -37,6 +39,7 @@ import javax.xml.bind.attachment.Attachm
 import org.apache.cxf.common.i18n.Message;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ReflectionUtil;
 import org.apache.cxf.databinding.DataWriter;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.jaxb.JAXBDataBase;
@@ -108,8 +111,13 @@ public class DataWriterImpl<T> extends J
             }
             
             final Map<String, String> nspref = databinding.getDeclaredNamespaceMappings();
-            if (nspref != null) {
-                JAXBUtils.setNamespaceMapper(nspref, marshaller);
+            final Map<String, String> nsctxt = databinding.getContextualNamespaceMap();
+            // set the prefix mapper if either of the prefix map is configured
+            if (nspref != null || nsctxt != null) {
+                Object mapper = JAXBUtils.setNamespaceMapper(nspref != null ? nspref : nsctxt, marshaller);
+                if (nsctxt != null) {
+                    setContextualNamespaceDecls(mapper, nsctxt);
+                }
             }
             if (databinding.getMarshallerProperties() != null) {
                 for (Map.Entry<String, Object> propEntry 
@@ -145,6 +153,25 @@ public class DataWriterImpl<T> extends J
         return marshaller;
     }
     
+    //REVISIT should this go into JAXBUtils?
+    private static void setContextualNamespaceDecls(Object mapper, Map<String, String> nsctxt) {
+        try {
+            Method m = ReflectionUtil.getDeclaredMethod(mapper.getClass(), 
+                                                        "setContextualNamespaceDecls", new Class<?>[]{String[].class});
+            String[] args = new String[nsctxt.size() * 2];
+            int ai = 0;
+            for (Entry<String, String> nsp : nsctxt.entrySet()) {
+                args[ai++] = nsp.getValue();
+                args[ai++] = nsp.getKey();
+            }
+            m.invoke(mapper, new Object[]{args});
+        } catch (Exception e) {
+            // ignore
+            LOG.log(Level.WARNING, "Failed to set the contextual namespace map", e);
+        }
+        
+    }
+
     public void write(Object obj, MessagePartInfo part, T output) {
         boolean honorJaxbAnnotation = honorJAXBAnnotations(part);
         if (part != null && !part.isElement() && part.getTypeClass() != null) {

Modified: cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java (original)
+++ cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java Mon Sep 30 17:46:44 2013
@@ -20,7 +20,16 @@
 package org.apache.cxf.jaxb;
 
 
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
 import org.apache.cxf.common.jaxb.JAXBUtils;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.hello_world_soap_http.types.GreetMe;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -149,4 +158,31 @@ public class JAXBUtilsTest extends Asser
         pkg = JAXBUtils.namespaceURIToPackage(urn);
         assertEquals("org.apache.cxf.test_v4_6_4", pkg);       
     }
+    
+    @Test
+    public void testSetNamespaceMapper() throws Exception {
+        JAXBContext ctx = JAXBContext.newInstance(GreetMe.class);
+        Marshaller marshaller = ctx.createMarshaller();
+        Map<String, String> nspref = new HashMap<String, String>();
+        nspref.put("http://cxf.apache.org/hello_world_soap_http/types", "x");
+        JAXBUtils.setNamespaceMapper(nspref, marshaller);
+        String mapperkey = null;
+        if (marshaller.getClass().getName().contains(".internal.")) {
+            mapperkey = "com.sun.xml.internal.bind.namespacePrefixMapper";
+        } else if (marshaller.getClass().getName().contains("com.sun")) {
+            mapperkey = "com.sun.xml.bind.namespacePrefixMapper";
+        } else if (marshaller.getClass().getName().contains("eclipse")) {
+            mapperkey = "eclipselink.namespace-prefix-mapper";
+        }
+        if (mapperkey != null) {
+            Object mapper = marshaller.getProperty(mapperkey);
+            assertNotNull(mapper);
+            
+            // also verify this mapper has setContextualNamespaceDecls
+            Method m = ReflectionUtil.getDeclaredMethod(mapper.getClass(), 
+                                                        "setContextualNamespaceDecls", new Class<?>[]{String[].class});
+            assertNotNull(m);
+        }
+        
+    }
 }

Modified: cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/io/XMLStreamDataWriterTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/io/XMLStreamDataWriterTest.java?rev=1527683&r1=1527682&r2=1527683&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/io/XMLStreamDataWriterTest.java (original)
+++ cxf/branches/2.7.x-fixes/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/io/XMLStreamDataWriterTest.java Mon Sep 30 17:46:44 2013
@@ -21,6 +21,9 @@ package org.apache.cxf.jaxb.io;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.namespace.QName;
@@ -38,6 +41,7 @@ import org.apache.hello_world_doc_lit_ba
 import org.apache.hello_world_rpclit.types.MyComplexStruct;
 import org.apache.hello_world_soap_http.types.GreetMe;
 import org.apache.hello_world_soap_http.types.GreetMeResponse;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -224,6 +228,66 @@ public class XMLStreamDataWriterTest ext
         assertEquals("TESTOUTPUTMESSAGE", reader.getText());
     }
 
+    @Test
+    public void testWriteWithNamespacePrefixMapping() throws Exception {
+        JAXBDataBinding db = getTestWriterFactory(GreetMe.class);
+        Map<String, String> nspref = new HashMap<String, String>();
+        nspref.put("http://apache.org/hello_world_soap_http/types", "x");
+        db.setNamespaceMap(nspref);
+        
+        // use the output stream instead of XMLStreamWriter to test
+        DataWriter<OutputStream> dw = db.createWriter(OutputStream.class);
+        assertNotNull(dw);
+
+        GreetMe val = new GreetMe();
+        val.setRequestType("Hello");
+        dw.write(val, baos);
+        
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        XMLStreamReader xr = inFactory.createXMLStreamReader(bais);
+        DepthXMLStreamReader reader = new DepthXMLStreamReader(xr);
+        StaxUtils.toNextElement(reader);
+        QName qname = reader.getName(); 
+        assertEquals(new QName("http://apache.org/hello_world_soap_http/types", "greetMe"), qname);
+        assertEquals("x", qname.getPrefix());
+        
+        assertEquals(1, reader.getNamespaceCount());
+        assertEquals("http://apache.org/hello_world_soap_http/types", reader.getNamespaceURI(0));
+        assertEquals("x", reader.getNamespacePrefix(0));
+        
+        StaxUtils.nextEvent(reader);
+        StaxUtils.toNextElement(reader);
+        qname = reader.getName();
+        assertEquals(new QName("http://apache.org/hello_world_soap_http/types", "requestType"), qname);
+        assertEquals("x", qname.getPrefix());
+        
+        StaxUtils.nextEvent(reader);
+        StaxUtils.toNextText(reader);
+        assertEquals("Hello", reader.getText());
+    }
+
+    @Test
+    public void testWriteWithContextualNamespaceDecls() throws Exception {
+        JAXBDataBinding db = getTestWriterFactory(GreetMe.class);
+        Map<String, String> nspref = new HashMap<String, String>();
+        nspref.put("http://apache.org/hello_world_soap_http/types", "x");
+        db.setNamespaceMap(nspref);
+        db.setContextualNamespaceMap(nspref);
+        
+        // use the output stream instead of XMLStreamWriter to test
+        DataWriter<OutputStream> dw = db.createWriter(OutputStream.class);
+        assertNotNull(dw);
+
+        GreetMe val = new GreetMe();
+        val.setRequestType("Hello");
+        dw.write(val, baos);
+        
+        String xstr = new String(baos.toByteArray());
+        
+        // there should be no namespace decls
+        assertEquals("<x:greetMe><x:requestType>Hello</x:requestType></x:greetMe>", xstr);
+    }
+
     private JAXBDataBinding getTestWriterFactory(Class<?>... clz) throws Exception {
         JAXBContext ctx = JAXBContext.newInstance(clz);
         return new JAXBDataBinding(ctx);