package org.jboss.resteasy.core.interception.jaxrs;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.tracing.InterceptorTimestampPair;
import org.jboss.resteasy.tracing.RESTEasyTracingLogger;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
public abstract class AbstractReaderInterceptorContext implements ReaderInterceptorContext
{
protected RESTEasyTracingLogger tracingLogger;
private InterceptorTimestampPair<ReaderInterceptor> lastTracedInterceptor;
protected ReaderInterceptor[] interceptors;
protected ResteasyProviderFactory providerFactory;
protected Class type;
protected Type genericType;
protected Annotation[] annotations;
protected MediaType mediaType;
protected MultivaluedMap<String, String> ;
protected InputStream inputStream;
protected int index = 0;
@Deprecated
public AbstractReaderInterceptorContext(final MediaType mediaType, final ResteasyProviderFactory providerFactory, final Annotation[] annotations, final ReaderInterceptor[] interceptors, final MultivaluedMap<String, String> headers, final Type genericType, final Class type, final InputStream inputStream)
{
this.mediaType = mediaType;
this.annotations = annotations;
this.interceptors = interceptors;
this.headers = headers;
this.genericType = genericType;
this.type = type;
this.inputStream = inputStream;
this.providerFactory = providerFactory;
this.tracingLogger = RESTEasyTracingLogger.empty();
}
public AbstractReaderInterceptorContext(final MediaType mediaType, final ResteasyProviderFactory providerFactory, final Annotation[] annotations, final ReaderInterceptor[] interceptors, final MultivaluedMap<String, String> headers, final Type genericType, final Class type, final InputStream inputStream, final RESTEasyTracingLogger logger)
{
this.mediaType = mediaType;
this.annotations = annotations;
this.interceptors = interceptors;
this.headers = headers;
this.genericType = genericType;
this.type = type;
this.inputStream = inputStream;
this.providerFactory = providerFactory;
this.tracingLogger = logger;
if (logger == null) {
this.tracingLogger = RESTEasyTracingLogger.empty();
}
}
@Override
public Object proceed() throws IOException
{
LogMessages.LOGGER.debugf("Interceptor Context: %s, Method : proceed", getClass().getName());
if (interceptors == null || index >= interceptors.length)
{
MessageBodyReader reader = getReader();
if (reader!=null) {
tracingLogger.log("MBR_READ_FROM", reader.getClass().getName());
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
}
return readFrom(reader);
}
LogMessages.LOGGER.debugf("ReaderInterceptor: %s", interceptors[index].getClass().getName());
int x = index;
traceBefore(interceptors[x]);
try {
return interceptors[index++].aroundReadFrom(this);
} finally {
traceAfter(interceptors[x]);
}
}
@SuppressWarnings(value = "unchecked")
protected Object readFrom(MessageBodyReader reader) throws IOException
{
return reader.readFrom(type, genericType, annotations, mediaType, headers, inputStream);
}
protected final void traceBefore(final ReaderInterceptor interceptor) {
if (tracingLogger.isLogEnabled("RI_BEFORE")) {
if ((lastTracedInterceptor != null) && (interceptor != null)) {
tracingLogger.logDuration("RI_BEFORE", lastTracedInterceptor.getTimestamp(), lastTracedInterceptor.getInterceptor());
}
lastTracedInterceptor = new InterceptorTimestampPair<>(interceptor, System.nanoTime());
}
}
protected final void traceAfter(final ReaderInterceptor interceptor) {
if (tracingLogger.isLogEnabled("RI_AFTER")) {
if ((lastTracedInterceptor != null) && (lastTracedInterceptor.getInterceptor() != null)) {
tracingLogger.logDuration("RI_AFTER", lastTracedInterceptor.getTimestamp(), interceptor);
}
lastTracedInterceptor = new InterceptorTimestampPair<>(interceptor, System.nanoTime());
}
}
protected MessageBodyReader getReader()
{
MediaType mediaType = this.mediaType;
if (getHeaders() != null && getHeaders().getFirst(HttpHeaders.CONTENT_TYPE) == null && mediaType.isWildcardType())
{
mediaType = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
MessageBodyReader reader = resolveReader(mediaType);
if (reader == null)
{
throwReaderNotFound();
}
return reader;
}
protected abstract MessageBodyReader resolveReader(MediaType mediaType);
protected abstract void throwReaderNotFound();
@Override
public InputStream getInputStream()
{
return inputStream;
}
@Override
public void setInputStream(InputStream is)
{
this.inputStream = is;
}
@Override
public MultivaluedMap<String, String> ()
{
return headers;
}
@Override
public Annotation[] getAnnotations()
{
return annotations;
}
@Override
public void setAnnotations(Annotation[] annotations)
{
if (annotations == null) throw new NullPointerException(Messages.MESSAGES.annotationsParamNull());
this.annotations = annotations;
}
@Override
public Class getType()
{
return type;
}
@Override
public void setType(Class type)
{
this.type = type;
}
@Override
public Type getGenericType()
{
return genericType;
}
@Override
public void setGenericType(Type genericType)
{
this.genericType = genericType;
}
@Override
public MediaType getMediaType()
{
return mediaType;
}
@Override
public void setMediaType(MediaType mediaType)
{
this.mediaType = mediaType;
}
public Object getProcessedInterceptorCount() {
return index;
}
}