001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nicolas Chapurlat <nchapurlat@nuxeo.com>
018 */
019
020package org.nuxeo.ecm.webengine.jaxrs.coreiodelegate;
021
022import java.util.Enumeration;
023import java.util.Map;
024
025import javax.servlet.ServletRequest;
026import javax.servlet.http.HttpServletRequest;
027
028import org.nuxeo.ecm.core.api.CoreSession;
029import org.nuxeo.ecm.core.io.registry.context.RenderingContext;
030import org.nuxeo.ecm.core.io.registry.context.RenderingContext.CtxBuilder;
031import org.nuxeo.ecm.core.io.registry.context.RenderingContextImpl.RenderingContextBuilder;
032import org.nuxeo.ecm.webengine.jaxrs.session.SessionFactory;
033
034/**
035 * Utility class that get or create a {@link RenderingContext} from the current {@link HttpServletRequest}.
036 *
037 * @since 7.2
038 */
039public final class RenderingContextWebUtils {
040
041    private static final String CTX_KEY = "_STORED_GENERATED_RENDERING_CONTEXT";
042
043    public static final String REQUEST_KEY = "_STORED_GENERATED_HTTP_SERVLET_REQUEST";
044
045    private RenderingContextWebUtils() {
046    }
047
048    /**
049     * Get the current context in the current {@link HttpServletRequest} or create it from the current
050     * {@link HttpServletRequest}.
051     *
052     * @since 7.2
053     */
054    public static RenderingContext getContext(ServletRequest request) {
055        // try to get an existing RenderingContext from the request
056        Object stored = request.getAttribute(getContextKey());
057        if (stored != null) {
058            return (RenderingContext) stored;
059        }
060        RenderingContextBuilder builder = CtxBuilder.builder();
061        fillContext(builder, request);
062        RenderingContext ctx = builder.get();
063        registerContext(request, ctx);
064        return ctx;
065    }
066
067    /**
068     * Register the given context as the context to use to manage the marshalling.
069     *
070     * @param request The current request.
071     * @param ctx The context to register.
072     * @since 7.10
073     */
074    public static void registerContext(ServletRequest request, RenderingContext ctx) {
075        request.setAttribute(getContextKey(), ctx);
076    }
077
078    /**
079     * Return the key used to store the context in the request.
080     *
081     * @since 7.10
082     */
083    public static String getContextKey() {
084        return CTX_KEY;
085    }
086
087    /**
088     * Create an {@link RenderingContextBuilder}, fill it with the current {@link HttpServletRequest} and return it.
089     *
090     * @since 7.2
091     */
092    public static RenderingContextBuilder getBuilder(ServletRequest request) {
093        RenderingContextBuilder builder = CtxBuilder.builder();
094        fillContext(builder, request);
095        return builder;
096    }
097
098    /**
099     * Fill an existing with the current {@link HttpServletRequest}.
100     *
101     * @since 7.2
102     */
103    public static RenderingContextBuilder fillContext(RenderingContextBuilder builder, ServletRequest request) {
104        // create a context builder and put base url, session and request
105        builder.param(REQUEST_KEY, request);
106        // for web context, put the base url, the session and the headers
107        if (request instanceof HttpServletRequest) {
108            HttpServletRequest webRequest = (HttpServletRequest) request;
109            // base url
110            @SuppressWarnings("deprecation")
111            String baseURL = VirtualHostHelper.getBaseURL(webRequest);
112            // current session
113            CoreSession session = SessionFactory.getSession(webRequest);
114            builder.base(baseURL).session(session);
115            // headers
116            Enumeration<String> headerNames = webRequest.getHeaderNames();
117            while (headerNames.hasMoreElements()) {
118                String headerName = headerNames.nextElement();
119                Enumeration<String> headerValues = webRequest.getHeaders(headerName);
120                while (headerValues.hasMoreElements()) {
121                    builder.param(headerName, headerValues.nextElement());
122                }
123            }
124        }
125        // parameters
126        for (Map.Entry<String, String[]> parameter : request.getParameterMap().entrySet()) {
127            builder.paramValues(parameter.getKey(), (Object[]) parameter.getValue());
128        }
129        // attributes
130        Enumeration<String> attributeNames = request.getAttributeNames();
131        while (attributeNames.hasMoreElements()) {
132            String attributeName = attributeNames.nextElement();
133            Object attributeValue = request.getAttribute(attributeName);
134            builder.param(attributeName, attributeValue);
135        }
136        return builder;
137    }
138
139}