Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jsecurity.session.mgt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jsecurity.session.ExpiredSessionException; import org.jsecurity.session.InvalidSessionException; import org.jsecurity.session.StoppedSessionException; import java.io.Serializable; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.DateFormat; import java.util.*; /** * Simple {@link org.jsecurity.session.Session} POJO implementation, intended to be used on the business/server tier. * * @author Les Hazlewood * @since 0.1 */ public class SimpleSession implements ValidatingSession, Serializable { //TODO - complete JavaDoc protected static final long MILLIS_PER_SECOND = 1000; protected static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND; protected static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE; private transient static final Log log = LogFactory.getLog(SimpleSession.class); private Serializable id = null; private Date startTimestamp = null; private Date stopTimestamp = null; private Date lastAccessTime = null; private long timeout = DefaultSessionManager.DEFAULT_GLOBAL_SESSION_TIMEOUT; private boolean expired = false; private InetAddress hostAddress = null; private Map<Object, Object> attributes = null; public SimpleSession() { this(getLocalHost()); } public SimpleSession(InetAddress hostAddress) { this.startTimestamp = new Date(); this.lastAccessTime = startTimestamp; this.hostAddress = hostAddress; } private static InetAddress getLocalHost() { try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { throw new IllegalStateException(e); } } public Serializable getId() { return this.id; } public void setId(Serializable id) { this.id = id; } public Date getStartTimestamp() { return startTimestamp; } public void setStartTimestamp(Date startTimestamp) { this.startTimestamp = startTimestamp; } /** * Returns the time the session was stopped, or <tt>null</tt> if the session is still active. * * <p>A session may become stopped under a number of conditions: * <ul> * <li>If the user logs out of the system, their current session is terminated (released).</li> * <li>If the session expires</li> * <li>The application explicitly calls {@link #stop() destroy()}</li> * <li>If there is an internal system error and the session state can no longer accurately * reflect the user's behavior, such in the case of a system crash</li> * </ul> * </p> * * <p>Once stopped, a session may no longer be used. It is locked from all further activity. * * @return The time the session was stopped, or <tt>null</tt> if the session is still * active. */ public Date getStopTimestamp() { return stopTimestamp; } public void setStopTimestamp(Date stopTimestamp) { this.stopTimestamp = stopTimestamp; } public Date getLastAccessTime() { return lastAccessTime; } public void setLastAccessTime(Date lastAccessTime) { this.lastAccessTime = lastAccessTime; } /** * Returns true if this session has expired, false otherwise. If the session has * expired, no further user interaction with the system may be done under this session. * * @return true if this session has expired, false otherwise. */ public boolean isExpired() { return expired; } public void setExpired(boolean expired) { this.expired = expired; } public long getTimeout() { return timeout; } public void setTimeout(long timeout) { this.timeout = timeout; } public InetAddress getHostAddress() { return hostAddress; } public void setHostAddress(InetAddress hostAddress) { this.hostAddress = hostAddress; } public Map<Object, Object> getAttributes() { return attributes; } public void setAttributes(Map<Object, Object> attributes) { this.attributes = attributes; } public void touch() { this.lastAccessTime = new Date(); } public void stop() { if (this.stopTimestamp == null) { this.stopTimestamp = new Date(); } } protected boolean isStopped() { return getStopTimestamp() != null; } protected void expire() { stop(); if (!this.expired) { this.expired = true; } } /** * @since 0.9 */ public boolean isValid() { return !isStopped() && !isExpired(); } /** * Determines if this session is expired. * * @return true if the specified session has expired, false otherwise. */ protected boolean isTimedOut() { if (isExpired()) { return true; } long timeout = getTimeout(); if (timeout >= 0l) { Date lastAccessTime = getLastAccessTime(); if (lastAccessTime == null) { String msg = "session.lastAccessTime for session with id [" + getId() + "] is null. This value must be set at " + "least once, preferably at least upon instantiation. Please check the " + getClass().getName() + " implementation and ensure " + "this value will be set (perhaps in the constructor?)"; throw new IllegalStateException(msg); } // Calculate at what time a session would have been last accessed // for it to be expired at this point. In other words, subtract // from the current time the amount of time that a session can // be inactive before expiring. If the session was last accessed // before this time, it is expired. long expireTimeMillis = System.currentTimeMillis() - timeout; Date expireTime = new Date(expireTimeMillis); return lastAccessTime.before(expireTime); } else { if (log.isTraceEnabled()) { log.trace("No timeout for session with id [" + getId() + "]. Session is not considered expired."); } } return false; } public void validate() throws InvalidSessionException { //check for stopped: if (isStopped()) { //timestamp is set, so the session is considered stopped: String msg = "Session with id [" + getId() + "] has been " + "explicitly stopped. No further interaction under this session is " + "allowed."; throw new StoppedSessionException(msg, getId()); } //check for expiration if (isTimedOut()) { expire(); //throw an exception explaining details of why it expired: Date lastAccessTime = getLastAccessTime(); long timeout = getTimeout(); Serializable sessionId = getId(); DateFormat df = DateFormat.getInstance(); String msg = "Session with id [" + sessionId + "] has expired. " + "Last access time: " + df.format(lastAccessTime) + ". Current time: " + df.format(new Date()) + ". Session timeout is set to " + timeout / MILLIS_PER_SECOND + " seconds (" + timeout / MILLIS_PER_MINUTE + " minutes)"; if (log.isTraceEnabled()) { log.trace(msg); } throw new ExpiredSessionException(msg, sessionId); } } private Map<Object, Object> getAttributesLazy() { Map<Object, Object> attributes = getAttributes(); if (attributes == null) { attributes = new HashMap<Object, Object>(); setAttributes(attributes); } return attributes; } public Collection<Object> getAttributeKeys() throws InvalidSessionException { Map<Object, Object> attributes = getAttributes(); if (attributes == null) { //noinspection unchecked return Collections.EMPTY_SET; } return attributes.keySet(); } public Object getAttribute(Object key) { Map<Object, Object> attributes = getAttributes(); if (attributes == null) { return null; } return attributes.get(key); } public void setAttribute(Object key, Object value) { if (value == null) { removeAttribute(key); } else { getAttributesLazy().put(key, value); } } public Object removeAttribute(Object key) { Map<Object, Object> attributes = getAttributes(); if (attributes == null) { return null; } else { return attributes.remove(key); } } }