001: /*
002: * Helma License Notice
003: *
004: * The contents of this file are subject to the Helma License
005: * Version 2.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://adele.helma.org/download/helma/license.txt
008: *
009: * Copyright 1998-2003 Helma Software. All Rights Reserved.
010: *
011: * $RCSfile$
012: * $Author: hannes $
013: * $Revision: 8687 $
014: * $Date: 2007-12-06 21:18:59 +0100 (Don, 06 Dez 2007) $
015: */
016:
017: package helma.framework.core;
018:
019: import helma.objectmodel.*;
020: import helma.objectmodel.db.*;
021: import helma.framework.ResponseTrans;
022: import helma.framework.UploadStatus;
023:
024: import java.io.*;
025: import java.util.*;
026:
027: /**
028: * This represents a session currently using the Hop application.
029: * This includes anybody who happens to request a page from this application.
030: * Depending on whether the user is logged in or not, the session holds a
031: * persistent user node.
032: */
033: public class Session implements Serializable {
034:
035: transient protected Application app;
036: protected String sessionId;
037:
038: // the unique id (login name) for the user, if logged in
039: protected String uid;
040:
041: // the handle to this user's persistent db node, if logged in
042: protected NodeHandle userHandle;
043:
044: // the transient cache node that is exposed to javascript
045: // this stays the same across logins and logouts.
046: protected TransientNode cacheNode;
047: protected long onSince;
048: protected long lastTouched;
049: protected long lastModified;
050:
051: // used to remember messages to the user between requests, mainly between redirects.
052: protected String message;
053: protected StringBuffer debugBuffer;
054:
055: protected HashMap uploads = null;
056:
057: /**
058: * Creates a new Session object.
059: *
060: * @param sessionId ...
061: * @param app ...
062: */
063: public Session(String sessionId, Application app) {
064: this .sessionId = sessionId;
065: this .app = app;
066: this .uid = null;
067: this .userHandle = null;
068: cacheNode = new TransientNode("session");
069: onSince = System.currentTimeMillis();
070: lastTouched = lastModified = onSince;
071: }
072:
073: /**
074: * Attach the given user node to this session.
075: */
076: public void login(INode usernode) {
077: if (usernode == null) {
078: userHandle = null;
079: uid = null;
080: } else {
081: userHandle = ((Node) usernode).getHandle();
082: uid = usernode.getElementName();
083: }
084:
085: lastModified = System.currentTimeMillis();
086: }
087:
088: /**
089: * Try logging in this session given the userName and password.
090: *
091: * @param userName
092: * @param password
093: * @return true if session was logged in.
094: */
095: public boolean login(String userName, String password) {
096: return app.loginSession(userName, password, this );
097: }
098:
099: /**
100: * Remove this sessions's user node.
101: */
102: public void logout() {
103: if (userHandle != null) {
104: try {
105: // Invoke User.onLogout() iff this is a transactor request with a request
106: // evaluator already associated (i.e., if this is called from an app/script).
107: // Otherwise, we assume being called from the scheduler thread, which takes
108: // care of calling User.onLogout().
109: RequestEvaluator reval = app
110: .getCurrentRequestEvaluator();
111: if (reval != null) {
112: Node userNode = userHandle.getNode(app.nmgr.safe);
113: if (userNode != null)
114: reval.invokeDirectFunction(userNode,
115: "onLogout", new Object[] { sessionId });
116: }
117: } catch (Exception x) {
118: // errors should already be logged by request evaluator, but you never know
119: app.logError("Error in onLogout", x);
120: } finally {
121: // do log out
122: userHandle = null;
123: uid = null;
124: lastModified = System.currentTimeMillis();
125: }
126: }
127: }
128:
129: /**
130: * Returns true if this session is currently associated with a user object.
131: *
132: * @return ...
133: */
134: public boolean isLoggedIn() {
135: return (userHandle != null) && (uid != null);
136: }
137:
138: /**
139: * Set the user handle for this session.
140: */
141: public void setUserHandle(NodeHandle handle) {
142: this .userHandle = handle;
143: }
144:
145: /**
146: * Get the Node handle for the current user, if logged in.
147: */
148: public NodeHandle getUserHandle() {
149: return userHandle;
150: }
151:
152: /**
153: * Gets the user Node from this Application's NodeManager.
154: */
155: public INode getUserNode() {
156: if (userHandle != null) {
157: return userHandle.getNode(app.getWrappedNodeManager());
158: } else {
159: return null;
160: }
161: }
162:
163: /**
164: * Set the cache node for this session.
165: */
166: public void setCacheNode(TransientNode node) {
167: this .cacheNode = node;
168: }
169:
170: /**
171: * Gets the transient cache node.
172: */
173: public INode getCacheNode() {
174: return cacheNode;
175: }
176:
177: /**
178: * Get this session's application
179: *
180: * @return ...
181: */
182: public Application getApp() {
183: return app;
184: }
185:
186: /**
187: * Set this session's application
188: *
189: * @param app ...
190: */
191: public void setApp(Application app) {
192: this .app = app;
193: }
194:
195: /**
196: * Return this session's id.
197: *
198: * @return ...
199: */
200: public String getSessionId() {
201: return sessionId;
202: }
203:
204: /**
205: * Called at the beginning of a request to let the session know it's
206: * being used.
207: */
208: public void touch() {
209: lastTouched = System.currentTimeMillis();
210: }
211:
212: /**
213: * Called after a request has been handled.
214: *
215: * @param reval the request evaluator that handled the request
216: */
217: public void commit(RequestEvaluator reval) {
218: // nothing to do
219: }
220:
221: /**
222: * Returns the time this session was last touched.
223: *
224: * @return ...
225: */
226: public long lastTouched() {
227: return lastTouched;
228: }
229:
230: /**
231: * Returns the time this session was last modified, meaning the last time
232: * its user status changed or its cache node was modified.
233: *
234: * @return ...
235: */
236: public long lastModified() {
237: return lastModified;
238: }
239:
240: /**
241: * Set the last modified time on this session.
242: *
243: * @param date ...
244: */
245: public void setLastModified(Date date) {
246: if (date != null) {
247: lastModified = date.getTime();
248: }
249: }
250:
251: /**
252: * Return the time this session was created.
253: *
254: * @return ...
255: */
256: public long onSince() {
257: return onSince;
258: }
259:
260: /**
261: * Return a string representation for this session.
262: *
263: * @return ...
264: */
265: public String toString() {
266: if (uid != null) {
267: return "[Session for user " + uid + "]";
268: } else {
269: return "[Anonymous Session]";
270: }
271: }
272:
273: /**
274: * Get the persistent user id of a registered user.
275: * This is usually the user name, or null if the user is not logged in.
276: */
277: public String getUID() {
278: return uid;
279: }
280:
281: /**
282: * Set the user and debug messages over from a previous response.
283: * This is used for redirects, where messages can't be displayed immediately.
284: * @param res the response to set the messages on
285: */
286: public synchronized void recoverResponseMessages(ResponseTrans res) {
287: if (message != null || debugBuffer != null) {
288: res.setMessage(message);
289: res.setDebugBuffer(debugBuffer);
290: message = null;
291: debugBuffer = null;
292: }
293: }
294:
295: /**
296: * Remember the response's user and debug messages for a later response.
297: * This is used for redirects, where messages can't be displayed immediately.
298: * @param res the response to retrieve the messages from
299: */
300: public synchronized void storeResponseMessages(ResponseTrans res) {
301: message = res.getMessage();
302: debugBuffer = res.getDebugBuffer();
303: }
304:
305: /**
306: * Return the message that is to be displayed upon the next
307: * request within this session.
308: *
309: * @return the message, or null if none was set.
310: */
311: public String getMessage() {
312: return message;
313: }
314:
315: /**
316: * Set a message to be displayed to this session's user. This
317: * can be used to save a message over to the next request when
318: * the current request can't be used to display a user visible
319: * message.
320: *
321: * @param msg the message
322: */
323: public void setMessage(String msg) {
324: message = msg;
325: }
326:
327: /**
328: * Return the debug buffer that is to be displayed upon the next
329: * request within this session.
330: *
331: * @return the debug buffer, or null if none was set.
332: */
333: public StringBuffer getDebugBuffer() {
334: return debugBuffer;
335: }
336:
337: /**
338: * Set the debug buffer to be displayed to this session's user. This
339: * can be used to save the debug buffer over to the next request when
340: * the current request can't be used to display a user visible
341: * message.
342: *
343: * @param buffer the buffer
344: */
345: public void setDebugBuffer(StringBuffer buffer) {
346: debugBuffer = buffer;
347: }
348:
349: protected UploadStatus createUpload(String uploadId) {
350: if (uploads == null) {
351: uploads = new HashMap();
352: }
353: UploadStatus status = new UploadStatus();
354: uploads.put(uploadId, status);
355: return status;
356: }
357:
358: protected UploadStatus getUpload(String uploadId) {
359: if (uploads == null) {
360: return null;
361: } else {
362: return (UploadStatus) uploads.get(uploadId);
363: }
364: }
365:
366: protected void pruneUploads() {
367: if (uploads == null || uploads.isEmpty())
368: return;
369: for (Iterator it = uploads.values().iterator(); it.hasNext();) {
370: UploadStatus status = (UploadStatus) it.next();
371: if (status.isDisposable()) {
372: it.remove();
373: }
374: }
375: }
376: }
|