001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.cluster.session;
018:
019: /**
020: * This class is used to track the series of actions that happens when
021: * a request is executed. These actions will then translate into invokations of methods
022: * on the actual session.
023: * This class is NOT thread safe. One DeltaRequest per session
024: * @author <a href="mailto:fhanik@apache.org">Filip Hanik</a>
025: * @version 1.0
026: */
027:
028: import java.util.LinkedList;
029: import javax.servlet.http.HttpSession;
030: import java.io.Externalizable;
031: import java.security.Principal;
032: import org.apache.catalina.realm.GenericPrincipal;
033: import org.apache.catalina.cluster.ClusterSession;
034:
035: public class DeltaRequest implements Externalizable {
036:
037: public static final int TYPE_ATTRIBUTE = 0;
038: public static final int TYPE_PRINCIPAL = 1;
039: public static final int TYPE_ISNEW = 2;
040: public static final int TYPE_MAXINTERVAL = 3;
041:
042: public static final int ACTION_SET = 0;
043: public static final int ACTION_REMOVE = 1;
044:
045: public static final String NAME_PRINCIPAL = "__SET__PRINCIPAL__";
046: public static final String NAME_MAXINTERVAL = "__SET__MAXINTERVAL__";
047: public static final String NAME_ISNEW = "__SET__ISNEW__";
048:
049: private String sessionId;
050: private LinkedList actions = new LinkedList();
051: private LinkedList actionPool = new LinkedList();
052:
053: private boolean recordAllActions = false;
054:
055: public DeltaRequest() {
056:
057: }
058:
059: public DeltaRequest(String sessionId, boolean recordAllActions) {
060: this .recordAllActions = recordAllActions;
061: setSessionId(sessionId);
062: }
063:
064: public void setAttribute(String name, Object value) {
065: int action = (value == null) ? ACTION_REMOVE : ACTION_SET;
066: addAction(TYPE_ATTRIBUTE, action, name, value);
067: }
068:
069: public void removeAttribute(String name) {
070: int action = ACTION_REMOVE;
071: addAction(TYPE_ATTRIBUTE, action, name, null);
072: }
073:
074: public void setMaxInactiveInterval(int interval) {
075: int action = ACTION_SET;
076: addAction(TYPE_MAXINTERVAL, action, NAME_MAXINTERVAL,
077: new Integer(interval));
078: }
079:
080: public void setPrincipal(Principal p) {
081: int action = (p == null) ? ACTION_REMOVE : ACTION_SET;
082: SerializablePrincipal sp = null;
083: if (p != null) {
084: sp = SerializablePrincipal
085: .createPrincipal((GenericPrincipal) p);
086: }
087: addAction(TYPE_PRINCIPAL, action, NAME_PRINCIPAL, sp);
088: }
089:
090: public void setNew(boolean n) {
091: int action = ACTION_SET;
092: addAction(TYPE_ISNEW, action, NAME_ISNEW, new Boolean(n));
093: }
094:
095: protected void addAction(int type, int action, String name,
096: Object value) {
097: AttributeInfo info = null;
098: if (this .actionPool.size() > 0) {
099: info = (AttributeInfo) actionPool.removeFirst();
100: info.init(type, action, name, value);
101: } else {
102: info = new AttributeInfo(type, action, name, value);
103: }
104: //if we have already done something to this attribute, make sure
105: //we don't send multiple actions across the wire
106: if (!recordAllActions)
107: actions.remove(info);
108: //add the action
109: actions.addLast(info);
110: }
111:
112: public void execute(DeltaSession session) {
113: if (!this .sessionId.equals(session.getId()))
114: throw new java.lang.IllegalArgumentException(
115: "Session id mismatch, not executing the delta request");
116: session.access();
117: for (int i = 0; i < actions.size(); i++) {
118: AttributeInfo info = (AttributeInfo) actions.get(i);
119: switch (info.getType()) {
120: case TYPE_ATTRIBUTE: {
121: if (info.getAction() == ACTION_SET) {
122: session.setAttribute(info.getName(), info
123: .getValue(), false);
124: } else
125: session
126: .removeAttribute(info.getName(), true,
127: false);
128: break;
129: }//case
130: case TYPE_ISNEW: {
131: session.setNew(((Boolean) info.getValue())
132: .booleanValue(), false);
133: break;
134: }//case
135: case TYPE_MAXINTERVAL: {
136: session.setMaxInactiveInterval(((Integer) info
137: .getValue()).intValue(), false);
138: break;
139: }//case
140: case TYPE_PRINCIPAL: {
141: Principal p = null;
142: if (info.getAction() == ACTION_SET) {
143: SerializablePrincipal sp = (SerializablePrincipal) info
144: .getValue();
145: p = (Principal) sp.getPrincipal(session
146: .getManager().getContainer().getRealm());
147: }
148: session.setPrincipal(p, false);
149: break;
150: }//case
151: default:
152: throw new java.lang.IllegalArgumentException(
153: "Invalid attribute info type=" + info);
154: }//switch
155: }//for
156: session.endAccess();
157: }
158:
159: public void reset() {
160: while (actions.size() > 0) {
161: AttributeInfo info = (AttributeInfo) actions.removeFirst();
162: info.recycle();
163: actionPool.addLast(info);
164: }
165: actions.clear();
166: }
167:
168: public String getSessionId() {
169: return sessionId;
170: }
171:
172: public void setSessionId(String sessionId) {
173: this .sessionId = sessionId;
174: if (sessionId == null) {
175: new Exception("Session Id is null for setSessionId")
176: .fillInStackTrace().printStackTrace();
177: }
178: }
179:
180: public int getSize() {
181: return actions.size();
182: }
183:
184: public void clear() {
185: actions.clear();
186: actionPool.clear();
187: }
188:
189: public void readExternal(java.io.ObjectInput in)
190: throws java.io.IOException,
191: java.lang.ClassNotFoundException {
192: //sessionId - String
193: //recordAll - boolean
194: //size - int
195: //AttributeInfo - in an array
196: reset();
197: sessionId = in.readUTF();
198: recordAllActions = in.readBoolean();
199: int cnt = in.readInt();
200: if (actions == null)
201: actions = new LinkedList();
202: else
203: actions.clear();
204: for (int i = 0; i < cnt; i++) {
205: AttributeInfo info = null;
206: if (this .actionPool.size() > 0) {
207: info = (AttributeInfo) actionPool.removeFirst();
208: } else {
209: info = new AttributeInfo(-1, -1, null, null);
210: }
211: info.readExternal(in);
212: actions.addLast(info);
213: }//for
214: }
215:
216: public void writeExternal(java.io.ObjectOutput out)
217: throws java.io.IOException {
218: //sessionId - String
219: //recordAll - boolean
220: //size - int
221: //AttributeInfo - in an array
222: out.writeUTF(getSessionId());
223: out.writeBoolean(recordAllActions);
224: out.writeInt(getSize());
225: for (int i = 0; i < getSize(); i++) {
226: AttributeInfo info = (AttributeInfo) actions.get(i);
227: info.writeExternal(out);
228: }
229: }
230:
231: public static class AttributeInfo implements java.io.Externalizable {
232: private String name = null;
233: private Object value = null;
234: private int action;
235: private int type;
236:
237: public AttributeInfo() {
238: }
239:
240: public AttributeInfo(int type, int action, String name,
241: Object value) {
242: super ();
243: init(type, action, name, value);
244: }
245:
246: public void init(int type, int action, String name, Object value) {
247: this .name = name;
248: this .value = value;
249: this .action = action;
250: this .type = type;
251: }
252:
253: public int getType() {
254: return type;
255: }
256:
257: public int getAction() {
258: return action;
259: }
260:
261: public Object getValue() {
262: return value;
263: }
264:
265: public int hashCode() {
266: return name.hashCode();
267: }
268:
269: public String getName() {
270: return name;
271: }
272:
273: public void recycle() {
274: name = null;
275: value = null;
276: type = -1;
277: action = -1;
278: }
279:
280: public boolean equals(Object o) {
281: if (!(o instanceof AttributeInfo))
282: return false;
283: AttributeInfo other = (AttributeInfo) o;
284: return other.getName().equals(this .getName());
285: }
286:
287: public void readExternal(java.io.ObjectInput in)
288: throws java.io.IOException,
289: java.lang.ClassNotFoundException {
290: //type - int
291: //action - int
292: //name - String
293: //value - object
294: type = in.readInt();
295: action = in.readInt();
296: name = in.readUTF();
297: value = in.readObject();
298: }
299:
300: public void writeExternal(java.io.ObjectOutput out)
301: throws java.io.IOException {
302: //type - int
303: //action - int
304: //name - String
305: //value - object
306: out.writeInt(getType());
307: out.writeInt(getAction());
308: out.writeUTF(getName());
309: out.writeObject(getValue());
310: }
311:
312: public String toString() {
313: StringBuffer buf = new StringBuffer("AttributeInfo[type=");
314: buf.append(getType()).append(", action=").append(
315: getAction());
316: buf.append(", name=").append(getName()).append(", value=")
317: .append(getValue());
318: buf.append(", addr=").append(super .toString()).append("]");
319: return buf.toString();
320: }
321:
322: }
323:
324: }
|