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 2012/09/18 16:34:42 UTC
svn commit: r1387188 - in
/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs:
impl/ReaderInterceptorMBR.java impl/WriterInterceptorMBW.java
interceptor/JAXRSOutInterceptor.java provider/ProviderFactory.java
utils/JAXRSUtils.java
Author: sergeyb
Date: Tue Sep 18 14:34:41 2012
New Revision: 1387188
URL: http://svn.apache.org/viewvc?rev=1387188&view=rev
Log:
[CXF-4455] Initial support for calling reader amd writer interceptors on the server side
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorMBR.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorMBW.java
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/provider/ProviderFactory.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorMBR.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorMBR.java?rev=1387188&r1=1387187&r2=1387188&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorMBR.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ReaderInterceptorMBR.java Tue Sep 18 14:34:41 2012
@@ -25,12 +25,21 @@ import javax.ws.rs.ext.MessageBodyReader
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
+import org.apache.cxf.message.Message;
+
public class ReaderInterceptorMBR implements ReaderInterceptor {
private MessageBodyReader<?> reader;
+ private Message m;
- public ReaderInterceptorMBR(MessageBodyReader<?> reader) {
+ public ReaderInterceptorMBR(MessageBodyReader<?> reader,
+ Message m) {
this.reader = reader;
+ this.m = m;
+ }
+
+ public MessageBodyReader<?> getMBR() {
+ return reader;
}
@SuppressWarnings({
@@ -40,7 +49,8 @@ public class ReaderInterceptorMBR implem
public Object aroundReadFrom(ReaderInterceptorContext c) throws IOException, WebApplicationException {
return reader.readFrom((Class)c.getType(), c.getGenericType(),
c.getAnnotations(), c.getMediaType(),
- c.getHeaders(), c.getInputStream());
+ new HttpHeadersImpl(m).getRequestHeaders(),
+ c.getInputStream());
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorMBW.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorMBW.java?rev=1387188&r1=1387187&r2=1387188&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorMBW.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WriterInterceptorMBW.java Tue Sep 18 14:34:41 2012
@@ -19,22 +19,37 @@
package org.apache.cxf.jaxrs.impl;
import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
+import org.apache.cxf.common.logging.LogUtils;
+
public class WriterInterceptorMBW implements WriterInterceptor {
+ private static final Logger LOG = LogUtils.getL7dLogger(WriterInterceptorMBW.class);
+
private MessageBodyWriter<Object> writer;
public WriterInterceptorMBW(MessageBodyWriter<Object> writer) {
this.writer = writer;
}
+ public MessageBodyWriter<Object> getMBW() {
+ return writer;
+ }
+
@Override
public void aroundWriteTo(WriterInterceptorContext c) throws IOException, WebApplicationException {
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("Response EntityProvider is: " + writer.getClass().getName());
+ }
+
writer.writeTo(c.getEntity(),
c.getType(),
c.getGenericType(),
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=1387188&r1=1387187&r2=1387188&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 Tue Sep 18 14:34:41 2012
@@ -42,6 +42,8 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.WriterInterceptor;
+import javax.ws.rs.ext.WriterInterceptorContext;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.events.XMLEvent;
@@ -52,6 +54,8 @@ import org.apache.cxf.interceptor.Abstra
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.jaxrs.ext.ResponseHandler;
import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.WriterInterceptorContextImpl;
+import org.apache.cxf.jaxrs.impl.WriterInterceptorMBW;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
@@ -224,26 +228,26 @@ public class JAXRSOutInterceptor extends
Annotation[] annotations = invoked != null ? invoked.getAnnotations() : new Annotation[]{};
- MessageBodyWriter<?> writer = null;
+ List<WriterInterceptor> writers = null;
MediaType responseType = null;
for (MediaType type : availableContentTypes) {
- writer = ProviderFactory.getInstance(message)
- .createMessageBodyWriter(targetType, genericType, annotations, type, message);
+ writers = ProviderFactory.getInstance(message)
+ .createMessageBodyWriterInterceptor(targetType, genericType, annotations, type, message);
- if (writer != null) {
+ if (writers != null) {
responseType = type;
break;
}
}
OutputStream outOriginal = message.getContent(OutputStream.class);
- if (writer == null) {
+ if (writers == null) {
message.put(Message.CONTENT_TYPE, "text/plain");
message.put(Message.RESPONSE_CODE, 500);
writeResponseErrorMessage(outOriginal, "NO_MSG_WRITER", targetType.getSimpleName());
return;
}
- boolean enabled = checkBufferingMode(message, writer, firstTry);
+ boolean enabled = checkBufferingMode(message, writers, firstTry);
Object entity = getEntity(responseObj);
try {
responseType = checkFinalContentType(responseType);
@@ -252,21 +256,15 @@ public class JAXRSOutInterceptor extends
}
message.put(Message.CONTENT_TYPE, responseType.toString());
- long size = getSize(writer, entity, targetType, genericType, annotations, responseType);
- if (size > 0) {
- LOG.fine("Setting ContentLength to " + size + " as requested by "
- + writer.getClass().getName());
- responseHeaders.putSingle(HttpHeaders.CONTENT_LENGTH, Long.toString(size));
- }
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Response EntityProvider is: " + writer.getClass().getName());
- }
try {
- writeTo(writer, entity, targetType, genericType,
+ writeTo(writers,
+ entity,
+ targetType,
+ genericType,
annotations,
- responseType,
- responseHeaders,
- message.getContent(OutputStream.class));
+ responseType,
+ responseHeaders,
+ message);
if (isResponseRedirected(message)) {
return;
@@ -292,27 +290,33 @@ public class JAXRSOutInterceptor extends
}
//CHECKSTYLE:OFF
- private static <T> void writeTo(MessageBodyWriter<?> mwriter,
- T entity,
- Class<?> type, Type genericType,
- Annotation[] annotations,
- MediaType mediaType,
- MultivaluedMap<String, Object> httpHeaders,
- OutputStream entityStream)
+ private static void writeTo(List<WriterInterceptor> writers,
+ Object entity,
+ Class<?> type, Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders,
+ Message message)
throws WebApplicationException, IOException {
- @SuppressWarnings("unchecked")
- MessageBodyWriter<T> writer = (MessageBodyWriter<T>)mwriter;
- writer.writeTo(entity, type, genericType, annotations, mediaType,
+
+ OutputStream entityStream = message.getContent(OutputStream.class);
+ if (writers.size() > 1) {
+ WriterInterceptor first = writers.remove(0);
+ WriterInterceptorContext context = new WriterInterceptorContextImpl(entity,
+ type,
+ genericType,
+ annotations,
+ mediaType,
+ entityStream,
+ message,
+ writers);
+
+ first.aroundWriteTo(context);
+ } else {
+ MessageBodyWriter<Object> writer = ((WriterInterceptorMBW)writers.get(0)).getMBW();
+ writer.writeTo(entity, type, genericType, annotations, mediaType,
httpHeaders, entityStream);
- }
-
- private static <T> long getSize(MessageBodyWriter<?> mwriter, T entity,
- Class<?> targetType,
- Type genericType,
- Annotation[] annotations, MediaType responseType) {
- @SuppressWarnings("unchecked")
- MessageBodyWriter<T> writer = (MessageBodyWriter<T>)mwriter;
- return writer.getSize(entity, targetType, genericType, annotations, responseType);
+ }
}
//CHECKSTYLE:ON
@@ -325,10 +329,12 @@ public class JAXRSOutInterceptor extends
return GenericEntity.class.isAssignableFrom(o.getClass()) ? ((GenericEntity<?>)o).getEntity() : o;
}
- private boolean checkBufferingMode(Message m, MessageBodyWriter<?> w, boolean firstTry) {
+ private boolean checkBufferingMode(Message m, List<WriterInterceptor> writers, boolean firstTry) {
if (!firstTry) {
return false;
}
+ WriterInterceptor last = writers.get(writers.size() - 1);
+ MessageBodyWriter<Object> w = ((WriterInterceptorMBW)last).getMBW();
Object outBuf = m.getContextualProperty(OUT_BUFFERING);
boolean enabled = MessageUtils.isTrue(outBuf);
boolean configurableProvider = w instanceof AbstractConfigurableProvider;
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java?rev=1387188&r1=1387187&r2=1387188&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java Tue Sep 18 14:34:41 2012
@@ -456,7 +456,7 @@ public final class ProviderFactory {
mediaType,
m);
if (mr != null) {
- ReaderInterceptor mbrReader = new ReaderInterceptorMBR(mr);
+ ReaderInterceptor mbrReader = new ReaderInterceptorMBR(mr, m);
int size = readerInterceptors.size();
List<ReaderInterceptor> interceptors = null;
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1387188&r1=1387187&r2=1387188&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Tue Sep 18 14:34:41 2012
@@ -82,6 +82,8 @@ import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.ReaderInterceptorContext;
import javax.xml.namespace.QName;
import org.apache.cxf.common.i18n.BundleUtils;
@@ -102,6 +104,8 @@ import org.apache.cxf.jaxrs.impl.HttpSer
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.impl.PathSegmentImpl;
import org.apache.cxf.jaxrs.impl.ProvidersImpl;
+import org.apache.cxf.jaxrs.impl.ReaderInterceptorContextImpl;
+import org.apache.cxf.jaxrs.impl.ReaderInterceptorMBR;
import org.apache.cxf.jaxrs.impl.RequestImpl;
import org.apache.cxf.jaxrs.impl.SecurityContextImpl;
import org.apache.cxf.jaxrs.impl.UriInfoImpl;
@@ -1047,7 +1051,7 @@ public final class JAXRSUtils {
}
}
- private static <T> T readFromMessageBody(Class<T> targetTypeClass,
+ private static Object readFromMessageBody(Class<?> targetTypeClass,
Type parameterType,
Annotation[] parameterAnnotations,
InputStream is,
@@ -1057,20 +1061,23 @@ public final class JAXRSUtils {
List<MediaType> types = JAXRSUtils.intersectMimeTypes(consumeTypes, contentType);
- MessageBodyReader<T> provider = null;
+ final ProviderFactory pf = ProviderFactory.getInstance(m);
for (MediaType type : types) {
- provider = ProviderFactory.getInstance(m)
- .createMessageBodyReader(targetTypeClass,
+ List<ReaderInterceptor> readers = pf.createMessageBodyReaderInterceptor(
+ targetTypeClass,
parameterType,
parameterAnnotations,
type,
m);
- if (provider != null) {
+ if (readers != null) {
try {
- HttpHeaders headers = new HttpHeadersImpl(m);
- return provider.readFrom(
- targetTypeClass, parameterType, parameterAnnotations, contentType,
- headers.getRequestHeaders(), is);
+ return readFromMessageBodyReader(readers,
+ targetTypeClass,
+ parameterType,
+ parameterAnnotations,
+ is,
+ type,
+ m);
} catch (IOException e) {
throw e;
} catch (WebApplicationException ex) {
@@ -1090,6 +1097,37 @@ public final class JAXRSUtils {
return null;
}
+
+ @SuppressWarnings("unchecked")
+ public static Object readFromMessageBodyReader(List<ReaderInterceptor> readers,
+ Class<?> targetTypeClass,
+ Type parameterType,
+ Annotation[] parameterAnnotations,
+ InputStream is,
+ MediaType mediaType,
+ Message m) throws IOException, WebApplicationException {
+
+ // Verbose but avoids an extra context instantiation for the typical path
+ if (readers.size() > 1) {
+ ReaderInterceptor first = readers.remove(0);
+ ReaderInterceptorContext context = new ReaderInterceptorContextImpl(targetTypeClass,
+ parameterType,
+ parameterAnnotations,
+ mediaType,
+ is,
+ m,
+ readers);
+
+ return first.aroundReadFrom(context);
+ } else {
+ MessageBodyReader<?> provider = ((ReaderInterceptorMBR)readers.get(0)).getMBR();
+ @SuppressWarnings("rawtypes")
+ Class cls = (Class)targetTypeClass;
+ return provider.readFrom(
+ cls, parameterType, parameterAnnotations, mediaType,
+ new HttpHeadersImpl(m).getRequestHeaders(), is);
+ }
+ }