Adapted to other classes moving to the helma.scripting packages

This commit is contained in:
hns 2001-08-29 18:04:30 +00:00
parent 6353177656
commit dd3cbc45e9
6 changed files with 172 additions and 86 deletions

View file

@ -8,6 +8,7 @@ import java.lang.reflect.*;
import java.rmi.*;
import java.rmi.server.*;
import helma.framework.*;
import helma.scripting.fesi.*;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import helma.xmlrpc.*;
@ -34,7 +35,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
private String baseURI;
TypeManager typemgr;
public TypeManager typemgr;
RequestEvaluator eval;
protected Stack freeThreads;
@ -43,8 +44,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
boolean stopped = false;
boolean debug;
Hashtable sessions;
Hashtable activeUsers;
public Hashtable sessions;
public Hashtable activeUsers;
Hashtable dbMappings;
Hashtable dbSources;
@ -181,8 +182,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
activeRequests = new Hashtable ();
typemgr = new TypeManager (this);
typemgr.check ();
logEvent ("Started type manager for "+name);
typemgr.createPrototypes ();
// logEvent ("Started type manager for "+name);
rootMapping = getDbMapping ("root");
userMapping = getDbMapping ("user");
@ -196,16 +197,16 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props);
worker = new Thread (this, "Worker-"+name);
worker.setPriority (Thread.NORM_PRIORITY+2);
worker.start ();
// worker = new Thread (this, "Worker-"+name);
// worker.setPriority (Thread.NORM_PRIORITY+2);
// worker.start ();
// logEvent ("session cleanup and scheduler thread started");
String xmlrpcHandlerName = props.getProperty ("xmlrpcHandlerName", this.name);
if (xmlrpc != null)
xmlrpc.addHandler (xmlrpcHandlerName, new XmlRpcInvoker (this));
typemgr.start ();
// typemgr.start ();
}
@ -264,7 +265,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
* This can be used to set the maximum number of evaluators which will be allocated.
* If evaluators are required beyound this number, an error will be thrown.
*/
protected boolean setNumberOfEvaluators (int n) {
public boolean setNumberOfEvaluators (int n) {
if (n < 2 || n > 511)
return false;
int current = allThreads.size();
@ -293,13 +294,20 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
return true;
}
/**
* Return the number of currently active threads
*/
public int getActiveThreads () {
return 0;
}
/**
* Execute a request coming in from a web client.
*/
public ResponseTrans execute (RequestTrans req) {
requestCount += 1;
// long reqstart = System.currentTimeMillis ();
User u = getUser (req.session);
ResponseTrans res = null;
@ -342,7 +350,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
res.waitForClose ();
}
}
// System.err.println ("********************** ABSOLUTE TIME: "+(System.currentTimeMillis() - reqstart));
return res;
}
@ -697,7 +705,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
Hashtable cloned = (Hashtable) sessions.clone ();
for (Enumeration e = cloned.elements (); e.hasMoreElements (); ) {
User u = (User) e.nextElement ();
if (now - u.touched () > sessionTimeout * 60000) {
if (now - u.lastTouched () > sessionTimeout * 60000) {
if (u.uid != null) {
try {
eval.invokeFunction (u, "onLogout", new ESValue[0]);
@ -766,11 +774,11 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
String protoname = m.getExtends ();
if (protoname == null)
protoname = "hopobject";
Prototype protoProto = (Prototype) typemgr.prototypes.get (protoname);
if (protoProto == null)
protoProto = (Prototype) typemgr.prototypes.get ("hopobject");
if (protoProto != null)
proto.setPrototype (protoProto);
Prototype parentProto = (Prototype) typemgr.prototypes.get (protoname);
if (parentProto == null)
parentProto = (Prototype) typemgr.prototypes.get ("hopobject");
if (parentProto != null)
proto.setParentPrototype (parentProto);
}
}
} catch (Exception x) {
@ -822,6 +830,13 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
dbMappings.put (typename, dbmap);
}
/**
* Proxy method to get a property from the applications properties.
*/
public String getProperty (String propname, String defvalue) {
return props.getProperty (propname, defvalue);
}
/**
* Periodically called to log thread stats for this application
*/

View file

@ -7,7 +7,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.io.*;
import helma.framework.*;
import helma.scripting.*;
import helma.scripting.fesi.*;
import helma.objectmodel.*;
import helma.util.Updatable;
import FESI.Data.*;
import FESI.Exceptions.EcmaScriptException;
@ -25,12 +28,10 @@ public class Prototype {
String id;
String name;
Application app;
HashMap templates, functions, actions, skins, updatables;
public HashMap templates, functions, actions, skins, updatables;
long lastUpdate;
// DbMapping dbmap;
Prototype prototype;
Prototype parent;
public Prototype (String name, Application app) {
@ -40,11 +41,20 @@ public class Prototype {
this.app = app;
this.name = name;
lastUpdate = System.currentTimeMillis ();
lastUpdate = 0; // System.currentTimeMillis ();
}
/**
* Return the application this prototype is a part of
*/
public Application getApplication () {
return app;
}
/**
* Get an action defined for this prototype
*/
public Action getActionOrTemplate (String aname) {
Action retval = null;
@ -56,21 +66,24 @@ public class Prototype {
if (retval == null && "true".equalsIgnoreCase (app.props.getProperty ("exposetemplates")))
retval = (Action) templates.get (aname);
// if still not found, check if the action is defined for the generic node prototype
if (retval == null && prototype != null)
retval = prototype.getActionOrTemplate (aname);
if (retval == null && parent != null)
retval = parent.getActionOrTemplate (aname);
return retval;
}
public void setPrototype (Prototype prototype) {
/**
* Set the parent prototype of this prototype, i.e. the prototype this one inherits from.
*/
public void setParentPrototype (Prototype parent) {
// this is not allowed for the hopobject and global prototypes
if ("hopobject".equalsIgnoreCase (name) || "global".equalsIgnoreCase (name))
return;
Prototype old = this.prototype;
this.prototype = prototype;
Prototype old = this.parent;
this.parent = parent;
// if prototype has changed, update ES-prototypes in request evaluators
if (prototype != old) {
// if parent has changed, update ES-prototypes in request evaluators
if (parent != old) {
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
while (evals.hasNext ()) {
try {
@ -78,8 +91,8 @@ public class Prototype {
ObjectPrototype op = reval.getPrototype (getName());
// use hopobject (node) as prototype even if prototype is null -
// this is the case if no hopobject directory exists
ObjectPrototype opp = prototype == null ?
reval.esNodePrototype : reval.getPrototype (prototype.getName ());
ObjectPrototype opp = parent == null ?
reval.esNodePrototype : reval.getPrototype (parent.getName ());
// don't think this is possible, but check anyway
if (opp == null)
opp = reval.esNodePrototype;
@ -90,8 +103,8 @@ public class Prototype {
}
}
public Prototype getPrototype () {
return prototype;
public Prototype getParentPrototype () {
return parent;
}
public Template getTemplate (String tmpname) {
@ -123,6 +136,18 @@ public class Prototype {
return name;
}
Updatable[] upd = null;
public Updatable[] getUpdatables () {
if (upd == null) {
upd = new Updatable[updatables.size()];
int i = 0;
for (Iterator it = updatables.values().iterator(); it.hasNext(); ) {
upd[i++] = (Updatable) it.next();
}
}
return upd;
}
public void initRequestEvaluator (RequestEvaluator reval) {
// see if we already registered with this evaluator
@ -133,12 +158,12 @@ public class Prototype {
// get the prototype's prototype if possible and necessary
ObjectPrototype opp = null;
if (prototype != null) {
if (parent != null) {
// see if parent prototype is already registered. if not, register it
opp = reval.getPrototype (prototype.getName ());
opp = reval.getPrototype (parent.getName ());
if (opp == null) {
prototype.initRequestEvaluator (reval);
opp = reval.getPrototype (prototype.getName ());
parent.initRequestEvaluator (reval);
opp = reval.getPrototype (parent.getName ());
}
}
if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) {

View file

@ -6,7 +6,9 @@ package helma.framework.core;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import helma.framework.*;
import helma.framework.extensions.*;
import helma.scripting.*;
import helma.scripting.fesi.*;
import helma.scripting.fesi.extensions.*;
import helma.xmlrpc.fesi.*;
import helma.util.*;
import java.util.*;
@ -27,11 +29,11 @@ import FESI.Exceptions.*;
public class RequestEvaluator implements Runnable {
Application app;
public Application app;
protected boolean initialized;
RequestTrans req;
ResponseTrans res;
public RequestTrans req;
public ResponseTrans res;
volatile Transactor rtx;
@ -46,16 +48,16 @@ public class RequestEvaluator implements Runnable {
protected ArrayPrototype reqPath;
private ESRequestData reqData;
// vars for FESI EcmaScript support
public Evaluator evaluator;
public ObjectPrototype esNodePrototype;
public ObjectPrototype esUserPrototype;
public LruHashtable objectcache;
Hashtable prototypes;
// Used to cache skins within one request evaluation
HashMap skincache;
// vars for FESI EcmaScript support
protected Evaluator evaluator;
protected ObjectPrototype esNodePrototype;
protected ObjectPrototype esUserPrototype;
protected LruHashtable objectcache;
protected Hashtable prototypes;
GlobalObject global;
HopExtension hopx;
MailExtension mailx;
@ -65,8 +67,8 @@ public class RequestEvaluator implements Runnable {
"FESI.Extensions.BasicIO",
"FESI.Extensions.FileIO",
"helma.xmlrpc.fesi.FesiRpcExtension",
"helma.framework.extensions.ImageExtension",
"helma.framework.extensions.FtpExtension",
"helma.scripting.fesi.extensions.ImageExtension",
"helma.scripting.fesi.extensions.FtpExtension",
"FESI.Extensions.JavaAccess",
"FESI.Extensions.OptionalRegExp"};
@ -106,9 +108,9 @@ public class RequestEvaluator implements Runnable {
evaluator.addExtension (extensions[i]);
hopx = new HopExtension ();
hopx.initializeExtension (this);
mailx = (MailExtension) evaluator.addExtension ("helma.framework.extensions.MailExtension");
mailx = (MailExtension) evaluator.addExtension ("helma.scripting.fesi.extensions.MailExtension");
mailx.setProperties (this.app.props);
Database dbx = (Database) evaluator.addExtension ("helma.framework.extensions.Database");
Database dbx = (Database) evaluator.addExtension ("helma.scripting.fesi.extensions.Database");
dbx.setApplication (this.app);
// fake a cache member like the one found in ESNodes
@ -142,6 +144,7 @@ public class RequestEvaluator implements Runnable {
try {
do {
app.typemgr.checkPrototypes ();
IPathElement root, currentElement;
// reset skinManager
skinmanagers = null;
@ -751,7 +754,7 @@ public class RequestEvaluator implements Runnable {
if (proto == null)
return null;
// First check if the skin has been already used within the execution of this request
CompositeKey key = new CompositeKey (proto.getName(), skinname);
SkinKey key = new SkinKey (proto.getName(), skinname);
Skin skin = (Skin) skincache.get (key);
if (skin != null) {
return skin;
@ -775,7 +778,7 @@ public class RequestEvaluator implements Runnable {
return skin;
}
// still not found. See if there is a parent prototype which might define the skin
proto = proto.getPrototype ();
proto = proto.getParentPrototype ();
} while (proto != null);
// looked every where, nothing to be found
return null;
@ -932,18 +935,18 @@ public class RequestEvaluator implements Runnable {
prototypes.put (protoName, op);
}
final class CompositeKey {
final class SkinKey {
final String first, second;
public CompositeKey (String first, String second) {
public SkinKey (String first, String second) {
this.first = first;
this.second = second;
}
public boolean equals (Object other) {
try {
CompositeKey key = (CompositeKey) other;
SkinKey key = (SkinKey) other;
return first.equals (key.first) && second.equals (key.second);
} catch (Exception x) {
return false;

View file

@ -4,11 +4,12 @@
package helma.framework.core;
import java.io.*;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.*;
import helma.framework.*;
import FESI.Data.*;
import FESI.Exceptions.*;
import helma.scripting.*;
import helma.scripting.fesi.*;
import helma.objectmodel.INode;
import helma.objectmodel.ConcurrencyException;
import helma.util.HtmlEncoder;
@ -24,13 +25,19 @@ public class Skin {
Object[] parts;
Application app;
String source;
ESObject sandbox;
HashSet sandbox;
/**
* Create a skin without any restrictions on which macros are allowed to be called from it
*/
public Skin (String content, Application app) {
this (content, app, null);
}
public Skin (String content, Application app, ESObject sandbox) {
/**
* Create a skin with a sandbox which contains the names of macros allowed to be called
*/
public Skin (String content, Application app, HashSet sandbox) {
this.app = app;
this.sandbox = sandbox;
parse (content);
@ -110,18 +117,23 @@ public class Skin {
for (int i=0; i<parts.length; i++) {
if (parts[i] instanceof Macro) {
Macro m = (Macro) parts[i];
String mname = null;
if (m.handler == null)
mname = m.name;
else
mname = m.handler+"."+m.name;
if (macroname.equals (mname))
if (macroname.equals (m.getFullName ()))
return true;
}
}
return false;
}
/**
* Adds a macro to the list of allowed macros. The macro is in handler.name notation.
*/
public void allowMacro (String macroname) {
if (sandbox == null) {
sandbox = new HashSet ();
}
sandbox.add (macroname);
}
static final int HANDLER = 0;
static final int MACRO = 1;
static final int PARAMNAME = 2;
@ -131,8 +143,8 @@ public class Skin {
String handler;
String name;
String fullname;
Hashtable parameters;
boolean notallowed = false;
public Macro (String str) {
@ -219,24 +231,17 @@ public class Skin {
else if (state <= MACRO)
name = b.toString().trim();
}
if (sandbox != null && name != null) try {
ESValue allow = handler == null ?
sandbox.getProperty ("global", "global".hashCode ()) :
sandbox.getProperty (handler, handler.hashCode ());
allow = ((ESObject) allow).getProperty (name, name.hashCode ());
if (allow == null || allow == ESUndefined.theUndefined)
notallowed = true;
} catch (Exception x) {
notallowed = true;
}
}
/**
* Render the macro given a handler object
*/
public void render (RequestEvaluator reval, ESObject thisObject, IPathElement elem, ESObject paramObject) throws RedirectException {
if (notallowed) {
if (sandbox != null && sandbox.contains (getFullName ())) {
String h = handler == null ? "global" : handler;
reval.res.write ("[Macro "+h+"."+name+" not allowed in sandbox]");
reval.res.write ("[Macro "+getFullName()+" not allowed in sandbox]");
return;
} else if ("response".equalsIgnoreCase (handler)) {
renderFromResponse (reval);
@ -305,7 +310,7 @@ public class Skin {
if (v != ESUndefined.theUndefined && v != ESNull.theNull)
reval.res.write (v);
} else {
String msg = "[HopMacro unhandled: "+handler+"."+name+"]";
String msg = "[HopMacro unhandled: "+getFullName()+"]";
reval.res.write (" "+msg+" ");
app.logEvent (msg);
}
@ -352,6 +357,10 @@ public class Skin {
}
}
/**
* Utility method for performing different kind of character encodings on the
* macro output.
*/
public String encode (String text, String encoding) {
if (encoding == null || text == null)
return text;
@ -367,8 +376,22 @@ public class Skin {
}
public String toString () {
return "[HopMacro: "+handler+","+name+"]";
return "[HopMacro: "+getFullName()+"]";
}
/**
* Return the full name of the macro in handler.name notation
*/
public String getFullName () {
if (fullname == null) {
if (handler == null)
fullname = name;
else
fullname = handler+"."+name;
}
return fullname;
}
}

View file

@ -74,10 +74,29 @@ public class User implements Serializable {
lastTouched = System.currentTimeMillis ();
}
public long touched () {
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;
}
}

View file

@ -7,6 +7,7 @@ import java.util.*;
import java.util.zip.*;
import java.io.*;
import helma.framework.*;
import helma.scripting.*;
import helma.util.Updatable;
import helma.util.SystemProperties;
import helma.objectmodel.db.DbMapping;
@ -35,7 +36,7 @@ public class ZippedAppFile implements Updatable {
* the file has been modified or deleted.
*/
public boolean needsUpdate () {
return lastmod != file.lastModified () || !file.exists ();
return lastmod != file.lastModified ();
}