📄 deltasession.java
字号:
/* * Copyright 1999,2004 The Apache Software Foundation. * * Licensed 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.apache.catalina.ha.session;import java.beans.PropertyChangeSupport;import java.io.IOException;import java.io.NotSerializableException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.lang.reflect.Method;import java.security.AccessController;import java.security.Principal;import java.security.PrivilegedAction;import java.util.ArrayList;import java.util.Enumeration;import java.util.HashMap;import java.util.Hashtable;import java.util.Iterator;import java.util.Map;import javax.servlet.ServletContext;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSessionAttributeListener;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionBindingListener;import javax.servlet.http.HttpSessionContext;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;import org.apache.catalina.Context;import org.apache.catalina.Manager;import org.apache.catalina.Session;import org.apache.catalina.SessionEvent;import org.apache.catalina.SessionListener;import org.apache.catalina.ha.ClusterSession;import org.apache.catalina.realm.GenericPrincipal;import org.apache.catalina.util.Enumerator;import org.apache.catalina.util.StringManager;import org.apache.catalina.tribes.tipis.ReplicatedMapEntry;import java.util.concurrent.locks.ReentrantReadWriteLock;import java.util.concurrent.locks.Lock;import org.apache.catalina.ha.ClusterManager;import org.apache.catalina.tribes.io.ReplicationStream;import java.io.Externalizable;import java.io.ObjectInput;import java.io.ObjectOutput;/** * * Similar to the StandardSession, this code is identical, but for update and * some small issues, simply copied in the first release. This session will keep * track of deltas during a request. * <p> * <b>IMPLEMENTATION NOTE </b>: An instance of this class represents both the * internal (Session) and application level (HttpSession) view of the session. * However, because the class itself is not declared public, Java logic outside * of the <code>org.apache.catalina.session</code> package cannot cast an * HttpSession view of this instance back to a Session view. * <p> * <b>IMPLEMENTATION NOTE </b>: If you add fields to this class, you must make * sure that you carry them over in the read/writeObject methods so that this * class is properly serialized. * * @author Filip Hanik * @author Craig R. McClanahan * @author Sean Legassick * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens </a> * @version $Revision: 372887 $ $Date: 2006-01-27 09:58:58 -0600 (Fri, 27 Jan 2006) $ */public class DeltaSession implements HttpSession, Session, Externalizable,ClusterSession,ReplicatedMapEntry { public static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(DeltaManager.class); /** * The string manager for this package. */ protected static StringManager sm = StringManager.getManager(Constants.Package); // ----------------------------------------------------- Instance Variables /** * Type array. */ protected static final String EMPTY_ARRAY[] = new String[0]; /** * The dummy attribute value serialized when a NotSerializableException is * encountered in <code>writeObject()</code>. */ private static final String NOT_SERIALIZED = "___NOT_SERIALIZABLE_EXCEPTION___"; /** * The collection of user data attributes associated with this Session. */ private Map attributes = new Hashtable(); /** * The authentication type used to authenticate our cached Principal, if * any. NOTE: This value is not included in the serialized version of this * object. */ private transient String authType = null; /** * The <code>java.lang.Method</code> for the * <code>fireContainerEvent()</code> method of the * <code>org.apache.catalina.core.StandardContext</code> method, if our * Context implementation is of this class. This value is computed * dynamically the first time it is needed, or after a session reload (since * it is declared transient). */ private transient Method containerEventMethod = null; /** * The method signature for the <code>fireContainerEvent</code> method. */ private static final Class containerEventTypes[] = { String.class, Object.class }; /** * The time this session was created, in milliseconds since midnight, * January 1, 1970 GMT. */ private long creationTime = 0L; /** * We are currently processing a session expiration, so bypass certain * IllegalStateException tests. NOTE: This value is not included in the * serialized version of this object. */ private transient boolean expiring = false; /** * The facade associated with this session. NOTE: This value is not included * in the serialized version of this object. */ private transient DeltaSessionFacade facade = null; /** * The session identifier of this Session. */ private String id = null; /** * Descriptive information describing this Session implementation. */ private static final String info = "DeltaSession/1.1"; /** * The last accessed time for this Session. */ private long lastAccessedTime = creationTime; /** * The session event listeners for this Session. */ private transient ArrayList listeners = new ArrayList(); /** * The Manager with which this Session is associated. */ private transient Manager manager = null; /** * The maximum time interval, in seconds, between client requests before the * servlet container may invalidate this session. A negative time indicates * that the session should never time out. */ private int maxInactiveInterval = -1; /** * Flag indicating whether this session is new or not. */ private boolean isNew = false; /** * Flag indicating whether this session is valid or not. */ protected boolean isValid = false; /** * Internal notes associated with this session by Catalina components and * event listeners. <b>IMPLEMENTATION NOTE: </b> This object is <em>not</em> * saved and restored across session serializations! */ private transient Map notes = new Hashtable(); /** * The authenticated Principal associated with this session, if any. * <b>IMPLEMENTATION NOTE: </b> This object is <i>not </i> saved and * restored across session serializations! */ private transient Principal principal = null; /** * The HTTP session context associated with this session. */ private static HttpSessionContext sessionContext = null; /** * The property change support for this component. NOTE: This value is not * included in the serialized version of this object. */ private transient PropertyChangeSupport support = new PropertyChangeSupport(this); /** * The current accessed time for this session. */ private long thisAccessedTime = creationTime; /** * only the primary session will expire, or be able to expire due to * inactivity. This is set to false as soon as I receive this session over * the wire in a session message. That means that someone else has made a * request on another server. */ private transient boolean isPrimarySession = true; /** * The delta request contains all the action info * */ private transient DeltaRequest deltaRequest = null; /** * Last time the session was replicatd, used for distributed expiring of * session */ private transient long lastTimeReplicated = System.currentTimeMillis(); /** * The access count for this session */ protected transient int accessCount = 0; protected Lock diffLock = new ReentrantReadWriteLock().writeLock(); // ----------------------------------------------------------- Constructors /** * Construct a new Session associated with the specified Manager. * * @param manager * The manager with which this Session is associated */ public DeltaSession() { this.resetDeltaRequest(); } public DeltaSession(Manager manager) { this(); this.manager = manager; } // ----------------------------------------------------- ReplicatedMapEntry /** * Has the object changed since last replication * and is not in a locked state * @return boolean */ public boolean isDirty() { return getDeltaRequest().getSize()>0; } /** * If this returns true, the map will extract the diff using getDiff() * Otherwise it will serialize the entire object. * @return boolean */ public boolean isDiffable() { return true; } /** * Returns a diff and sets the dirty map to false * @return byte[] * @throws IOException */ public byte[] getDiff() throws IOException { return getDeltaRequest().serialize(); } /** * Applies a diff to an existing object. * @param diff byte[] * @param offset int * @param length int * @throws IOException */ public void applyDiff(byte[] diff, int offset, int length) throws IOException, ClassNotFoundException { ReplicationStream stream = ((ClusterManager)getManager()).getReplicationStream(diff,offset,length); getDeltaRequest().readExternal(stream); getDeltaRequest().execute(this); } /** * Resets the current diff state and resets the dirty flag */ public void resetDiff() { resetDeltaRequest(); } /** * Lock during serialization */ public void lock() { diffLock.lock(); } /** * Unlock after serialization */ public void unlock() { diffLock.unlock(); } public void setOwner(Object owner) { if ( owner instanceof ClusterManager && getManager()==null) { ClusterManager cm = (ClusterManager)owner; this.setManager(cm); this.setValid(true); this.setPrimarySession(false); this.access(); if (cm.isNotifyListenersOnReplication()) this.setId(getIdInternal()); this.resetDeltaRequest(); this.endAccess(); } } // ----------------------------------------------------- Session Properties /** * returns true if this session is the primary session, if that is the case, * the manager can expire it upon timeout. */ public boolean isPrimarySession() { return isPrimarySession; } /** * Sets whether this is the primary session or not. * * @param primarySession * Flag value */ public void setPrimarySession(boolean primarySession) { this.isPrimarySession = primarySession; } /** * Return the authentication type used to authenticate our cached Principal, * if any. */ public String getAuthType() { return (this.authType); } /** * Set the authentication type used to authenticate our cached Principal, if * any. * * @param authType * The new cached authentication type */ public void setAuthType(String authType) { String oldAuthType = this.authType; this.authType = authType; support.firePropertyChange("authType", oldAuthType, this.authType); } /** * Set the creation time for this session. This method is called by the * Manager when an existing Session instance is reused. * * @param time * The new creation time */ public void setCreationTime(long time) { this.creationTime = time; this.lastAccessedTime = time; this.thisAccessedTime = time; } /** * Return the session identifier for this session. */ public String getId() { return (this.id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -