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 }