Repository: cxf Updated Branches: refs/heads/master 38bb9fea4 -> d16fd1e70
[CXF-5976] Some changes to support more explicit collection variations Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/d16fd1e7 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/d16fd1e7 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/d16fd1e7 Branch: refs/heads/master Commit: d16fd1e7059f059bafe12738ac1f29061888bcd2 Parents: 38bb9fe Author: Sergey Beryozkin <[email protected]> Authored: Mon Sep 1 13:14:57 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Mon Sep 1 13:14:57 2014 +0100 ---------------------------------------------------------------------- .../jaxrs/provider/AbstractJAXBProvider.java | 34 +++++++--- .../cxf/jaxrs/provider/JAXBElementProvider.java | 8 +-- .../cxf/jaxrs/provider/json/JSONProvider.java | 2 +- .../org/apache/cxf/systest/jaxrs/BookStore.java | 30 ++++++++- .../jaxrs/JAXRS20ClientServerBookTest.java | 35 +++++++++++ .../jaxrs/JAXRSClientServerBookTest.java | 66 ++++++++++++++++++-- 6 files changed, 152 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/d16fd1e7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java index 74646a6..e1c7bdd 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java @@ -410,7 +410,7 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid } } - private QName getQNameFromNamespaceAndName(String ns, String localName, Class<?> cls, boolean plural) { + private static QName getQNameFromNamespaceAndName(String ns, String localName, Class<?> cls, boolean plural) { String name = getLocalName(localName, cls.getSimpleName() , plural); String namespace = getNamespace(ns); if ("".equals(namespace)) { @@ -419,7 +419,7 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid return new QName(namespace, name); } - private String getLocalName(String name, String clsName, boolean pluralName) { + private static String getLocalName(String name, String clsName, boolean pluralName) { if (JAXB_DEFAULT_NAME.equals(name)) { name = clsName; if (name.length() > 1) { @@ -434,12 +434,12 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid return name; } - private String getPackageNamespace(Class<?> cls) { + private static String getPackageNamespace(Class<?> cls) { String packageNs = JAXBUtils.getPackageNamespace(cls); return packageNs != null ? getNamespace(packageNs) : ""; } - private String getNamespace(String namespace) { + private static String getNamespace(String namespace) { if (JAXB_DEFAULT_NAMESPACE.equals(namespace)) { return ""; } @@ -883,7 +883,10 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid } @SuppressWarnings("unchecked") - public <T> Object getCollectionOrArray(Unmarshaller unm, Class<T> type, Class<?> origType, + public <T> Object getCollectionOrArray(Unmarshaller unm, + Class<T> type, + Class<?> collectionType, + Type genericType, XmlJavaTypeAdapter adapter) throws JAXBException { List<?> theList = getList(); boolean adapterChecked = false; @@ -893,14 +896,17 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid if (first instanceof Element) { List<Object> newList = new ArrayList<Object>(theList.size()); for (Object o : theList) { - newList.add(unm.unmarshal((Element)o)); + newList.add(unm.unmarshal((Element)o, type)); } theList = newList; } first = theList.get(0); + Type[] types = InjectionUtils.getActualTypes(genericType); + boolean isJaxbElement = types != null && types.length > 0 + && InjectionUtils.getRawType(types[0]) == JAXBElement.class; - if (first instanceof JAXBElement && !JAXBElement.class.isAssignableFrom(type)) { + if (first instanceof JAXBElement && !isJaxbElement && !JAXBElement.class.isAssignableFrom(type)) { adapterChecked = true; List<Object> newList = new ArrayList<Object>(theList.size()); for (Object o : theList) { @@ -908,9 +914,19 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid ((JAXBElement<?>)o).getValue(), adapter, false)); } theList = newList; + } else if (!(first instanceof JAXBElement) && isJaxbElement) { + List<Object> newList = new ArrayList<Object>(theList.size()); + XmlRootElement root = type.getAnnotation(XmlRootElement.class); + QName qname = getQNameFromNamespaceAndName(root.namespace(), root.name(), type, false); + @SuppressWarnings("rawtypes") + Class theType = type; + for (Object o : theList) { + newList.add(new JAXBElement<Object>(qname, theType, null, o)); + } + theList = newList; } } - if (origType.isArray()) { + if (collectionType.isArray()) { T[] values = (T[])Array.newInstance(type, theList.size()); for (int i = 0; i < theList.size(); i++) { values[i] = (T)org.apache.cxf.jaxrs.utils.JAXBUtils.useAdapter( @@ -925,7 +941,7 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid } theList = newList; } - if (origType == Set.class) { + if (collectionType == Set.class) { return new HashSet<Object>(theList); } else { return theList; http://git-wip-us.apache.org/repos/asf/cxf/blob/d16fd1e7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java index 6da794b..3ea8d50 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java @@ -195,7 +195,7 @@ public class JAXBElementProvider<T> extends AbstractJAXBProvider<T> { } if (isCollection) { response = ((CollectionWrapper)response).getCollectionOrArray( - unmarshaller, theType, type, + unmarshaller, theType, type, genericType, org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns)); } else { response = checkAdapter(response, type, anns, false); @@ -400,12 +400,10 @@ public class JAXBElementProvider<T> extends AbstractJAXBProvider<T> { MediaType mt, String ns) throws Exception { //CHECKSTYLE:ON - if (obj instanceof JAXBElement) { - obj = ((JAXBElement<?>)obj).getValue(); - } else { + if (!(obj instanceof JAXBElement)) { obj = convertToJaxbElementIfNeeded(obj, cls, genericType); } - + if (obj instanceof JAXBElement && cls != JAXBElement.class) { cls = JAXBElement.class; } http://git-wip-us.apache.org/repos/asf/cxf/blob/d16fd1e7/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java index d3ee719..fcb6feb 100644 --- a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java +++ b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/json/JSONProvider.java @@ -243,7 +243,7 @@ public class JSONProvider<T> extends AbstractJAXBProvider<T> { } if (isCollection) { response = ((CollectionWrapper)response).getCollectionOrArray( - unmarshaller, theType, type, + unmarshaller, theType, type, genericType, org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns)); } else { response = checkAdapter(response, type, anns, false); http://git-wip-us.apache.org/repos/asf/cxf/blob/d16fd1e7/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java index dab5a7a..91d93e6 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java @@ -101,6 +101,8 @@ import org.apache.cxf.systest.jaxrs.BookServer20.CustomHeaderAdded; import org.apache.cxf.systest.jaxrs.BookServer20.CustomHeaderAddedAsync; import org.apache.cxf.systest.jaxrs.BookServer20.PostMatchMode; +import org.junit.Assert; + @Path("/bookstore") @GZIP(threshold = 1) public class BookStore { @@ -598,14 +600,37 @@ public class BookStore { } @POST - @Path("/collections2") + @Path("/jaxbelementcollections") @Produces({"application/xml", "application/json" }) @Consumes({"application/xml", "application/json" }) - public List<JAXBElement<BookNoXmlRootElement>> getBookCollection2( + public List<JAXBElement<BookNoXmlRootElement>> getJAXBElementBookCollection( List<JAXBElement<BookNoXmlRootElement>> bs) throws Exception { if (bs == null || bs.size() != 2) { throw new RuntimeException(); } + BookNoXmlRootElement b11 = bs.get(0).getValue(); + Assert.assertEquals(123L, b11.getId()); + Assert.assertEquals("CXF in Action", b11.getName()); + BookNoXmlRootElement b22 = bs.get(1).getValue(); + Assert.assertEquals(124L, b22.getId()); + Assert.assertEquals("CXF Rocks", b22.getName()); + return bs; + } + @POST + @Path("/jaxbelementxmlrootcollections") + @Produces({"application/xml", "application/json" }) + @Consumes({"application/xml", "application/json" }) + public List<JAXBElement<Book>> getJAXBElementBookXmlRootCollection( + List<JAXBElement<Book>> bs) throws Exception { + if (bs == null || bs.size() != 2) { + throw new RuntimeException(); + } + Book b11 = bs.get(0).getValue(); + Assert.assertEquals(123L, b11.getId()); + Assert.assertEquals("CXF in Action", b11.getName()); + Book b22 = bs.get(1).getValue(); + Assert.assertEquals(124L, b22.getId()); + Assert.assertEquals("CXF Rocks", b22.getName()); return bs; } @@ -1030,6 +1055,7 @@ public class BookStore { @POST @Path("/books/element/echo") public JAXBElement<Book> echoBookElement(JAXBElement<Book> element) throws Exception { + Assert.assertTrue(element instanceof JAXBElement); return element; } @POST http://git-wip-us.apache.org/repos/asf/cxf/blob/d16fd1e7/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java index a70bea6..4a593a2 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java @@ -598,6 +598,41 @@ public class JAXRS20ClientServerBookTest extends AbstractBusClientServerTestBase doTestPostBookAsyncHandler(address); } + @Test + public void testJAXBElementBookCollection() throws Exception { + String address = "http://localhost:" + PORT + "/bookstore/jaxbelementxmlrootcollections"; + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(address); + + Book b1 = new Book("CXF in Action", 123L); + Book b2 = new Book("CXF Rocks", 124L); + List<JAXBElement<Book>> books = + new ArrayList<JAXBElement<Book>>(); + books.add(new JAXBElement<Book>(new QName("bookRootElement"), + Book.class, b1)); + books.add(new JAXBElement<Book>(new QName("bookRootElement"), + Book.class, b2)); + + GenericEntity<List<JAXBElement<Book>>> collectionEntity = + new GenericEntity<List<JAXBElement<Book>>>(books) { }; + GenericType<List<JAXBElement<Book>>> genericResponseType = + new GenericType<List<JAXBElement<Book>>>() { }; + + List<JAXBElement<Book>> books2 = + target.request().accept("application/xml") + .post(Entity.entity(collectionEntity, "application/xml"), genericResponseType); + + assertNotNull(books2); + assertNotSame(books, books2); + assertEquals(2, books2.size()); + Book b11 = books.get(0).getValue(); + assertEquals(123L, b11.getId()); + assertEquals("CXF in Action", b11.getName()); + Book b22 = books.get(1).getValue(); + assertEquals(124L, b22.getId()); + assertEquals("CXF Rocks", b22.getName()); + } + private static class ReplaceBodyFilter implements ClientRequestFilter { @Override http://git-wip-us.apache.org/repos/asf/cxf/blob/d16fd1e7/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java index 09f6d72..1cdc92f 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java @@ -959,17 +959,63 @@ public class JAXRSClientServerBookTest extends AbstractBusClientServerTestBase { assertNotNull(books2); assertNotSame(books, books2); assertEquals(2, books2.size()); - Book b11 = books.get(0); + Book b11 = books2.get(0); assertEquals(123L, b11.getId()); assertEquals("CXF in Action", b11.getName()); - Book b22 = books.get(1); + Book b22 = books2.get(1); assertEquals(124L, b22.getId()); assertEquals("CXF Rocks", b22.getName()); } @Test - @Ignore - public void testGetBookCollection2() throws Exception { + public void testGetJAXBElementXmlRootBookCollection() throws Exception { + BookStore store = JAXRSClientFactory.create("http://localhost:" + PORT, + BookStore.class); + WebClient.getConfig(store).getHttpConduit().getClient().setReceiveTimeout(10000000); + Book b1 = new Book("CXF in Action", 123L); + Book b2 = new Book("CXF Rocks", 124L); + List<JAXBElement<Book>> books = + new ArrayList<JAXBElement<Book>>(); + books.add(new JAXBElement<Book>(new QName("bookRootElement"), + Book.class, b1)); + books.add(new JAXBElement<Book>(new QName("bookRootElement"), + Book.class, b2)); + List<JAXBElement<Book>> books2 = store.getJAXBElementBookXmlRootCollection(books); + assertNotNull(books2); + assertNotSame(books, books2); + assertEquals(2, books2.size()); + Book b11 = books2.get(0).getValue(); + assertEquals(123L, b11.getId()); + assertEquals("CXF in Action", b11.getName()); + Book b22 = books2.get(1).getValue(); + assertEquals(124L, b22.getId()); + assertEquals("CXF Rocks", b22.getName()); + } + @Test + public void testGetJAXBElementXmlRootBookCollectionWebClient() throws Exception { + WebClient store = WebClient.create("http://localhost:" + PORT + + "/bookstore/jaxbelementxmlrootcollections"); + WebClient.getConfig(store).getHttpConduit().getClient().setReceiveTimeout(10000000); + Book b1 = new Book("CXF in Action", 123L); + Book b2 = new Book("CXF Rocks", 124L); + List<Book> books = new ArrayList<Book>(); + books.add(b1); + books.add(b2); + store.type("application/xml").accept("application/xml"); + List<Book> books2 = new ArrayList<Book>(store.postAndGetCollection(books, Book.class, Book.class)); + assertNotNull(books2); + assertNotSame(books, books2); + assertEquals(2, books2.size()); + Book b11 = books2.get(0); + assertEquals(123L, b11.getId()); + assertEquals("CXF in Action", b11.getName()); + Book b22 = books2.get(1); + assertEquals(124L, b22.getId()); + assertEquals("CXF Rocks", b22.getName()); + } + + @Test + public void testGetJAXBElementBookCollection() throws Exception { JAXBElementProvider<?> provider = new JAXBElementProvider<Object>(); provider.setMarshallAsJaxbElement(true); provider.setUnmarshallAsJaxbElement(true); @@ -984,8 +1030,7 @@ public class JAXRSClientServerBookTest extends AbstractBusClientServerTestBase { BookNoXmlRootElement.class, b1)); books.add(new JAXBElement<BookNoXmlRootElement>(new QName("bookNoXmlRootElement"), BookNoXmlRootElement.class, b2)); - WebClient.getConfig(store).getHttpConduit().getClient().setReceiveTimeout(10000000L); - List<JAXBElement<BookNoXmlRootElement>> books2 = store.getBookCollection2(books); + List<JAXBElement<BookNoXmlRootElement>> books2 = store.getJAXBElementBookCollection(books); assertNotNull(books2); assertNotSame(books, books2); assertEquals(2, books2.size()); @@ -1869,6 +1914,15 @@ public class JAXRSClientServerBookTest extends AbstractBusClientServerTestBase { } @Test + public void testEchoBookElementWebClient() throws Exception { + WebClient wc = WebClient.create("http://localhost:" + PORT + "/bookstore/books/element/echo"); + wc.type("application/xml").accept("application/xml"); + Book book = wc.post(new Book("CXF", 123L), Book.class); + assertEquals(123L, book.getId()); + assertEquals("CXF", book.getName()); + } + + @Test public void testEchoBookElementWildcard() throws Exception { BookStore store = JAXRSClientFactory.create("http://localhost:" + PORT, BookStore.class); JAXBElement<? super Book> element = store.echoBookElementWildcard(
