Author: sergeyb
Date: Thu Apr 9 16:26:20 2009
New Revision: 763724
URL: http://svn.apache.org/viewvc?rev=763724&view=rev
Log:
support for JAX-RS GenericEntity
Added:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java
(with props)
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java
(with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.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/interceptor/JAXRSOutInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=763724&r1=763723&r2=763724&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
Thu Apr 9 16:26:20 2009
@@ -23,6 +23,7 @@
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
@@ -31,6 +32,7 @@
import java.util.ResourceBundle;
import java.util.logging.Logger;
+import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
@@ -125,14 +127,14 @@
boolean firstTry) {
int status = response.getStatus();
Object responseObj = response.getEntity();
- if (status == 200 && responseObj != null && firstTry
+ if (status == 200 && !isResponseNull(responseObj) && firstTry
&& JAXRSUtils.headMethodPossible(ori.getHttpMethod(),
(String)message.getExchange().getInMessage().get(Message.HTTP_REQUEST_METHOD)))
{
LOG.info(new
org.apache.cxf.common.i18n.Message("HEAD_WITHOUT_ENTITY", BUNDLE).toString());
responseObj = null;
}
if (status == -1) {
- status = responseObj == null ? 204 : 200;
+ status = isResponseNull(responseObj) ? 204 : 200;
}
message.put(Message.RESPONSE_CODE, status);
@@ -147,11 +149,11 @@
MultivaluedMap<String, Object> responseHeaders =
(MultivaluedMap)message.get(Message.PROTOCOL_HEADERS);
setResponseDate(responseHeaders, firstTry);
- if (responseObj == null) {
+ if (isResponseNull(responseObj)) {
return;
}
- Class targetType = responseObj.getClass();
+ Class<?> targetType = getRawResponseClass(responseObj);
List<MediaType> availableContentTypes =
computeAvailableContentTypes(message, response);
Method invoked = null;
@@ -164,7 +166,7 @@
for (MediaType type : availableContentTypes) {
writer = ProviderFactory.getInstance(message)
.createMessageBodyWriter(targetType,
- invoked != null ? invoked.getGenericReturnType() : null,
+ getGenericResponseType(invoked, responseObj),
invoked != null ? invoked.getAnnotations() : new
Annotation[]{},
type,
message);
@@ -182,15 +184,15 @@
return;
}
boolean enabled = checkBufferingMode(message, writer, firstTry);
+ Object entity = getEntity(responseObj);
try {
-
responseType = checkFinalContentType(responseType);
LOG.fine("Response content type is: " + responseType.toString());
message.put(Message.CONTENT_TYPE, responseType.toString());
LOG.fine("Response EntityProvider is: " +
writer.getClass().getName());
try {
- writer.writeTo(responseObj, targetType,
+ writer.writeTo(entity, targetType,
invoked != null ?
invoked.getGenericReturnType() : null,
invoked != null ? invoked.getAnnotations() :
new Annotation[]{},
responseType,
@@ -209,12 +211,21 @@
}
} catch (IOException ex) {
- handleWriteException(message, response, ori, ex, responseObj,
firstTry);
+ handleWriteException(message, response, ori, ex, entity, firstTry);
} catch (Throwable ex) {
- handleWriteException(message, response, ori, ex, responseObj,
firstTry);
+ handleWriteException(message, response, ori, ex, entity, firstTry);
}
}
+ private boolean isResponseNull(Object o) {
+ return o == null || GenericEntity.class.isAssignableFrom(o.getClass())
+ && ((GenericEntity)o).getEntity() == null;
+ }
+
+ private Object getEntity(Object o) {
+ return GenericEntity.class.isAssignableFrom(o.getClass()) ?
((GenericEntity)o).getEntity() : o;
+ }
+
private boolean checkBufferingMode(Message m, MessageBodyWriter w, boolean
firstTry) {
if (!firstTry) {
return false;
@@ -320,6 +331,22 @@
}
+ private Class<?> getRawResponseClass(Object targetObject) {
+ if (GenericEntity.class.isAssignableFrom(targetObject.getClass())) {
+ return ((GenericEntity)targetObject).getRawType();
+ } else {
+ return targetObject.getClass();
+ }
+ }
+
+ private Type getGenericResponseType(Method invoked, Object targetObject) {
+ if (GenericEntity.class.isAssignableFrom(targetObject.getClass())) {
+ return ((GenericEntity)targetObject).getType();
+ } else {
+ return invoked == null ? targetObject.getClass() :
invoked.getGenericReturnType();
+ }
+ }
+
private MediaType checkFinalContentType(MediaType mt) {
if (mt.isWildcardType() || mt.isWildcardSubtype()) {
return MediaType.APPLICATION_OCTET_STREAM_TYPE;
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=763724&r1=763723&r2=763724&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
Thu Apr 9 16:26:20 2009
@@ -164,7 +164,9 @@
return cls.isArray() ? cls.getComponentType() : null;
}
ParameterizedType paramType = (ParameterizedType)genericType;
- return (Class<?>)paramType.getActualTypeArguments()[0];
+ Type t = paramType.getActualTypeArguments()[0];
+ // we don't recurse at this stage, otherwise GenericEntity won't be
handled properly
+ return t instanceof Class ? (Class<?>)t : null;
}
public static Type[] getActualTypes(Type genericType) {
Modified:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java?rev=763724&r1=763723&r2=763724&view=diff
==============================================================================
---
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java
(original)
+++
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java
Thu Apr 9 16:26:20 2009
@@ -34,11 +34,17 @@
protected void run() {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(BookStore.class, BookStorePerRequest.class);
+
+ List<Object> providers = new ArrayList<Object>();
+
//default lifecycle is per-request, change it to singleton
BinaryDataProvider p = new BinaryDataProvider();
p.setProduceMediaTypes(Collections.singletonList("application/bar"));
p.setEnableBuffering(true);
- sf.setProvider(p);
+
+ providers.add(p);
+ providers.add(new GenericHandlerWriter());
+ sf.setProviders(providers);
List<Interceptor> ints = new ArrayList<Interceptor>();
ints.add(new CustomOutInterceptor());
sf.setOutInterceptors(ints);
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=763724&r1=763723&r2=763724&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
Thu Apr 9 16:26:20 2009
@@ -45,6 +45,7 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
@@ -213,6 +214,22 @@
}
@GET
+ @Path("/genericbooks/{bookId}/")
+ @Produces("application/xml")
+ public GenericEntity<GenericHandler<Book>>
getGenericBook(@PathParam("bookId") String id)
+ throws BookNotFoundFault {
+ return new GenericEntity<GenericHandler<Book>>(new
GenericHandler<Book>(doGetBook(id))) { };
+ }
+
+ @GET
+ @Path("/genericresponse/{bookId}/")
+ @Produces("application/xml")
+ public Response getGenericResponseBook(@PathParam("bookId") String id)
+ throws BookNotFoundFault {
+ return Response.ok(getGenericBook(id)).build();
+ }
+
+ @GET
@Path("/books/{bookId}/")
@Produces("application/xml")
public Book getBook(@PathParam("bookId") String id) throws
BookNotFoundFault {
Added:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java?rev=763724&view=auto
==============================================================================
---
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java
(added)
+++
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java
Thu Apr 9 16:26:20 2009
@@ -0,0 +1,33 @@
+/**
+ * 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.systest.jaxrs;
+
+public class GenericHandler<T> {
+
+ private T entity;
+
+ public GenericHandler(T t) {
+ entity = t;
+ }
+
+ public T getEntity() {
+ return entity;
+ }
+
+}
Propchange:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java?rev=763724&view=auto
==============================================================================
---
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java
(added)
+++
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java
Thu Apr 9 16:26:20 2009
@@ -0,0 +1,52 @@
+/**
+ * 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.systest.jaxrs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+
+public class GenericHandlerWriter implements
MessageBodyWriter<GenericHandler<Book>> {
+
+ public long getSize(GenericHandler<Book> t, Class type, Type genericType,
Annotation[] annotations,
+ MediaType mediaType) {
+ return -1;
+ }
+
+ public boolean isWriteable(Class type, Type genericType, Annotation[]
annotations, MediaType mediaType) {
+ return type == GenericHandler.class &&
InjectionUtils.getActualType(genericType) == Book.class;
+ }
+
+ public void writeTo(GenericHandler<Book> o, Class c, Type t, Annotation[]
anns, MediaType m,
+ MultivaluedMap<String, Object> headers, OutputStream
os)
+ throws IOException, WebApplicationException {
+ JAXBElementProvider jaxb = new JAXBElementProvider();
+ jaxb.writeTo(o.getEntity(), c, InjectionUtils.getActualType(t), anns,
m, headers, os);
+ }
+
+}
Propchange:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/GenericHandlerWriter.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=763724&r1=763723&r2=763724&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
Thu Apr 9 16:26:20 2009
@@ -49,7 +49,7 @@
@BeforeClass
public static void startServers() throws Exception {
assertTrue("server did not launch correctly",
- launchServer(BookServer.class, true));
+ launchServer(BookServer.class));
}
@Test
@@ -96,6 +96,20 @@
}
@Test
+ public void testGetGenericBook() throws Exception {
+
getAndCompareAsStrings("http://localhost:9080/bookstore/genericbooks/123",
+ "resources/expected_get_book123.txt",
+ "application/xml", 200);
+ }
+
+ @Test
+ public void testGetGenericResponseBook() throws Exception {
+
getAndCompareAsStrings("http://localhost:9080/bookstore/genericresponse/123",
+ "resources/expected_get_book123.txt",
+ "application/xml", 200);
+ }
+
+ @Test
public void testGetBookByArrayQuery() throws Exception {
getAndCompareAsStrings("http://localhost:9080/bookstore/bookidarray?"
+ "id=1&id=2&id=3",