org.nuxeo.ecm.webengine.session.UserSession.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.webengine.session.UserSession.java

Source

/*
 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *     bstefanescu
 *
 * $Id$
 */

package org.nuxeo.ecm.webengine.session;

import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.webengine.jaxrs.context.RequestCleanupHandler;
import org.nuxeo.ecm.webengine.jaxrs.context.RequestContext;
import org.nuxeo.ecm.webengine.jaxrs.session.SessionFactory;

/**
 * Used to store user session. This object is cached in a the HTTP session
 * Principal, subject and credentials are immutable per user session
 *
 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
 *
 */
// TODO: should be synchronized? concurrent access may happen for the same
// session
public final class UserSession extends HashMap<String, Object> {

    private static final long serialVersionUID = 260562970988817064L;

    protected static final Log log = LogFactory.getLog(UserSession.class);

    protected Map<Class<?>, ComponentMap<?>> comps = new HashMap<Class<?>, ComponentMap<?>>();

    protected HttpServletRequest request;

    protected UserSession(HttpServletRequest request) {
        this.request = request;
    }

    public static UserSession getCurrentSession(HttpServletRequest request) {
        String key = UserSession.class.getName();
        HttpSession session = request.getSession(false);
        UserSession us = null;
        if (session != null) {
            us = (UserSession) session.getAttribute(key);
        }
        if (us == null) {
            us = (UserSession) request.getAttribute(key);
        }
        if (us == null) {
            us = new UserSession(request);
            if (session != null) {
                session.setAttribute(key, us);
            } else {
                request.setAttribute(key, us);
            }
        }
        return us;
    }

    /**
     * Gets a core session.
     * <p>
     * If it does not already exist, it will be opened against the given
     * repository.
     *
     * @param repoName
     * @return the core session
     *
     * @deprecated use {@link SessionFactory#getSession(HttpServletRequest, String)}
     */
    public CoreSession getCoreSession(String repoName) {
        try {
            return SessionFactory.getSession(request, repoName);
        } catch (Exception e) {
            log.error("Failed to open core session for repository: " + repoName, e);
            return null;
        }
    }

    /**
     * Gets a core session.
     * <p>
     * If not already opened, opens a new core session against the default
     * repository.
     *
     * @deprecated use {@link SessionFactory#getSession(HttpServletRequest)}
     */
    public CoreSession getCoreSession() {
        try {
            return SessionFactory.getSession(request);
        } catch (Exception e) {
            log.error("Failed to open core session for default repository", e);
            return null;
        }
    }

    public Principal getPrincipal() {
        return request.getUserPrincipal();
    }

    /**
     * Register a cleanup handler that will be invoked when HTTP request
     * terminate. This method is not thread safe.
     */
    public static void addRequestCleanupHandler(HttpServletRequest request, RequestCleanupHandler handler) {
        RequestContext.getActiveContext(request).addRequestCleanupHandler(handler);
    }

    /**
     * Finds an existing component.
     * <p>
     * The component state will not be modified before being returned as in
     * {@link #getComponent(Class, String)}.
     * <p>
     * If the component was not found in that session, returns null.
     */
    @SuppressWarnings("unchecked")
    public synchronized <T extends Component> T findComponent(Class<T> type, String name) {
        ComponentMap<T> map = (ComponentMap<T>) comps.get(type);
        if (map == null) {
            return null;
        }
        if (name == null) {
            return map.getComponent();
        } else {
            return type.cast(map.get(name));
        }
    }

    /**
     * Gets a component given its class and an optional name.
     * <p>
     * If the component was not yet created in this session, it will be created
     * and registered against the session.
     */
    @SuppressWarnings("unchecked")
    public synchronized <T extends Component> T getComponent(Class<T> type, String name) throws SessionException {
        ComponentMap<T> map = (ComponentMap<T>) comps.get(type);
        T comp;
        if (map == null) {
            map = new ComponentMap<T>();
            comps.put(type, map);
        } else {
            if (name == null) {
                comp = map.getComponent();
            } else {
                comp = type.cast(map.get(name));
            }
            if (comp != null) {
                return comp;
            }
        }
        // component not found
        try {
            comp = type.newInstance();
        } catch (Exception e) {
            throw new SessionException("Failed to instantiate component: " + type, e);
        }
        comp.initialize(this, name);
        if (name == null) {
            map.setComponent(comp);
        } else {
            map.put(name, comp);
        }
        return type.cast(comp);
    }

    public <T extends Component> T getComponent(Class<T> type) throws SessionException {
        return getComponent(type, null);
    }

    @SuppressWarnings("unchecked")
    public <T extends Component> T getComponent(String typeName, String name) throws SessionException {
        try {
            Class<T> type = (Class<T>) Class.forName(typeName);
            return getComponent(type, name);
        } catch (ClassNotFoundException e) {
            throw new SessionException("Could not find component class: " + typeName, e);
        }
    }

    /**
     * Gets component by ID.
     * <p>
     * The ID is of the form <code>type#name</code> for non-null names and
     * <code>type</code> for null names.
     */
    @SuppressWarnings("unchecked")
    public <T extends Component> T getComponent(String id) throws SessionException {
        int p = id.lastIndexOf('#');
        if (p > -1) {
            return (T) getComponent(id.substring(0, p), id.substring(p + 1));
        } else {
            return (T) getComponent(id, null);
        }
    }

}