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>