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/03/04 12:07:50 UTC
svn commit: r749963 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/
rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/
rt/frontend/jaxrs/src/tes...
Author: sergeyb
Date: Wed Mar 4 11:07:50 2009
New Revision: 749963
URL: http://svn.apache.org/viewvc?rev=749963&view=rev
Log:
JAXRS: CXF-2058 plus support for XmlJavaTypeAdapter on the inbound path
Added:
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java (with props)
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java (with props)
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/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JAXBElementProviderTest.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/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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -70,12 +70,11 @@
}
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
- return isSupported(type, genericType, anns)
- || AnnotationUtils.getAnnotation(anns, XmlJavaTypeAdapter.class) != null;
+ return isSupported(type, genericType, anns);
}
- public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
- return isSupported(type, genericType, annotations);
+ public boolean isReadable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
+ return isSupported(type, genericType, anns);
}
public void setSchemaLocations(List<String> locations) {
@@ -133,7 +132,7 @@
}
}
- private JAXBContext getPackageContext(Class<?> type) {
+ protected JAXBContext getPackageContext(Class<?> type) {
if (type == null) {
return null;
}
@@ -144,27 +143,38 @@
try {
context = JAXBContext.newInstance(packageName, type.getClassLoader());
packageContexts.put(packageName, context);
- return context;
} catch (JAXBException ex) {
LOG.fine("Error creating a JAXBContext using ObjectFactory : "
+ ex.getMessage());
return null;
}
}
+ return context;
}
- return null;
}
- protected boolean isSupported(Class<?> type, Type genericType, Annotation[] annotations) {
+ protected boolean isSupported(Class<?> type, Type genericType, Annotation[] anns) {
+ // TODO : Shall we just return true and let readFrom/writeTo
+ // fail if JAXB can't handle a given type ?
+
+ // TODO: still not checked :
+ // - XmlJavaTypeAdapter at package level
+ // - anything else ?
return type.getAnnotation(XmlRootElement.class) != null
|| JAXBElement.class.isAssignableFrom(type)
|| objectFactoryForClass(type)
- || (type != genericType && objectFactoryForType(genericType));
+ || (type != genericType && objectFactoryForType(genericType))
+ || adapterAvailable(type, anns);
+
+ }
+ protected boolean adapterAvailable(Class<?> type, Annotation[] anns) {
+ return AnnotationUtils.getAnnotation(anns, XmlJavaTypeAdapter.class) != null
+ || type.getAnnotation(XmlJavaTypeAdapter.class) != null;
}
- private boolean objectFactoryForClass(Class<?> type) {
+ protected boolean objectFactoryForClass(Class<?> type) {
try {
return type.getClassLoader().loadClass(PackageUtils.getPackageName(type)
+ ".ObjectFactory") != null;
@@ -201,24 +211,39 @@
return marshaller;
}
- protected Class<?> getActualType(Class<?> type, Type genericType) {
+ protected Class<?> getActualType(Class<?> type, Type genericType, Annotation[] anns) {
Class<?> theType = null;
if (JAXBElement.class.isAssignableFrom(type)) {
theType = InjectionUtils.getActualType(genericType);
} else {
theType = type;
}
+ XmlJavaTypeAdapter adapter = getAdapter(theType, anns);
+ if (adapter != null) {
+ if (adapter.type() != XmlJavaTypeAdapter.DEFAULT.class) {
+ theType = adapter.type();
+ } else {
+ Type[] types = InjectionUtils.getActualTypes(adapter.value().getGenericSuperclass());
+ if (types != null && types.length == 2) {
+ theType = (Class)types[0];
+ }
+ }
+ }
return theType;
}
@SuppressWarnings("unchecked")
- protected Object checkAdapter(Object obj, Annotation[] anns) {
- XmlJavaTypeAdapter typeAdapter = AnnotationUtils.getAnnotation(anns, XmlJavaTypeAdapter.class);
+ protected Object checkAdapter(Object obj, Annotation[] anns, boolean marshal) {
+ XmlJavaTypeAdapter typeAdapter = getAdapter(obj.getClass(), anns);
if (typeAdapter != null) {
try {
XmlAdapter xmlAdapter = typeAdapter.value().newInstance();
- return xmlAdapter.marshal(obj);
+ if (marshal) {
+ return xmlAdapter.marshal(obj);
+ } else {
+ return xmlAdapter.unmarshal(obj);
+ }
} catch (Exception ex) {
LOG.warning("Problem using the XmlJavaTypeAdapter");
ex.printStackTrace();
@@ -227,9 +252,24 @@
return obj;
}
+ protected XmlJavaTypeAdapter getAdapter(Class<?> type, Annotation[] anns) {
+ XmlJavaTypeAdapter typeAdapter = AnnotationUtils.getAnnotation(anns, XmlJavaTypeAdapter.class);
+ if (typeAdapter == null) {
+ typeAdapter = type.getAnnotation(XmlJavaTypeAdapter.class);
+ }
+ return typeAdapter;
+ }
+
+
protected Schema getSchema() {
return schema;
}
+
+
+ static void clearContexts() {
+ classContexts.clear();
+ packageContexts.clear();
+ }
protected static void handleJAXBException(JAXBException e) {
Throwable t = e.getLinkedException() != null
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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -84,14 +84,17 @@
MultivaluedMap<String, String> headers, InputStream is)
throws IOException {
try {
- Class<?> theType = getActualType(type, genericType);
+ Class<?> theType = getActualType(type, genericType, anns);
Unmarshaller unmarshaller = createUnmarshaller(theType, genericType);
+ Object response = null;
if (JAXBElement.class.isAssignableFrom(type)) {
- return unmarshaller.unmarshal(new StreamSource(is), theType);
+ response = unmarshaller.unmarshal(new StreamSource(is), theType);
} else {
- return unmarshaller.unmarshal(is);
+ response = unmarshaller.unmarshal(is);
}
+ response = checkAdapter(response, anns, false);
+ return response;
} catch (JAXBException e) {
handleJAXBException(e);
@@ -109,7 +112,7 @@
MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
throws IOException {
try {
- Object actualObject = checkAdapter(obj, anns);
+ Object actualObject = checkAdapter(obj, anns, true);
Class<?> actualClass = actualObject.getClass();
if (cls == genericType) {
genericType = actualClass;
@@ -122,6 +125,10 @@
} catch (JAXBException e) {
throw new WebApplicationException(e);
+ } catch (WebApplicationException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new WebApplicationException(e);
}
}
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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -103,7 +103,8 @@
throws IOException {
try {
- Class<?> theType = getActualType(type, genericType);
+ Class<?> theType = getActualType(type, genericType, anns);
+
Unmarshaller unmarshaller = createUnmarshaller(theType, genericType);
MappedXMLInputFactory factory = new MappedXMLInputFactory(namespaceMap);
@@ -114,6 +115,7 @@
} else {
response = unmarshaller.unmarshal(xsw);
}
+ response = checkAdapter(response, anns, false);
return response;
} catch (JAXBException e) {
@@ -134,7 +136,7 @@
throws IOException {
try {
- Object actualObject = checkAdapter(obj, anns);
+ Object actualObject = checkAdapter(obj, anns, true);
Class<?> actualClass = actualObject.getClass();
if (cls == genericType) {
genericType = actualClass;
@@ -164,6 +166,8 @@
throw new WebApplicationException(e);
} catch (XMLStreamException e) {
throw new WebApplicationException(e);
+ } catch (Exception e) {
+ throw new WebApplicationException(e);
}
}
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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -132,6 +132,15 @@
return (Class<?>)paramType.getActualTypeArguments()[0];
}
+ public static Type[] getActualTypes(Type genericType) {
+ if (genericType == null
+ || !ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
+ return null;
+ }
+ ParameterizedType paramType = (ParameterizedType)genericType;
+ return paramType.getActualTypeArguments();
+ }
+
public static void injectThroughMethod(Object requestObject,
Method method,
Object parameterValue) {
Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java?rev=749963&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java Wed Mar 4 11:07:50 2009
@@ -0,0 +1,45 @@
+/**
+ * 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.fortest.jaxb;
+
+
+public class Book {
+ private String name;
+ private long id;
+
+ public Book() {
+ }
+
+ public void setName(String n) {
+ name = n;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setId(long i) {
+ id = i;
+ }
+ public long getId() {
+ return id;
+ }
+
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/Book.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java?rev=749963&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java Wed Mar 4 11:07:50 2009
@@ -0,0 +1,26 @@
+/**
+ * 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.fortest.jaxb;
+
+
+public class ObjectFactory {
+ public Book createBook() {
+ return new Book();
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/fortest/jaxb/ObjectFactory.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -31,6 +31,7 @@
import java.util.Map;
import javax.ws.rs.core.MediaType;
+import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
@@ -43,6 +44,7 @@
import javax.xml.validation.Schema;
import org.w3c.dom.Node;
+
import org.xml.sax.ContentHandler;
import org.junit.Assert;
@@ -71,6 +73,21 @@
assertNotNull("schema can not be read from disk", s);
}
+ @Test
+ public void testPackageContext() {
+ JAXBElementProvider p = new JAXBElementProvider();
+ try {
+ JAXBContext context = p.getPackageContext(org.apache.cxf.jaxrs.fortest.jaxb.Book.class);
+ JAXBContext context2 = p.getPackageContext(org.apache.cxf.jaxrs.fortest.jaxb.Book.class);
+ assertNotNull(context);
+ assertNotNull(context2);
+ assertSame(context, context2);
+ } finally {
+ JAXBElementProvider.clearContexts();
+ }
+
+ }
+
@Test
public void testSetMarshallProperties() throws Exception {
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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -315,6 +315,15 @@
return Response.ok(book).build();
}
+
+ @POST
+ @Path("/booksinfo")
+ @Produces("text/xml")
+ @Consumes("application/xml")
+ public Response addBook(@XmlJavaTypeAdapter(BookInfoAdapter.class)
+ BookInfo bookInfo) {
+ return Response.ok(bookInfo.asBook()).build();
+ }
@POST
@Path("/binarybooks")
@@ -455,9 +464,16 @@
private String name;
private long id;
+ public BookInfo() {
+
+ }
+
public BookInfo(Book b) {
this.name = b.getName();
this.id = b.getId();
+ if (id == 0) {
+ id = 124;
+ }
}
public String getName() {
@@ -467,6 +483,13 @@
public long getId() {
return id;
}
+
+ public Book asBook() {
+ Book b = new Book();
+ b.setId(id);
+ b.setName(name);
+ return b;
+ }
}
public static class BookInfoAdapter extends XmlAdapter<Book, BookInfo> {
@@ -477,9 +500,8 @@
}
@Override
- public BookInfo unmarshal(Book v) throws Exception {
- // TODO Auto-generated method stub
- return null;
+ public BookInfo unmarshal(Book b) throws Exception {
+ return new BookInfo(b);
}
}
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=749963&r1=749962&r2=749963&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 Wed Mar 4 11:07:50 2009
@@ -357,11 +357,17 @@
@Test
public void testAddBook() throws Exception {
- String endpointAddress =
- "http://localhost:9080/bookstore/books";
-
+ doAddBook("http://localhost:9080/bookstore/books");
+ }
+
+ @Test
+ public void testAddBookXmlAdapter() throws Exception {
+ doAddBook("http://localhost:9080/bookstore/booksinfo");
+ }
+
+ private void doAddBook(String address) throws Exception {
File input = new File(getClass().getResource("resources/add_book.txt").toURI());
- PostMethod post = new PostMethod(endpointAddress);
+ PostMethod post = new PostMethod(address);
post.setRequestHeader("Content-Type", "application/xml");
RequestEntity entity = new FileRequestEntity(input, "text/xml; charset=ISO-8859-1");
post.setRequestEntity(entity);
@@ -377,8 +383,8 @@
} finally {
// Release current connection to the connection pool once you are done
post.releaseConnection();
- }
- }
+ }
+ }
@Test
public void testUpdateBook() throws Exception {