001/*
002 * (C) Copyright 2006-2011 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 *     bstefanescu
018 */
019package org.nuxeo.ecm.webengine.jaxrs.context;
020
021import java.security.Principal;
022import java.util.ArrayList;
023import java.util.HashMap;
024import java.util.List;
025
026import javax.servlet.ServletRequest;
027import javax.servlet.http.HttpServletRequest;
028import javax.servlet.http.HttpServletResponse;
029
030/**
031 * An HTTP request context
032 *
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public class RequestContext extends HashMap<String, Object> {
036
037    private static final long serialVersionUID = 1L;
038
039    private static final ThreadLocal<RequestContext> CTX = new ThreadLocal<RequestContext>();
040
041    public static RequestContext getActiveContext() {
042        return CTX.get();
043    }
044
045    public static RequestContext getActiveContext(ServletRequest request) {
046        return (RequestContext) request.getAttribute(RequestContext.class.getName());
047    }
048
049    protected HttpServletRequest request;
050
051    protected HttpServletResponse response;
052
053    protected List<RequestCleanupHandler> cleanupHandlers;
054
055    public RequestContext(HttpServletRequest request, HttpServletResponse response) {
056        this.request = request;
057        this.response = response;
058        this.cleanupHandlers = new ArrayList<RequestCleanupHandler>();
059        CTX.set(this);
060        request.setAttribute(RequestContext.class.getName(), this);
061    }
062
063    public HttpServletRequest getRequest() {
064        return request;
065    }
066
067    public HttpServletResponse getResponse() {
068        return response;
069    }
070
071    public Principal getUserPrincipal() {
072        return request.getUserPrincipal();
073    }
074
075    @SuppressWarnings("unchecked")
076    public <T> T get(String key, Class<T> type) {
077        Object o = get(key);
078        return (T) o;
079    }
080
081    public void addRequestCleanupHandler(RequestCleanupHandler handler) {
082        cleanupHandlers.add(handler);
083    }
084
085    public boolean removeCleanupHandler(RequestCleanupHandler handler) {
086        return cleanupHandlers.remove(handler);
087    }
088
089    public void dispose() {
090        request.removeAttribute(RequestContext.class.getName());
091        CTX.remove();
092        RuntimeException suppressed = null;
093        for (RequestCleanupHandler handler : cleanupHandlers) {
094            try {
095                handler.cleanup(request);
096            } catch (RuntimeException e) {
097                // allow other cleanup handlers to do their work
098                if (suppressed == null) {
099                    suppressed = new RuntimeException("Exceptions during cleanup");
100                }
101                suppressed.addSuppressed(e);
102            }
103        }
104        cleanupHandlers = null;
105        request = null;
106        response = null;
107        if (suppressed != null) {
108            throw suppressed;
109        }
110    }
111}