Merged in changes from Stefan Pollach's "usersession_05_15" branch.

This commit is contained in:
hns 2002-05-31 13:35:33 +00:00
parent 5818dd8d52
commit 7bfc14d164
17 changed files with 833 additions and 753 deletions

View file

@ -0,0 +1,61 @@
package helma.framework;
import java.io.Serializable;
import java.util.Map;
import helma.framework.core.Application;
public class RequestBean implements Serializable {
RequestTrans req;
public RequestBean(RequestTrans req) {
this.req = req;
}
public Object get (String name) {
return req.get (name);
}
public boolean isGet () {
return req.isGet ();
}
public boolean isPost () {
return req.isPost ();
}
public String toString() {
return "[Request]";
}
// property related methods:
public String getaction () {
return req.action;
}
public Map getdata () {
return req.getRequestData ();
}
public long getruntime () {
return (System.currentTimeMillis() - req.startTime);
}
public String getpassword () {
return req.getPassword ();
}
public String getpath () {
return req.path;
}
public String getusername () {
return req.getUsername ();
}
}

View file

@ -0,0 +1,138 @@
package helma.framework;
import java.io.Serializable;
import java.util.Map;
import helma.framework.core.Application;
public class ResponseBean implements Serializable {
ResponseTrans res;
public ResponseBean(ResponseTrans res) {
this.res = res;
}
public void encode (Object what) {
res.encode (what);
}
public void encodeXml (Object what) {
res.encodeXml (what);
}
public void format (Object what) {
res.format (what);
}
public void pushStringBuffer () {
res.pushStringBuffer ();
}
public String popStringBuffer () {
return res.popStringBuffer ();
}
public void redirect (String url) throws RedirectException {
res.redirect (url);
}
public void reset () {
res.reset ();
}
public void setCookie (String key, String value) {
res.setCookie (key, value, -1);
}
public void setCookie (String key, String value, int days) {
res.setCookie (key, value, days);
}
public void write (Object what) {
res.write (what);
}
public void writeln (Object what) {
res.writeln (what);
}
public void writeBinary (byte[] what) {
res.writeBinary (what);
}
public String toString() {
return "[Response]";
}
// property-related methods:
public boolean getcache () {
return res.cache;
}
public void setcache (boolean cache) {
res.cache = cache;
}
public String getcharset () {
return res.charset;
}
public void setcharset (String charset) {
res.charset = charset;
}
public String getcontentType () {
return res.contentType;
}
public void setcontentType (String contentType) {
res.contentType = contentType;
}
public Map getdata () {
return res.getResponseData ();
}
public String geterror () {
return res.error;
}
public String getmessage () {
return res.message;
}
public void setmessage (String message) {
res.message = message;
}
public String getrealm () {
return res.realm;
}
public void setrealm (String realm) {
res.realm = realm;
}
public void setskinpath (Object[] arr) {
res.setTranslatedSkinpath (arr);
}
public Object[] getskinpath () {
return res.getTranslatedSkinpath ();
}
public int getstatus () {
return res.status;
}
public void setstatus (int status) {
res.status = status;
}
}

View file

@ -8,7 +8,6 @@ import helma.doc.DocException;
import helma.framework.*;
import helma.main.Server;
import helma.scripting.*;
import helma.scripting.fesi.ESUser;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import helma.xmlrpc.*;
@ -66,10 +65,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
boolean stopped = false;
boolean debug;
public long starttime;
long starttime;
public Hashtable sessions;
public Hashtable activeUsers;
Hashtable sessions;
Hashtable dbMappings;
Hashtable dbSources;
@ -86,7 +84,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
protected String templateExtension, scriptExtension, actionExtension, skinExtension;
// A transient node that is shared among all evaluators
protected INode appnode;
protected INode cachenode;
protected volatile long requestCount = 0;
protected volatile long xmlrpcCount = 0;
protected volatile long errorCount = 0;
@ -218,11 +216,10 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
skinExtension = ".skin";
sessions = new Hashtable ();
activeUsers = new Hashtable ();
dbMappings = new Hashtable ();
dbSources = new Hashtable ();
appnode = new TransientNode ("app");
cachenode = new TransientNode ("app");
xmlrpc = helma.main.Server.getXmlRpcServer ();
xmlrpcAccess = new XmlRpcAccess (this);
}
@ -262,8 +259,11 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
String usernameField = userMapping.getNameField ();
if (usernameField == null)
usernameField = "name";
p.put ("_properties", "user."+usernameField);
p.put ("_version","1.2");
p.put ("_children", "collection(user)");
p.put ("_children.accessname", usernameField);
userRootMapping = new DbMapping (this, "__userroot__", p);
rewireDbMappings ();
nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props);
@ -399,7 +399,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
requestCount += 1;
// get user for this request's session
User u = getUser (req.session);
Session session = checkSession (req.session);
session.touch();
ResponseTrans res = null;
RequestEvaluator ev = null;
@ -418,7 +419,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
// if attachRequest returns null this means we came too late
// and the other request was finished in the meantime
ev = getEvaluator ();
res = ev.invoke (req, u);
res = ev.invoke (req, session);
}
} catch (ApplicationStoppedException stopped) {
// let the servlet know that this application has gone to heaven
@ -441,7 +442,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
res.waitForClose ();
}
}
return res;
}
@ -530,8 +531,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
/**
* Return a transient node that is shared by all evaluators of this application ("app node")
*/
public INode getAppNode () {
return appnode;
public INode getCacheNode () {
return cachenode;
}
@ -570,51 +571,130 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
}
/**
* Retrurn a skin for a given object. The skin is found by determining the prototype
* Return a skin for a given object. The skin is found by determining the prototype
* to use for the object, then looking up the skin for the prototype.
*/
public Skin getSkin (Object object, String skinname, Object[] skinpath) {
return skinmgr.getSkin (object, skinname, skinpath);
return skinmgr.getSkin (object, skinname, skinpath);
}
/**
* Return the user currently associated with a given Hop session ID. This may be
* a registered or an anonymous user.
* Return the session currently associated with a given Hop session ID.
* Create a new session if necessary.
*/
public User getUser (String sessionID) {
if (sessionID == null)
return null;
User u = (User) sessions.get (sessionID);
if (u != null) {
u.touch ();
} else {
u = new User (sessionID, this);
sessions.put (sessionID, u);
public Session checkSession (String sessionID) {
Session session = getSession(sessionID);
if ( session==null ) {
session = new Session (sessionID, this);
sessions.put (sessionID, session);
}
return u;
return session;
}
/**
* Remove the session from the sessions-table and logout the user.
*/
public void destroySession (String sessionID) {
logoutSession (getSession (sessionID));
sessions.remove (sessionID);
}
/**
* Remove the session from the sessions-table and logout the user.
*/
public void destroySession (Session session) {
logoutSession (session);
sessions.remove (session.getSessionID ());
}
public Enumeration getActiveUsers () {
return new SessionFilter (null);
}
/**
* Return an array of session currently associated with a given Hop user object.
*/
public Enumeration getSessionsForUsername (String username) {
return new SessionFilter (username);
}
class SessionFilter implements Enumeration {
String username;
Session nextSession;
Enumeration sessionEnum;
Vector usernames;
SessionFilter (String username) {
this.username = username;
if (username==null)
usernames = new Vector();
sessionEnum = sessions.elements ();
nextSession = nextValidSession ();
}
public boolean hasMoreElements () {
if (nextSession==null)
return false;
else
return true;
}
public Object nextElement () {
Session thisSession = nextSession;
nextSession = nextValidSession ();
return thisSession;
}
private Session nextValidSession () {
while( sessionEnum.hasMoreElements () ) {
Session s = (Session)sessionEnum.nextElement ();
if(s==null) {
continue;
} else {
if (username!=null && username.equals(s.getUID ())) {
// returns a session if it is logged in and fits
// the given username
return s;
} else if (username==null && s.isLoggedIn()==true && !usernames.contains (s.getUID ()) ) {
// returns a session if it is logged in and has not been
// returned before (so for each logged-in user we get one
// session object, even if this user is logged in several
// times (used to retrieve the active users list).
usernames.add (s.getUID ());
return s;
}
}
}
return null;
}
}
/**
* Return the session currently associated with a given Hop session ID.
*/
public Session getSession (String sessionID) {
if (sessionID == null)
return null;
return (Session) sessions.get (sessionID);
}
/**
* Register a user with the given user name and password.
*/
public INode registerUser (String uname, String password) {
// Register a user who already has a user object
// (i.e. who has been surfing around)
if (uname == null)
return null;
uname = uname.toLowerCase ().trim ();
if ("".equals (uname))
return null;
INode unode = null;
try {
INode users = getUserRoot ();
unode = users.getNode (uname, false);
if (unode != null)
if (unode != null)
return null;
unode = users.createNode (uname);
unode.setPrototype ("user");
unode.setDbMapping (userMapping);
@ -627,8 +707,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
unode.setName (uname);
unode.setString (usernameProp, uname);
unode.setString ("password", password);
// users.setNode (uname, unode);
// return users.getNode (uname, false);
return unode;
} catch (Exception x) {
logEvent ("Error registering User: "+x);
@ -639,26 +717,23 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
/**
* Log in a user given his or her user name and password.
*/
public boolean loginUser (String uname, String password, ESUser u) {
// Check the name/password of a user who already has a user object
// (i.e. who has been surfing around)
public boolean loginSession (String uname, String password, Session session) {
// Check the name/password of a user and log it in to the current session
if (uname == null)
return false;
uname = uname.toLowerCase ().trim ();
if ("".equals (uname))
return false;
try {
INode users = getUserRoot ();
INode unode = users.getNode (uname, false);
Node unode = (Node)users.getNode (uname, false);
String pw = unode.getString ("password", false);
if (pw != null && pw.equals (password)) {
// give the user his/her persistant node
u.setNode (unode);
activeUsers.put (unode.getName (), u.user);
// let the old user-object forget about this session
logoutSession(session);
session.login (unode);
return true;
}
} catch (Exception x) {
return false;
}
@ -666,18 +741,10 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
}
/**
* Log out a user from this application.
* Log out a session from this application.
*/
public boolean logoutUser (ESUser u) {
if (u.user != null) {
String uid = u.user.uid;
if (uid != null)
activeUsers.remove (uid);
// switch back to the non-persistent user node as cache
u.setNode (null);
}
return true;
public void logoutSession (Session session) {
session.logout();
}
/**
@ -725,13 +792,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
if (rootproto != null && rootproto.equals (getPrototypeName (p)))
break;
b.insert (0, divider);
// users always have a canonical URL like /users/username
if ("user".equals (getPrototypeName (p))) {
b.insert (0, URLEncoder.encode (getElementName (p)));
p = users;
break;
}
b.insert (0, URLEncoder.encode (getElementName (p)));
p = getParentElement (p);
@ -739,11 +799,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
break;
}
if (p == users) {
b.insert (0, divider);
b.insert (0, "users");
}
if (actionName != null)
b.append (URLEncoder.encode (actionName));
@ -957,29 +1012,25 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
int sessionTimeout = 30;
try {
sessionTimeout = Math.max (0, Integer.parseInt (props.getProperty ("sessionTimeout", "30")));
} catch (Exception ignore) {}
} catch (Exception ignore) {
System.out.println(ignore.toString());
}
long now = System.currentTimeMillis ();
// check if we should clean up user sessions
if (now - lastCleanup > cleanupSleep) try {
lastCleanup = now;
// logEvent ("Cleaning up "+name+": " + sessions.size () + " sessions active");
Hashtable cloned = (Hashtable) sessions.clone ();
for (Enumeration e = cloned.elements (); e.hasMoreElements (); ) {
User u = (User) e.nextElement ();
if (now - u.lastTouched () > sessionTimeout * 60000) {
if (u.uid != null) {
try {
eval.invokeFunction (u, "onLogout", new Object[0]);
} catch (Exception ignore) {}
activeUsers.remove (u.uid);
}
sessions.remove (u.getSessionID ());
u.setNode (null);
Session session = (Session) e.nextElement ();
if (now - session.lastTouched () > sessionTimeout * 60000) {
// if (session.uid != null) {
// FIXME onlogout()! try {eval.invokeFunction (u, "onLogout", new Object[0]);} catch (Exception ignore) {}
// }
destroySession(session);
}
}
// logEvent ("Cleaned up "+name+": " + sessions.size () + " sessions remaining");
} catch (Exception cx) {
logEvent ("Error cleaning up sessions: "+cx);
cx.printStackTrace ();
@ -1126,9 +1177,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
return props.getProperty (propname, defvalue);
}
public SystemProperties getProperties() {
return props;
}
public SystemProperties getProperties() {
return props;
}
/**
*

View file

@ -0,0 +1,195 @@
package helma.framework.core;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import helma.objectmodel.INode;
public class ApplicationBean implements Serializable {
Application app;
public ApplicationBean(Application app) {
this.app = app;
}
public void clearCache () {
app.clearCache ();
}
public void log (String msg) {
app.logEvent (msg);
}
public void log (String logname, String msg) {
app.getLogger (logname).log (msg);
}
public void debug (String msg) {
if (app.debug()) {
app.logEvent (msg);
}
}
public void debug (String logname, String msg) {
if (app.debug()) {
app.getLogger (logname).log (msg);
}
}
public int countSessions () {
return app.sessions.size();
}
public SessionBean getSession (String sessionID) {
if (sessionID==null)
return null;
Session session = app.getSession (sessionID.trim ());
if (session == null)
return null;
return new SessionBean (session);
}
public SessionBean createSession (String sessionID) {
if (sessionID==null)
return null;
Session session = session = app.checkSession (sessionID.trim ());
if (session == null)
return null;
return new SessionBean (session);
}
public SessionBean[] getSessions () {
SessionBean[] theArray = new SessionBean[app.sessions.size()];
int i=0;
for (Enumeration e=app.sessions.elements(); e.hasMoreElements(); ) {
SessionBean sb = new SessionBean ((Session) e.nextElement ());
theArray[i++] = sb;
}
return theArray;
}
public INode registerUser (String username, String password) {
if (username==null || password==null || "".equals (username.trim ()) || "".equals (password.trim ()) )
return null;
else
return app.registerUser (username, password);
}
public INode getUser (String username) {
if (username==null || "".equals (username.trim()) )
return null;
return app.getUserNode (username);
}
public INode[] getActiveUsers () {
Enumeration loggedInSessions = app.getActiveUsers ();
if (loggedInSessions.hasMoreElements ()==false)
return new INode[0];
ArrayList theArray = new ArrayList();
while (loggedInSessions.hasMoreElements ()) {
INode usernode = ((Session) loggedInSessions.nextElement ()).getUserNode ();
if (usernode!=null)
theArray.add (usernode);
}
return (INode[]) theArray.toArray (new INode[0]);
}
public SessionBean[] getSessionsForUser (INode usernode) {
if (usernode==null)
return new SessionBean[0];
else
return getSessionsForUser(usernode.getName());
}
public SessionBean[] getSessionsForUser (String username) {
if (username==null || "".equals (username.trim ()) )
return new SessionBean[0];
Enumeration userSessions = app.getSessionsForUsername (username);
if (userSessions.hasMoreElements()==false )
return new SessionBean[0];
ArrayList theArray = new ArrayList();
while (userSessions.hasMoreElements() ) {
SessionBean sb = new SessionBean ((Session) userSessions.nextElement ());
theArray.add(sb);
}
return (SessionBean[]) theArray.toArray (new SessionBean[0]);
}
// getter methods for readonly properties of this application
public INode getdata() {
return app.getCacheNode ();
}
public Date getupSince () {
return new Date (app.starttime);
}
public long getrequestCount () {
return app.getRequestCount ();
}
public long getxmlrpcCount () {
return app.getXmlrpcCount ();
}
public long geterrorCount () {
return app.getErrorCount ();
}
public Application get__app__ () {
return app;
}
public Map getproperties () {
return app.getProperties ();
}
public int getfreeThreads () {
return app.countFreeEvaluators ();
}
public int getactiveThreads () {
return app.countActiveEvaluators ();
}
public int getmaxThreads () {
return app.countEvaluators ();
}
public void setmaxThreads (int n) {
// add one to the number to compensate for the internal scheduler.
app.setNumberOfEvaluators (n+1);
}
public Map getskinfiles () {
Map skinz = new Hashtable ();
for (Iterator it = app.getPrototypes().iterator(); it.hasNext(); ) {
Prototype p = (Prototype) it.next ();
Map proto = new Hashtable ();
for (Iterator it2 = p.skins.values().iterator(); it2.hasNext(); ) {
SkinFile sf = (SkinFile) it2.next ();
String name = sf.getName ();
Skin skin = sf.getSkin ();
proto.put (name, skin.getSource ());
}
skinz.put (p.getName (), proto);
}
return skinz;
}
public String toString() {
return "[Application " + app.getName() + "]";
}
}

View file

@ -35,8 +35,8 @@ public class RequestEvaluator implements Runnable {
// the method to be executed
String method;
// the user object associated with the current request
User user;
// the session object associated with the current request
Session session;
// arguments passed to the function
Object[] args;
@ -113,17 +113,18 @@ public class RequestEvaluator implements Runnable {
HashMap globals = new HashMap ();
globals.put ("root", root);
globals.put ("user", user);
globals.put ("session", session);
globals.put ("req", req);
globals.put ("res", res);
globals.put ("path", requestPath);
globals.put ("app", app.getAppNode());
globals.put ("app", app);
req.startTime = System.currentTimeMillis ();
if (error != null)
res.error = error;
if (user.message != null) {
if (session.message != null) {
// bring over the message from a redirect
res.message = user.message;
user.message = null;
res.message = session.message;
session.message = null;
}
try {
@ -284,7 +285,7 @@ public class RequestEvaluator implements Runnable {
// res.redirect = redirect.getMessage ();
// if there is a message set, save it on the user object for the next request
if (res.message != null)
user.message = res.message;
session.message = res.message;
done = true;
}
@ -360,7 +361,7 @@ public class RequestEvaluator implements Runnable {
HashMap globals = new HashMap ();
globals.put ("root", root);
globals.put ("res", res);
globals.put ("app", app.getAppNode());
globals.put ("app", app);
currentElement = root;
@ -419,7 +420,7 @@ public class RequestEvaluator implements Runnable {
HashMap globals = new HashMap ();
globals.put ("root", root);
globals.put ("res", res);
globals.put ("app", app.getAppNode());
globals.put ("app", app);
app.scriptingEngine.invoke (thisObject, method, args, globals, this);
commitTransaction ();
@ -497,10 +498,10 @@ public class RequestEvaluator implements Runnable {
} catch (InterruptedException ir) {}
}
public synchronized ResponseTrans invoke (RequestTrans req, User user) throws Exception {
public synchronized ResponseTrans invoke (RequestTrans req, Session session) throws Exception {
this.reqtype = HTTP;
this.req = req;
this.user = user;
this.session = session;
this.res = new ResponseTrans ();
app.activeRequests.put (req, this);
@ -534,7 +535,7 @@ public class RequestEvaluator implements Runnable {
public synchronized Object invokeXmlRpc (String method, Object[] args) throws Exception {
this.reqtype = XMLRPC;
this.user = null;
this.session = null;
this.method = method;
this.args = args;
this.res = new ResponseTrans ();
@ -559,7 +560,7 @@ public class RequestEvaluator implements Runnable {
public synchronized Object invokeFunction (Object object, String functionName, Object[] args)
throws Exception {
reqtype = INTERNAL;
user = null;
session = null;
thisObject = object;
method = functionName;
this.args =args;
@ -579,10 +580,10 @@ public class RequestEvaluator implements Runnable {
return result;
}
public synchronized Object invokeFunction (User user, String functionName, Object[] args)
public synchronized Object invokeFunction (Session session, String functionName, Object[] args)
throws Exception {
reqtype = INTERNAL;
this.user = user;
this.session = session;
thisObject = null;
method = functionName;
this.args = args;

View file

@ -0,0 +1,131 @@
// Session.java
package helma.framework.core;
import java.io.*;
import java.util.*;
import java.net.URLEncoder;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
/**
* This represents a session currently using the Hop application.
* This comprends anybody who happens to surf the site.
* Depending on whether the user is logged in or not, the user object holds a
* persistent user node.
*/
public class Session implements Serializable {
Application app;
String sessionID;
// the unique id (login name) for the user, if logged in
String uid;
// the handle to this user's persistent db node, if logged in
NodeHandle userHandle;
// the transient cache node that is exposed to javascript
// this stays the same across logins and logouts.
public TransientNode cacheNode;
long onSince, lastTouched;
// used to remember messages to the user between requests -
// used for redirects.
String message;
public Session (String sessionID, Application app) {
this.sessionID = sessionID;
this.app = app;
this.uid = null;
this.userHandle = null;
cacheNode = new TransientNode ("session");
onSince = System.currentTimeMillis ();
lastTouched = onSince;
}
/**
* attach the given user node to this session.
*/
public void login (INode usernode) {
if (usernode==null) {
userHandle = null;
uid = null;
} else {
userHandle = ((Node)usernode).getHandle();
uid = usernode.getElementName();
}
}
/**
* remove this sessions's user node.
*/
public void logout() {
userHandle = null;
uid = null;
}
public boolean isLoggedIn() {
if (userHandle!=null && uid!=null) {
return true;
} else {
return false;
}
}
/**
* Gets the user Node from this Application's NodeManager.
*/
public INode getUserNode() {
if (userHandle!=null)
return userHandle.getNode (app.getWrappedNodeManager());
else
return null;
}
/**
* Gets the transient cache node.
*/
public INode getCacheNode () {
return cacheNode;
}
public Application getApp () {
return app;
}
public String getSessionID () {
return sessionID;
}
public void touch () {
lastTouched = System.currentTimeMillis ();
}
public long lastTouched () {
return lastTouched;
}
public long onSince () {
return onSince;
}
public String toString () {
if ( uid!=null )
return "[Session for user " + uid + "]";
else
return "[Anonymous Session]";
}
/**
* Get the persistent user id of a registered user. This is usually the user name, or
* null if the user is not logged in.
*/
public String getUID () {
return uid;
}
}

View file

@ -0,0 +1,73 @@
package helma.framework.core;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import helma.objectmodel.INode;
import helma.scripting.ScriptingEnvironment;
import helma.scripting.ScriptingException;
import helma.scripting.fesi.*;
public class SessionBean implements Serializable {
// the wrapped session object
Session session;
public SessionBean(Session session) {
this.session = session;
}
public String toString() {
return session.toString ();
}
public boolean login (String username, String password) {
boolean success = session.getApp().loginSession (username, password, session);
return success;
}
public void logout () {
session.getApp().logoutSession (session);
}
public void touch () {
session.touch ();
}
public Date lastActive() {
return new Date (session.lastTouched ());
}
public Date onSince() {
return new Date (session.onSince ());
}
// property-related methods:
public INode getdata() {
return session.getCacheNode ();
}
public INode getuser() {
return session.getUserNode();
}
public String get_id () {
return session.getSessionID ();
}
public String getcookie() {
return session.getSessionID ();
}
public Date getlastActive() {
return new Date (session.lastTouched ());
}
public Date getonSince() {
return new Date (session.onSince ());
}
}

View file

@ -266,10 +266,7 @@ public class Skin {
boolean objectFound = true;
if (handler != null) {
if ("currentuser".equalsIgnoreCase (handler)) {
// as a special convention, we use "currentuser" to access macros in the current user object
handlerObject = reval.user.getNode ();
} else if (thisObject != null) {
if (thisObject != null) {
// not a global macro - need to find handler object
// was called with this object - check it or its parents for matching prototype
if (!handler.equalsIgnoreCase ("this") && !handler.equalsIgnoreCase (app.getPrototypeName (thisObject))) {

View file

@ -1,134 +0,0 @@
// User.java
// Copyright (c) Hannes Wallnöfer 1998-2000
package helma.framework.core;
import java.io.*;
import java.util.*;
import java.net.URLEncoder;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
/**
* This represents a user who is currently using the Hop application. This does
* not just comprend registered users, but anybody who happens to surf the site.
* Depending on whether the user is logged in or not, the user object holds a
* persistent user node or just a transient cache node
*/
public class User implements Serializable {
Application app;
String sessionID;
// the unique id (login name) for the user, if logged in
String uid;
// the handle to this user's persistent db node, if logged in
NodeHandle nhandle;
// the transient cache node. This stays the same across logins and logouts.
// If logged out, this also represents the user's main node.
TransientNode cache;
DbMapping umap;
long onSince, lastTouched;
// used to remember messages to the user between requests -
// used for redirects.
String message;
public User (String sid, Application app) {
this.uid = null;
this.nhandle = null;
this.app = app;
setNode (null);
umap = app.getDbMapping ("user");
cache = new TransientNode ("[session cache]");
cache.setPrototype ("user");
cache.setDbMapping (umap);
sessionID = sid;
onSince = System.currentTimeMillis ();
lastTouched = onSince;
}
/**
* This is used to turn for login and logout.
* Calling this weith a DB Node object will turn an anonymous user into a registered or known one.
* The user object remains the same, but he or she gets some persistent storage.
* On the other side, calling this method with a parameter value of null is means the user
* is logged out and will be represented by its transient cache node.
*/
public void setNode (INode n) {
// IServer.getLogger().log ("esn = "+esn);
if (n == null) {
nhandle = null;
uid = null;
} else {
uid = n.getElementName ();
nhandle = ((Node) n).getHandle ();
}
// System.err.println ("User.setNode: "+nhandle);
}
public INode getNode () {
if (nhandle == null) {
return cache;
} else {
// in some special cases, a user's node handle may go bad, for instance
// if something bad happens during registration. For this reason, we check
// if the handle actually works. If not, it is reset to the transient cache, which
// means the user is logged out.
Node n = nhandle.getNode (app.nmgr.safe);
if (n == null) {
setNode (null);
return cache;
}
return n;
}
}
public String getSessionID () {
return sessionID;
}
public void touch () {
lastTouched = System.currentTimeMillis ();
}
public long lastTouched () {
return lastTouched;
}
public long onSince () {
return onSince;
}
/**
* Get the persistent user id of a registered user. This is usually the user name, or
* null if the user is not logged in.
*/
public String getUID () {
return uid;
}
/**
* Return the transient cache node for this user.
*/
public INode getCache () {
return cache;
}
/**
* Reset the session cache node, clearing all properties.
* This is done by recreating the cache node object.
*/
public void clearCache () {
cache = new TransientNode ("[session cache]");
cache.setPrototype ("user");
cache.setDbMapping (umap);
}
}

View file

@ -1,149 +0,0 @@
// ESAppNode.java
// Copyright (c) Hannes Wallnöfer 1998-2000
package helma.scripting.fesi;
import helma.framework.core.*;
import helma.objectmodel.*;
import FESI.Exceptions.*;
import FESI.Data.*;
import FESI.Interpreter.Evaluator;
import java.util.Iterator;
/**
* ESApp represents the app node of an application, providing an app-wide transient shared
* space as well as access to some app related runtime information.
*/
public class ESAppNode extends ESNode {
private Application app;
private DatePrototype createtime;
public ESAppNode (INode node, FesiEvaluator eval) throws EcmaScriptException {
super (eval.getPrototype("hopobject"), eval.getEvaluator(), node, eval);
app = eval.getApplication();
createtime = new DatePrototype (evaluator, node.created());
FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
putHiddenProperty("getThreads", new AppCountThreads ("getThreads", evaluator, fp));
putHiddenProperty("getMaxThreads", new AppCountEvaluators ("getMaxThreads", evaluator, fp));
putHiddenProperty("getFreeThreads", new AppCountFreeEvaluators ("getFreeThreads", evaluator, fp));
putHiddenProperty("getActiveThreads", new AppCountActiveEvaluators ("getActiveThreads", evaluator, fp));
putHiddenProperty("getMaxActiveThreads", new AppCountMaxActiveEvaluators ("getMaxActiveThreads", evaluator, fp));
putHiddenProperty("setMaxThreads", new AppSetNumberOfEvaluators ("setMaxThreads", evaluator, fp));
putHiddenProperty("clearCache", new AppClearCache ("clearCache", evaluator, fp));
}
/**
* Overrides getProperty to return some app-specific properties
*/
public ESValue getProperty (String propname, int hash) throws EcmaScriptException {
if ("requestCount".equals (propname)) {
return new ESNumber (app.getRequestCount ());
}
if ("xmlrpcCount".equals (propname)) {
return new ESNumber (app.getXmlrpcCount ());
}
if ("errorCount".equals (propname)) {
return new ESNumber (app.getErrorCount ());
}
if ("upSince".equals (propname)) {
return createtime;
}
if ("skinfiles".equals (propname)) {
ESObject skinz = new ObjectPrototype (null, evaluator);
for (Iterator it = app.getPrototypes().iterator(); it.hasNext(); ) {
Prototype p = (Prototype) it.next ();
ESObject proto = new ObjectPrototype (null, evaluator);
for (Iterator it2 = p.skins.values().iterator(); it2.hasNext(); ) {
SkinFile sf = (SkinFile) it2.next ();
String name = sf.getName ();
Skin skin = sf.getSkin ();
proto.putProperty (name, new ESString (skin.getSource ()), name.hashCode ());
}
skinz.putProperty (p.getName (), proto, p.getName ().hashCode ());
}
return skinz;
}
if ("__app__".equals (propname)) {
return new ESWrapper (app, evaluator);
}
return super.getProperty (propname, hash);
}
class AppCountEvaluators extends BuiltinFunctionObject {
AppCountEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 0);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return new ESNumber (app.countEvaluators ());
}
}
class AppCountFreeEvaluators extends BuiltinFunctionObject {
AppCountFreeEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 0);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return new ESNumber (app.countFreeEvaluators ());
}
}
class AppCountActiveEvaluators extends BuiltinFunctionObject {
AppCountActiveEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 0);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return new ESNumber (app.countActiveEvaluators ());
}
}
class AppCountMaxActiveEvaluators extends BuiltinFunctionObject {
AppCountMaxActiveEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 0);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return new ESNumber (app.countMaxActiveEvaluators ());
}
}
class AppCountThreads extends BuiltinFunctionObject {
AppCountThreads (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 0);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return new ESNumber (app.countThreads ());
}
}
class AppSetNumberOfEvaluators extends BuiltinFunctionObject {
AppSetNumberOfEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
RequestEvaluator ev = new RequestEvaluator (app);
if (arguments.length != 1)
return ESBoolean.makeBoolean (false);
// add one to the number to compensate for the internal scheduler.
return ESBoolean.makeBoolean (app.setNumberOfEvaluators (1 + arguments[0].toInt32()));
}
}
class AppClearCache extends BuiltinFunctionObject {
AppClearCache (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
app.clearCache ();
return ESBoolean.makeBoolean (true);
}
}
public String toString () {
return ("AppNode "+node.getElementName ());
}
}

View file

@ -0,0 +1,59 @@
package helma.scripting.fesi;
import java.util.Map;
import helma.objectmodel.INode;
import FESI.Interpreter.Evaluator;
import FESI.Exceptions.EcmaScriptException;
import FESI.Data.ESNull;
import FESI.Data.ESValue;
import FESI.Data.ESWrapper;
/**
* Wrap a Java Bean for use in EcmaScript.
*/
public class ESBeanWrapper extends ESWrapper {
FesiEvaluator eval;
public ESBeanWrapper (Object object, FesiEvaluator eval) {
super (object, eval.getEvaluator(),true);
this.eval = eval;
}
/**
* Wrap getProperty, return ESNode if INode would be returned.
*/
public ESValue getProperty(String propertyName, int hash)
throws EcmaScriptException {
try {
ESValue val = super.getProperty (propertyName, hash);
if (val instanceof ESWrapper && ((ESWrapper)val).getJavaObject() instanceof INode) {
return eval.getNodeWrapper( (INode) ((ESWrapper)val).getJavaObject() );
} else if (val instanceof ESWrapper && ((ESWrapper)val).getJavaObject() instanceof Map) {
return new ESMapWrapper(eval, (Map) ((ESWrapper)val).getJavaObject() );
} else {
return val;
}
} catch (Exception rte) {
return ESNull.theNull;
}
}
public void putProperty(String propertyName, ESValue propertyValue, int hash)
throws EcmaScriptException {
try {
super.putProperty (propertyName, propertyValue, hash);
} catch (Exception rte) {
// create a nice error message
throw new EcmaScriptException("can't set property " + propertyName +
" to this value on " + getJavaObject().toString() );
}
}
}

View file

@ -64,6 +64,8 @@ public class ESMapWrapper extends ESWrapper {
return new ESString ((String) val);
else if (val instanceof INode)
return fesi.getNodeWrapper ((INode) val);
else if (val instanceof Map)
return new ESMapWrapper (fesi, (Map)val);
else if (val instanceof ESValue)
return (ESValue) val;
return ESLoader.normalizeValue(val, evaluator);

View file

@ -1,121 +0,0 @@
// ESUser.java
// Copyright (c) Hannes Wallnöfer 1998-2000
package helma.scripting.fesi;
import helma.framework.core.*;
import helma.objectmodel.*;
import helma.objectmodel.db.Node;
import FESI.Interpreter.*;
import FESI.Exceptions.*;
import FESI.Data.*;
/**
* The ESUser is a special kind of Node object that represents a user of
* a Helma application. The actual user session data are kept in class User.
* If the user is logged in as a registered member, the wrapped node represents
* the user object in the database, while for anonymous surfers the node object
* is just a transient node. <p>
* This means that the wrapped node will be swapped when the user logs in or out.
* To save session state across logins and logouts, the
* cache property of the user object stays the same for the whole time the user
* spends on this site.
*/
public class ESUser extends ESNode {
/** if the user is online, this is his/her online session object */
public User user;
public ESUser (INode node, FesiEvaluator eval, User user) {
super (eval.getPrototype("user"), eval.getEvaluator(), node, eval);
this.user = user;
if (user != null) {
cache = user.getCache ();
cacheWrapper = new ESNode (cache, eval);
}
}
/**
* Overrides getProperty to return the uid (which is not a regular property)
*/
public ESValue getProperty (String propname, int hash) throws EcmaScriptException {
// if there is a user session object, we expose some of its properties.
// Otherwise, we call the parent's class getProperty method.
if ("uid".equals (propname)) {
if (user == null || user.getUID () == null)
return ESNull.theNull;
else
return new ESString (user.getUID ());
}
if ("sessionID".equals (propname)) {
if (user == null || user.getSessionID () == null)
return ESNull.theNull;
else
return new ESString (user.getSessionID ());
}
// if this represents an active user object, we override
// the cache property to come from the user session object
// instead of the Node object.
if ("cache".equals (propname) && user != null) {
cache = user.getCache ();
cacheWrapper.node = cache;
return cacheWrapper;
}
return super.getProperty (propname, hash);
}
/**
* The node for a user object changes at login and logout, so we don't use our
* own node, but just reach through to the session user object instead.
*/
public void setNode (INode node) {
// this only makes sense if this wrapper represents an active user
if (user == null)
return;
// set the node on the transient user session object
user.setNode (node);
if (node != null) {
this.node = node;
} else {
// user.getNode will never return null. If the node is set to null (=user logged out)
// it will user the original transient cache node again.
this.node = user.getNode ();
}
// set node handle to wrapped node
if (node instanceof Node)
handle = ((Node) node).getHandle ();
else
handle = null;
// we don't take over the transient cache from the node,
// because we always stick to the one from the user object.
}
public void updateNodeFromUser () {
// this only makes sense if this wrapper represents an active user
if (user == null)
return;
node = user.getNode ();
// set node handle to wrapped node
if (node instanceof Node)
handle = ((Node) node).getHandle ();
else
handle = null;
}
public boolean clearCache () {
if (user != null)
user.clearCache ();
else
super.clearCache ();
return true;
}
public String toString () {
return ("UserObject "+node.getName ());
}
}

View file

@ -29,7 +29,7 @@ public final class FesiEvaluator {
// The FESI evaluator
Evaluator evaluator;
// the global object
GlobalObject global;
@ -78,7 +78,7 @@ public final class FesiEvaluator {
// fake a cache member like the one found in ESNodes
global.putHiddenProperty ("cache", new ESNode (new TransientNode ("cache"), this));
global.putHiddenProperty ("undefined", ESUndefined.theUndefined);
ESAppNode appnode = new ESAppNode (app.getAppNode (), this);
ESBeanWrapper appnode = new ESBeanWrapper (new ApplicationBean (app), this);
global.putHiddenProperty ("app", appnode);
initialize();
} catch (Exception e) {
@ -227,11 +227,13 @@ public final class FesiEvaluator {
// comfortable to EcmaScript coders, i.e. we use a lot of custom wrappers
// that expose properties and functions in a special way instead of just going
// with the standard java object wrappers.
if (v instanceof RequestTrans)
((RequestTrans) v).data = new ESMapWrapper (this, ((RequestTrans) v).getRequestData ());
sv = new ESBeanWrapper (new RequestBean ((RequestTrans) v), this);
else if (v instanceof ResponseTrans)
((ResponseTrans) v).data = new ESMapWrapper (this, ((ResponseTrans) v).getResponseData ());
if (v instanceof Map)
sv = new ESBeanWrapper (new ResponseBean ((ResponseTrans) v), this);
else if (v instanceof Map)
sv = new ESMapWrapper (this, (Map) v);
else if ("path".equals (k)) {
ArrayPrototype parr = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator);
@ -246,10 +248,10 @@ public final class FesiEvaluator {
parr.putHiddenProperty (protoname, wrappedElement);
}
sv = parr;
} else if ("user".equals (k)) {
sv = getNodeWrapper ((User) v);
} else if ("session".equals (k)) {
sv = new ESBeanWrapper (new SessionBean ((Session)v), this);
} else if ("app".equals (k)) {
sv = new ESAppNode ((INode) v, this);
sv = new ESBeanWrapper (new ApplicationBean ((Application)v), this);
}
else
sv = ESLoader.normalizeValue (v, evaluator);
@ -432,7 +434,7 @@ public final class FesiEvaluator {
* Get a script wrapper for an implemntation of helma.objectmodel.INode
*/
public ESNode getNodeWrapper (INode n) {
// FIXME: should this return ESNull.theNull?
if (n == null)
return null;
@ -455,12 +457,7 @@ public final class FesiEvaluator {
if (op == null)
op = getPrototype("hopobject");
DbMapping dbm = n.getDbMapping ();
if (dbm != null && dbm.isInstanceOf ("user"))
esn = new ESUser (n, this, null);
else
esn = new ESNode (op, evaluator, n, this);
esn = new ESNode (op, evaluator, n, this);
wrappercache.put (n, esn);
// app.logEvent ("Wrapper for "+n+" created");
@ -478,28 +475,6 @@ public final class FesiEvaluator {
wrappercache.put (n, esn);
}
/**
* Get a scripting wrapper object for a user object. Active user objects are represented by
* the special ESUser wrapper class.
*/
public ESNode getNodeWrapper (User u) {
if (u == null)
return null;
ESUser esn = (ESUser) wrappercache.get (u);
if (esn == null) {
esn = new ESUser (u.getNode(), this, u);
wrappercache.put (u, esn);
} else {
// the user node may have changed (login/logout) while the ESUser was
// lingering in the cache.
esn.updateNodeFromUser ();
}
return esn;
}
/**
* Return the RequestEvaluator owning and driving this FESI evaluator.
*/

View file

@ -20,7 +20,7 @@ import org.xml.sax.InputSource;
/**
* This is the basic Extension for FESI interpreters used in Helma. It sets up
* varios constructors, global functions and properties on the HopObject prototype
* (Node objects), the user prototype, the global prototype etc.
* (Node objects), the global prototype, the session object etc.
*/
public class HopExtension {
@ -61,8 +61,8 @@ public class HopExtension {
ObjectPrototype esObjectPrototype = new ObjectPrototype (op, evaluator);
// the Node prototype
ObjectPrototype esNodePrototype = new ObjectPrototype(op, evaluator);
// the User prototype
ObjectPrototype esUserPrototype = new ObjectPrototype (esNodePrototype, evaluator);
// the Session prototype
ObjectPrototype esSessionPrototype = new ObjectPrototype (esNodePrototype, evaluator);
// the Node constructor
ESObject node = new NodeConstructor ("Node", fp, fesi);
@ -97,12 +97,6 @@ public class HopExtension {
go.putHiddenProperty("HopObject", node); // HopObject is the new name for node.
go.putHiddenProperty("getProperty", new GlobalGetProperty ("getProperty", evaluator, fp));
go.putHiddenProperty("token", new GlobalGetProperty ("token", evaluator, fp));
go.putHiddenProperty("getUser", new GlobalGetUser ("getUser", evaluator, fp));
go.putHiddenProperty("getUserBySession", new GlobalGetUserBySession ("getUserBySession", evaluator, fp));
go.putHiddenProperty("getAllUsers", new GlobalGetAllUsers ("getAllUsers", evaluator, fp));
go.putHiddenProperty("getActiveUsers", new GlobalGetActiveUsers ("getActiveUsers", evaluator, fp));
go.putHiddenProperty("countActiveUsers", new GlobalCountActiveUsers ("countActiveUsers", evaluator, fp));
go.putHiddenProperty("isActive", new GlobalIsActive ("isActive", evaluator, fp));
go.putHiddenProperty("getAge", new GlobalGetAge ("getAge", evaluator, fp));
go.putHiddenProperty("getURL", new GlobalGetURL ("getURL", evaluator, fp));
go.putHiddenProperty("encode", new GlobalEncode ("encode", evaluator, fp));
@ -120,20 +114,11 @@ public class HopExtension {
go.putHiddenProperty("authenticate", new GlobalAuthenticate ("authenticate", evaluator, fp));
go.deleteProperty("exit", "exit".hashCode());
// and some methods for session management from JS...
esUserPrototype.putHiddenProperty("logon", new UserLogin ("logon", evaluator, fp));
esUserPrototype.putHiddenProperty("login", new UserLogin ("login", evaluator, fp));
esUserPrototype.putHiddenProperty("register", new UserRegister ("register", evaluator, fp));
esUserPrototype.putHiddenProperty("logout", new UserLogout ("logout", evaluator, fp));
esUserPrototype.putHiddenProperty("onSince", new UserOnSince ("onSince", evaluator, fp));
esUserPrototype.putHiddenProperty("lastActive", new UserLastActive ("lastActive", evaluator, fp));
esUserPrototype.putHiddenProperty("touch", new UserTouch ("touch", evaluator, fp));
// register object prototypes with FesiEvaluator
fesi.putPrototype ("global", go);
fesi.putPrototype ("hopobject", esNodePrototype);
fesi.putPrototype ("__javaobject__", esObjectPrototype);
fesi.putPrototype ("user", esUserPrototype);
// fesi.putPrototype ("session", esSessionPrototype);
}
class NodeAdd extends BuiltinFunctionObject {
@ -415,92 +400,6 @@ public class HopExtension {
}
}
class UserLogin extends BuiltinFunctionObject {
UserLogin (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length < 2)
return ESBoolean.makeBoolean(false);
ESUser u = (ESUser) thisObject;
if (u.user == null)
throw new EcmaScriptException ("login() can only be called for user objects that are online at the moment!");
boolean success = app.loginUser (arguments[0].toString (), arguments[1].toString (), u);
try {
u.doIndirectCall (this.evaluator, u, "onLogin", new ESValue[0]);
} catch (Exception nosuch) {}
return ESBoolean.makeBoolean (success);
}
}
class UserRegister extends BuiltinFunctionObject {
UserRegister (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 2);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length < 2)
return ESBoolean.makeBoolean(false);
INode unode = app.registerUser (arguments[0].toString (), arguments[1].toString ());
if (unode == null)
return ESNull.theNull;
else
return fesi.getNodeWrapper (unode);
}
}
class UserLogout extends BuiltinFunctionObject {
UserLogout (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
ESUser u = (ESUser) thisObject;
if (u.user == null)
return ESBoolean.makeBoolean (true);
try {
u.doIndirectCall (this.evaluator, u, "onLogout", new ESValue[0]);
} catch (Exception nosuch) {}
return ESBoolean.makeBoolean (app.logoutUser (u));
}
}
class UserOnSince extends BuiltinFunctionObject {
UserOnSince (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
ESUser u = (ESUser) thisObject;
if (u.user == null)
throw new EcmaScriptException ("onSince() can only be called for users that are online at the moment!");
DatePrototype date = new DatePrototype(this.evaluator, new Date (u.user.onSince ()));
return date;
}
}
class UserLastActive extends BuiltinFunctionObject {
UserLastActive (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
ESUser u = (ESUser) thisObject;
if (u.user == null)
throw new EcmaScriptException ("lastActive() can only be called for users that are online at the moment!");
DatePrototype date = new DatePrototype(this.evaluator, new Date (u.user.lastTouched ()));
return date;
}
}
class UserTouch extends BuiltinFunctionObject {
UserTouch (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
ESUser u = (ESUser) thisObject;
if (u.user != null)
u.user.touch ();
return ESNull.theNull;
}
}
class GlobalGetProperty extends BuiltinFunctionObject {
GlobalGetProperty (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
@ -625,109 +524,6 @@ public class HopExtension {
}
class GlobalGetUser extends BuiltinFunctionObject {
GlobalGetUser (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
INode user = null;
if (arguments.length > 0) {
String uname = arguments[0].toString ().trim ();
user = app.getUserNode (uname);
}
if (user == null)
return ESNull.theNull;
return fesi.getNodeWrapper (user);
}
}
class GlobalGetUserBySession extends BuiltinFunctionObject {
GlobalGetUserBySession (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
User user = null;
if (arguments.length > 0) {
String sid = arguments[0].toString ().trim ();
user = app.getUser (sid);
}
if (user == null || user.getUID() == null)
return ESNull.theNull;
user.touch ();
return fesi.getNodeWrapper (user.getNode ());
}
}
class GlobalGetAllUsers extends BuiltinFunctionObject {
GlobalGetAllUsers (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
INode users = app.getUserRoot ();
ESObject ap = this.evaluator.getArrayPrototype();
ArrayPrototype theArray = new ArrayPrototype(ap, this.evaluator);
int i=0;
for (Enumeration e=users.properties (); e.hasMoreElements (); ) {
String propname = (String) e.nextElement ();
theArray.putProperty (i++, new ESString (propname));
}
return theArray;
}
}
class GlobalGetActiveUsers extends BuiltinFunctionObject {
GlobalGetActiveUsers (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
Hashtable sessions = (Hashtable) app.sessions.clone ();
ESObject ap = this.evaluator.getArrayPrototype();
ArrayPrototype theArray = new ArrayPrototype (ap, this.evaluator);
theArray.setSize (sessions.size ());
int i=0;
// Hashtable visited = new Hashtable ();
for (Enumeration e=sessions.elements(); e.hasMoreElements(); ) {
User u = (User) e.nextElement ();
// Note: we previously sorted out duplicate users - now we simply enumerate all active sessions.
// if (u.uid == null || !visited.containsKey (u.uid)) {
theArray.setElementAt (fesi.getNodeWrapper (u), i++);
// if (u.uid != null) visited.put (u.uid, u);
// }
}
return theArray;
}
}
class GlobalCountActiveUsers extends BuiltinFunctionObject {
GlobalCountActiveUsers (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return new ESNumber (app.sessions.size ());
}
}
class GlobalIsActive extends BuiltinFunctionObject {
GlobalIsActive (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length < 1)
return ESBoolean.makeBoolean (false);
String username = null;
boolean active = false;
if (arguments[0] instanceof ESUser) {
ESUser esu = (ESUser) arguments[0];
active = (esu.user != null);
} else {
active = app.activeUsers.contains (arguments[0].toString ());
}
return ESBoolean.makeBoolean (active);
}
}
class GlobalGetAge extends BuiltinFunctionObject {
GlobalGetAge (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);

View file

@ -9,7 +9,6 @@ import javax.mail.internet.*;
import javax.activation.*;
import java.io.*;
import java.util.*;
import helma.framework.core.*;
import helma.util.*;
import FESI.Data.*;
import FESI.Interpreter.*;

View file

@ -141,6 +141,12 @@ public final class SystemProperties extends Properties {
return props.keys();
}
public Set keySet () {
if (System.currentTimeMillis () - lastcheck > cacheTime)
checkFile ();
return props.keySet();
}
public Enumeration elements () {
if (System.currentTimeMillis () - lastcheck > cacheTime)
checkFile ();