package com.hwlcn.security.session.mgt; import com.hwlcn.security.authz.AuthorizationException; import com.hwlcn.security.session.*; import com.hwlcn.security.util.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; public abstract class AbstractNativeSessionManager extends AbstractSessionManager implements NativeSessionManager { private static final Logger log = LoggerFactory.getLogger(AbstractSessionManager.class); private Collection<SessionListener> listeners; public AbstractNativeSessionManager() { this.listeners = new ArrayList<SessionListener>(); } public void setSessionListeners(Collection<SessionListener> listeners) { this.listeners = listeners != null ? listeners : new ArrayList<SessionListener>(); } @SuppressWarnings({"UnusedDeclaration"}) public Collection<SessionListener> getSessionListeners() { return this.listeners; } public Session start(SessionContext context) { Session session = createSession(context); applyGlobalSessionTimeout(session); onStart(session, context); notifyStart(session); //Don't expose the EIS-tier Session object to the client-tier: return createExposedSession(session, context); } protected abstract Session createSession(SessionContext context) throws AuthorizationException; protected void applyGlobalSessionTimeout(Session session) { session.setTimeout(getGlobalSessionTimeout()); onChange(session); } protected void onStart(Session session, SessionContext context) { } public Session getSession(SessionKey key) throws SessionException { Session session = lookupSession(key); return session != null ? createExposedSession(session, key) : null; } private Session lookupSession(SessionKey key) throws SessionException { if (key == null) { throw new NullPointerException("SessionKey argument cannot be null."); } return doGetSession(key); } private Session lookupRequiredSession(SessionKey key) throws SessionException { Session session = lookupSession(key); if (session == null) { String msg = "Unable to locate required Session instance based on SessionKey [" + key + "]."; throw new UnknownSessionException(msg); } return session; } protected abstract Session doGetSession(SessionKey key) throws InvalidSessionException; protected Session createExposedSession(Session session, SessionContext context) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); } protected Session createExposedSession(Session session, SessionKey key) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); } protected Session beforeInvalidNotification(Session session) { return new ImmutableProxiedSession(session); } protected void notifyStart(Session session) { for (SessionListener listener : this.listeners) { listener.onStart(session); } } protected void notifyStop(Session session) { Session forNotification = beforeInvalidNotification(session); for (SessionListener listener : this.listeners) { listener.onStop(forNotification); } } protected void notifyExpiration(Session session) { Session forNotification = beforeInvalidNotification(session); for (SessionListener listener : this.listeners) { listener.onExpiration(forNotification); } } public Date getStartTimestamp(SessionKey key) { return lookupRequiredSession(key).getStartTimestamp(); } public Date getLastAccessTime(SessionKey key) { return lookupRequiredSession(key).getLastAccessTime(); } public long getTimeout(SessionKey key) throws InvalidSessionException { return lookupRequiredSession(key).getTimeout(); } public void setTimeout(SessionKey key, long maxIdleTimeInMillis) throws InvalidSessionException { Session s = lookupRequiredSession(key); s.setTimeout(maxIdleTimeInMillis); onChange(s); } public void touch(SessionKey key) throws InvalidSessionException { Session s = lookupRequiredSession(key); s.touch(); onChange(s); } public String getHost(SessionKey key) { return lookupRequiredSession(key).getHost(); } public Collection<Object> getAttributeKeys(SessionKey key) { Collection<Object> c = lookupRequiredSession(key).getAttributeKeys(); if (!CollectionUtils.isEmpty(c)) { return Collections.unmodifiableCollection(c); } return Collections.emptySet(); } public Object getAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException { return lookupRequiredSession(sessionKey).getAttribute(attributeKey); } public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) throws InvalidSessionException { if (value == null) { removeAttribute(sessionKey, attributeKey); } else { Session s = lookupRequiredSession(sessionKey); s.setAttribute(attributeKey, value); onChange(s); } } public Object removeAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException { Session s = lookupRequiredSession(sessionKey); Object removed = s.removeAttribute(attributeKey); if (removed != null) { onChange(s); } return removed; } public boolean isValid(SessionKey key) { try { checkValid(key); return true; } catch (InvalidSessionException e) { return false; } } public void stop(SessionKey key) throws InvalidSessionException { Session session = lookupRequiredSession(key); try { if (log.isDebugEnabled()) { log.debug("Stopping session with id [" + session.getId() + "]"); } session.stop(); onStop(session, key); notifyStop(session); } finally { afterStopped(session); } } protected void onStop(Session session, SessionKey key) { onStop(session); } protected void onStop(Session session) { onChange(session); } protected void afterStopped(Session session) { } public void checkValid(SessionKey key) throws InvalidSessionException { lookupRequiredSession(key); } protected void onChange(Session s) { } }