cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1086535 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/
Date Tue, 29 Mar 2011 10:17:50 GMT
Author: sergeyb
Date: Tue Mar 29 10:17:49 2011
New Revision: 1086535

URL: http://svn.apache.org/viewvc?rev=1086535&view=rev
Log:
[CXF-3430] XmlJavaTypeAdapter with explicit collections

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.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/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1086535&r1=1086534&r2=1086535&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
Tue Mar 29 10:17:49 2011
@@ -491,10 +491,16 @@ public abstract class AbstractJAXBProvid
         return theType;
     }
     
+    protected static Object checkAdapter(Object obj, Class<?> cls, Annotation[] anns,
boolean marshal) {
+        return useAdapter(obj, getAdapter(obj.getClass(), anns), marshal); 
+    }
+    
     @SuppressWarnings("unchecked")
-    protected Object checkAdapter(Object obj, Class<?> cls, Annotation[] anns, boolean
marshal) {
-        XmlJavaTypeAdapter typeAdapter = getAdapter(obj.getClass(), anns); 
+    protected static Object useAdapter(Object obj, XmlJavaTypeAdapter typeAdapter, boolean
marshal) {
         if (typeAdapter != null) {
+            if (InjectionUtils.isSupportedCollectionOrArray(typeAdapter.value().getClass()))
{
+                return obj;
+            }
             try {
                 XmlAdapter xmlAdapter = typeAdapter.value().newInstance();
                 if (marshal) {
@@ -510,7 +516,7 @@ public abstract class AbstractJAXBProvid
         return obj;
     }
     
-    protected XmlJavaTypeAdapter getAdapter(Class<?> objectClass, Annotation[] anns)
{
+    protected static XmlJavaTypeAdapter getAdapter(Class<?> objectClass, Annotation[]
anns) {
         XmlJavaTypeAdapter typeAdapter = AnnotationUtils.getAnnotation(anns, XmlJavaTypeAdapter.class);
         if (typeAdapter == null) {
             typeAdapter = objectClass.getAnnotation(XmlJavaTypeAdapter.class);
@@ -614,14 +620,17 @@ public abstract class AbstractJAXBProvid
         }
         
         @SuppressWarnings("unchecked")
-        public <T> Object getCollectionOrArray(Class<T> type, Class<?>
origType) {
+        public <T> Object getCollectionOrArray(Class<T> type, Class<?>
origType,
+                                               XmlJavaTypeAdapter adapter) {
             List<?> theList = getList();
+            boolean adapterChecked = false;
             if (theList.size() > 0) {
                 Object first = theList.get(0);
                 if (first instanceof JAXBElement && !JAXBElement.class.isAssignableFrom(type))
{
+                    adapterChecked = true;
                     List<Object> newList = new ArrayList<Object>(theList.size());
                     for (Object o : theList) {
-                        newList.add(((JAXBElement)o).getValue());
+                        newList.add(useAdapter(((JAXBElement)o).getValue(), adapter, false));
                     }
                     theList = newList;
                 }
@@ -629,13 +638,22 @@ public abstract class AbstractJAXBProvid
             if (origType.isArray()) {
                 T[] values = (T[])Array.newInstance(type, theList.size());
                 for (int i = 0; i < theList.size(); i++) {
-                    values[i] = (T)theList.get(i);
+                    values[i] = (T)useAdapter(theList.get(i), adapter, false);
                 }
                 return values;
-            } else if (origType == Set.class) {
-                return new HashSet(theList);
             } else {
-                return theList;
+                if (!adapterChecked && adapter != null) {
+                    List<Object> newList = new ArrayList<Object>(theList.size());
+                    for (Object o : theList) {
+                        newList.add(useAdapter(o, adapter, false));
+                    }
+                    theList = newList;
+                }
+                if (origType == Set.class) {
+                    return new HashSet(theList);
+                } else {
+                    return theList;
+                }
             }
         }
         

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=1086535&r1=1086534&r2=1086535&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 Mar 29 10:17:49 2011
@@ -45,6 +45,7 @@ import javax.xml.bind.Marshaller;
 import javax.xml.bind.PropertyException;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.ValidationEventHandler;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLOutputFactory;
@@ -164,10 +165,11 @@ public class JAXBElementProvider extends
                 response = ((JAXBElement)response).getValue();    
             }
             if (isCollection) {
-                response = ((CollectionWrapper)response).getCollectionOrArray(theType, type);

+                response = ((CollectionWrapper)response).getCollectionOrArray(theType, type,

+                                                         getAdapter(theType, anns)); 
+            } else {
+                response = checkAdapter(response, type, anns, false);
             }
-            
-            response = checkAdapter(response, type, anns, false);
             return response;
             
         } catch (JAXBException e) {
@@ -234,14 +236,13 @@ public class JAXBElementProvider extends
         MediaType m, MultivaluedMap<String, Object> headers, OutputStream os) 
         throws IOException {
         try {
-            Object actualObject = checkAdapter(obj, cls, anns, true);
-            Class<?> actualClass = obj != actualObject || cls.isInterface() ? actualObject.getClass()
: cls;
             String encoding = HttpUtils.getSetEncoding(m, headers, null);
-            if (InjectionUtils.isSupportedCollectionOrArray(actualClass)) {
-                actualClass = InjectionUtils.getActualType(genericType);
-                actualClass = getActualType(actualClass, genericType, anns);
-                marshalCollection(cls, actualObject, actualClass, genericType, encoding,
os, m);
+            if (InjectionUtils.isSupportedCollectionOrArray(cls)) {
+                marshalCollection(cls, obj, genericType, encoding, os, m, anns);
             } else {
+                Object actualObject = checkAdapter(obj, cls, anns, true);
+                Class<?> actualClass = obj != actualObject || cls.isInterface() 
+                    ? actualObject.getClass() : cls;
                 marshal(actualObject, actualClass, genericType, encoding, os, m);
             }
         } catch (JAXBException e) {
@@ -254,12 +255,16 @@ public class JAXBElementProvider extends
         }
     }
 
-    protected void marshalCollection(Class<?> originalCls, Object actualObject, Class<?>
actualClass,
-                                     Type genericType, String encoding, OutputStream os,
MediaType m) 
+    protected void marshalCollection(Class<?> originalCls, Object collection, 
+                                     Type genericType, String encoding, OutputStream os,

+                                     MediaType m, Annotation[] anns) 
         throws Exception {
         
-        Collection c = originalCls.isArray() ? Arrays.asList((Object[]) actualObject) 
-                                             : (Collection) actualObject;
+        Class<?> actualClass = InjectionUtils.getActualType(genericType);
+        actualClass = getActualType(actualClass, genericType, anns);
+        
+        Collection c = originalCls.isArray() ? Arrays.asList((Object[]) collection) 
+                                             : (Collection) collection;
 
         Iterator it = c.iterator();
         
@@ -271,7 +276,7 @@ public class JAXBElementProvider extends
             qname = el.getName();
             actualClass = el.getDeclaredType();
         } else {
-            qname = getCollectionWrapperQName(actualClass, genericType, actualObject, true);
+            qname = getCollectionWrapperQName(actualClass, genericType, firstObj, true);
         }
         if (qname == null) {
             String message = new org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT",

@@ -292,24 +297,37 @@ public class JAXBElementProvider extends
         }
         os.write(startTag.getBytes());
         if (firstObj != null) {
-            marshalCollectionMember(firstObj instanceof JAXBElement 
-                ? ((JAXBElement) firstObj).getValue() : firstObj, actualClass, genericType,
encoding, os, m, 
-                qname.getNamespaceURI());
+            XmlJavaTypeAdapter adapter = getAdapter(firstObj.getClass(), anns);
+            marshalCollectionMember(useAdapter(firstObj, adapter, true), 
+                                    actualClass, genericType, encoding, os, m, 
+                                    qname.getNamespaceURI());
             while (it.hasNext()) {
-                Object o = it.next();
-                marshalCollectionMember(o instanceof JAXBElement ? ((JAXBElement)o).getValue()
: o, 
-                                    actualClass, genericType, encoding, os, m, qname.getNamespaceURI());
+                marshalCollectionMember(useAdapter(it.next(), adapter, true), actualClass,

+                                        genericType, encoding, os, m, 
+                                        qname.getNamespaceURI());
             }
         }
         os.write(endTag.getBytes());
     }
     
-    protected void marshalCollectionMember(Object obj, Class<?> cls, Type genericType,

-                           String enc, OutputStream os, MediaType mt, String ns) throws Exception
{
-        obj = convertToJaxbElementIfNeeded(obj, cls, genericType);
+    protected void marshalCollectionMember(Object obj, 
+                                           Class<?> cls, 
+                                           Type genericType, 
+                                           String enc, 
+                                           OutputStream os, 
+                                           MediaType mt, 
+                                           String ns) throws Exception {
+        
+        if (obj instanceof JAXBElement) {
+            obj = ((JAXBElement)obj).getValue();    
+        } else {
+            obj = convertToJaxbElementIfNeeded(obj, cls, genericType);
+        }
+        
         if (obj instanceof JAXBElement && cls != JAXBElement.class) {
             cls = JAXBElement.class;
         }
+        
         Marshaller ms = createMarshaller(obj, cls, genericType, enc);
         ms.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
         if (ns.length() > 0) {

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=1086535&r1=1086534&r2=1086535&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 Mar 29 10:17:49 2011
@@ -27,8 +27,10 @@ import java.io.OutputStream;
 import java.io.SequenceInputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -39,12 +41,12 @@ import javax.ws.rs.WebApplicationExcepti
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.Provider;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
@@ -268,18 +270,17 @@ public class JSONProvider extends Abstra
         throws IOException {
         try {
             
-            Object actualObject = checkAdapter(obj, cls, anns, true);
-            Class<?> actualClass = obj != actualObject ? actualObject.getClass() :
cls;
-            if (cls == genericType) {
-                genericType = actualClass;
-            }
             String encoding = HttpUtils.getSetEncoding(m, headers, "UTF-8");
             
-            if (InjectionUtils.isSupportedCollectionOrArray(actualClass)) {
-                actualClass = InjectionUtils.getActualType(genericType);
-                actualClass = getActualType(actualClass, genericType, anns);
-                marshalCollection(cls, actualObject, actualClass, genericType, encoding,
os, m);
+            if (InjectionUtils.isSupportedCollectionOrArray(cls)) {
+                marshalCollection(cls, obj, genericType, encoding, os, m, anns);
             } else {
+                Object actualObject = checkAdapter(obj, cls, anns, true);
+                Class<?> actualClass = obj != actualObject ? actualObject.getClass()
: cls;
+                if (cls == genericType) {
+                    genericType = actualClass;
+                }
+                
                 marshal(actualObject, actualClass, genericType, encoding, os);
             }
             
@@ -292,19 +293,31 @@ public class JSONProvider extends Abstra
         }
     }
 
-    protected void marshalCollection(Class<?> originalCls, Object actualObject, Class<?>
actualClass,
-                                     Type genericType, String encoding, OutputStream os,
MediaType m) 
+    protected void marshalCollection(Class<?> originalCls, Object collection, 
+                                     Type genericType, String encoding, 
+                                     OutputStream os, MediaType m, Annotation[] anns) 
         throws Exception {
         
+        Class<?> actualClass = InjectionUtils.getActualType(genericType);
+        actualClass = getActualType(actualClass, genericType, anns);
+        
+        Collection c = originalCls.isArray() ? Arrays.asList((Object[]) collection) 
+                                             : (Collection) collection;
+
+        Iterator it = c.iterator();
+        
+        Object firstObj = it.hasNext() ? it.next() : null;
+
         String startTag = null;
         String endTag = null;
         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());
+            QName qname = null;
+            if (firstObj instanceof JAXBElement) {
+                JAXBElement el = (JAXBElement)firstObj;
+                qname = el.getName();
+                actualClass = el.getDeclaredType();
+            } else {
+                qname = getCollectionWrapperQName(actualClass, genericType, firstObj, true);
             }
             if (qname.getNamespaceURI().length() > 0) {
                 startTag = "{\"ns1." + qname.getLocalPart() + "\":[";
@@ -319,23 +332,37 @@ public class JSONProvider extends Abstra
             startTag = "{";
             endTag = "}";
         }
+        
         os.write(startTag.getBytes());
-        Object[] arr = originalCls.isArray() ? (Object[])actualObject : ((Collection)actualObject).toArray();
-        for (int i = 0; i < arr.length; i++) {
-            Object obj = convertToJaxbElementIfNeeded(arr[i], actualClass, genericType);
-            Class<?> cls = actualClass;
-            if (obj instanceof JAXBElement && actualClass != JAXBElement.class) {
-                cls = JAXBElement.class;
-            }
-            Marshaller ms = createMarshaller(obj, cls, genericType, encoding);
-            marshal(ms, obj, cls, genericType, encoding, os, true);
-            if (i + 1 < arr.length) {
+        if (firstObj != null) {
+            XmlJavaTypeAdapter adapter = getAdapter(firstObj.getClass(), anns);
+            marshalCollectionMember(useAdapter(firstObj, adapter, true),
+                                    actualClass, genericType, encoding, os);
+            while (it.hasNext()) {
                 os.write(",".getBytes());
+                marshalCollectionMember(useAdapter(it.next(), adapter, true), 
+                                        actualClass, genericType, encoding, os);
             }
         }
         os.write(endTag.getBytes());
     }
     
+    protected void marshalCollectionMember(Object obj, Class<?> cls, Type genericType,
+                                           String enc, OutputStream os) throws Exception
{
+        if (obj instanceof JAXBElement) {
+            obj = ((JAXBElement)obj).getValue();    
+        } else {
+            obj = convertToJaxbElementIfNeeded(obj, cls, genericType);
+        }
+        
+        if (obj instanceof JAXBElement && cls != JAXBElement.class) {
+            cls = JAXBElement.class;
+        }
+        Marshaller ms = createMarshaller(obj, cls, genericType, enc);
+        marshal(ms, obj, cls, genericType, enc, os, true);
+        
+    }
+    
     protected void marshal(Marshaller ms, Object actualObject, Class<?> actualClass,

                   Type genericType, String enc, OutputStream os, boolean isCollection) throws
Exception {
         

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=1086535&r1=1086534&r2=1086535&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Tue
Mar 29 10:17:49 2011
@@ -29,14 +29,11 @@ import java.net.URI;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collections;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -535,21 +532,23 @@ public class BookStore {
     public BookInfo getBookAdapter() throws Exception {
         return new BookInfo(doGetBook("123"));
     }
-    
     @POST
     @Path("/books/adapter-list")
-    @XmlJavaTypeAdapter(BookInfoAdapterList.class)
-    public Set<Book> getBookAdapterList(Set<Book> collection) 
+    @XmlJavaTypeAdapter(BookInfoAdapter.class)
+    @Consumes("application/xml")
+    @Produces({"application/xml", "application/json" })
+    public List<BookInfo> getBookAdapterList(@XmlJavaTypeAdapter(BookInfoAdapter.class)

+                                              List<BookInfo> collection) 
         throws Exception {
         if (collection.size() != 1) {
             throw new WebApplicationException(400);
         }
-        return Collections.singleton(doGetBook(Long.toString(collection.iterator().next().getId())));
+        return collection;
     }
     
     @GET
     @Path("/books/interface/adapter")
-    public BookInfoInterface getBookAdapter2() throws Exception {
+    public BookInfoInterface getBookAdapterInterface() throws Exception {
         return new BookInfo2(doGetBook("123"));
     }
     
@@ -898,19 +897,7 @@ public class BookStore {
             super(b);
         }
     }
-    
-    public static class BookInfoAdapterList extends XmlAdapter<List<Book>, Set<Book>>
{
-
-        public List marshal(Set<Book> set) throws Exception {
-            return new ArrayList<Book>(set);
-        }
-
-        public Set<Book> unmarshal(List<Book> list) throws Exception {
-            return new HashSet<Book>(list);
-        }
         
-    }
-    
     public static class BookInfoAdapter extends XmlAdapter<Book, BookInfo> {
 
         @Override

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1086535&r1=1086534&r2=1086535&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
(original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Tue Mar 29 10:17:49 2011
@@ -64,7 +64,7 @@ public class JAXRSClientServerBookTest e
     @BeforeClass
     public static void startServers() throws Exception {
         assertTrue("server did not launch correctly",
-                   launchServer(BookServer.class, true));
+                   launchServer(BookServer.class));
     }
     
     @Test
@@ -883,7 +883,6 @@ public class JAXRSClientServerBookTest e
         provider.setOutTransformElements(outMap);
         WebClient wc = WebClient.create("http://localhost:" + PORT + "/bookstore/books/adapter-list",
                                         Collections.singletonList(provider));
-        
         Collection<? extends Book> books = wc.type("application/xml").accept("application/xml")
             .postAndGetCollection(new Books(new Book("CXF", 123L)), Book.class);
         assertEquals(1, books.size());
@@ -891,6 +890,22 @@ public class JAXRSClientServerBookTest e
     }
     
     @Test
+    public void testPostGetBookAdapterListJSON() throws Exception {
+        JAXBElementProvider provider = new JAXBElementProvider();
+        Map<String, String> outMap = new HashMap<String, String>();
+        outMap.put("Books", "CollectionWrapper");
+        outMap.put("books", "Book");
+        provider.setOutTransformElements(outMap);
+        WebClient wc = WebClient.create("http://localhost:" + PORT + "/bookstore/books/adapter-list",
+                                        Collections.singletonList(provider));
+        WebClient.getConfig(wc).getHttpConduit().getClient().setReceiveTimeout(10000000);
+        Response r = wc.type("application/xml").accept("application/json")
+            .post(new Books(new Book("CXF", 123L)));
+        assertEquals("{\"Books\":[{\"id\":123,\"name\":\"CXF\"}]}",
+                     IOUtils.readStringFromStream((InputStream)r.getEntity()));
+    }
+    
+    @Test
     public void testGetBookAdapterInterface() throws Exception {
         getAndCompareAsStrings("http://localhost:" + PORT + "/bookstore/books/interface/adapter",
                                "resources/expected_get_book123.txt",



Mime
View raw message