Merged in changes from Stefan Pollach's "usersession_05_15" branch.
This commit is contained in:
parent
5818dd8d52
commit
7bfc14d164
17 changed files with 833 additions and 753 deletions
61
src/helma/framework/RequestBean.java
Normal file
61
src/helma/framework/RequestBean.java
Normal 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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
138
src/helma/framework/ResponseBean.java
Normal file
138
src/helma/framework/ResponseBean.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import helma.doc.DocException;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.main.Server;
|
import helma.main.Server;
|
||||||
import helma.scripting.*;
|
import helma.scripting.*;
|
||||||
import helma.scripting.fesi.ESUser;
|
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.*;
|
import helma.objectmodel.db.*;
|
||||||
import helma.xmlrpc.*;
|
import helma.xmlrpc.*;
|
||||||
|
@ -66,10 +65,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
|
|
||||||
boolean stopped = false;
|
boolean stopped = false;
|
||||||
boolean debug;
|
boolean debug;
|
||||||
public long starttime;
|
long starttime;
|
||||||
|
|
||||||
public Hashtable sessions;
|
Hashtable sessions;
|
||||||
public Hashtable activeUsers;
|
|
||||||
Hashtable dbMappings;
|
Hashtable dbMappings;
|
||||||
Hashtable dbSources;
|
Hashtable dbSources;
|
||||||
|
|
||||||
|
@ -86,7 +84,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
protected String templateExtension, scriptExtension, actionExtension, skinExtension;
|
protected String templateExtension, scriptExtension, actionExtension, skinExtension;
|
||||||
|
|
||||||
// A transient node that is shared among all evaluators
|
// A transient node that is shared among all evaluators
|
||||||
protected INode appnode;
|
protected INode cachenode;
|
||||||
protected volatile long requestCount = 0;
|
protected volatile long requestCount = 0;
|
||||||
protected volatile long xmlrpcCount = 0;
|
protected volatile long xmlrpcCount = 0;
|
||||||
protected volatile long errorCount = 0;
|
protected volatile long errorCount = 0;
|
||||||
|
@ -218,11 +216,10 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
skinExtension = ".skin";
|
skinExtension = ".skin";
|
||||||
|
|
||||||
sessions = new Hashtable ();
|
sessions = new Hashtable ();
|
||||||
activeUsers = new Hashtable ();
|
|
||||||
dbMappings = new Hashtable ();
|
dbMappings = new Hashtable ();
|
||||||
dbSources = new Hashtable ();
|
dbSources = new Hashtable ();
|
||||||
|
|
||||||
appnode = new TransientNode ("app");
|
cachenode = new TransientNode ("app");
|
||||||
xmlrpc = helma.main.Server.getXmlRpcServer ();
|
xmlrpc = helma.main.Server.getXmlRpcServer ();
|
||||||
xmlrpcAccess = new XmlRpcAccess (this);
|
xmlrpcAccess = new XmlRpcAccess (this);
|
||||||
}
|
}
|
||||||
|
@ -262,8 +259,11 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
String usernameField = userMapping.getNameField ();
|
String usernameField = userMapping.getNameField ();
|
||||||
if (usernameField == null)
|
if (usernameField == null)
|
||||||
usernameField = "name";
|
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);
|
userRootMapping = new DbMapping (this, "__userroot__", p);
|
||||||
|
|
||||||
rewireDbMappings ();
|
rewireDbMappings ();
|
||||||
|
|
||||||
nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props);
|
nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props);
|
||||||
|
@ -399,7 +399,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
requestCount += 1;
|
requestCount += 1;
|
||||||
|
|
||||||
// get user for this request's session
|
// get user for this request's session
|
||||||
User u = getUser (req.session);
|
Session session = checkSession (req.session);
|
||||||
|
session.touch();
|
||||||
|
|
||||||
ResponseTrans res = null;
|
ResponseTrans res = null;
|
||||||
RequestEvaluator ev = 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
|
// if attachRequest returns null this means we came too late
|
||||||
// and the other request was finished in the meantime
|
// and the other request was finished in the meantime
|
||||||
ev = getEvaluator ();
|
ev = getEvaluator ();
|
||||||
res = ev.invoke (req, u);
|
res = ev.invoke (req, session);
|
||||||
}
|
}
|
||||||
} catch (ApplicationStoppedException stopped) {
|
} catch (ApplicationStoppedException stopped) {
|
||||||
// let the servlet know that this application has gone to heaven
|
// 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 ();
|
res.waitForClose ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
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")
|
* Return a transient node that is shared by all evaluators of this application ("app node")
|
||||||
*/
|
*/
|
||||||
public INode getAppNode () {
|
public INode getCacheNode () {
|
||||||
return appnode;
|
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.
|
* to use for the object, then looking up the skin for the prototype.
|
||||||
*/
|
*/
|
||||||
public Skin getSkin (Object object, String skinname, Object[] skinpath) {
|
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
|
* Return the session currently associated with a given Hop session ID.
|
||||||
* a registered or an anonymous user.
|
* Create a new session if necessary.
|
||||||
*/
|
*/
|
||||||
public User getUser (String sessionID) {
|
public Session checkSession (String sessionID) {
|
||||||
if (sessionID == null)
|
Session session = getSession(sessionID);
|
||||||
return null;
|
if ( session==null ) {
|
||||||
|
session = new Session (sessionID, this);
|
||||||
User u = (User) sessions.get (sessionID);
|
sessions.put (sessionID, session);
|
||||||
if (u != null) {
|
|
||||||
u.touch ();
|
|
||||||
} else {
|
|
||||||
u = new User (sessionID, this);
|
|
||||||
sessions.put (sessionID, u);
|
|
||||||
}
|
}
|
||||||
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.
|
* Register a user with the given user name and password.
|
||||||
*/
|
*/
|
||||||
public INode registerUser (String uname, String 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)
|
if (uname == null)
|
||||||
return null;
|
return null;
|
||||||
uname = uname.toLowerCase ().trim ();
|
uname = uname.toLowerCase ().trim ();
|
||||||
if ("".equals (uname))
|
if ("".equals (uname))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
INode unode = null;
|
INode unode = null;
|
||||||
try {
|
try {
|
||||||
INode users = getUserRoot ();
|
INode users = getUserRoot ();
|
||||||
unode = users.getNode (uname, false);
|
unode = users.getNode (uname, false);
|
||||||
if (unode != null)
|
if (unode != null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
unode = users.createNode (uname);
|
unode = users.createNode (uname);
|
||||||
unode.setPrototype ("user");
|
unode.setPrototype ("user");
|
||||||
unode.setDbMapping (userMapping);
|
unode.setDbMapping (userMapping);
|
||||||
|
@ -627,8 +707,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
unode.setName (uname);
|
unode.setName (uname);
|
||||||
unode.setString (usernameProp, uname);
|
unode.setString (usernameProp, uname);
|
||||||
unode.setString ("password", password);
|
unode.setString ("password", password);
|
||||||
// users.setNode (uname, unode);
|
|
||||||
// return users.getNode (uname, false);
|
|
||||||
return unode;
|
return unode;
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
logEvent ("Error registering User: "+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.
|
* Log in a user given his or her user name and password.
|
||||||
*/
|
*/
|
||||||
public boolean loginUser (String uname, String password, ESUser u) {
|
public boolean loginSession (String uname, String password, Session session) {
|
||||||
// Check the name/password of a user who already has a user object
|
// Check the name/password of a user and log it in to the current session
|
||||||
// (i.e. who has been surfing around)
|
|
||||||
if (uname == null)
|
if (uname == null)
|
||||||
return false;
|
return false;
|
||||||
uname = uname.toLowerCase ().trim ();
|
uname = uname.toLowerCase ().trim ();
|
||||||
if ("".equals (uname))
|
if ("".equals (uname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
INode users = getUserRoot ();
|
INode users = getUserRoot ();
|
||||||
INode unode = users.getNode (uname, false);
|
Node unode = (Node)users.getNode (uname, false);
|
||||||
String pw = unode.getString ("password", false);
|
String pw = unode.getString ("password", false);
|
||||||
if (pw != null && pw.equals (password)) {
|
if (pw != null && pw.equals (password)) {
|
||||||
// give the user his/her persistant node
|
// let the old user-object forget about this session
|
||||||
u.setNode (unode);
|
logoutSession(session);
|
||||||
activeUsers.put (unode.getName (), u.user);
|
session.login (unode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
return false;
|
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) {
|
public void logoutSession (Session session) {
|
||||||
if (u.user != null) {
|
session.logout();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -725,13 +792,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
if (rootproto != null && rootproto.equals (getPrototypeName (p)))
|
if (rootproto != null && rootproto.equals (getPrototypeName (p)))
|
||||||
break;
|
break;
|
||||||
b.insert (0, divider);
|
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)));
|
b.insert (0, URLEncoder.encode (getElementName (p)));
|
||||||
p = getParentElement (p);
|
p = getParentElement (p);
|
||||||
|
|
||||||
|
@ -739,11 +799,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == users) {
|
|
||||||
b.insert (0, divider);
|
|
||||||
b.insert (0, "users");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actionName != null)
|
if (actionName != null)
|
||||||
b.append (URLEncoder.encode (actionName));
|
b.append (URLEncoder.encode (actionName));
|
||||||
|
|
||||||
|
@ -957,29 +1012,25 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
int sessionTimeout = 30;
|
int sessionTimeout = 30;
|
||||||
try {
|
try {
|
||||||
sessionTimeout = Math.max (0, Integer.parseInt (props.getProperty ("sessionTimeout", "30")));
|
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 ();
|
long now = System.currentTimeMillis ();
|
||||||
|
|
||||||
// check if we should clean up user sessions
|
// check if we should clean up user sessions
|
||||||
if (now - lastCleanup > cleanupSleep) try {
|
if (now - lastCleanup > cleanupSleep) try {
|
||||||
lastCleanup = now;
|
lastCleanup = now;
|
||||||
// logEvent ("Cleaning up "+name+": " + sessions.size () + " sessions active");
|
|
||||||
Hashtable cloned = (Hashtable) sessions.clone ();
|
Hashtable cloned = (Hashtable) sessions.clone ();
|
||||||
for (Enumeration e = cloned.elements (); e.hasMoreElements (); ) {
|
for (Enumeration e = cloned.elements (); e.hasMoreElements (); ) {
|
||||||
User u = (User) e.nextElement ();
|
Session session = (Session) e.nextElement ();
|
||||||
if (now - u.lastTouched () > sessionTimeout * 60000) {
|
if (now - session.lastTouched () > sessionTimeout * 60000) {
|
||||||
if (u.uid != null) {
|
// if (session.uid != null) {
|
||||||
try {
|
// FIXME onlogout()! try {eval.invokeFunction (u, "onLogout", new Object[0]);} catch (Exception ignore) {}
|
||||||
eval.invokeFunction (u, "onLogout", new Object[0]);
|
// }
|
||||||
} catch (Exception ignore) {}
|
destroySession(session);
|
||||||
activeUsers.remove (u.uid);
|
|
||||||
}
|
|
||||||
sessions.remove (u.getSessionID ());
|
|
||||||
u.setNode (null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// logEvent ("Cleaned up "+name+": " + sessions.size () + " sessions remaining");
|
|
||||||
} catch (Exception cx) {
|
} catch (Exception cx) {
|
||||||
logEvent ("Error cleaning up sessions: "+cx);
|
logEvent ("Error cleaning up sessions: "+cx);
|
||||||
cx.printStackTrace ();
|
cx.printStackTrace ();
|
||||||
|
@ -1126,9 +1177,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
|
||||||
return props.getProperty (propname, defvalue);
|
return props.getProperty (propname, defvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SystemProperties getProperties() {
|
public SystemProperties getProperties() {
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
195
src/helma/framework/core/ApplicationBean.java
Normal file
195
src/helma/framework/core/ApplicationBean.java
Normal 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() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ public class RequestEvaluator implements Runnable {
|
||||||
// the method to be executed
|
// the method to be executed
|
||||||
String method;
|
String method;
|
||||||
|
|
||||||
// the user object associated with the current request
|
// the session object associated with the current request
|
||||||
User user;
|
Session session;
|
||||||
|
|
||||||
// arguments passed to the function
|
// arguments passed to the function
|
||||||
Object[] args;
|
Object[] args;
|
||||||
|
@ -113,17 +113,18 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
HashMap globals = new HashMap ();
|
HashMap globals = new HashMap ();
|
||||||
globals.put ("root", root);
|
globals.put ("root", root);
|
||||||
globals.put ("user", user);
|
globals.put ("session", session);
|
||||||
globals.put ("req", req);
|
globals.put ("req", req);
|
||||||
globals.put ("res", res);
|
globals.put ("res", res);
|
||||||
globals.put ("path", requestPath);
|
globals.put ("path", requestPath);
|
||||||
globals.put ("app", app.getAppNode());
|
globals.put ("app", app);
|
||||||
|
req.startTime = System.currentTimeMillis ();
|
||||||
if (error != null)
|
if (error != null)
|
||||||
res.error = error;
|
res.error = error;
|
||||||
if (user.message != null) {
|
if (session.message != null) {
|
||||||
// bring over the message from a redirect
|
// bring over the message from a redirect
|
||||||
res.message = user.message;
|
res.message = session.message;
|
||||||
user.message = null;
|
session.message = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -284,7 +285,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
// res.redirect = redirect.getMessage ();
|
// res.redirect = redirect.getMessage ();
|
||||||
// if there is a message set, save it on the user object for the next request
|
// if there is a message set, save it on the user object for the next request
|
||||||
if (res.message != null)
|
if (res.message != null)
|
||||||
user.message = res.message;
|
session.message = res.message;
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +361,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
HashMap globals = new HashMap ();
|
HashMap globals = new HashMap ();
|
||||||
globals.put ("root", root);
|
globals.put ("root", root);
|
||||||
globals.put ("res", res);
|
globals.put ("res", res);
|
||||||
globals.put ("app", app.getAppNode());
|
globals.put ("app", app);
|
||||||
|
|
||||||
currentElement = root;
|
currentElement = root;
|
||||||
|
|
||||||
|
@ -419,7 +420,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
HashMap globals = new HashMap ();
|
HashMap globals = new HashMap ();
|
||||||
globals.put ("root", root);
|
globals.put ("root", root);
|
||||||
globals.put ("res", res);
|
globals.put ("res", res);
|
||||||
globals.put ("app", app.getAppNode());
|
globals.put ("app", app);
|
||||||
|
|
||||||
app.scriptingEngine.invoke (thisObject, method, args, globals, this);
|
app.scriptingEngine.invoke (thisObject, method, args, globals, this);
|
||||||
commitTransaction ();
|
commitTransaction ();
|
||||||
|
@ -497,10 +498,10 @@ public class RequestEvaluator implements Runnable {
|
||||||
} catch (InterruptedException ir) {}
|
} 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.reqtype = HTTP;
|
||||||
this.req = req;
|
this.req = req;
|
||||||
this.user = user;
|
this.session = session;
|
||||||
this.res = new ResponseTrans ();
|
this.res = new ResponseTrans ();
|
||||||
|
|
||||||
app.activeRequests.put (req, this);
|
app.activeRequests.put (req, this);
|
||||||
|
@ -534,7 +535,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
public synchronized Object invokeXmlRpc (String method, Object[] args) throws Exception {
|
public synchronized Object invokeXmlRpc (String method, Object[] args) throws Exception {
|
||||||
this.reqtype = XMLRPC;
|
this.reqtype = XMLRPC;
|
||||||
this.user = null;
|
this.session = null;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
this.res = new ResponseTrans ();
|
this.res = new ResponseTrans ();
|
||||||
|
@ -559,7 +560,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
public synchronized Object invokeFunction (Object object, String functionName, Object[] args)
|
public synchronized Object invokeFunction (Object object, String functionName, Object[] args)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
reqtype = INTERNAL;
|
reqtype = INTERNAL;
|
||||||
user = null;
|
session = null;
|
||||||
thisObject = object;
|
thisObject = object;
|
||||||
method = functionName;
|
method = functionName;
|
||||||
this.args =args;
|
this.args =args;
|
||||||
|
@ -579,10 +580,10 @@ public class RequestEvaluator implements Runnable {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Object invokeFunction (User user, String functionName, Object[] args)
|
public synchronized Object invokeFunction (Session session, String functionName, Object[] args)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
reqtype = INTERNAL;
|
reqtype = INTERNAL;
|
||||||
this.user = user;
|
this.session = session;
|
||||||
thisObject = null;
|
thisObject = null;
|
||||||
method = functionName;
|
method = functionName;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
|
131
src/helma/framework/core/Session.java
Normal file
131
src/helma/framework/core/Session.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
73
src/helma/framework/core/SessionBean.java
Normal file
73
src/helma/framework/core/SessionBean.java
Normal 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 ());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -266,10 +266,7 @@ public class Skin {
|
||||||
boolean objectFound = true;
|
boolean objectFound = true;
|
||||||
|
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
if ("currentuser".equalsIgnoreCase (handler)) {
|
if (thisObject != null) {
|
||||||
// as a special convention, we use "currentuser" to access macros in the current user object
|
|
||||||
handlerObject = reval.user.getNode ();
|
|
||||||
} else if (thisObject != null) {
|
|
||||||
// not a global macro - need to find handler object
|
// not a global macro - need to find handler object
|
||||||
// was called with this object - check it or its parents for matching prototype
|
// was called with this object - check it or its parents for matching prototype
|
||||||
if (!handler.equalsIgnoreCase ("this") && !handler.equalsIgnoreCase (app.getPrototypeName (thisObject))) {
|
if (!handler.equalsIgnoreCase ("this") && !handler.equalsIgnoreCase (app.getPrototypeName (thisObject))) {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
59
src/helma/scripting/fesi/ESBeanWrapper.java
Normal file
59
src/helma/scripting/fesi/ESBeanWrapper.java
Normal 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() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ public class ESMapWrapper extends ESWrapper {
|
||||||
return new ESString ((String) val);
|
return new ESString ((String) val);
|
||||||
else if (val instanceof INode)
|
else if (val instanceof INode)
|
||||||
return fesi.getNodeWrapper ((INode) val);
|
return fesi.getNodeWrapper ((INode) val);
|
||||||
|
else if (val instanceof Map)
|
||||||
|
return new ESMapWrapper (fesi, (Map)val);
|
||||||
else if (val instanceof ESValue)
|
else if (val instanceof ESValue)
|
||||||
return (ESValue) val;
|
return (ESValue) val;
|
||||||
return ESLoader.normalizeValue(val, evaluator);
|
return ESLoader.normalizeValue(val, evaluator);
|
||||||
|
|
|
@ -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 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public final class FesiEvaluator {
|
||||||
|
|
||||||
// The FESI evaluator
|
// The FESI evaluator
|
||||||
Evaluator evaluator;
|
Evaluator evaluator;
|
||||||
|
|
||||||
// the global object
|
// the global object
|
||||||
GlobalObject global;
|
GlobalObject global;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public final class FesiEvaluator {
|
||||||
// fake a cache member like the one found in ESNodes
|
// fake a cache member like the one found in ESNodes
|
||||||
global.putHiddenProperty ("cache", new ESNode (new TransientNode ("cache"), this));
|
global.putHiddenProperty ("cache", new ESNode (new TransientNode ("cache"), this));
|
||||||
global.putHiddenProperty ("undefined", ESUndefined.theUndefined);
|
global.putHiddenProperty ("undefined", ESUndefined.theUndefined);
|
||||||
ESAppNode appnode = new ESAppNode (app.getAppNode (), this);
|
ESBeanWrapper appnode = new ESBeanWrapper (new ApplicationBean (app), this);
|
||||||
global.putHiddenProperty ("app", appnode);
|
global.putHiddenProperty ("app", appnode);
|
||||||
initialize();
|
initialize();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -227,11 +227,13 @@ public final class FesiEvaluator {
|
||||||
// comfortable to EcmaScript coders, i.e. we use a lot of custom wrappers
|
// 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
|
// that expose properties and functions in a special way instead of just going
|
||||||
// with the standard java object wrappers.
|
// with the standard java object wrappers.
|
||||||
|
|
||||||
|
|
||||||
if (v instanceof RequestTrans)
|
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)
|
else if (v instanceof ResponseTrans)
|
||||||
((ResponseTrans) v).data = new ESMapWrapper (this, ((ResponseTrans) v).getResponseData ());
|
sv = new ESBeanWrapper (new ResponseBean ((ResponseTrans) v), this);
|
||||||
if (v instanceof Map)
|
else if (v instanceof Map)
|
||||||
sv = new ESMapWrapper (this, (Map) v);
|
sv = new ESMapWrapper (this, (Map) v);
|
||||||
else if ("path".equals (k)) {
|
else if ("path".equals (k)) {
|
||||||
ArrayPrototype parr = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator);
|
ArrayPrototype parr = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator);
|
||||||
|
@ -246,10 +248,10 @@ public final class FesiEvaluator {
|
||||||
parr.putHiddenProperty (protoname, wrappedElement);
|
parr.putHiddenProperty (protoname, wrappedElement);
|
||||||
}
|
}
|
||||||
sv = parr;
|
sv = parr;
|
||||||
} else if ("user".equals (k)) {
|
} else if ("session".equals (k)) {
|
||||||
sv = getNodeWrapper ((User) v);
|
sv = new ESBeanWrapper (new SessionBean ((Session)v), this);
|
||||||
} else if ("app".equals (k)) {
|
} else if ("app".equals (k)) {
|
||||||
sv = new ESAppNode ((INode) v, this);
|
sv = new ESBeanWrapper (new ApplicationBean ((Application)v), this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sv = ESLoader.normalizeValue (v, evaluator);
|
sv = ESLoader.normalizeValue (v, evaluator);
|
||||||
|
@ -432,7 +434,7 @@ public final class FesiEvaluator {
|
||||||
* Get a script wrapper for an implemntation of helma.objectmodel.INode
|
* Get a script wrapper for an implemntation of helma.objectmodel.INode
|
||||||
*/
|
*/
|
||||||
public ESNode getNodeWrapper (INode n) {
|
public ESNode getNodeWrapper (INode n) {
|
||||||
|
// FIXME: should this return ESNull.theNull?
|
||||||
if (n == null)
|
if (n == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -455,12 +457,7 @@ public final class FesiEvaluator {
|
||||||
if (op == null)
|
if (op == null)
|
||||||
op = getPrototype("hopobject");
|
op = getPrototype("hopobject");
|
||||||
|
|
||||||
|
esn = new ESNode (op, evaluator, n, this);
|
||||||
DbMapping dbm = n.getDbMapping ();
|
|
||||||
if (dbm != null && dbm.isInstanceOf ("user"))
|
|
||||||
esn = new ESUser (n, this, null);
|
|
||||||
else
|
|
||||||
esn = new ESNode (op, evaluator, n, this);
|
|
||||||
|
|
||||||
wrappercache.put (n, esn);
|
wrappercache.put (n, esn);
|
||||||
// app.logEvent ("Wrapper for "+n+" created");
|
// app.logEvent ("Wrapper for "+n+" created");
|
||||||
|
@ -478,28 +475,6 @@ public final class FesiEvaluator {
|
||||||
wrappercache.put (n, esn);
|
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.
|
* Return the RequestEvaluator owning and driving this FESI evaluator.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.xml.sax.InputSource;
|
||||||
/**
|
/**
|
||||||
* This is the basic Extension for FESI interpreters used in Helma. It sets up
|
* This is the basic Extension for FESI interpreters used in Helma. It sets up
|
||||||
* varios constructors, global functions and properties on the HopObject prototype
|
* 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 {
|
public class HopExtension {
|
||||||
|
@ -61,8 +61,8 @@ public class HopExtension {
|
||||||
ObjectPrototype esObjectPrototype = new ObjectPrototype (op, evaluator);
|
ObjectPrototype esObjectPrototype = new ObjectPrototype (op, evaluator);
|
||||||
// the Node prototype
|
// the Node prototype
|
||||||
ObjectPrototype esNodePrototype = new ObjectPrototype(op, evaluator);
|
ObjectPrototype esNodePrototype = new ObjectPrototype(op, evaluator);
|
||||||
// the User prototype
|
// the Session prototype
|
||||||
ObjectPrototype esUserPrototype = new ObjectPrototype (esNodePrototype, evaluator);
|
ObjectPrototype esSessionPrototype = new ObjectPrototype (esNodePrototype, evaluator);
|
||||||
// the Node constructor
|
// the Node constructor
|
||||||
ESObject node = new NodeConstructor ("Node", fp, fesi);
|
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("HopObject", node); // HopObject is the new name for node.
|
||||||
go.putHiddenProperty("getProperty", new GlobalGetProperty ("getProperty", evaluator, fp));
|
go.putHiddenProperty("getProperty", new GlobalGetProperty ("getProperty", evaluator, fp));
|
||||||
go.putHiddenProperty("token", new GlobalGetProperty ("token", 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("getAge", new GlobalGetAge ("getAge", evaluator, fp));
|
||||||
go.putHiddenProperty("getURL", new GlobalGetURL ("getURL", evaluator, fp));
|
go.putHiddenProperty("getURL", new GlobalGetURL ("getURL", evaluator, fp));
|
||||||
go.putHiddenProperty("encode", new GlobalEncode ("encode", 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.putHiddenProperty("authenticate", new GlobalAuthenticate ("authenticate", evaluator, fp));
|
||||||
go.deleteProperty("exit", "exit".hashCode());
|
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
|
// register object prototypes with FesiEvaluator
|
||||||
fesi.putPrototype ("global", go);
|
fesi.putPrototype ("global", go);
|
||||||
fesi.putPrototype ("hopobject", esNodePrototype);
|
fesi.putPrototype ("hopobject", esNodePrototype);
|
||||||
fesi.putPrototype ("__javaobject__", esObjectPrototype);
|
fesi.putPrototype ("__javaobject__", esObjectPrototype);
|
||||||
fesi.putPrototype ("user", esUserPrototype);
|
// fesi.putPrototype ("session", esSessionPrototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NodeAdd extends BuiltinFunctionObject {
|
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 {
|
class GlobalGetProperty extends BuiltinFunctionObject {
|
||||||
GlobalGetProperty (String name, Evaluator evaluator, FunctionPrototype fp) {
|
GlobalGetProperty (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
super (fp, evaluator, name, 1);
|
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 {
|
class GlobalGetAge extends BuiltinFunctionObject {
|
||||||
GlobalGetAge (String name, Evaluator evaluator, FunctionPrototype fp) {
|
GlobalGetAge (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
super (fp, evaluator, name, 1);
|
super (fp, evaluator, name, 1);
|
||||||
|
|
|
@ -9,7 +9,6 @@ import javax.mail.internet.*;
|
||||||
import javax.activation.*;
|
import javax.activation.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import helma.framework.core.*;
|
|
||||||
import helma.util.*;
|
import helma.util.*;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
import FESI.Interpreter.*;
|
import FESI.Interpreter.*;
|
||||||
|
|
|
@ -141,6 +141,12 @@ public final class SystemProperties extends Properties {
|
||||||
return props.keys();
|
return props.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set keySet () {
|
||||||
|
if (System.currentTimeMillis () - lastcheck > cacheTime)
|
||||||
|
checkFile ();
|
||||||
|
return props.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
public Enumeration elements () {
|
public Enumeration elements () {
|
||||||
if (System.currentTimeMillis () - lastcheck > cacheTime)
|
if (System.currentTimeMillis () - lastcheck > cacheTime)
|
||||||
checkFile ();
|
checkFile ();
|
||||||
|
|
Loading…
Add table
Reference in a new issue