package org.jboss.resteasy.core; import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages; import org.jboss.resteasy.specimpl.BuiltResponse; import org.jboss.resteasy.spi.HttpRequest; import org.jboss.resteasy.spi.HttpResponse; import org.jboss.resteasy.spi.ResteasyAsynchronousResponse; import org.jboss.resteasy.spi.ResteasyProviderFactory; import javax.ws.rs.container.CompletionCallback; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.container.TimeoutHandler; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.WriterInterceptor; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public abstract class AbstractAsynchronousResponse implements ResteasyAsynchronousResponse { protected SynchronousDispatcher dispatcher; protected ResourceMethodInvoker method; protected HttpRequest request; protected HttpResponse response; protected ContainerResponseFilter[] responseFilters; protected WriterInterceptor[] writerInterceptors; protected Annotation[] annotations; protected TimeoutHandler timeoutHandler; protected List<CompletionCallback> completionCallbacks = new ArrayList<CompletionCallback>(); protected Map<Class<?>, Object> contextDataMap; protected AbstractAsynchronousResponse(SynchronousDispatcher dispatcher, HttpRequest request, HttpResponse response) { this.dispatcher = dispatcher; this.request = request; this.response = response; contextDataMap = ResteasyProviderFactory.getContextDataMap(); } @Override public Collection<Class<?>> register(Class<?> callback) throws NullPointerException { if (callback == null) throw new NullPointerException(Messages.MESSAGES.callbackWasNull()); Object cb = dispatcher.getProviderFactory().createProviderInstance(callback); return register(cb); } @Override public Collection<Class<?>> register(Object callback) throws NullPointerException { if (callback == null) throw new NullPointerException(Messages.MESSAGES.callbackWasNull()); ArrayList<Class<?>> registered = new ArrayList<Class<?>>(); if (callback instanceof CompletionCallback) { completionCallbacks.add((CompletionCallback) callback); registered.add(CompletionCallback.class); } return registered; } @Override public Map<Class<?>, Collection<Class<?>>> register(Class<?> callback, Class<?>... callbacks) throws NullPointerException { Map<Class<?>, Collection<Class<?>>> map = new HashMap<Class<?>, Collection<Class<?>>>(); map.put(callback, register(callback)); for (Class<?> call : callbacks) { map.put(call, register(call)); } return map; } @Override public Map<Class<?>, Collection<Class<?>>> register(Object callback, Object... callbacks) throws NullPointerException { Map<Class<?>, Collection<Class<?>>> map = new HashMap<Class<?>, Collection<Class<?>>>(); map.put(callback.getClass(), register(callback)); for (Object call : callbacks) { map.put(call.getClass(), register(call)); } return map; } @Override public void setTimeoutHandler(TimeoutHandler handler) { this.timeoutHandler = handler; } @Override public ResourceMethodInvoker getMethod() { return method; } @Override public void setMethod(ResourceMethodInvoker method) { this.method = method; } @Override public ContainerResponseFilter[] getResponseFilters() { return responseFilters; } @Override public void setResponseFilters(ContainerResponseFilter[] responseFilters) { this.responseFilters = responseFilters; } @Override public WriterInterceptor[] getWriterInterceptors() { return writerInterceptors; } @Override public void setWriterInterceptors(WriterInterceptor[] writerInterceptors) { this.writerInterceptors = writerInterceptors; } @Override public Annotation[] getAnnotations() { return annotations; } @Override public void setAnnotations(Annotation[] annotations) { this.annotations = annotations; } protected void completionCallbacks(Throwable throwable) { for (CompletionCallback callback : completionCallbacks) { callback.onComplete(throwable); } } protected boolean internalResume(Object entity) { ResteasyProviderFactory.pushContextDataMap(contextDataMap); Response response = null; if (entity == null) { response = Response.noContent().build(); } else if (entity instanceof Response) { response = (Response) entity; } else { if (method == null) throw new IllegalStateException(Messages.MESSAGES.unknownMediaTypeResponseEntity()); MediaType type = method.resolveContentType(request, entity); BuiltResponse jaxrsResponse = (BuiltResponse)Response.ok(entity, type).build(); jaxrsResponse.setGenericType(method.getGenericReturnType()); jaxrsResponse.addMethodAnnotations(method.getMethodAnnotations()); response = jaxrsResponse; } try { dispatcher.asynchronousDelivery(this.request, this.response, response); } catch (Throwable e) { return internalResume(e); } completionCallbacks(null); return true; } protected boolean internalResume(Throwable exc) { ResteasyProviderFactory.pushContextDataMap(contextDataMap); try { dispatcher.asynchronousExceptionDelivery(request, response, exc); } finally { completionCallbacks(exc); } return true; } }