View Javadoc

1   /*
2    * Copyright 2000-2002,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  // package
18  package org.apache.jetspeed.services.statemanager;
19  
20  // imports
21  import java.util.Map;
22  import java.util.Vector;
23  import java.util.Enumeration;
24  
25  import javax.servlet.http.HttpSession;
26  import javax.servlet.http.HttpSessionBindingListener;
27  import javax.servlet.http.HttpSessionBindingEvent;
28  
29  import org.apache.jetspeed.services.statemanager.BaseStateManagerService;
30  
31  /***
32  * <p>JetspeedHttpStateManagerService is an implementation of the BaseStateManagerService
33  * which manages the states stored in the "current" HttpSession.</p>
34  * <p>Note: This implementation of the StateManagerService takes advantage of the
35  * Servlet container's management of the HttpSession.
36  * When the session is invalidated, the states we manage will be automatically cleaned up.
37  * When this happens, the objects placed into our states will have their
38  * SessionStateBindingListener mechanism invoked.</p>
39  * <p>Note: This implementation segments the states by session.  States created in one session will NOT BE AVAILABLE
40  * from other sessions.</p>
41  * @version $Revision: 1.4 $
42  * @see org.apache.jetspeed.services.statemanager.BaseStateManagerService
43  * @see org.apache.jetspeed.services.statemanager.StateManagerService
44  * @see org.apache.jetspeed.services.statemanager.SessionState
45  * @author <a href="mailto:ggolden@apache.org">Glenn R. Golden</a>
46  */
47  public class JetspeedHttpStateManagerService
48      extends BaseStateManagerService
49  {
50      /***
51      * Initialize the states storage.
52      */
53      protected void initStates()
54      {
55      }   // initStates
56  
57      /***
58      * Cleanup the states storage.
59      */
60      protected void shutdownStates()
61      {
62      }   // shutdownStates
63  
64      /***
65      * Access the current HttpSession.
66      */
67      private HttpSession getSession()
68      {
69          // get the current session that was installed for this thread
70          HttpSession session = (HttpSession) m_httpSessions.get(Thread.currentThread());
71          if (session == null) return null;
72  
73          // call isNew just to see if the session has been invalidated already
74          try
75          {
76              session.isNew();
77          }
78          catch (IllegalStateException e)
79          {
80              return null;
81          }
82  
83          return session;
84  
85      }   // getSession
86  
87      /***
88      * Convert the key to a name safe to store directly in the session.
89      * @param key The state key.
90      * @return a name safe to store directly in the session based on key.
91      */
92      private String getSessionKey( String key )
93      {
94          // we want our keys not to conflict with any other session usage...
95          return JetspeedHttpStateManagerService.class.getName() + "." + key;
96  
97      }   // getSessionKey
98  
99      /***
100     * Access the Map which is the set of attributes for a state.
101     * @param key The state key.
102     * @return The Map which is the set of attributes for a state.
103     */
104     protected Map getState( String key )
105     {
106         // get the session
107         HttpSession session = getSession();
108         if (session == null) return null;
109 
110         // get this state from our entry in the session
111         StateEntry stateEntry = (StateEntry) session.getAttribute(getSessionKey(key));
112         if (stateEntry == null) return null;
113 
114         return stateEntry.getMap();
115 
116     }   // getState
117 
118     /***
119     * Add a new state to the states we are managing.
120     * @param key The state key.
121     * @param state The Map which is the set of attributes for the state.
122     */
123     protected void addState( String key, Map state )
124     {
125         // get the session
126         HttpSession session = getSession();
127         if (session == null) return;
128 
129         // create a stateEntry to hold our state Map
130         StateEntry stateEntry = new StateEntry(key, state);
131 
132         // put it in the session
133         session.setAttribute(getSessionKey(key), stateEntry);
134 
135     }   // addState
136 
137     /***
138     * Remove a state from the states we are managing.
139     * @param key The state key.
140     */
141     protected void removeState( String key )
142     {
143         // get the session
144         HttpSession session = getSession();
145         if (session == null) return;
146 
147         // remove the key from the session - the StateEntry will be notified
148         session.removeAttribute(getSessionKey(key));
149 
150     }   // removeState
151 
152     /***
153     * Access an array of the keys of all states managed, those that start with the parameter.
154     * @param start The starting string used to select the keys.
155     * @return an array of the keys of all states managed.
156     */
157     protected String[] getStateKeys( String start )
158     {
159         // get the session
160         HttpSession session = getSession();
161         if (session == null) return null;
162 
163         // use this as the test pattern
164         String pattern = getSessionKey(start);
165 
166         // for those that match, this starts the session key
167         int subStart = getSessionKey("").length();
168 
169         // collect for return
170         Vector rv = new Vector();
171 
172         // get the session names
173         Enumeration names = session.getAttributeNames();
174         while (names.hasMoreElements())
175         {
176             String sessionName = (String) names.nextElement();
177             
178             // pick our states, and those whose key starts with the pattern
179             if (sessionName.startsWith(pattern))
180             {
181                 rv.add(sessionName.substring(subStart));
182             }
183         }
184 
185         if (rv.size() == 0) return null;
186 
187         return (String[]) rv.toArray(new String[rv.size()]);
188 
189     }   // getStateKeys
190 
191     /***
192     * Store the Map for the state, and listen for HttpSessionBinding events
193     */
194     private class StateEntry
195         implements HttpSessionBindingListener
196     {
197         /*** Store the map. */
198         private Map m_map = null;
199         
200         /*** The state key. */
201         private String m_key = null;
202 
203         /***
204         * Construct.
205         * @param key The state key.
206         * @param map The map to hold.
207         */
208         public StateEntry( String key, Map map )
209         {
210             m_key = key;
211             m_map = map;
212 
213         }   // StateEntry
214         
215         /***
216         * Access the map we are holding.
217         * @return the Map we are holding.
218         */
219         public Map getMap()
220         {
221             return m_map;
222 
223         }   // getMap
224 
225         /***
226         * We don't care about when we are bound...
227         */
228         public void valueBound( HttpSessionBindingEvent event ) {}
229 
230         /***
231         * When we are unbound, unbind our state's (map's) attributes
232         */
233         public void valueUnbound( HttpSessionBindingEvent event )
234         {
235             // notify all attribute and clear the state
236             retireAttributes(m_key, m_map);
237             m_map = null;
238             m_key = null;
239         }
240 
241     }   // class StateEntry
242 
243 }   // JetspeedHttpStateManagerService
244 
245 /***********************************************************************************
246 *
247 * $Header: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/statemanager/JetspeedHttpStateManagerService.java,v 1.4 2004/02/23 03:38:28 jford Exp $
248 *
249 **********************************************************************************/
250