package org.jboss.resteasy.springmvc;
import org.jboss.resteasy.core.AsynchronousDispatcher;
import org.jboss.resteasy.core.ServerResponse;
import org.jboss.resteasy.core.SynchronousDispatcher;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.jboss.resteasy.spi.UnhandledException;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author <a href="mailto:sduskis@gmail.com">Solomn Duskis</a>
* @version $Revision: 1 $
*/
// TODO: Right now there's a problematic relationship between Dispatcher and
// Registry. Ideally, the Registry shouldn't be owned by the Dispatcher, and the
// methods needed from SynchronousDispatcher should move into a shared class.
public class ResteasyHandlerAdapter extends
ResteasyWebHandlerTemplate<ModelAndView> implements HandlerAdapter
{
protected SynchronousDispatcher dispatcher;
public ResteasyHandlerAdapter(SynchronousDispatcher dispatcher)
{
super(dispatcher.getProviderFactory());
this.dispatcher = dispatcher;
}
public long getLastModified(HttpServletRequest request, Object handler)
{
return -1;
}
public ModelAndView handle(HttpServletRequest servletRequest,
HttpServletResponse servletResponse, Object handler) throws Exception
{
ResteasyRequestWrapper requestWrapper = (ResteasyRequestWrapper) handler;
// super.handle wraps the handle call you see below
return super.handle(requestWrapper, servletResponse);
}
protected ModelAndView handle(ResteasyRequestWrapper requestWrapper,
HttpResponse response) throws IOException
{
if (requestWrapper.getErrorCode() != null)
{
try
{
response.sendError(requestWrapper.getErrorCode(), requestWrapper
.getErrorMessage());
}
catch (Exception e)
{
throw new UnhandledException(e);
}
return null;
}
HttpRequest request = requestWrapper.getHttpRequest();
if (dispatcher instanceof AsynchronousDispatcher)
{
AsynchronousDispatcher asyncDispatcher = (AsynchronousDispatcher) dispatcher;
if (asyncDispatcher.isAsynchrnousRequest(request))
{
asyncDispatcher.invoke(request, response);
return null;
}
}
return createModelAndView(requestWrapper, response);
}
protected ModelAndView createModelAndView(
ResteasyRequestWrapper requestWrapper, HttpResponse response)
{
HttpRequest request = requestWrapper.getHttpRequest();
dispatcher.pushContextObjects(request, response);
try
{
ServerResponse jaxrsResponse = null;
try
{
jaxrsResponse = (ServerResponse) requestWrapper.getInvoker().invoke(request, response);
}
catch (Exception e)
{
dispatcher.handleInvokerException(request, response, e);
}
if (jaxrsResponse == null)
return null;
try
{
Object entity = jaxrsResponse.getEntity();
if (entity instanceof ModelAndView)
{
jaxrsResponse.commitHeaders(response);
return (ModelAndView) entity;
}
return createModelAndView(jaxrsResponse);
}
catch (Exception e)
{
dispatcher.handleWriteResponseException(request, response, e);
return null;
}
}
finally
{
dispatcher.clearContextData();
}
}
protected ModelAndView createModelAndView(ServerResponse serverResponse)
{
View view = createView(serverResponse);
return new ModelAndView(view, "responseInvoker", serverResponse);
}
protected View createView(ServerResponse serverResponse)
{
String contentType = serverResponse.resolveContentType().toString();
return new ResteasyView(contentType, dispatcher);
}
public boolean supports(Object handler)
{
return handler instanceof ResteasyRequestWrapper;
}
}