All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wink.server.internal.handlers.ServerMessageContext Maven / Gradle / Ivy

/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *  
 *******************************************************************************/
package org.apache.wink.server.internal.handlers;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Properties;

import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Providers;

import org.apache.wink.common.internal.WinkConfiguration;
import org.apache.wink.common.internal.contexts.MediaTypeCharsetAdjuster;
import org.apache.wink.common.internal.contexts.ProvidersImpl;
import org.apache.wink.common.internal.registry.ProvidersRegistry;
import org.apache.wink.common.internal.runtime.AbstractRuntimeContext;
import org.apache.wink.server.handlers.MessageContext;
import org.apache.wink.server.internal.DeploymentConfiguration;
import org.apache.wink.server.internal.MediaTypeMapper;
import org.apache.wink.server.internal.contexts.HttpHeadersImpl;
import org.apache.wink.server.internal.contexts.RequestImpl;
import org.apache.wink.server.internal.contexts.SecurityContextImpl;
import org.apache.wink.server.internal.contexts.ServerMediaTypeCharsetAdjuster;
import org.apache.wink.server.internal.contexts.UriInfoImpl;
import org.apache.wink.server.internal.registry.ResourceRegistry;
import org.apache.wink.server.internal.utils.LinkBuildersImpl;
import org.apache.wink.server.utils.LinkBuilders;

public class ServerMessageContext extends AbstractRuntimeContext implements MessageContext {

    private int       responseStatusCode;
    private Object    responseEntity;
    private MediaType responseMediaType;
    private String    httpMethod;

    public ServerMessageContext(HttpServletRequest servletRequest,
                                HttpServletResponse servletResponse,
                                DeploymentConfiguration configuration) {
        
        this.httpMethod =
            buildHttpMethod(configuration.getHttpMethodOverrideHeaders(), servletRequest);
        this.responseStatusCode = -1;

        // save stuff on attributes
        setAttribute(HttpServletRequest.class, servletRequest);

        // note that a HttpServlet*Wrapper is needed for injection of
        // singletons that had a @Context HttpServlet*; see [WINK-73]
        setAttribute(HttpServletRequestWrapper.class, new HttpServletRequestWrapper(servletRequest));
        HttpServletResponseWrapper responseWrapper =
            new WrappedResponse(servletRequest, servletResponse, configuration.getMediaTypeMapper());
        setAttribute(HttpServletResponse.class, responseWrapper);
        setAttribute(HttpServletResponseWrapper.class, responseWrapper);
        setAttribute(ServletContext.class, configuration.getServletContext());
        setAttribute(ServletConfig.class, configuration.getServletConfig());
        setAttribute(FilterConfig.class, configuration.getFilterConfig());
        setAttribute(WinkConfiguration.class, configuration);
        setAttribute(DeploymentConfiguration.class, configuration);  // legacy
        setAttribute(ResourceRegistry.class, configuration.getResourceRegistry());
        setAttribute(ProvidersRegistry.class, configuration.getProvidersRegistry());
        if (configuration.isDefaultResponseCharset() || configuration.isUseAcceptCharset()) {
            setAttribute(MediaTypeCharsetAdjuster.class, ServerMediaTypeCharsetAdjuster.getInstance());
        }

        initContexts();
        List apps = configuration.getApplications();
        if (apps != null && !apps.isEmpty()) {
            setAttribute(Application.class, apps.get(0));
        }
    }

    private void initContexts() {
        setAttribute(Providers.class, new ProvidersImpl(getDeploymentConfiguration()
            .getProvidersRegistry(), this));
        setAttribute(HttpHeaders.class, new HttpHeadersImpl(this));
        UriInfoImpl uriInfoImpl = new UriInfoImpl(this);
        setAttribute(UriInfo.class, uriInfoImpl);
        setAttribute(UriInfoImpl.class, uriInfoImpl);
        setAttribute(SecurityContext.class, new SecurityContextImpl(this));
        setAttribute(Request.class, new RequestImpl(this));
        setAttribute(LinkBuilders.class, new LinkBuildersImpl(this));
    }

    private String buildHttpMethod(String[] httpMethodOverrideHeaders,
                                   HttpServletRequest servletRequest) {

        if (httpMethodOverrideHeaders != null) {
            for (String httpMethodOverrideHeader : httpMethodOverrideHeaders) {
                String xHttpMethodOverride =
                    servletRequest.getHeader(httpMethodOverrideHeader.trim());
                if (xHttpMethodOverride != null) {
                    return xHttpMethodOverride.trim();
                }
            }
        }
        try {
            return servletRequest.getMethod();
        } catch (IllegalArgumentException e) {
            return null; // return null for unknown methods
        }
    }

    // MessageContext methods
    public Properties getProperties() {
        return getDeploymentConfiguration().getProperties();
    }

    public void setResponseStatusCode(int responseStatusCode) {
        this.responseStatusCode = responseStatusCode;
    }

    public int getResponseStatusCode() {
        return responseStatusCode;
    }

    public void setResponseEntity(Object entity) {
        this.responseEntity = entity;
    }

    public Object getResponseEntity() {
        return responseEntity;
    }

    public void setResponseMediaType(MediaType responseMediaType) {
        this.responseMediaType = responseMediaType;
    }

    public MediaType getResponseMediaType() {
        return responseMediaType;
    }

    public void setHttpMethod(String method) {
        this.httpMethod = method;
    }

    public String getHttpMethod() {
        return httpMethod;
    }

    @Override
    public String toString() {
        return String.format("Method: %s, Path: %s, MediaType: %s", //$NON-NLS-1$
                             getHttpMethod(),
                             getUriInfo().getPath(false),
                             getHttpHeaders().getMediaType());
    }

    // Contexts methods

    public LinkBuilders getLinkBuilders() {
        return getAttribute(LinkBuilders.class);
    }

    public InputStream getInputStream() throws IOException {
        return getAttribute(HttpServletRequest.class).getInputStream();
    }

    public OutputStream getOutputStream() throws IOException {
        return getAttribute(HttpServletResponse.class).getOutputStream();
    }

    private DeploymentConfiguration getDeploymentConfiguration() {
        // this cast is safe because we're on the server
        return (DeploymentConfiguration)getAttribute(WinkConfiguration.class);
    }

    // Wrapped response for changing the output media type according to the
    // media type mapper
    private class WrappedResponse extends HttpServletResponseWrapper {

        private final HttpServletRequest servletRequest;
        private final MediaTypeMapper    mediaTypeMapper;
        private String                   userContentType = null;

        WrappedResponse(HttpServletRequest servletRequest,
                        HttpServletResponse servletResponse,
                        MediaTypeMapper mediaTypeMapper) {
            super(servletResponse);
            this.servletRequest = servletRequest;
            this.mediaTypeMapper = mediaTypeMapper;
        }

        @Override
        public void setHeader(String name, String value) {
            if (name.equals(HttpHeaders.CONTENT_TYPE)) {
                setContentType(value);
            } else {
                super.setHeader(name, value);
            }
        }

        @Override
        public void addHeader(String name, String value) {
            if (name.equals(HttpHeaders.CONTENT_TYPE)) {
                setContentType(value);
            } else {
                super.addHeader(name, value);
            }
        }

        @Override
        public void setContentType(String type) {
            userContentType = type;
            if (mediaTypeMapper == null) {
                super.setContentType(type);
            } else {
                MediaType realResponseMimeType = getRealResponseMimeType(type);
                super.setContentType(realResponseMimeType.toString());
            }
        }

        @Override
        public String getContentType() {
            if (userContentType != null) {
                return userContentType;
            }
            return super.getContentType();
        }

        private MediaType getRealResponseMimeType(String responseMimeType) {
            return mediaTypeMapper.mapOutputMediaType(MediaType.valueOf(responseMimeType),
                                                      getHttpHeaders());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy