001 package org.springframework.richclient.application.session;
002
003 import org.springframework.binding.value.support.PropertyChangeSupport;
004 import org.springframework.context.ApplicationEvent;
005 import org.springframework.context.ApplicationListener;
006 import org.springframework.richclient.application.Application;
007 import org.springframework.richclient.security.LoginEvent;
008 import org.springframework.richclient.security.LogoutEvent;
009 import org.springframework.security.Authentication;
010
011 import java.beans.PropertyChangeListener;
012 import java.util.HashMap;
013 import java.util.Map;
014
015 /**
016 * This object is a singleton that will: act as a storage for session and
017 * user variables, registers itself on ApplicationEvents and can be used
018 * to monitor changes on the contained variables.
019 *
020 * @author Jan Hoskens
021 *
022 */
023 public final class ApplicationSession implements ApplicationListener
024 {
025
026 /** Holds the singleton instance. */
027 private static final ApplicationSession INSTANCE = new ApplicationSession();
028
029 /** Custom initialising code/variables will be passed by an initialiser. */
030 private ApplicationSessionInitializer applicationSessionInitializer;
031
032 /** Handler managing listeners registered on properties. */
033 private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
034
035 /** Property that can be monitored. */
036 public static final String USER = "user";
037
038 /** Property that can be monitored. */
039 public static final String USER_ATTRIBUTES = "userAttributes";
040
041 /** Property that can be monitored. */
042 public static final String SESSION_ATTRIBUTES = "sessionAttributes";
043
044 /** User attributes map. */
045 private Map<String, Object> userAttributes = new HashMap<String, Object>();
046
047 /** Session attributes map. */
048 private Map<String, Object> sessionAttributes = new HashMap<String, Object>();
049
050
051 /**
052 * Private constructor: Singleton Pattern.
053 */
054 private ApplicationSession()
055 {
056 }
057
058 /**
059 * Get the instance: Singleton Pattern.
060 *
061 * @return the ApplicationSession.
062 */
063 public static ApplicationSession getSession()
064 {
065 return INSTANCE;
066 }
067
068 /**
069 * Handle events that influence the session/user context.
070 */
071 public void onApplicationEvent(ApplicationEvent event)
072 {
073 if ((event instanceof LoginEvent)
074 && (event.getSource() != LoginEvent.NO_AUTHENTICATION))
075 handleLoginEvent((LoginEvent) event);
076 else if ((event instanceof LogoutEvent))
077 handleLogoutEvent((LogoutEvent) event);
078 }
079
080 /**
081 * When a correct login occurs, read all relevant userinformation into
082 * session.
083 *
084 * @param event
085 * the loginEvent that triggered this handler.
086 */
087 protected void handleLoginEvent(LoginEvent event)
088 {
089 ApplicationSessionInitializer asi = getApplicationSessionInitializer();
090 if (asi != null)
091 {
092 asi.initializeUser();
093 Map<String, Object> userAttributes = asi.getUserAttributes();
094 if (userAttributes != null)
095 {
096 setUserAttributes(userAttributes);
097 }
098 }
099 Authentication auth = (Authentication) event.getSource();
100 propertyChangeSupport.firePropertyChange(USER, null, auth);
101 }
102
103 /**
104 * When a logout occurs, remove all user related information from the
105 * session.
106 *
107 * @param event
108 * the logoutEvent that triggered this handler.
109 */
110 protected void handleLogoutEvent(LogoutEvent event)
111 {
112 clearUser();
113 Authentication auth = (Authentication) event.getSource();
114 propertyChangeSupport.firePropertyChange(USER, auth, null);
115 }
116
117 /**
118 * Set an initializer object containing vars/commands and custom init code.
119 *
120 * @param applicationSessionInitializer The application session initializer
121 */
122 public void setApplicationSessionInitializer(ApplicationSessionInitializer applicationSessionInitializer)
123 {
124 this.applicationSessionInitializer = applicationSessionInitializer;
125 }
126
127 /**
128 * @return the applicationSessionInitializer.
129 */
130 public ApplicationSessionInitializer getApplicationSessionInitializer()
131 {
132 if (applicationSessionInitializer == null)
133 {
134 applicationSessionInitializer = Application.instance()
135 .getLifecycleAdvisor().getApplicationSessionInitializer();
136 }
137 return applicationSessionInitializer;
138 }
139
140 /**
141 * Register a listener on the specified property.
142 *
143 * @param property
144 * Property to monitor.
145 * @param listener
146 * PropertyChangeListener to add.
147 */
148 public void addPropertyChangeListener(String property, PropertyChangeListener listener)
149 {
150 propertyChangeSupport.addPropertyChangeListener(property, listener);
151 }
152
153 /**
154 * Unregister a listener from the specified property.
155 *
156 * @param property
157 * Property that currently is being monitored.
158 * @param listener
159 * PropertyChangeListener to remove.
160 */
161 public void removePropertyChangeListener(String property, PropertyChangeListener listener)
162 {
163 propertyChangeSupport.removePropertyChangeListener(property, listener);
164 }
165
166 /**
167 * Initialize the session attributes.
168 */
169 public void initializeSession()
170 {
171 ApplicationSessionInitializer asi = getApplicationSessionInitializer();
172 if (asi != null)
173 {
174 asi.initializeSession();
175 Map<String, Object> sessionAttributes = asi.getSessionAttributes();
176 if (sessionAttributes != null)
177 {
178 setSessionAttributes(sessionAttributes);
179 }
180 propertyChangeSupport.firePropertyChange(SESSION_ATTRIBUTES, null, sessionAttributes);
181 }
182 }
183
184 /**
185 * gets a named attribute of the user associated to this context
186 *
187 * @param key
188 * name of the attribute
189 * @return the attribute value (attribute values are strings)
190 */
191 public Object getUserAttribute(String key)
192 {
193 return this.getUserAttribute(key, null);
194 }
195
196 /**
197 * Get a value from the user attributes map.
198 *
199 * @param key
200 * name of the attribute
201 * @param defaultValue
202 * a default value to return if no value is found.
203 * @return the attribute value
204 */
205 public Object getUserAttribute(String key, Object defaultValue)
206 {
207 Object attributeValue = this.userAttributes.get(key);
208 if (attributeValue == null)
209 attributeValue = defaultValue;
210 return attributeValue;
211 }
212
213 /**
214 * Add a key/value pair to the user attributes map.
215 *
216 * @param key
217 * a unique string code.
218 * @param newValue
219 * the associated value.
220 */
221 public void setUserAttribute(String key, Object newValue)
222 {
223 Object oldValue = userAttributes.put(key, newValue);
224 propertyChangeSupport.firePropertyChange(key, oldValue, newValue);
225 propertyChangeSupport.firePropertyChange(USER_ATTRIBUTES, null, userAttributes);
226 }
227
228 /**
229 * Add the given key/value pairs to the user attributes.
230 *
231 * @param attributes
232 * a map of key/value pairs.
233 */
234 public void setUserAttributes(Map<String, Object> attributes)
235 {
236 userAttributes.putAll(attributes);
237 propertyChangeSupport.firePropertyChange(USER_ATTRIBUTES, null, userAttributes);
238 }
239
240 /**
241 * Clear all user attributes.
242 */
243 public void clearUser()
244 {
245 this.userAttributes.clear();
246 propertyChangeSupport.firePropertyChange(USER_ATTRIBUTES, null, null);
247 }
248
249 /**
250 * Get a value from the session attributes map.
251 *
252 * @param key
253 * name of the attribute
254 * @return the attribute value
255 */
256 public Object getSessionAttribute(String key)
257 {
258 return this.getSessionAttribute(key, null);
259 }
260
261 /**
262 * Get a value from the session attributes map.
263 *
264 * @param key a unique string code
265 * @param defaultValue the default value if not found
266 * @return The session attibute or the default value if not found
267 */
268 public Object getSessionAttribute(String key, Object defaultValue)
269 {
270 Object attributeValue = this.sessionAttributes.get(key);
271 if (attributeValue == null)
272 attributeValue = defaultValue;
273 return attributeValue;
274 }
275
276 /**
277 * Add a key/value pair to the session attributes map.
278 *
279 * @param key
280 * a unique string code.
281 * @param newValue
282 * the associated value.
283 */
284 public void setSessionAttribute(String key, Object newValue)
285 {
286 Object oldValue = sessionAttributes.put(key, newValue);
287 propertyChangeSupport.firePropertyChange(key, oldValue, newValue);
288 propertyChangeSupport.firePropertyChange(SESSION_ATTRIBUTES, null, sessionAttributes);
289 }
290
291 /**
292 * Add the given key/value pairs to the session attributes.
293 *
294 * @param attributes
295 * a map of key/value pairs.
296 */
297 public void setSessionAttributes(Map<String, Object> attributes)
298 {
299 this.sessionAttributes.putAll(attributes);
300 propertyChangeSupport.firePropertyChange(SESSION_ATTRIBUTES, null, sessionAttributes);
301 }
302
303 /**
304 * Clear all session attributes.
305 */
306 public void clearSession()
307 {
308 this.sessionAttributes.clear();
309 propertyChangeSupport.firePropertyChange(SESSION_ATTRIBUTES, null, sessionAttributes);
310 }
311
312 /**
313 * Get a value from the user OR session attributes map.
314 *
315 * @param key
316 * name of the attribute
317 * @return the attribute value
318 */
319 public Object getAttribute(String key)
320 {
321 return getAttribute(key, null);
322 }
323
324 /**
325 * Get a value from the user OR session attributes map.
326 *
327 * @param key
328 * name of the attribute
329 * @param defaultValue
330 * a default value to return if no value is found.
331 * @return the attribute value
332 */
333 public Object getAttribute(String key, Object defaultValue)
334 {
335 Object attributeValue = getUserAttribute(key, null);
336 if (attributeValue != null)
337 return attributeValue;
338 attributeValue = getSessionAttribute(key, null);
339 if (attributeValue != null)
340 return attributeValue;
341 return defaultValue;
342 }
343 }