You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by gg...@apache.org on 2002/06/10 21:57:18 UTC

cvs commit: jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager BaseStateManagerService.java JetspeedHttpStateManagerService.java JetspeedStateManagerService.java

ggolden     2002/06/10 12:57:18

  Modified:    src/java/org/apache/jetspeed/services/statemanager
                        JetspeedStateManagerService.java
  Added:       src/java/org/apache/jetspeed/services/statemanager
                        BaseStateManagerService.java
                        JetspeedHttpStateManagerService.java
  Log:
  Introducing the BaseStateManagerService, an abstract implementation
  of the StateManagerService.  JetspeedStateManagerService re-organized
  to extend this.
  
  Introducing JetspeedHttpStateManagerService, an implementation of the
  StateManagerService which stores attribute sets (for each session state)
  in the actual HTTP Session, and has automatic cleanup of attributes when
  the session invalidates.
  
  Revision  Changes    Path
  1.5       +54 -268   jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java
  
  Index: JetspeedStateManagerService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- JetspeedStateManagerService.java	17 May 2002 18:37:46 -0000	1.4
  +++ JetspeedStateManagerService.java	10 Jun 2002 19:57:18 -0000	1.5
  @@ -1,6 +1,6 @@
   /**********************************************************************************
   *
  -* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.4 2002/05/17 18:37:46 ggolden Exp $
  +* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.5 2002/06/10 19:57:18 ggolden Exp $
   *
   * ====================================================================
    * The Apache Software License, Version 1.1
  @@ -60,339 +60,125 @@
   package org.apache.jetspeed.services.statemanager;
   
   // imports
  -import java.util.Iterator;
   import java.util.HashMap;
   import java.util.Map;
  -import java.util.Set;
   import java.util.Collections;
  +import java.util.Iterator;
   import java.util.Vector;
  -import javax.servlet.ServletConfig;
  +import java.util.Set;
   
  -import org.apache.jetspeed.services.statemanager.StateManagerService;
  -import org.apache.jetspeed.services.statemanager.SessionStateBindingListener;
  -import org.apache.turbine.services.TurbineBaseService;
  -import org.apache.turbine.services.InitializationException;
  -import org.apache.turbine.util.RunData;
  -import org.apache.turbine.util.Log;
  +import org.apache.jetspeed.services.statemanager.BaseStateManagerService;
   
   /**
  -* <p>JetspeedStateManagerService is a Turbine Service implementation of the
  -* StateManagerService.</p>
  -* <p>SessionState is stored in a HashMap, keyed by state key.  In the HashMap, each
  -* SessionState has another HashMap, storing the names and values of the state info. </p>
  -* <p>See the proposal: jakarta-jetspeed/proposals/StateManager.txt for more details.</p>
  -* @version $Revision: 1.4 $
  +* <p>JetspeedStateManagerService is an implementation of the BaseStateManagerService
  +* which manages the states stored in a local Map (synchronized HashMap).</p>
  +* <p>Note: This implementation of the StateManagerService is independent of all other
  +* services; but it has no automatic way to retire no longer used state.  If the
  +* application does not explicitly retire the states created, they will hang around
  +* forever. (see clear() and retireState() of the StateManagerService).</p>
  +* @version $Revision: 1.5 $
  +* @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>
  -* @todo attach to the HTTP session somehow to auto-retire when the session expires
   */
   public class JetspeedStateManagerService
  -    extends TurbineBaseService
  -    implements StateManagerService
  +    extends BaseStateManagerService
   {
       /** Store each set of state parameters by state key
           (each is a HashMap keyed by parameter name) */
       private Map m_states = null;
   
       /**
  -    * Performs early initialization.
  -    *
  -    * @param config A ServletConfing to use for initialization
  -    * activities.
  -    * @exception InitializationException, if initialization of this
  -    * class was not successful.
  -    */
  -    public void init( ServletConfig config )
  -        throws InitializationException
  -    {
  -        super.init(config);
  -
  -    }   // init
  -
  -    /**
  -    * Performs early initialization.
  -    *
  -    * @param data An RunData to use for initialization activities.
  -    * @exception InitializationException, if initialization of this
  -    * class was not successful.
  +    * Initialize the states storage.
       */
  -    public void init( RunData data )
  -        throws InitializationException
  +    protected void initStates()
       {
  -        super.init(data);
  -
  -    }   // init
  -
  -    /**
  -    * Performs late initialization.
  -    *
  -    * If your class relies on early initialization, and the object it
  -    * expects was not received, you can use late initialization to
  -    * throw an exception and complain.
  -    *
  -    * @exception InitializationException, if initialization of this
  -    * class was not successful.
  -    */
  -    public void init()
  -        throws InitializationException
  -    {
  -        super.init();
  -
           // create our states map synchronized
           m_states = Collections.synchronizedMap(new HashMap());
   
  -    }   // init
  +    }   // initStates
   
       /**
  -    * Returns to uninitialized state.
  -    *
  -    * You can use this method to release resources thet your Service
  -    * allocated when Turbine shuts down.
  +    * Cleanup the states storage.
       */
  -    public void shutdown()
  +    protected void shutdownStates()
       {
           m_states.clear();
           m_states = null;
   
  -        super.shutdown();
  -
  -    }   // shutdown
  +    }   // shutdownStates
   
       /**
  -    * Access the named attribute of the keyed state.
  +    * Access the Map which is the set of attributes for a state.
       * @param key The state key.
  -    * @param name The attribute name.
  -    * @return The named attribute value of the keyed state.
  +    * @return The Map which is the set of attributes for a state.
       */
  -    public Object getAttribute ( String key, String name )
  +    protected Map getState( String key )
       {
  -        Map state = (Map) m_states.get(key);
  -        if (state == null) return null;
  -        return state.get(name);
  +        return (Map) m_states.get(key);
   
  -    }   // getAttribute
  +    }   // getState
   
       /**
  -    * Set the named state attribute of the keyed state with the provided object.
  +    * Add a new state to the states we are managing.
       * @param key The state key.
  -    * @param name The attribute name.
  -    * @param value The new value of the attribute (any object type).
  +    * @param state The Map which is the set of attributes for the state.
       */
  -    public void setAttribute( String key, String name, Object value )
  +    protected void addState( String key, Map state )
       {
  -        Map state = (Map) m_states.get(key);
  -        if (state == null)
  -        {
  -            // create a synchronized map to store the state attributes
  -            state = Collections.synchronizedMap(new HashMap());
  -            m_states.put(key, state);
  -        }
  +        m_states.put(key, state);
   
  -        state.put(name, value);
  -
  -    }   // setAttribute
  +    }   // addState
   
       /**
  -    * Remove the named state attribute of the keyed state, if it exists.
  +    * Remove a state from the states we are managing.
       * @param key The state key.
  -    * @param name The attribute name.
       */
  -    public void removeAttribute( String key, String name )
  +    protected void removeState( String key )
       {
  -        Map state = (Map) m_states.get(key);
  -        if (state == null) return;
  -        state.remove(name);
  +        m_states.remove(key);
   
  -    }   // removeAttribute
  +    }   // removeState
   
       /**
  -    * Remove all state attribute of the keyed state.
  -    * @param key The state key.
  +    * 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.
       */
  -    public void clear( String key )
  +    protected String[] getStateKeys( String start )
       {
  -        Map state = (Map) m_states.get(key);
  -        if (state != null)
  +        // collect for return
  +        Vector rv = new Vector();
  +
  +        // get the entire set of keys to iterate over
  +        Set allStateKeys = m_states.keySet();
  +        synchronized (m_states)
           {
  -            Set attributes = state.entrySet();
  -            synchronized (state)
  +            Iterator i = allStateKeys.iterator();
  +            while (i.hasNext())
               {
  -                Iterator i = attributes.iterator();
  -                while (i.hasNext())
  +                String key = (String) i.next();
  +                
  +                // if this matches our pattern
  +                if (key.startsWith(start))
                   {
  -                    Map.Entry attribute = (Map.Entry) i.next();
  -
  -                    // if this object wants session binding notification
  -                    if (attribute.getValue() instanceof SessionStateBindingListener)
  -                    {
  -                        try
  -                        {
  -                            ((SessionStateBindingListener)attribute.getValue())
  -                                .valueUnbound(key, (String)attribute.getKey());
  -                        }
  -                        catch (Throwable e) {Log.warn("JetspeedStateManagerService.clear: unbinding exception: ", e);}
  -                    }
  +                    rv.add(key);
                   }
               }
  -
  -            // remove all attributes
  -            state.clear();
  -            
  -            // and forget about it
  -            m_states.remove(key);
  -        }
  -
  -    }   // clear
  -
  -    /**
  -    * Access an array of all names of attributes stored in the keyed state.
  -    * @param key The state key.
  -    * @return An array of all names of attributes stored in the keyed state.
  -    */
  -    public String[] getAttributeNames( String key )
  -    {
  -        Map state = (Map) m_states.get(key);
  -        if (state == null) return null;
  -
  -        // process all the current keys, synchronized
  -        return (String[]) state.keySet().toArray(new String[state.size()]);
  -
  -    }   // getAttributeNames
  -
  -    /**
  -    * Access an SessionState object with the given key.
  -    * @param key The SessionState key.
  -    * @return an SessionState object with the given key.
  -    */
  -    public SessionState getSessionState( String key )
  -    {
  -        return new MySessionState(key, this);
  -
  -    }   // getSessionState
  -
  -    /**
  -    * Retire, forget about and clean up all states that start with the given key.
  -    * @param keyStart The beginning of the key of the states to clean up.
  -    */
  -    public synchronized void retireState( String keyStart )
  -    {
  -        // get the current state keys into an array
  -        String keys[] = (String[]) m_states.keySet().toArray(new String[m_states.size()]);
  -        
  -        // clear all those that begin with keyStart
  -        for (int i = 0; i < keys.length; i++)
  -        {
  -            if (keys[i].startsWith(keyStart))
  -            {
  -                clear(keys[i]);
  -            }
           }
   
  -    }   // retireState
  -
  -    /**
  -    * An SessionState implementation, as covers to this service, storing the key.
  -    */
  -    private class MySessionState
  -        implements SessionState
  -    {
  -        /** The state key. */
  -        private String m_key = null;
  -
  -        /** The JetspeedStateManagerService object. */
  -        private JetspeedStateManagerService m_service = null;
  -
  -        /**
  -        * Construct.
  -        * @param key The state key.
  -        * @param service The JetspeedStateManagerService instance.
  -        */
  -        public MySessionState( String key,
  -                                JetspeedStateManagerService service)
  -        {
  -            m_key = key;
  -            m_service = service;
  -
  -        }   // MySessionState
  -
  -        /**
  -        * Access the named attribute.
  -        * @param name The attribute name.
  -        * @return The named attribute value.
  -        */
  -        public Object getAttribute( String name )
  -        {
  -            return m_service.getAttribute(m_key, name);
  -
  -        }   // getAttribute
  -
  -        /**
  -        * Set the named attribute value to the provided object.
  -        * @param name The attribute name.
  -        * @param value The value of the attribute (any object type).
  -        */
  -        public void setAttribute( String name, Object value )
  -        {
  -            m_service.setAttribute(m_key, name, value);
  -
  -        }   // setAttribute
  -
  -        /**
  -        * Remove the named attribute, if it exists.
  -        * @param name The attribute name.
  -        */
  -        public void removeAttribute( String name )
  -        {
  -            m_service.removeAttribute(m_key, name);
  -
  -        }   // removeAttribute
  -
  -        /**
  -        * Remove all attributes.
  -        */
  -        public void clear()
  -        {
  -            m_service.clear(m_key);
  -
  -        }   // clear
  -
  -        /**
  -        * Access an array of all names of attributes stored in the SessionState.
  -        * @return An array of all names of attribute stored in the SessionState.
  -        */
  -        public String[] getAttributeNames()
  -        {
  -            return m_service.getAttributeNames(m_key);
  -
  -        }   // getAttributeNames
  -
  -        /**
  -        * Access the full unique StateManager key for the SessionState.
  -        * @return the full unique StateManager key for the SessionState.
  -        */
  -        public String getKey()
  -        {
  -            return m_key;
  -
  -        }   // getKey
  -
  -        /**
  -        * Retire, forget about and clean up this state.
  -        */
  -        public void retire()
  -        {
  -            m_service.retireState(m_key);
  +        if (rv.size() == 0) return null;
   
  -        }   // retire
  +        return (String[]) rv.toArray(new String[rv.size()]);
   
  -    }   // class MySessionState
  +    }   // getStateKeys
   
   }   // JetspeedStateManagerService
   
   /**********************************************************************************
   *
  -* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.4 2002/05/17 18:37:46 ggolden Exp $
  +* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.5 2002/06/10 19:57:18 ggolden Exp $
   *
   **********************************************************************************/
   
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/BaseStateManagerService.java
  
  Index: BaseStateManagerService.java
  ===================================================================
  /**********************************************************************************
  *
  * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/BaseStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
  *
  * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  // package
  package org.apache.jetspeed.services.statemanager;
  
  // imports
  import java.util.Iterator;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Set;
  import java.util.Collections;
  import java.util.Vector;
  import javax.servlet.ServletConfig;
  
  import org.apache.jetspeed.services.statemanager.StateManagerService;
  import org.apache.jetspeed.services.statemanager.SessionStateBindingListener;
  import org.apache.turbine.services.TurbineBaseService;
  import org.apache.turbine.services.InitializationException;
  import org.apache.turbine.util.RunData;
  import org.apache.turbine.util.Log;
  
  /**
  * <p>BaseStateManagerService is a Turbine Service implementation of the
  * StateManagerService.</p>
  * <p>Each SessionState is stored in a Map, storing the names and values
  * of the state attributes.</p>
  * <p>The set of states managed is stored in some specific way by extension classes.</p>
  * <p>See the proposal: jakarta-jetspeed/proposals/StateManager.txt for more details.</p>
  * @version $Revision: 1.1 $
  * @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 abstract class BaseStateManagerService
      extends TurbineBaseService
      implements StateManagerService
  {
      /*******************************************************************************
      * Abstract methods
      *******************************************************************************/
  
      /**
      * Initialize the states storage.
      */
      protected abstract void initStates();
  
      /**
      * Cleanup the states storage.
      */
      protected abstract void shutdownStates();
  
      /**
      * 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.
      */
      protected abstract Map getState( String key );
  
      /**
      * 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.
      */
      protected abstract void addState( String key, Map state );
  
      /**
      * Remove a state from the states we are managing.
      * @param key The state key.
      */
      protected abstract void removeState( String key );
  
      /**
      * 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.
      */
      protected abstract String[] getStateKeys( String start );
  
      /**
      * retire the attributes of the state.
      * @param key The state key.
      * @param state The Map of attributes to retire.
      */
      protected void retireAttributes( String key, Map state )
      {
          if (state == null) return;
  
          Set attributes = state.entrySet();
          synchronized (state)
          {
              Iterator i = attributes.iterator();
              while (i.hasNext())
              {
                  Map.Entry attribute = (Map.Entry) i.next();
                  unBindAttributeValue(key, (String)attribute.getKey(), attribute.getValue());
              }
          }
  
          // remove all attributes
          state.clear();
  
      }   // retireAttributes
  
      /**
      * If the object is a SessionStateBindingListener, unbind it
      * @param stateKey The state key.
      * @param attributeName The attribute name.
      * @param attribute The attribute object
      */
      protected void unBindAttributeValue( String stateKey, String attributeName, Object attribute )
      {
          // if this object wants session binding notification
          if ((attribute != null) && (attribute instanceof SessionStateBindingListener))
          {
              try
              {
                  ((SessionStateBindingListener)attribute)
                      .valueUnbound(stateKey, attributeName);
              }
              catch (Throwable e) {Log.warn("JetspeedStateManagerService.unBindAttributeValue: unbinding exception: ", e);}
          }
  
      }   // unBindAttributeValue
  
      /**
      * If the object is a SessionStateBindingListener, bind it
      * @param stateKey The state key.
      * @param attributeName The attribute name.
      * @param attribute The attribute object
      */
      protected void bindAttributeValue( String stateKey, String attributeName, Object attribute )
      {
          // if this object wants session binding notification
          if ((attribute != null) && (attribute instanceof SessionStateBindingListener))
          {
              try
              {
                  ((SessionStateBindingListener)attribute)
                      .valueBound(stateKey, attributeName);
              }
              catch (Throwable e) {Log.warn("JetspeedStateManagerService.bindAttributeValue: unbinding exception: ", e);}
          }
  
      }   // bindAttributeValue
  
      /*******************************************************************************
      * Service implementation
      *******************************************************************************/
  
      /**
      * Performs early initialization.
      *
      * @param config A ServletConfing to use for initialization
      * activities.
      * @exception InitializationException, if initialization of this
      * class was not successful.
      */
      public void init( ServletConfig config )
          throws InitializationException
      {
          super.init(config);
  
      }   // init
  
      /**
      * Performs early initialization.
      *
      * @param data An RunData to use for initialization activities.
      * @exception InitializationException, if initialization of this
      * class was not successful.
      */
      public void init( RunData data )
          throws InitializationException
      {
          super.init(data);
  
      }   // init
  
      /**
      * Performs late initialization.
      *
      * If your class relies on early initialization, and the object it
      * expects was not received, you can use late initialization to
      * throw an exception and complain.
      *
      * @exception InitializationException, if initialization of this
      * class was not successful.
      */
      public void init()
          throws InitializationException
      {
          super.init();
  
          // create our states storage
          initStates();
  
      }   // init
  
      /**
      * Returns to uninitialized state.
      *
      * You can use this method to release resources thet your Service
      * allocated when Turbine shuts down.
      */
      public void shutdown()
      {
          shutdownStates();
          super.shutdown();
  
      }   // shutdown
  
      /*******************************************************************************
      * StateManagerService implementation
      *******************************************************************************/
  
      /**
      * Access the named attribute of the keyed state.
      * @param key The state key.
      * @param name The attribute name.
      * @return The named attribute value of the keyed state.
      */
      public Object getAttribute ( String key, String name )
      {
          Map state = getState(key);
          if (state == null) return null;
          return state.get(name);
  
      }   // getAttribute
  
      /**
      * Set the named state attribute of the keyed state with the provided object.
      * @param key The state key.
      * @param name The attribute name.
      * @param value The new value of the attribute (any object type).
      */
      public void setAttribute( String key, String name, Object value )
      {
          Map state = getState(key);
          if (state == null)
          {
              // create a synchronized map to store the state attributes
              state = Collections.synchronizedMap(new HashMap());
              addState(key, state);
          }
  
          // get the old, if any
          Object old = getAttribute(key, name);
          
          // store the new
          state.put(name, value);
  
          // if there was an old value, unbind it
          if (old != null)
          {
              unBindAttributeValue(key, name, old);
          }
  
          // bind the new
          bindAttributeValue(key, name, value);
  
      }   // setAttribute
  
      /**
      * Remove the named state attribute of the keyed state, if it exists.
      * @param key The state key.
      * @param name The attribute name.
      */
      public void removeAttribute( String key, String name )
      {
          Map state = getState(key);
          if (state == null) return;
  
          // get the old, if any
          Object old = getAttribute(key, name);
  
          // remove
          state.remove(name);
          
          // if the state is now empty, remove it
          if (state.isEmpty())
          {
              removeState(key);
          }
  
          // if there was an old value, unbind it
          if (old != null)
          {
              unBindAttributeValue(key, name, old);
          }
  
      }   // removeAttribute
  
      /**
      * Remove all state attribute of the keyed state.
      * @param key The state key.
      */
      public void clear( String key )
      {
          Map state = getState(key);
          if (state == null) return;
  
          // notify all attribute and clear the state
          retireAttributes(key, state);
          
          // and forget about it
          removeState(key);
  
      }   // clear
  
      /**
      * Access an array of all names of attributes stored in the keyed state.
      * @param key The state key.
      * @return An array of all names of attributes stored in the keyed state.
      */
      public String[] getAttributeNames( String key )
      {
          Map state = (Map) getState(key);
          if (state == null) return null;
          if (state.size() == 0) return null;
  
          // put the names into an array for return
          return (String[]) state.keySet().toArray(new String[state.size()]);
  
      }   // getAttributeNames
  
      /**
      * Access an SessionState object with the given key.
      * @param key The SessionState key.
      * @return an SessionState object with the given key.
      */
      public SessionState getSessionState( String key )
      {
          return new MySessionState(key, this);
  
      }   // getSessionState
  
      /**
      * Retire, forget about and clean up all states that start with the given key.
      * @param keyStart The beginning of the key of the states to clean up.
      */
      public synchronized void retireState( String keyStart )
      {
          // get the current state keys into an array
          String keys[] = getStateKeys(keyStart);
          if (keys == null) return;
          
          // clear them
          for (int i = 0; i < keys.length; i++)
          {
              clear(keys[i]);
          }
  
      }   // retireState
  
      /*******************************************************************************
      * SessionState implementation
      *******************************************************************************/
  
      /**
      * A SessionState implementation, as covers to this service, storing the key.
      */
      private class MySessionState
          implements SessionState
      {
          /** The state key. */
          private String m_key = null;
  
          /** The StateManagerService object. */
          private BaseStateManagerService m_service = null;
  
          /**
          * Construct.
          * @param key The state key.
          * @param service The JetspeedStateManagerService instance.
          */
          public MySessionState( String key,
                                  BaseStateManagerService service)
          {
              m_key = key;
              m_service = service;
  
          }   // MySessionState
  
          /**
          * Access the named attribute.
          * @param name The attribute name.
          * @return The named attribute value.
          */
          public Object getAttribute( String name )
          {
              return m_service.getAttribute(m_key, name);
  
          }   // getAttribute
  
          /**
          * Set the named attribute value to the provided object.
          * @param name The attribute name.
          * @param value The value of the attribute (any object type).
          */
          public void setAttribute( String name, Object value )
          {
              m_service.setAttribute(m_key, name, value);
  
          }   // setAttribute
  
          /**
          * Remove the named attribute, if it exists.
          * @param name The attribute name.
          */
          public void removeAttribute( String name )
          {
              m_service.removeAttribute(m_key, name);
  
          }   // removeAttribute
  
          /**
          * Remove all attributes.
          */
          public void clear()
          {
              m_service.clear(m_key);
  
          }   // clear
  
          /**
          * Access an array of all names of attributes stored in the SessionState.
          * @return An array of all names of attribute stored in the SessionState.
          */
          public String[] getAttributeNames()
          {
              return m_service.getAttributeNames(m_key);
  
          }   // getAttributeNames
  
          /**
          * Access the full unique StateManager key for the SessionState.
          * @return the full unique StateManager key for the SessionState.
          */
          public String getKey()
          {
              return m_key;
  
          }   // getKey
  
          /**
          * Retire, forget about and clean up this state.
          */
          public void retire()
          {
              m_service.retireState(m_key);
  
          }   // retire
  
      }   // class MySessionState
  
  }   // BaseStateManagerService
  
  /**********************************************************************************
  *
  * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/BaseStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
  *
  **********************************************************************************/
  
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java
  
  Index: JetspeedHttpStateManagerService.java
  ===================================================================
  /**********************************************************************************
  *
  * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
  *
  * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  // package
  package org.apache.jetspeed.services.statemanager;
  
  // imports
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Collections;
  import java.util.Vector;
  import java.util.Enumeration;
  
  import javax.servlet.http.HttpSession;
  import javax.servlet.http.HttpSessionBindingListener;
  import javax.servlet.http.HttpSessionBindingEvent;
  
  import org.apache.turbine.services.rundata.RunDataService;
  import org.apache.turbine.services.TurbineServices;
  
  import org.apache.jetspeed.services.statemanager.BaseStateManagerService;
  import org.apache.jetspeed.services.rundata.JetspeedRunDataService;
  import org.apache.jetspeed.services.rundata.JetspeedRunData;
  
  /**
  * <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 is dependent on the JetspeedRunDataService,
  * but it 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.1 $
  * @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
  {
      /** The JetspeedRunData Service. */
      private JetspeedRunDataService runDataService = null;
  
      /**
      * Initialize the states storage.
      */
      protected void initStates()
      {
          // get the runData service
          this.runDataService =
              (JetspeedRunDataService)TurbineServices.getInstance()
                  .getService(RunDataService.SERVICE_NAME);
  
      }   // initStates
  
      /**
      * Cleanup the states storage.
      */
      protected void shutdownStates()
      {
          // Note: this is called out of any specific request thread, so we
          //      do not have any access to sessions... let the Servlet Container
          //      clean up the stuff in the sessions.
          this.runDataService = null;
  
      }   // shutdownStates
  
      /**
      * Access the current HttpSession.
      */
      private HttpSession getSession()
      {
          if (runDataService == null) return null;
  
          JetspeedRunData rundata = runDataService.getCurrentRunData();
          if (rundata == null) return null;
          
          HttpSession session = rundata.getSession();
          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.
      */
      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.
      */
      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.
      */
      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.
      */
      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
      {
          /** Store the map. */
          private Map m_map = null;
          
          /** The state key. */
          private String m_key = null;
  
          /**
          * Construct.
          * @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...
          */
          public void valueBound( HttpSessionBindingEvent event ) {}
  
          /**
          * When we are unbound, unbind our state's (map's) attributes
          */
          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/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
  *
  **********************************************************************************/
  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager BaseStateManagerService.java JetspeedHttpStateManagerService.java JetspeedStateManagerService.java

Posted by Paul Spencer <pa...@apache.org>.
Glenn,
I did not see a test case.

Paul Spencer

ggolden@apache.org wrote:

> ggolden     2002/06/10 12:57:18
> 
>   Modified:    src/java/org/apache/jetspeed/services/statemanager
>                         JetspeedStateManagerService.java
>   Added:       src/java/org/apache/jetspeed/services/statemanager
>                         BaseStateManagerService.java
>                         JetspeedHttpStateManagerService.java
>   Log:
>   Introducing the BaseStateManagerService, an abstract implementation
>   of the StateManagerService.  JetspeedStateManagerService re-organized
>   to extend this.
>   
>   Introducing JetspeedHttpStateManagerService, an implementation of the
>   StateManagerService which stores attribute sets (for each session state)
>   in the actual HTTP Session, and has automatic cleanup of attributes when
>   the session invalidates.
>   
>   Revision  Changes    Path
>   1.5       +54 -268   jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java
>   
>   Index: JetspeedStateManagerService.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v
>   retrieving revision 1.4
>   retrieving revision 1.5
>   diff -u -r1.4 -r1.5
>   --- JetspeedStateManagerService.java	17 May 2002 18:37:46 -0000	1.4
>   +++ JetspeedStateManagerService.java	10 Jun 2002 19:57:18 -0000	1.5
>   @@ -1,6 +1,6 @@
>    /**********************************************************************************
>    *
>   -* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.4 2002/05/17 18:37:46 ggolden Exp $
>   +* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.5 2002/06/10 19:57:18 ggolden Exp $
>    *
>    * ====================================================================
>     * The Apache Software License, Version 1.1
>   @@ -60,339 +60,125 @@
>    package org.apache.jetspeed.services.statemanager;
>    
>    // imports
>   -import java.util.Iterator;
>    import java.util.HashMap;
>    import java.util.Map;
>   -import java.util.Set;
>    import java.util.Collections;
>   +import java.util.Iterator;
>    import java.util.Vector;
>   -import javax.servlet.ServletConfig;
>   +import java.util.Set;
>    
>   -import org.apache.jetspeed.services.statemanager.StateManagerService;
>   -import org.apache.jetspeed.services.statemanager.SessionStateBindingListener;
>   -import org.apache.turbine.services.TurbineBaseService;
>   -import org.apache.turbine.services.InitializationException;
>   -import org.apache.turbine.util.RunData;
>   -import org.apache.turbine.util.Log;
>   +import org.apache.jetspeed.services.statemanager.BaseStateManagerService;
>    
>    /**
>   -* <p>JetspeedStateManagerService is a Turbine Service implementation of the
>   -* StateManagerService.</p>
>   -* <p>SessionState is stored in a HashMap, keyed by state key.  In the HashMap, each
>   -* SessionState has another HashMap, storing the names and values of the state info. </p>
>   -* <p>See the proposal: jakarta-jetspeed/proposals/StateManager.txt for more details.</p>
>   -* @version $Revision: 1.4 $
>   +* <p>JetspeedStateManagerService is an implementation of the BaseStateManagerService
>   +* which manages the states stored in a local Map (synchronized HashMap).</p>
>   +* <p>Note: This implementation of the StateManagerService is independent of all other
>   +* services; but it has no automatic way to retire no longer used state.  If the
>   +* application does not explicitly retire the states created, they will hang around
>   +* forever. (see clear() and retireState() of the StateManagerService).</p>
>   +* @version $Revision: 1.5 $
>   +* @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>
>   -* @todo attach to the HTTP session somehow to auto-retire when the session expires
>    */
>    public class JetspeedStateManagerService
>   -    extends TurbineBaseService
>   -    implements StateManagerService
>   +    extends BaseStateManagerService
>    {
>        /** Store each set of state parameters by state key
>            (each is a HashMap keyed by parameter name) */
>        private Map m_states = null;
>    
>        /**
>   -    * Performs early initialization.
>   -    *
>   -    * @param config A ServletConfing to use for initialization
>   -    * activities.
>   -    * @exception InitializationException, if initialization of this
>   -    * class was not successful.
>   -    */
>   -    public void init( ServletConfig config )
>   -        throws InitializationException
>   -    {
>   -        super.init(config);
>   -
>   -    }   // init
>   -
>   -    /**
>   -    * Performs early initialization.
>   -    *
>   -    * @param data An RunData to use for initialization activities.
>   -    * @exception InitializationException, if initialization of this
>   -    * class was not successful.
>   +    * Initialize the states storage.
>        */
>   -    public void init( RunData data )
>   -        throws InitializationException
>   +    protected void initStates()
>        {
>   -        super.init(data);
>   -
>   -    }   // init
>   -
>   -    /**
>   -    * Performs late initialization.
>   -    *
>   -    * If your class relies on early initialization, and the object it
>   -    * expects was not received, you can use late initialization to
>   -    * throw an exception and complain.
>   -    *
>   -    * @exception InitializationException, if initialization of this
>   -    * class was not successful.
>   -    */
>   -    public void init()
>   -        throws InitializationException
>   -    {
>   -        super.init();
>   -
>            // create our states map synchronized
>            m_states = Collections.synchronizedMap(new HashMap());
>    
>   -    }   // init
>   +    }   // initStates
>    
>        /**
>   -    * Returns to uninitialized state.
>   -    *
>   -    * You can use this method to release resources thet your Service
>   -    * allocated when Turbine shuts down.
>   +    * Cleanup the states storage.
>        */
>   -    public void shutdown()
>   +    protected void shutdownStates()
>        {
>            m_states.clear();
>            m_states = null;
>    
>   -        super.shutdown();
>   -
>   -    }   // shutdown
>   +    }   // shutdownStates
>    
>        /**
>   -    * Access the named attribute of the keyed state.
>   +    * Access the Map which is the set of attributes for a state.
>        * @param key The state key.
>   -    * @param name The attribute name.
>   -    * @return The named attribute value of the keyed state.
>   +    * @return The Map which is the set of attributes for a state.
>        */
>   -    public Object getAttribute ( String key, String name )
>   +    protected Map getState( String key )
>        {
>   -        Map state = (Map) m_states.get(key);
>   -        if (state == null) return null;
>   -        return state.get(name);
>   +        return (Map) m_states.get(key);
>    
>   -    }   // getAttribute
>   +    }   // getState
>    
>        /**
>   -    * Set the named state attribute of the keyed state with the provided object.
>   +    * Add a new state to the states we are managing.
>        * @param key The state key.
>   -    * @param name The attribute name.
>   -    * @param value The new value of the attribute (any object type).
>   +    * @param state The Map which is the set of attributes for the state.
>        */
>   -    public void setAttribute( String key, String name, Object value )
>   +    protected void addState( String key, Map state )
>        {
>   -        Map state = (Map) m_states.get(key);
>   -        if (state == null)
>   -        {
>   -            // create a synchronized map to store the state attributes
>   -            state = Collections.synchronizedMap(new HashMap());
>   -            m_states.put(key, state);
>   -        }
>   +        m_states.put(key, state);
>    
>   -        state.put(name, value);
>   -
>   -    }   // setAttribute
>   +    }   // addState
>    
>        /**
>   -    * Remove the named state attribute of the keyed state, if it exists.
>   +    * Remove a state from the states we are managing.
>        * @param key The state key.
>   -    * @param name The attribute name.
>        */
>   -    public void removeAttribute( String key, String name )
>   +    protected void removeState( String key )
>        {
>   -        Map state = (Map) m_states.get(key);
>   -        if (state == null) return;
>   -        state.remove(name);
>   +        m_states.remove(key);
>    
>   -    }   // removeAttribute
>   +    }   // removeState
>    
>        /**
>   -    * Remove all state attribute of the keyed state.
>   -    * @param key The state key.
>   +    * 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.
>        */
>   -    public void clear( String key )
>   +    protected String[] getStateKeys( String start )
>        {
>   -        Map state = (Map) m_states.get(key);
>   -        if (state != null)
>   +        // collect for return
>   +        Vector rv = new Vector();
>   +
>   +        // get the entire set of keys to iterate over
>   +        Set allStateKeys = m_states.keySet();
>   +        synchronized (m_states)
>            {
>   -            Set attributes = state.entrySet();
>   -            synchronized (state)
>   +            Iterator i = allStateKeys.iterator();
>   +            while (i.hasNext())
>                {
>   -                Iterator i = attributes.iterator();
>   -                while (i.hasNext())
>   +                String key = (String) i.next();
>   +                
>   +                // if this matches our pattern
>   +                if (key.startsWith(start))
>                    {
>   -                    Map.Entry attribute = (Map.Entry) i.next();
>   -
>   -                    // if this object wants session binding notification
>   -                    if (attribute.getValue() instanceof SessionStateBindingListener)
>   -                    {
>   -                        try
>   -                        {
>   -                            ((SessionStateBindingListener)attribute.getValue())
>   -                                .valueUnbound(key, (String)attribute.getKey());
>   -                        }
>   -                        catch (Throwable e) {Log.warn("JetspeedStateManagerService.clear: unbinding exception: ", e);}
>   -                    }
>   +                    rv.add(key);
>                    }
>                }
>   -
>   -            // remove all attributes
>   -            state.clear();
>   -            
>   -            // and forget about it
>   -            m_states.remove(key);
>   -        }
>   -
>   -    }   // clear
>   -
>   -    /**
>   -    * Access an array of all names of attributes stored in the keyed state.
>   -    * @param key The state key.
>   -    * @return An array of all names of attributes stored in the keyed state.
>   -    */
>   -    public String[] getAttributeNames( String key )
>   -    {
>   -        Map state = (Map) m_states.get(key);
>   -        if (state == null) return null;
>   -
>   -        // process all the current keys, synchronized
>   -        return (String[]) state.keySet().toArray(new String[state.size()]);
>   -
>   -    }   // getAttributeNames
>   -
>   -    /**
>   -    * Access an SessionState object with the given key.
>   -    * @param key The SessionState key.
>   -    * @return an SessionState object with the given key.
>   -    */
>   -    public SessionState getSessionState( String key )
>   -    {
>   -        return new MySessionState(key, this);
>   -
>   -    }   // getSessionState
>   -
>   -    /**
>   -    * Retire, forget about and clean up all states that start with the given key.
>   -    * @param keyStart The beginning of the key of the states to clean up.
>   -    */
>   -    public synchronized void retireState( String keyStart )
>   -    {
>   -        // get the current state keys into an array
>   -        String keys[] = (String[]) m_states.keySet().toArray(new String[m_states.size()]);
>   -        
>   -        // clear all those that begin with keyStart
>   -        for (int i = 0; i < keys.length; i++)
>   -        {
>   -            if (keys[i].startsWith(keyStart))
>   -            {
>   -                clear(keys[i]);
>   -            }
>            }
>    
>   -    }   // retireState
>   -
>   -    /**
>   -    * An SessionState implementation, as covers to this service, storing the key.
>   -    */
>   -    private class MySessionState
>   -        implements SessionState
>   -    {
>   -        /** The state key. */
>   -        private String m_key = null;
>   -
>   -        /** The JetspeedStateManagerService object. */
>   -        private JetspeedStateManagerService m_service = null;
>   -
>   -        /**
>   -        * Construct.
>   -        * @param key The state key.
>   -        * @param service The JetspeedStateManagerService instance.
>   -        */
>   -        public MySessionState( String key,
>   -                                JetspeedStateManagerService service)
>   -        {
>   -            m_key = key;
>   -            m_service = service;
>   -
>   -        }   // MySessionState
>   -
>   -        /**
>   -        * Access the named attribute.
>   -        * @param name The attribute name.
>   -        * @return The named attribute value.
>   -        */
>   -        public Object getAttribute( String name )
>   -        {
>   -            return m_service.getAttribute(m_key, name);
>   -
>   -        }   // getAttribute
>   -
>   -        /**
>   -        * Set the named attribute value to the provided object.
>   -        * @param name The attribute name.
>   -        * @param value The value of the attribute (any object type).
>   -        */
>   -        public void setAttribute( String name, Object value )
>   -        {
>   -            m_service.setAttribute(m_key, name, value);
>   -
>   -        }   // setAttribute
>   -
>   -        /**
>   -        * Remove the named attribute, if it exists.
>   -        * @param name The attribute name.
>   -        */
>   -        public void removeAttribute( String name )
>   -        {
>   -            m_service.removeAttribute(m_key, name);
>   -
>   -        }   // removeAttribute
>   -
>   -        /**
>   -        * Remove all attributes.
>   -        */
>   -        public void clear()
>   -        {
>   -            m_service.clear(m_key);
>   -
>   -        }   // clear
>   -
>   -        /**
>   -        * Access an array of all names of attributes stored in the SessionState.
>   -        * @return An array of all names of attribute stored in the SessionState.
>   -        */
>   -        public String[] getAttributeNames()
>   -        {
>   -            return m_service.getAttributeNames(m_key);
>   -
>   -        }   // getAttributeNames
>   -
>   -        /**
>   -        * Access the full unique StateManager key for the SessionState.
>   -        * @return the full unique StateManager key for the SessionState.
>   -        */
>   -        public String getKey()
>   -        {
>   -            return m_key;
>   -
>   -        }   // getKey
>   -
>   -        /**
>   -        * Retire, forget about and clean up this state.
>   -        */
>   -        public void retire()
>   -        {
>   -            m_service.retireState(m_key);
>   +        if (rv.size() == 0) return null;
>    
>   -        }   // retire
>   +        return (String[]) rv.toArray(new String[rv.size()]);
>    
>   -    }   // class MySessionState
>   +    }   // getStateKeys
>    
>    }   // JetspeedStateManagerService
>    
>    /**********************************************************************************
>    *
>   -* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.4 2002/05/17 18:37:46 ggolden Exp $
>   +* $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedStateManagerService.java,v 1.5 2002/06/10 19:57:18 ggolden Exp $
>    *
>    **********************************************************************************/
>    
>   
>   
>   
>   1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/BaseStateManagerService.java
>   
>   Index: BaseStateManagerService.java
>   ===================================================================
>   /**********************************************************************************
>   *
>   * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/BaseStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
>   *
>   * ====================================================================
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution,
>    *    if any, must include the following acknowledgment:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgment may appear in the software itself,
>    *    if and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "Apache" and "Apache Software Foundation" and
>    *     "Apache Jetspeed" must not be used to endorse or promote products
>    *    derived from this software without prior written permission. For
>    *    written permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache" or
>    *    "Apache Jetspeed", nor may "Apache" appear in their name, without
>    *    prior written permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    */
>   
>   // package
>   package org.apache.jetspeed.services.statemanager;
>   
>   // imports
>   import java.util.Iterator;
>   import java.util.HashMap;
>   import java.util.Map;
>   import java.util.Set;
>   import java.util.Collections;
>   import java.util.Vector;
>   import javax.servlet.ServletConfig;
>   
>   import org.apache.jetspeed.services.statemanager.StateManagerService;
>   import org.apache.jetspeed.services.statemanager.SessionStateBindingListener;
>   import org.apache.turbine.services.TurbineBaseService;
>   import org.apache.turbine.services.InitializationException;
>   import org.apache.turbine.util.RunData;
>   import org.apache.turbine.util.Log;
>   
>   /**
>   * <p>BaseStateManagerService is a Turbine Service implementation of the
>   * StateManagerService.</p>
>   * <p>Each SessionState is stored in a Map, storing the names and values
>   * of the state attributes.</p>
>   * <p>The set of states managed is stored in some specific way by extension classes.</p>
>   * <p>See the proposal: jakarta-jetspeed/proposals/StateManager.txt for more details.</p>
>   * @version $Revision: 1.1 $
>   * @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 abstract class BaseStateManagerService
>       extends TurbineBaseService
>       implements StateManagerService
>   {
>       /*******************************************************************************
>       * Abstract methods
>       *******************************************************************************/
>   
>       /**
>       * Initialize the states storage.
>       */
>       protected abstract void initStates();
>   
>       /**
>       * Cleanup the states storage.
>       */
>       protected abstract void shutdownStates();
>   
>       /**
>       * 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.
>       */
>       protected abstract Map getState( String key );
>   
>       /**
>       * 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.
>       */
>       protected abstract void addState( String key, Map state );
>   
>       /**
>       * Remove a state from the states we are managing.
>       * @param key The state key.
>       */
>       protected abstract void removeState( String key );
>   
>       /**
>       * 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.
>       */
>       protected abstract String[] getStateKeys( String start );
>   
>       /**
>       * retire the attributes of the state.
>       * @param key The state key.
>       * @param state The Map of attributes to retire.
>       */
>       protected void retireAttributes( String key, Map state )
>       {
>           if (state == null) return;
>   
>           Set attributes = state.entrySet();
>           synchronized (state)
>           {
>               Iterator i = attributes.iterator();
>               while (i.hasNext())
>               {
>                   Map.Entry attribute = (Map.Entry) i.next();
>                   unBindAttributeValue(key, (String)attribute.getKey(), attribute.getValue());
>               }
>           }
>   
>           // remove all attributes
>           state.clear();
>   
>       }   // retireAttributes
>   
>       /**
>       * If the object is a SessionStateBindingListener, unbind it
>       * @param stateKey The state key.
>       * @param attributeName The attribute name.
>       * @param attribute The attribute object
>       */
>       protected void unBindAttributeValue( String stateKey, String attributeName, Object attribute )
>       {
>           // if this object wants session binding notification
>           if ((attribute != null) && (attribute instanceof SessionStateBindingListener))
>           {
>               try
>               {
>                   ((SessionStateBindingListener)attribute)
>                       .valueUnbound(stateKey, attributeName);
>               }
>               catch (Throwable e) {Log.warn("JetspeedStateManagerService.unBindAttributeValue: unbinding exception: ", e);}
>           }
>   
>       }   // unBindAttributeValue
>   
>       /**
>       * If the object is a SessionStateBindingListener, bind it
>       * @param stateKey The state key.
>       * @param attributeName The attribute name.
>       * @param attribute The attribute object
>       */
>       protected void bindAttributeValue( String stateKey, String attributeName, Object attribute )
>       {
>           // if this object wants session binding notification
>           if ((attribute != null) && (attribute instanceof SessionStateBindingListener))
>           {
>               try
>               {
>                   ((SessionStateBindingListener)attribute)
>                       .valueBound(stateKey, attributeName);
>               }
>               catch (Throwable e) {Log.warn("JetspeedStateManagerService.bindAttributeValue: unbinding exception: ", e);}
>           }
>   
>       }   // bindAttributeValue
>   
>       /*******************************************************************************
>       * Service implementation
>       *******************************************************************************/
>   
>       /**
>       * Performs early initialization.
>       *
>       * @param config A ServletConfing to use for initialization
>       * activities.
>       * @exception InitializationException, if initialization of this
>       * class was not successful.
>       */
>       public void init( ServletConfig config )
>           throws InitializationException
>       {
>           super.init(config);
>   
>       }   // init
>   
>       /**
>       * Performs early initialization.
>       *
>       * @param data An RunData to use for initialization activities.
>       * @exception InitializationException, if initialization of this
>       * class was not successful.
>       */
>       public void init( RunData data )
>           throws InitializationException
>       {
>           super.init(data);
>   
>       }   // init
>   
>       /**
>       * Performs late initialization.
>       *
>       * If your class relies on early initialization, and the object it
>       * expects was not received, you can use late initialization to
>       * throw an exception and complain.
>       *
>       * @exception InitializationException, if initialization of this
>       * class was not successful.
>       */
>       public void init()
>           throws InitializationException
>       {
>           super.init();
>   
>           // create our states storage
>           initStates();
>   
>       }   // init
>   
>       /**
>       * Returns to uninitialized state.
>       *
>       * You can use this method to release resources thet your Service
>       * allocated when Turbine shuts down.
>       */
>       public void shutdown()
>       {
>           shutdownStates();
>           super.shutdown();
>   
>       }   // shutdown
>   
>       /*******************************************************************************
>       * StateManagerService implementation
>       *******************************************************************************/
>   
>       /**
>       * Access the named attribute of the keyed state.
>       * @param key The state key.
>       * @param name The attribute name.
>       * @return The named attribute value of the keyed state.
>       */
>       public Object getAttribute ( String key, String name )
>       {
>           Map state = getState(key);
>           if (state == null) return null;
>           return state.get(name);
>   
>       }   // getAttribute
>   
>       /**
>       * Set the named state attribute of the keyed state with the provided object.
>       * @param key The state key.
>       * @param name The attribute name.
>       * @param value The new value of the attribute (any object type).
>       */
>       public void setAttribute( String key, String name, Object value )
>       {
>           Map state = getState(key);
>           if (state == null)
>           {
>               // create a synchronized map to store the state attributes
>               state = Collections.synchronizedMap(new HashMap());
>               addState(key, state);
>           }
>   
>           // get the old, if any
>           Object old = getAttribute(key, name);
>           
>           // store the new
>           state.put(name, value);
>   
>           // if there was an old value, unbind it
>           if (old != null)
>           {
>               unBindAttributeValue(key, name, old);
>           }
>   
>           // bind the new
>           bindAttributeValue(key, name, value);
>   
>       }   // setAttribute
>   
>       /**
>       * Remove the named state attribute of the keyed state, if it exists.
>       * @param key The state key.
>       * @param name The attribute name.
>       */
>       public void removeAttribute( String key, String name )
>       {
>           Map state = getState(key);
>           if (state == null) return;
>   
>           // get the old, if any
>           Object old = getAttribute(key, name);
>   
>           // remove
>           state.remove(name);
>           
>           // if the state is now empty, remove it
>           if (state.isEmpty())
>           {
>               removeState(key);
>           }
>   
>           // if there was an old value, unbind it
>           if (old != null)
>           {
>               unBindAttributeValue(key, name, old);
>           }
>   
>       }   // removeAttribute
>   
>       /**
>       * Remove all state attribute of the keyed state.
>       * @param key The state key.
>       */
>       public void clear( String key )
>       {
>           Map state = getState(key);
>           if (state == null) return;
>   
>           // notify all attribute and clear the state
>           retireAttributes(key, state);
>           
>           // and forget about it
>           removeState(key);
>   
>       }   // clear
>   
>       /**
>       * Access an array of all names of attributes stored in the keyed state.
>       * @param key The state key.
>       * @return An array of all names of attributes stored in the keyed state.
>       */
>       public String[] getAttributeNames( String key )
>       {
>           Map state = (Map) getState(key);
>           if (state == null) return null;
>           if (state.size() == 0) return null;
>   
>           // put the names into an array for return
>           return (String[]) state.keySet().toArray(new String[state.size()]);
>   
>       }   // getAttributeNames
>   
>       /**
>       * Access an SessionState object with the given key.
>       * @param key The SessionState key.
>       * @return an SessionState object with the given key.
>       */
>       public SessionState getSessionState( String key )
>       {
>           return new MySessionState(key, this);
>   
>       }   // getSessionState
>   
>       /**
>       * Retire, forget about and clean up all states that start with the given key.
>       * @param keyStart The beginning of the key of the states to clean up.
>       */
>       public synchronized void retireState( String keyStart )
>       {
>           // get the current state keys into an array
>           String keys[] = getStateKeys(keyStart);
>           if (keys == null) return;
>           
>           // clear them
>           for (int i = 0; i < keys.length; i++)
>           {
>               clear(keys[i]);
>           }
>   
>       }   // retireState
>   
>       /*******************************************************************************
>       * SessionState implementation
>       *******************************************************************************/
>   
>       /**
>       * A SessionState implementation, as covers to this service, storing the key.
>       */
>       private class MySessionState
>           implements SessionState
>       {
>           /** The state key. */
>           private String m_key = null;
>   
>           /** The StateManagerService object. */
>           private BaseStateManagerService m_service = null;
>   
>           /**
>           * Construct.
>           * @param key The state key.
>           * @param service The JetspeedStateManagerService instance.
>           */
>           public MySessionState( String key,
>                                   BaseStateManagerService service)
>           {
>               m_key = key;
>               m_service = service;
>   
>           }   // MySessionState
>   
>           /**
>           * Access the named attribute.
>           * @param name The attribute name.
>           * @return The named attribute value.
>           */
>           public Object getAttribute( String name )
>           {
>               return m_service.getAttribute(m_key, name);
>   
>           }   // getAttribute
>   
>           /**
>           * Set the named attribute value to the provided object.
>           * @param name The attribute name.
>           * @param value The value of the attribute (any object type).
>           */
>           public void setAttribute( String name, Object value )
>           {
>               m_service.setAttribute(m_key, name, value);
>   
>           }   // setAttribute
>   
>           /**
>           * Remove the named attribute, if it exists.
>           * @param name The attribute name.
>           */
>           public void removeAttribute( String name )
>           {
>               m_service.removeAttribute(m_key, name);
>   
>           }   // removeAttribute
>   
>           /**
>           * Remove all attributes.
>           */
>           public void clear()
>           {
>               m_service.clear(m_key);
>   
>           }   // clear
>   
>           /**
>           * Access an array of all names of attributes stored in the SessionState.
>           * @return An array of all names of attribute stored in the SessionState.
>           */
>           public String[] getAttributeNames()
>           {
>               return m_service.getAttributeNames(m_key);
>   
>           }   // getAttributeNames
>   
>           /**
>           * Access the full unique StateManager key for the SessionState.
>           * @return the full unique StateManager key for the SessionState.
>           */
>           public String getKey()
>           {
>               return m_key;
>   
>           }   // getKey
>   
>           /**
>           * Retire, forget about and clean up this state.
>           */
>           public void retire()
>           {
>               m_service.retireState(m_key);
>   
>           }   // retire
>   
>       }   // class MySessionState
>   
>   }   // BaseStateManagerService
>   
>   /**********************************************************************************
>   *
>   * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/BaseStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
>   *
>   **********************************************************************************/
>   
>   
>   
>   
>   1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java
>   
>   Index: JetspeedHttpStateManagerService.java
>   ===================================================================
>   /**********************************************************************************
>   *
>   * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
>   *
>   * ====================================================================
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution,
>    *    if any, must include the following acknowledgment:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgment may appear in the software itself,
>    *    if and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "Apache" and "Apache Software Foundation" and
>    *     "Apache Jetspeed" must not be used to endorse or promote products
>    *    derived from this software without prior written permission. For
>    *    written permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache" or
>    *    "Apache Jetspeed", nor may "Apache" appear in their name, without
>    *    prior written permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    */
>   
>   // package
>   package org.apache.jetspeed.services.statemanager;
>   
>   // imports
>   import java.util.HashMap;
>   import java.util.Map;
>   import java.util.Collections;
>   import java.util.Vector;
>   import java.util.Enumeration;
>   
>   import javax.servlet.http.HttpSession;
>   import javax.servlet.http.HttpSessionBindingListener;
>   import javax.servlet.http.HttpSessionBindingEvent;
>   
>   import org.apache.turbine.services.rundata.RunDataService;
>   import org.apache.turbine.services.TurbineServices;
>   
>   import org.apache.jetspeed.services.statemanager.BaseStateManagerService;
>   import org.apache.jetspeed.services.rundata.JetspeedRunDataService;
>   import org.apache.jetspeed.services.rundata.JetspeedRunData;
>   
>   /**
>   * <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 is dependent on the JetspeedRunDataService,
>   * but it 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.1 $
>   * @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
>   {
>       /** The JetspeedRunData Service. */
>       private JetspeedRunDataService runDataService = null;
>   
>       /**
>       * Initialize the states storage.
>       */
>       protected void initStates()
>       {
>           // get the runData service
>           this.runDataService =
>               (JetspeedRunDataService)TurbineServices.getInstance()
>                   .getService(RunDataService.SERVICE_NAME);
>   
>       }   // initStates
>   
>       /**
>       * Cleanup the states storage.
>       */
>       protected void shutdownStates()
>       {
>           // Note: this is called out of any specific request thread, so we
>           //      do not have any access to sessions... let the Servlet Container
>           //      clean up the stuff in the sessions.
>           this.runDataService = null;
>   
>       }   // shutdownStates
>   
>       /**
>       * Access the current HttpSession.
>       */
>       private HttpSession getSession()
>       {
>           if (runDataService == null) return null;
>   
>           JetspeedRunData rundata = runDataService.getCurrentRunData();
>           if (rundata == null) return null;
>           
>           HttpSession session = rundata.getSession();
>           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.
>       */
>       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.
>       */
>       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.
>       */
>       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.
>       */
>       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
>       {
>           /** Store the map. */
>           private Map m_map = null;
>           
>           /** The state key. */
>           private String m_key = null;
>   
>           /**
>           * Construct.
>           * @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...
>           */
>           public void valueBound( HttpSessionBindingEvent event ) {}
>   
>           /**
>           * When we are unbound, unbind our state's (map's) attributes
>           */
>           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/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java,v 1.1 2002/06/10 19:57:18 ggolden Exp $
>   *
>   **********************************************************************************/
>   
>   
>   
>   
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 
> 



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>