package org.jboss.resteasy.spi; import org.jboss.resteasy.core.Dispatcher; import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpResponse; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.net.URI; import static org.jboss.resteasy.spi.ResteasyProviderFactory.getContextData; /** * <p> * InternalDispatch represents a "forward" in servlet terms. You can perform an * internal GET/POST/DELETE/PUT using IntenalDispatch using Java Object. For * example: * </p> * <p/> * <p/> * <pre> * @GET * @Produces("text/plain") * @Path("/forward/object") * public SomeObject forward(@Context InternalDispatcher dispatcher) * { * return (SomeObject) dispatcher.getEntity("/some-object"); * } * </pre> * <p/> * <p> * That previous snippet performs an internal request to /some-object and * returns the Object representation of the Resource that lives at * "/some-object". * </p> * * @author <a href="mailto:sduskis@gmail.com">Solomon Duskis</a> * @version $Revision: 1 $ */ public class InternalDispatcher { private static InternalDispatcher instance = new InternalDispatcher(); // using a singleton so that that end users can override this behavior public static InternalDispatcher getInstance() { return instance; } public static void setInstance(InternalDispatcher instance) { InternalDispatcher.instance = instance; } public Object getEntity(String uri) { return getResponse(uri).getEntity(); } public Response delete(String uri) { return getResponse(createRequest(uri, "DELETE")); } public Response putEntity(String uri, String contentType, Object entity) { return executeEntity("PUT", uri, contentType, entity); } public Response putEntity(String uri, Object entity) { return putEntity(uri, "*/*", entity); } public Response executeEntity(String method, String uri, String contentType, Object entity) { MockHttpRequest post = createRequest(uri, method); post.contentType(contentType); return getResponse(post, entity); } public Response postEntity(String uri, String contentType, Object entity) { return executeEntity("POST", uri, contentType, entity); } public Response postEntity(String uri, Object entity) { return postEntity(uri, "*/*", entity); } public Response getResponse(String uri) { return getResponse(createRequest(uri, "GET")); } public Response getResponse(MockHttpRequest request) { return getResponse(request, null); } public Response getResponse(MockHttpRequest request, Object entity) { try { Dispatcher dispatcher = getContextData(Dispatcher.class); if (dispatcher == null) { return null; } enhanceRequest(request); return dispatcher.internalInvocation(request, new MockHttpResponse(), entity); } finally { } } protected void enhanceRequest(MockHttpRequest request) { HttpRequest previousRequest = getContextData(HttpRequest.class); if (previousRequest != null) { getHeaders(request).putAll(getHeaders(previousRequest)); } } private MultivaluedMap<String, String> getHeaders(HttpRequest request) { return request.getHttpHeaders().getRequestHeaders(); } public static MockHttpRequest createRequest(String relativeUri, String verb) { UriInfo uriInfo = ResteasyProviderFactory.getContextData(UriInfo.class); URI baseUri = uriInfo.getBaseUri(); URI absoluteUri = baseUri.resolve(parseRelativeUri(relativeUri)); return MockHttpRequest.create(verb, absoluteUri, baseUri); } private static URI parseRelativeUri(String relativeUri) { if(relativeUri.startsWith("/")) { return URI.create(relativeUri.substring(1)); } return URI.create(relativeUri); } }