You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/07/21 17:51:44 UTC

svn commit: r796352 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ rt/frontend/jaxrs/src/main/java/...

Author: sergeyb
Date: Tue Jul 21 15:51:43 2009
New Revision: 796352

URL: http://svn.apache.org/viewvc?rev=796352&view=rev
Log:
JAXRS : wrapping JAXB objects into JAXBElement, dropping root JSON elements, disabling exception propogation if needed

Added:
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java   (with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.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
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Book.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/CollectionsResource.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java Tue Jul 21 15:51:43 2009
@@ -126,7 +126,8 @@
                 if (criRoot != null) {
                     criRoot.clearThreadLocalProxies();
                 }
-                exchange.put(Message.PROPOGATE_EXCEPTION, Boolean.TRUE);
+                exchange.put(Message.PROPOGATE_EXCEPTION, 
+                             JAXRSUtils.propogateException(exchange.getInMessage()));
                 throw ex;
             }
             return new MessageContentsList(excResponse);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java Tue Jul 21 15:51:43 2009
@@ -54,7 +54,7 @@
 
     private static final Logger LOG = LogUtils.getL7dLogger(JAXRSInInterceptor.class);
     private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAXRSInInterceptor.class);
-
+    
     public JAXRSInInterceptor() {
         super(Phase.UNMARSHAL);
     }
@@ -67,7 +67,8 @@
             Response excResponse = JAXRSUtils.convertFaultToResponse(ex, message);
             if (excResponse == null) {
                 ProviderFactory.getInstance(message).clearThreadLocalProxies();
-                message.getExchange().put(Message.PROPOGATE_EXCEPTION, Boolean.TRUE);
+                message.getExchange().put(Message.PROPOGATE_EXCEPTION, 
+                                          JAXRSUtils.propogateException(message));
                 throw ex;
             }
             message.getExchange().put(Response.class, excResponse);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Tue Jul 21 15:51:43 2009
@@ -72,6 +72,7 @@
     private Map<String, Object> mProperties = new HashMap<String, Object>();
     private boolean enableStreaming;
     private ValidationEventHandler eventHandler;
+    private List<String> jaxbElementClassNames;
     
     @Override
     public boolean isReadable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
@@ -91,6 +92,10 @@
         super.setContext(mc);
     }
     
+    public void setJaxbElementClassNames(List<String> names) {
+        jaxbElementClassNames = names;
+    }
+    
     public void setValidationHandler(ValidationEventHandler handler) {
         eventHandler = handler;
     }
@@ -224,7 +229,16 @@
                                      Type genericType, String encoding, OutputStream os, MediaType m) 
         throws Exception {
         
-        QName qname = getCollectionWrapperQName(actualClass, genericType, actualObject, true);
+        Object[] arr = originalCls.isArray() ? (Object[])actualObject : ((Collection)actualObject).toArray();
+        
+        QName qname = null;
+        if (arr.length > 0 && arr[0] instanceof JAXBElement) {
+            JAXBElement el = (JAXBElement)arr[0];
+            qname = el.getName();
+            actualClass = el.getDeclaredType();
+        } else {
+            qname = getCollectionWrapperQName(actualClass, genericType, actualObject, true);
+        }
         if (qname == null) {
             String message = new org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT", 
                                                                     BUNDLE).toString();
@@ -243,10 +257,9 @@
             endTag = "</" + qname.getLocalPart() + ">";
         }
         os.write(startTag.getBytes());
-        Object[] arr = originalCls.isArray() ? (Object[])actualObject : ((Collection)actualObject).toArray();
         for (Object o : arr) {
-            marshalCollectionMember(o, actualClass, genericType, encoding, os, m, 
-                                    qname.getNamespaceURI());    
+            marshalCollectionMember(o instanceof JAXBElement ? ((JAXBElement)o).getValue() : o, 
+                                    actualClass, genericType, encoding, os, m, qname.getNamespaceURI());    
         }
         os.write(endTag.getBytes());
     }
@@ -269,6 +282,17 @@
     
     protected void marshal(Object obj, Class<?> cls, Type genericType, 
                            String enc, OutputStream os, MediaType mt) throws Exception {
+        
+        if (jaxbElementClassNames != null && jaxbElementClassNames.contains(cls.getName())) {
+            QName name = getJaxbQName(cls, genericType, obj, false);
+            if (name != null) {
+                @SuppressWarnings("unchecked")
+                JAXBElement el = new JAXBElement(name, cls, null, obj);
+                obj = el;
+                cls = JAXBElement.class;
+            }
+        }
+        
         Marshaller ms = createMarshaller(obj, cls, genericType, enc);
         marshal(obj, cls, genericType, enc, os, mt, ms);
     }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Tue Jul 21 15:51:43 2009
@@ -72,12 +72,22 @@
     private boolean unwrapped;
     private String wrapperName;
     private Map<String, String> wrapperMap;
+    private boolean dropRootElement;
+    private boolean dropCollectionWrapperElement;
     
     @Context
     public void setMessageContext(MessageContext mc) {
         super.setContext(mc);
     }
     
+    public void setDropRootElement(boolean drop) {
+        this.dropRootElement = drop;
+    }
+    
+    public void setDropCollectionWrapperElement(boolean drop) {
+        this.dropCollectionWrapperElement = drop;
+    }
+    
     public void setSupportUnwrapped(boolean unwrap) {
         this.unwrapped = unwrap;
     }
@@ -131,7 +141,7 @@
             Unmarshaller unmarshaller = createUnmarshaller(theType, genericType);
             
             InputStream realStream = getInputStream(type, genericType, is);
-            XMLStreamReader xsw = getStreamReader(type, realStream);
+            XMLStreamReader xsw = createReader(type, realStream);
             
             Object response = null;
             if (JAXBElement.class.isAssignableFrom(type)) {
@@ -155,7 +165,7 @@
         return null;
     }
 
-    protected XMLStreamReader getStreamReader(Class<?> type, InputStream is) 
+    protected XMLStreamReader createReader(Class<?> type, InputStream is) 
         throws Exception {
         MappedXMLInputFactory factory = new MappedXMLInputFactory(namespaceMap);
         return factory.createXMLStreamReader(is);
@@ -246,21 +256,26 @@
                                      Type genericType, String encoding, OutputStream os, MediaType m) 
         throws Exception {
         
-        QName qname = getCollectionWrapperQName(actualClass, genericType, actualObject, false);
-        if (qname == null) {
-            String message = new org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT", 
-                                                                    BUNDLE).toString();
-            throw new WebApplicationException(Response.serverError()
-                                              .entity(message).build());
-        }
         String startTag = null;
         String endTag = null;
-        if (qname.getNamespaceURI().length() > 0) {
-            startTag = "{\"ns1." + qname.getLocalPart() + "\":[";
+        if (!dropCollectionWrapperElement) {
+            QName qname = getCollectionWrapperQName(actualClass, genericType, actualObject, false);
+            if (qname == null) {
+                String message = new org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT", 
+                                                                        BUNDLE).toString();
+                throw new WebApplicationException(Response.serverError()
+                                                  .entity(message).build());
+            }
+            if (qname.getNamespaceURI().length() > 0) {
+                startTag = "{\"ns1." + qname.getLocalPart() + "\":[";
+            } else {
+                startTag = "{\"" + qname.getLocalPart() + "\":[";
+            }
+            endTag = "]}";
         } else {
-            startTag = "{\"" + qname.getLocalPart() + "\":[";
+            startTag = "{";
+            endTag = "}";
         }
-        endTag = "]}";
         os.write(startTag.getBytes());
         Object[] arr = originalCls.isArray() ? (Object[])actualObject : ((Collection)actualObject).toArray();
         for (int i = 0; i < arr.length; i++) {
@@ -275,12 +290,21 @@
     
     protected void marshal(Marshaller ms, Object actualObject, Class<?> actualClass, 
                   Type genericType, String enc, OutputStream os, boolean isCollection) throws Exception {
+        
+        XMLStreamWriter writer = createWriter(actualObject, actualClass, genericType, enc, 
+                                              os, isCollection);
+        ms.marshal(actualObject, writer);
+        writer.close();
+    }
+    
+    protected XMLStreamWriter createWriter(Object actualObject, Class<?> actualClass, 
+        Type genericType, String enc, OutputStream os, boolean isCollection) throws Exception {
         QName qname = getQName(actualClass, genericType, actualObject, true);
         Configuration c = new Configuration(namespaceMap);
         MappedNamespaceConvention convention = new MappedNamespaceConvention(c);
         AbstractXMLStreamWriter xsw = new MappedXMLStreamWriter(
-                                           convention, 
-                                           new OutputStreamWriter(os, enc));
+                                            convention, 
+                                            new OutputStreamWriter(os, enc));
         if (serializeAsArray) {
             if (arrayKeys != null) {
                 for (String key : arrayKeys) {
@@ -292,13 +316,9 @@
             }
         }
 
-        XMLStreamWriter writer = isCollection ? new JSONCollectionWriter(xsw, qname) : xsw; 
-        ms.marshal(actualObject, writer);
-        xsw.close();
+        return isCollection || dropRootElement ? new JSONCollectionWriter(xsw, qname) : xsw; 
     }
     
-    
-    
     protected void marshal(Object actualObject, Class<?> actualClass, 
                            Type genericType, String enc, OutputStream os) throws Exception {
         Marshaller ms = createMarshaller(actualObject, actualClass, genericType, enc);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Tue Jul 21 15:51:43 2009
@@ -206,8 +206,7 @@
             throw new RuntimeException("No type can be found at position " + pos);
         }
         Type t = types[pos];
-        // we don't recurse at this stage, otherwise GenericEntity won't be handled properly
-        return t instanceof Class ? (Class<?>)t : null;
+        return t instanceof Class ? (Class<?>)t : getActualType(t, pos);
     }
     
     public static Type[] getActualTypes(Type genericType) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Tue Jul 21 15:51:43 2009
@@ -97,6 +97,7 @@
     public static final MediaType ALL_TYPES = new MediaType();
     private static final Logger LOG = LogUtils.getL7dLogger(JAXRSUtils.class);
     private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAXRSUtils.class);
+    private static final String PROPOGATE_EXCEPTION = "org.apache.cxf.propogate.exception";
 
     private JAXRSUtils() {        
     }
@@ -1025,4 +1026,19 @@
         return sb.toString();
     }
         
+    public static boolean propogateException(Message m) {
+        
+        Object value = m.getContextualProperty(PROPOGATE_EXCEPTION);
+        
+        if (value == null) {
+            return true;
+        }
+
+        if (Boolean.TRUE.equals(value) || "true".equalsIgnoreCase(value.toString())) {
+            return true;
+        }
+        
+        return false;
+    }
+    
 }

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=796352&r1=796351&r2=796352&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 Tue Jul 21 15:51:43 2009
@@ -29,6 +29,7 @@
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -38,12 +39,14 @@
 
 import javax.ws.rs.core.MediaType;
 import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.PropertyException;
 import javax.xml.bind.ValidationEventHandler;
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import javax.xml.bind.attachment.AttachmentMarshaller;
+import javax.xml.namespace.QName;
 import javax.xml.stream.XMLEventWriter;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.Result;
@@ -56,6 +59,7 @@
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.resources.Book;
 import org.apache.cxf.jaxrs.resources.CollectionsResource;
+import org.apache.cxf.jaxrs.resources.SuperBook;
 import org.apache.cxf.jaxrs.resources.TagVO2;
 
 import org.junit.Assert;
@@ -78,10 +82,15 @@
         testIsWriteableCollection("getBookSet");
     }
     
+    @Test
+    public void testIsWriteableJAXBElements() throws Exception {
+        testIsWriteableCollection("getBookElements");
+    }
+    
     private void testIsWriteableCollection(String mName) throws Exception {
         JAXBElementProvider provider = new JAXBElementProvider();
         provider.setCollectionWrapperName("foo");
-        Method m = CollectionsResource.class.getMethod("getBooks", new Class[0]);
+        Method m = CollectionsResource.class.getMethod(mName, new Class[0]);
         assertTrue(provider.isWriteable(m.getReturnType(), m.getGenericReturnType(),
                              new Annotation[0], MediaType.TEXT_XML_TYPE));
     }
@@ -132,6 +141,65 @@
     }
     
     @Test
+    public void testWriteJAXBElementCollection() throws Exception {
+        doTestWriteJAXBCollection("getBookElements");
+    }
+    
+    @Test
+    public void testWriteJAXBElementCollection2() throws Exception {
+        doTestWriteJAXBCollection("getBookElements2");
+    }
+    
+    @Test
+    public void testWriteDerivedType() throws Exception {
+        JAXBElementProvider provider = new JAXBElementProvider();
+        provider.setJaxbElementClassNames(Collections.singletonList(Book.class.getName()));
+        Book b = new SuperBook("CXF in Action", 123L, 124L);
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        provider.writeTo(b, Book.class, Book.class,
+                       new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String, Object>(), bos);
+        readSuperBook(bos.toString());
+    }
+    
+    @Test
+    public void testWriteDerivedType2() throws Exception {
+        JAXBElementProvider provider = new JAXBElementProvider();
+        Book b = new SuperBook("CXF in Action", 123L, 124L);
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        provider.writeTo(b, Book.class, Book.class,
+                       new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String, Object>(), bos);
+        
+        readSuperBook(bos.toString());
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void readSuperBook(String data) throws Exception {
+        JAXBElementProvider provider = new JAXBElementProvider();
+        ByteArrayInputStream is = new ByteArrayInputStream(data.getBytes());
+        SuperBook book = (SuperBook)provider.readFrom(
+                       (Class)SuperBook.class, SuperBook.class,
+                       new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String, String>(), is);
+        assertEquals(124L, book.getSuperId());
+    }
+    
+    private void doTestWriteJAXBCollection(String mName) throws Exception {
+        JAXBElementProvider provider = new JAXBElementProvider();
+        List<JAXBElement<Book>> books = new ArrayList<JAXBElement<Book>>();
+        books.add(new JAXBElement<Book>(new QName("Books"), Book.class, null, 
+            new Book("CXF in Action", 123L)));
+        books.add(new JAXBElement<Book>(new QName("Books"), Book.class, null, 
+            new Book("CXF Rocks", 124L)));
+        
+        Method m = CollectionsResource.class.getMethod(mName, new Class[0]);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        provider.writeTo(books, m.getReturnType(), m.getGenericReturnType(),
+                       new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String, Object>(), bos);
+        doReadUnqualifiedCollection(bos.toString(), "setBooks", List.class);
+    }
+    
+    @Test
     public void testWriteQualifiedCollection() throws Exception {
         JAXBElementProvider provider = new JAXBElementProvider();
         provider.setCollectionWrapperName("{http://tags}tags");
@@ -168,8 +236,13 @@
             assertEquals(2, ((Book[])o).length);
             b1 = ((Book[])o)[0];
             b2 = ((Book[])o)[1];
+        } else if (type == Set.class) {
+            Set<Book> set = (Set)o;
+            List<Book> books = new ArrayList<Book>(new TreeSet<Book>(set));
+            b1 = books.get(0);
+            b2 = books.get(1);
         } else {
-            List<Book> books = type == Set.class ? new ArrayList<Book>(new TreeSet((Set)o)) : (List<Book>)o;
+            List<Book> books = (List<Book>)o;
             b1 = books.get(0);
             b2 = books.get(1);
         }

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=796352&r1=796351&r2=796352&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 Tue Jul 21 15:51:43 2009
@@ -162,13 +162,45 @@
         
         String s = os.toString();
         assertEquals("{\"ns1.thetag\":{\"group\":\"b\",\"name\":\"a\"}}", s);
+    }
+    
+    @Test
+    public void testDropRootElement() throws Exception {
+        JSONProvider p = new JSONProvider();
+        p.setDropRootElement(true);
+        Map<String, String> namespaceMap = new HashMap<String, String>();
+        namespaceMap.put("http://tags", "ns1");
+        p.setNamespaceMap(namespaceMap);
+        TagVO2 tag = createTag2("a", "b");
+        
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        
+        p.writeTo(tag, (Class)TagVO2.class, TagVO2.class, TagVO2.class.getAnnotations(), 
+                  MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), os);
+        
+        String s = os.toString();
+        assertEquals("{\"group\":\"b\",\"name\":\"a\"}", s);
         
     }
     
     @Test
     public void testWriteQualifiedCollection() throws Exception {
+        String data = "{\"ns1.tag\":[{\"group\":\"b\",\"name\":\"a\"}"
+            + ",{\"group\":\"d\",\"name\":\"c\"}]}";
+        doWriteQualifiedCollection(false, data);
+    }
+    
+    @Test
+    public void testWriteQualifiedCollection2() throws Exception {
+        String data = "{{\"group\":\"b\",\"name\":\"a\"}"
+            + ",{\"group\":\"d\",\"name\":\"c\"}}";
+        doWriteQualifiedCollection(true, data);
+    }
+    
+    public void doWriteQualifiedCollection(boolean drop, String data) throws Exception {
         JSONProvider p = new JSONProvider();
         p.setCollectionWrapperName("{http://tags}tag");
+        p.setDropCollectionWrapperElement(drop);
         Map<String, String> namespaceMap = new HashMap<String, String>();
         namespaceMap.put("http://tags", "ns1");
         p.setNamespaceMap(namespaceMap);
@@ -181,8 +213,6 @@
                   MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), os);
         
         String s = os.toString();
-        String data = "{\"ns1.tag\":[{\"group\":\"b\",\"name\":\"a\"}"
-            + ",{\"group\":\"d\",\"name\":\"c\"}]}";
         assertEquals(s, data);
     }
     

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Book.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Book.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Book.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/Book.java Tue Jul 21 15:51:43 2009
@@ -26,9 +26,11 @@
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
 
 
 @XmlRootElement(name = "Book")
+@XmlSeeAlso({SuperBook.class })
 public class Book implements Comparable<Book> {
     private String name;
     private long id;

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/CollectionsResource.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/CollectionsResource.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/CollectionsResource.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/CollectionsResource.java Tue Jul 21 15:51:43 2009
@@ -24,6 +24,7 @@
 
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
+import javax.xml.bind.JAXBElement;
 
 public class CollectionsResource {
     @GET
@@ -37,6 +38,16 @@
     }
     
     @GET
+    public List<JAXBElement<Book>> getBookElements() {
+        return null;
+    }
+    
+    @GET
+    public List<JAXBElement> getBookElements2() {
+        return null;
+    }
+    
+    @GET
     public Set<Book> getBookSet() {
         return null;
     }

Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java?rev=796352&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java Tue Jul 21 15:51:43 2009
@@ -0,0 +1,43 @@
+/**
+ * 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.jaxrs.resources;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement(name = "SuperBook")
+public class SuperBook extends Book {
+    private long superId;
+    public SuperBook() {
+    }
+    
+    public SuperBook(String name, long id, long superId) {
+        super(name, id);
+        this.superId = superId;
+    }
+    
+    public void setSuperId(long i) {
+        superId = i;
+    }
+    
+    public long getSuperId() {
+        return superId;
+    }
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/SuperBook.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Tue Jul 21 15:51:43 2009
@@ -60,6 +60,7 @@
 import javax.xml.transform.dom.DOMSource;
 
 import org.apache.cxf.helpers.XMLUtils;
+import org.apache.cxf.phase.PhaseInterceptorChain;
 
 @Path("/bookstore")
 public class BookStore {
@@ -95,6 +96,12 @@
         throw new BookNotFoundFault("Book Exception");
     }
     
+    @GET
+    @Path("propogateexception2")
+    public Book propogateException2() throws BookNotFoundFault {
+        PhaseInterceptorChain.getCurrentMessage().put("org.apache.cxf.propogate.exception", Boolean.FALSE);
+        throw new BookNotFoundFault("Book Exception");
+    }
     
     @GET
     @Path("books/check/{id}")

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=796352&r1=796351&r2=796352&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Tue Jul 21 15:51:43 2009
@@ -66,6 +66,16 @@
     }
     
     @Test
+    public void testPropogateException2() throws Exception {
+        String data = "<ns1:XMLFault xmlns:ns1=\"http://cxf.apache.org/bindings/xformat\">"
+            + "<ns1:faultstring xmlns:ns1=\"http://cxf.apache.org/bindings/xformat\">"
+            + "org.apache.cxf.systest.jaxrs.BookNotFoundFault: Book Exception</ns1:faultstring>"
+            + "</ns1:XMLFault>";
+        getAndCompare("http://localhost:9080/bookstore/propogateexception2",
+                      data, "application/xml", 500);
+    }
+    
+    @Test
     public void testWebApplicationException() throws Exception {
         getAndCompare("http://localhost:9080/bookstore/webappexception",
                       "This is a WebApplicationException",