/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.everrest.core.impl.integration;
import com.google.common.io.CharStreams;
import org.everrest.core.impl.BaseTest;
import org.everrest.core.impl.ContainerResponse;
import org.everrest.core.impl.EnvironmentContext;
import org.everrest.core.tools.ByteArrayContainerResponseWriter;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;
import static com.google.common.collect.Sets.newHashSet;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.MediaType.TEXT_PLAIN_TYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
public class ProviderContextParameterInjectionTest extends BaseTest {
@Provider
@Consumes("text/plain")
public static class MessageBodyReaderChecker implements MessageBodyReader<String> {
@Context private UriInfo uriInfo;
@Context private Request request;
@Context private HttpHeaders httpHeaders;
@Context private Providers providers;
@Context private HttpServletRequest httpRequest;
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type == String.class;
}
@Override
public String readFrom(Class<String> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
assertThatAllRequiredFieldsAreInjectedInMessageBodyReader(this);
return "MessageBodyReaderChecker: " + CharStreams.toString(new InputStreamReader(entityStream));
}
}
@Provider
@Produces("text/plain")
public static class MessageBodyWriterChecker implements MessageBodyWriter<String> {
@Context private UriInfo uriInfo;
@Context private Request request;
@Context private HttpHeaders httpHeaders;
@Context private Providers providers;
@Context private HttpServletRequest httpRequest;
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type == String.class;
}
@Override
public long getSize(String s, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
@Override
public void writeTo(String string, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
assertThatAllRequiredFieldsAreInjectedInMessageBodyWriter(this);
Writer writer = new OutputStreamWriter(entityStream);
writer.write("MessageBodyWriterChecker: ");
writer.write(string);
writer.flush();
}
}
@Provider
public static class ExceptionMapperChecker implements ExceptionMapper<RuntimeException> {
@Context private UriInfo uriInfo;
@Context private Request request;
@Context private HttpHeaders httpHeaders;
@Context private Providers providers;
@Context private HttpServletRequest httpRequest;
public Response toResponse(RuntimeException exception) {
assertThatAllRequiredFieldsAreInjectedInExceptionMapper(this);
return Response.ok().entity("ExceptionMapperChecker: " + exception.getMessage()).type("text/plain").build();
}
}
@Provider
@Produces("text/plain")
public static class ContextResolverChecker implements ContextResolver<String> {
@Context private UriInfo uriInfo;
@Context private Request request;
@Context private HttpHeaders httpHeaders;
@Context private Providers providers;
@Context private HttpServletRequest httpRequest;
public String getContext(Class<?> type) {
return null;
}
}
@Path("a")
public static class Resource1 {
@Context private Providers providers;
@GET
@Path("1")
public void m1(String string) {
assertEquals("MessageBodyReaderChecker: all fields injected", string);
}
@GET
@Path("2")
public String m2() {
return "all fields injected";
}
@GET
@Path("3")
public String m3() {
ContextResolverChecker contextResolver = (ContextResolverChecker)providers.getContextResolver(String.class, TEXT_PLAIN_TYPE);
assertThatAllRequiredFieldsAreInjectedInContextResolver(contextResolver);
return "ContextResolverChecker: all fields injected";
}
@GET
@Path("4")
public void m4() {
throw new RuntimeException("all fields injected");
}
}
private EnvironmentContext env;
@Before
public void setUp() throws Exception {
super.setUp();
env = new EnvironmentContext();
env.put(HttpServletRequest.class, mock(HttpServletRequest.class));
processor.addApplication(new Application() {
@Override
public Set<Class<?>> getClasses() {
return newHashSet(MessageBodyReaderChecker.class, MessageBodyWriterChecker.class, ExceptionMapperChecker.class,
ContextResolverChecker.class, Resource1.class);
}
});
}
private static void assertThatAllRequiredFieldsAreInjectedInContextResolver(ContextResolverChecker contextResolver) {
assertNotNull(contextResolver.uriInfo);
assertNotNull(contextResolver.request);
assertNotNull(contextResolver.httpHeaders);
assertNotNull(contextResolver.providers);
assertNotNull(contextResolver.httpRequest);
}
private static void assertThatAllRequiredFieldsAreInjectedInMessageBodyReader(MessageBodyReaderChecker messageBodyReader) {
assertNotNull(messageBodyReader.uriInfo);
assertNotNull(messageBodyReader.request);
assertNotNull(messageBodyReader.httpHeaders);
assertNotNull(messageBodyReader.providers);
assertNotNull(messageBodyReader.httpRequest);
}
private static void assertThatAllRequiredFieldsAreInjectedInMessageBodyWriter(MessageBodyWriterChecker messageBodyWriter) {
assertNotNull(messageBodyWriter.uriInfo);
assertNotNull(messageBodyWriter.request);
assertNotNull(messageBodyWriter.httpHeaders);
assertNotNull(messageBodyWriter.providers);
assertNotNull(messageBodyWriter.httpRequest);
}
private static void assertThatAllRequiredFieldsAreInjectedInExceptionMapper(ExceptionMapperChecker exceptionMapper) {
assertNotNull(exceptionMapper.uriInfo);
assertNotNull(exceptionMapper.request);
assertNotNull(exceptionMapper.httpHeaders);
assertNotNull(exceptionMapper.providers);
assertNotNull(exceptionMapper.httpRequest);
}
@Test
public void contextParameterInjectedInMessageBodyReader() throws Exception {
MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
headers.putSingle(CONTENT_TYPE, "text/plain");
ContainerResponse response = launcher.service("GET", "/a/1", "", headers, "all fields injected".getBytes(), env);
assertEquals(204, response.getStatus());
}
@Test
public void contextParameterInjectedInMessageBodyWriter() throws Exception {
ByteArrayContainerResponseWriter responseWriter = new ByteArrayContainerResponseWriter();
ContainerResponse response = launcher.service("GET", "/a/2", "", new MultivaluedHashMap<>(), null, responseWriter, env);
assertEquals(200, response.getStatus());
assertEquals("MessageBodyWriterChecker: all fields injected", new String(responseWriter.getBody()));
}
@Test
public void contextParameterInjectedInContextResolver() throws Exception {
ContainerResponse response = launcher.service("GET", "/a/3", "", new MultivaluedHashMap<>(), null, env);
assertEquals(200, response.getStatus());
assertEquals("ContextResolverChecker: all fields injected", response.getEntity());
}
@Test
public void contextParameterInjectedInExceptionMapper() throws Exception {
ContainerResponse response = launcher.service("GET", "/a/4", "", new MultivaluedHashMap<>(), null, env);
assertEquals(200, response.getStatus());
assertEquals("ExceptionMapperChecker: all fields injected", response.getEntity());
}
}