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 2011/03/29 12:20:44 UTC
svn commit: r1086538 - in /cxf/branches/2.3.x-fixes: ./
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/
systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/
Author: sergeyb
Date: Tue Mar 29 10:20:44 2011
New Revision: 1086538
URL: http://svn.apache.org/viewvc?rev=1086538&view=rev
Log:
Merged revisions 1086535 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r1086535 | sergeyb | 2011-03-29 11:17:49 +0100 (Tue, 29 Mar 2011) | 1 line
[CXF-3430] XmlJavaTypeAdapter with explicit collections
........
Modified:
cxf/branches/2.3.x-fixes/ (props changed)
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Propchange: cxf/branches/2.3.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar 29 10:20:44 2011
@@ -1 +1 @@
-/cxf/trunk:1084966,1086102,1086115
+/cxf/trunk:1084966,1086102,1086115,1086535
Propchange: cxf/branches/2.3.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1086538&r1=1086537&r2=1086538&view=diff
==============================================================================
--- cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original)
+++ cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Tue Mar 29 10:20:44 2011
@@ -504,10 +504,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) {
@@ -523,7 +529,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);
@@ -695,14 +701,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;
}
@@ -710,13 +719,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/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=1086538&r1=1086537&r2=1086538&view=diff
==============================================================================
--- cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original)
+++ cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Tue Mar 29 10:20:44 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;
@@ -163,10 +164,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) {
@@ -233,14 +235,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) {
@@ -253,12 +254,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();
@@ -270,7 +275,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",
@@ -291,24 +296,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/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=1086538&r1=1086537&r2=1086538&view=diff
==============================================================================
--- cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original)
+++ cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Tue Mar 29 10:20:44 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/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=1086538&r1=1086537&r2=1086538&view=diff
==============================================================================
--- cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Tue Mar 29 10:20:44 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/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1086538&r1=1086537&r2=1086538&view=diff
==============================================================================
--- cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/branches/2.3.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Tue Mar 29 10:20:44 2011
@@ -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",