/* * Copyright 2000-2002,2004 The Apache Software Foundation. * * Licensed 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 package org.apache.jetspeed.services.statemanager; // imports import java.io.Serializable; import java.util.Enumeration; import java.util.Map; import java.util.Vector; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; /** * <p> * JetspeedHttpStateManagerService is an implementation of the * BaseStateManagerService which manages the states stored in the "current" * HttpSession. * </p> * <p> * Note: This implementation of the StateManagerService takes advantage of the * Servlet container's management of the HttpSession. When the session is * invalidated, the states we manage will be automatically cleaned up. When this * happens, the objects placed into our states will have their * SessionStateBindingListener mechanism invoked. * </p> * <p> * Note: This implementation segments the states by session. States created in * one session will NOT BE AVAILABLE from other sessions. * </p> * * @version $Revision: 1.4 $ * @see org.apache.jetspeed.services.statemanager.BaseStateManagerService * @see org.apache.jetspeed.services.statemanager.StateManagerService * @see org.apache.jetspeed.services.statemanager.SessionState * @author <a href="mailto:ggolden@apache.org">Glenn R. Golden</a> */ public class JetspeedHttpStateManagerService extends BaseStateManagerService implements Serializable { private static final long serialVersionUID = 6138392597252459984L; /** * Initialize the states storage. */ @Override protected void initStates() { } // initStates /** * Cleanup the states storage. */ @Override protected void shutdownStates() { } // shutdownStates /** * Access the current HttpSession. */ private HttpSession getSession() { // get the current session that was installed for this thread HttpSession session = (HttpSession) m_httpSessions.get(Thread.currentThread()); if (session == null) { return null; } // call isNew just to see if the session has been invalidated already try { session.isNew(); } catch (IllegalStateException e) { return null; } return session; } // getSession /** * Convert the key to a name safe to store directly in the session. * * @param key * The state key. * @return a name safe to store directly in the session based on key. */ private String getSessionKey(String key) { // we want our keys not to conflict with any other session usage... return JetspeedHttpStateManagerService.class.getName() + "." + key; } // getSessionKey /** * Access the Map which is the set of attributes for a state. * * @param key * The state key. * @return The Map which is the set of attributes for a state. */ @Override protected Map getState(String key) { // get the session HttpSession session = getSession(); if (session == null) { return null; } // get this state from our entry in the session StateEntry stateEntry = (StateEntry) session.getAttribute(getSessionKey(key)); if (stateEntry == null) { return null; } return stateEntry.getMap(); } // getState /** * Add a new state to the states we are managing. * * @param key * The state key. * @param state * The Map which is the set of attributes for the state. */ @Override protected void addState(String key, Map state) { // get the session HttpSession session = getSession(); if (session == null) { return; } // create a stateEntry to hold our state Map StateEntry stateEntry = new StateEntry(key, state); // put it in the session session.setAttribute(getSessionKey(key), stateEntry); } // addState /** * Remove a state from the states we are managing. * * @param key * The state key. */ @Override protected void removeState(String key) { // get the session HttpSession session = getSession(); if (session == null) { return; } // remove the key from the session - the StateEntry will be notified session.removeAttribute(getSessionKey(key)); } // removeState /** * Access an array of the keys of all states managed, those that start with * the parameter. * * @param start * The starting string used to select the keys. * @return an array of the keys of all states managed. */ @Override protected String[] getStateKeys(String start) { // get the session HttpSession session = getSession(); if (session == null) { return null; } // use this as the test pattern String pattern = getSessionKey(start); // for those that match, this starts the session key int subStart = getSessionKey("").length(); // collect for return Vector rv = new Vector(); // get the session names Enumeration names = session.getAttributeNames(); while (names.hasMoreElements()) { String sessionName = (String) names.nextElement(); // pick our states, and those whose key starts with the pattern if (sessionName.startsWith(pattern)) { rv.add(sessionName.substring(subStart)); } } if (rv.size() == 0) { return null; } return (String[]) rv.toArray(new String[rv.size()]); } // getStateKeys /** * Store the Map for the state, and listen for HttpSessionBinding events */ private class StateEntry implements HttpSessionBindingListener, Serializable { private static final long serialVersionUID = 8630600178442354718L; /** Store the map. */ private Map m_map = null; /** The state key. */ private String m_key = null; /** * Construct. s * * @param key * The state key. * @param map * The map to hold. */ public StateEntry(String key, Map map) { m_key = key; m_map = map; } // StateEntry /** * Access the map we are holding. * * @return the Map we are holding. */ public Map getMap() { return m_map; } // getMap /** * We don't care about when we are bound... */ @Override public void valueBound(HttpSessionBindingEvent event) { } /** * When we are unbound, unbind our state's (map's) attributes */ @Override public void valueUnbound(HttpSessionBindingEvent event) { // notify all attribute and clear the state retireAttributes(m_key, m_map); m_map = null; m_key = null; } } // class StateEntry } // JetspeedHttpStateManagerService /********************************************************************************** * * $Header: * /home/cvspublic/jakarta-jetspeed/src/java/org/apache/jetspeed/services * /statemanager/JetspeedHttpStateManagerService.java,v 1.4 2004/02/23 03:38:28 * jford Exp $ * **********************************************************************************/