Adapted to other classes moving to the helma.scripting packages
This commit is contained in:
parent
6353177656
commit
dd3cbc45e9
6 changed files with 172 additions and 86 deletions
|
@ -8,6 +8,7 @@ import java.lang.reflect.*;
|
||||||
import java.rmi.*;
|
import java.rmi.*;
|
||||||
import java.rmi.server.*;
|
import java.rmi.server.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
|
import helma.scripting.fesi.*;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.*;
|
import helma.objectmodel.db.*;
|
||||||
import helma.xmlrpc.*;
|
import helma.xmlrpc.*;
|
||||||
|
@ -34,7 +35,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
|
|
||||||
private String baseURI;
|
private String baseURI;
|
||||||
|
|
||||||
TypeManager typemgr;
|
public TypeManager typemgr;
|
||||||
|
|
||||||
RequestEvaluator eval;
|
RequestEvaluator eval;
|
||||||
protected Stack freeThreads;
|
protected Stack freeThreads;
|
||||||
|
@ -43,8 +44,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
boolean stopped = false;
|
boolean stopped = false;
|
||||||
boolean debug;
|
boolean debug;
|
||||||
|
|
||||||
Hashtable sessions;
|
public Hashtable sessions;
|
||||||
Hashtable activeUsers;
|
public Hashtable activeUsers;
|
||||||
Hashtable dbMappings;
|
Hashtable dbMappings;
|
||||||
Hashtable dbSources;
|
Hashtable dbSources;
|
||||||
|
|
||||||
|
@ -181,8 +182,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
activeRequests = new Hashtable ();
|
activeRequests = new Hashtable ();
|
||||||
|
|
||||||
typemgr = new TypeManager (this);
|
typemgr = new TypeManager (this);
|
||||||
typemgr.check ();
|
typemgr.createPrototypes ();
|
||||||
logEvent ("Started type manager for "+name);
|
// logEvent ("Started type manager for "+name);
|
||||||
|
|
||||||
rootMapping = getDbMapping ("root");
|
rootMapping = getDbMapping ("root");
|
||||||
userMapping = getDbMapping ("user");
|
userMapping = getDbMapping ("user");
|
||||||
|
@ -196,16 +197,16 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
|
|
||||||
nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props);
|
nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props);
|
||||||
|
|
||||||
worker = new Thread (this, "Worker-"+name);
|
// worker = new Thread (this, "Worker-"+name);
|
||||||
worker.setPriority (Thread.NORM_PRIORITY+2);
|
// worker.setPriority (Thread.NORM_PRIORITY+2);
|
||||||
worker.start ();
|
// worker.start ();
|
||||||
// logEvent ("session cleanup and scheduler thread started");
|
// logEvent ("session cleanup and scheduler thread started");
|
||||||
|
|
||||||
String xmlrpcHandlerName = props.getProperty ("xmlrpcHandlerName", this.name);
|
String xmlrpcHandlerName = props.getProperty ("xmlrpcHandlerName", this.name);
|
||||||
if (xmlrpc != null)
|
if (xmlrpc != null)
|
||||||
xmlrpc.addHandler (xmlrpcHandlerName, new XmlRpcInvoker (this));
|
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.
|
* 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.
|
* 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)
|
if (n < 2 || n > 511)
|
||||||
return false;
|
return false;
|
||||||
int current = allThreads.size();
|
int current = allThreads.size();
|
||||||
|
@ -293,13 +294,20 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of currently active threads
|
||||||
|
*/
|
||||||
|
public int getActiveThreads () {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a request coming in from a web client.
|
* Execute a request coming in from a web client.
|
||||||
*/
|
*/
|
||||||
public ResponseTrans execute (RequestTrans req) {
|
public ResponseTrans execute (RequestTrans req) {
|
||||||
|
|
||||||
requestCount += 1;
|
requestCount += 1;
|
||||||
|
// long reqstart = System.currentTimeMillis ();
|
||||||
User u = getUser (req.session);
|
User u = getUser (req.session);
|
||||||
|
|
||||||
ResponseTrans res = null;
|
ResponseTrans res = null;
|
||||||
|
@ -342,7 +350,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
res.waitForClose ();
|
res.waitForClose ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// System.err.println ("********************** ABSOLUTE TIME: "+(System.currentTimeMillis() - reqstart));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +705,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
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 ();
|
User u = (User) e.nextElement ();
|
||||||
if (now - u.touched () > sessionTimeout * 60000) {
|
if (now - u.lastTouched () > sessionTimeout * 60000) {
|
||||||
if (u.uid != null) {
|
if (u.uid != null) {
|
||||||
try {
|
try {
|
||||||
eval.invokeFunction (u, "onLogout", new ESValue[0]);
|
eval.invokeFunction (u, "onLogout", new ESValue[0]);
|
||||||
|
@ -766,11 +774,11 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
String protoname = m.getExtends ();
|
String protoname = m.getExtends ();
|
||||||
if (protoname == null)
|
if (protoname == null)
|
||||||
protoname = "hopobject";
|
protoname = "hopobject";
|
||||||
Prototype protoProto = (Prototype) typemgr.prototypes.get (protoname);
|
Prototype parentProto = (Prototype) typemgr.prototypes.get (protoname);
|
||||||
if (protoProto == null)
|
if (parentProto == null)
|
||||||
protoProto = (Prototype) typemgr.prototypes.get ("hopobject");
|
parentProto = (Prototype) typemgr.prototypes.get ("hopobject");
|
||||||
if (protoProto != null)
|
if (parentProto != null)
|
||||||
proto.setPrototype (protoProto);
|
proto.setParentPrototype (parentProto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
|
@ -822,6 +830,13 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
dbMappings.put (typename, dbmap);
|
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
|
* Periodically called to log thread stats for this application
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,7 +7,10 @@ import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
|
import helma.scripting.*;
|
||||||
|
import helma.scripting.fesi.*;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
|
import helma.util.Updatable;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
import FESI.Exceptions.EcmaScriptException;
|
import FESI.Exceptions.EcmaScriptException;
|
||||||
|
|
||||||
|
@ -25,12 +28,10 @@ public class Prototype {
|
||||||
String id;
|
String id;
|
||||||
String name;
|
String name;
|
||||||
Application app;
|
Application app;
|
||||||
HashMap templates, functions, actions, skins, updatables;
|
public HashMap templates, functions, actions, skins, updatables;
|
||||||
long lastUpdate;
|
long lastUpdate;
|
||||||
|
|
||||||
// DbMapping dbmap;
|
Prototype parent;
|
||||||
|
|
||||||
Prototype prototype;
|
|
||||||
|
|
||||||
|
|
||||||
public Prototype (String name, Application app) {
|
public Prototype (String name, Application app) {
|
||||||
|
@ -40,11 +41,20 @@ public class Prototype {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.name = name;
|
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) {
|
public Action getActionOrTemplate (String aname) {
|
||||||
|
|
||||||
Action retval = null;
|
Action retval = null;
|
||||||
|
@ -56,21 +66,24 @@ public class Prototype {
|
||||||
if (retval == null && "true".equalsIgnoreCase (app.props.getProperty ("exposetemplates")))
|
if (retval == null && "true".equalsIgnoreCase (app.props.getProperty ("exposetemplates")))
|
||||||
retval = (Action) templates.get (aname);
|
retval = (Action) templates.get (aname);
|
||||||
// if still not found, check if the action is defined for the generic node prototype
|
// if still not found, check if the action is defined for the generic node prototype
|
||||||
if (retval == null && prototype != null)
|
if (retval == null && parent != null)
|
||||||
retval = prototype.getActionOrTemplate (aname);
|
retval = parent.getActionOrTemplate (aname);
|
||||||
return retval;
|
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
|
// this is not allowed for the hopobject and global prototypes
|
||||||
if ("hopobject".equalsIgnoreCase (name) || "global".equalsIgnoreCase (name))
|
if ("hopobject".equalsIgnoreCase (name) || "global".equalsIgnoreCase (name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Prototype old = this.prototype;
|
Prototype old = this.parent;
|
||||||
this.prototype = prototype;
|
this.parent = parent;
|
||||||
|
|
||||||
// if prototype has changed, update ES-prototypes in request evaluators
|
// if parent has changed, update ES-prototypes in request evaluators
|
||||||
if (prototype != old) {
|
if (parent != old) {
|
||||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||||
while (evals.hasNext ()) {
|
while (evals.hasNext ()) {
|
||||||
try {
|
try {
|
||||||
|
@ -78,8 +91,8 @@ public class Prototype {
|
||||||
ObjectPrototype op = reval.getPrototype (getName());
|
ObjectPrototype op = reval.getPrototype (getName());
|
||||||
// use hopobject (node) as prototype even if prototype is null -
|
// use hopobject (node) as prototype even if prototype is null -
|
||||||
// this is the case if no hopobject directory exists
|
// this is the case if no hopobject directory exists
|
||||||
ObjectPrototype opp = prototype == null ?
|
ObjectPrototype opp = parent == null ?
|
||||||
reval.esNodePrototype : reval.getPrototype (prototype.getName ());
|
reval.esNodePrototype : reval.getPrototype (parent.getName ());
|
||||||
// don't think this is possible, but check anyway
|
// don't think this is possible, but check anyway
|
||||||
if (opp == null)
|
if (opp == null)
|
||||||
opp = reval.esNodePrototype;
|
opp = reval.esNodePrototype;
|
||||||
|
@ -90,8 +103,8 @@ public class Prototype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Prototype getPrototype () {
|
public Prototype getParentPrototype () {
|
||||||
return prototype;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Template getTemplate (String tmpname) {
|
public Template getTemplate (String tmpname) {
|
||||||
|
@ -123,6 +136,18 @@ public class Prototype {
|
||||||
return name;
|
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) {
|
public void initRequestEvaluator (RequestEvaluator reval) {
|
||||||
// see if we already registered with this evaluator
|
// see if we already registered with this evaluator
|
||||||
|
@ -133,12 +158,12 @@ public class Prototype {
|
||||||
|
|
||||||
// get the prototype's prototype if possible and necessary
|
// get the prototype's prototype if possible and necessary
|
||||||
ObjectPrototype opp = null;
|
ObjectPrototype opp = null;
|
||||||
if (prototype != null) {
|
if (parent != null) {
|
||||||
// see if parent prototype is already registered. if not, register it
|
// see if parent prototype is already registered. if not, register it
|
||||||
opp = reval.getPrototype (prototype.getName ());
|
opp = reval.getPrototype (parent.getName ());
|
||||||
if (opp == null) {
|
if (opp == null) {
|
||||||
prototype.initRequestEvaluator (reval);
|
parent.initRequestEvaluator (reval);
|
||||||
opp = reval.getPrototype (prototype.getName ());
|
opp = reval.getPrototype (parent.getName ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) {
|
if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) {
|
||||||
|
|
|
@ -6,7 +6,9 @@ package helma.framework.core;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.*;
|
import helma.objectmodel.db.*;
|
||||||
import helma.framework.*;
|
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.xmlrpc.fesi.*;
|
||||||
import helma.util.*;
|
import helma.util.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -27,11 +29,11 @@ import FESI.Exceptions.*;
|
||||||
public class RequestEvaluator implements Runnable {
|
public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
|
|
||||||
Application app;
|
public Application app;
|
||||||
protected boolean initialized;
|
protected boolean initialized;
|
||||||
|
|
||||||
RequestTrans req;
|
public RequestTrans req;
|
||||||
ResponseTrans res;
|
public ResponseTrans res;
|
||||||
|
|
||||||
volatile Transactor rtx;
|
volatile Transactor rtx;
|
||||||
|
|
||||||
|
@ -46,16 +48,16 @@ public class RequestEvaluator implements Runnable {
|
||||||
protected ArrayPrototype reqPath;
|
protected ArrayPrototype reqPath;
|
||||||
private ESRequestData reqData;
|
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
|
// Used to cache skins within one request evaluation
|
||||||
HashMap skincache;
|
HashMap skincache;
|
||||||
|
|
||||||
// vars for FESI EcmaScript support
|
|
||||||
protected Evaluator evaluator;
|
|
||||||
protected ObjectPrototype esNodePrototype;
|
|
||||||
protected ObjectPrototype esUserPrototype;
|
|
||||||
protected LruHashtable objectcache;
|
|
||||||
protected Hashtable prototypes;
|
|
||||||
|
|
||||||
GlobalObject global;
|
GlobalObject global;
|
||||||
HopExtension hopx;
|
HopExtension hopx;
|
||||||
MailExtension mailx;
|
MailExtension mailx;
|
||||||
|
@ -65,8 +67,8 @@ public class RequestEvaluator implements Runnable {
|
||||||
"FESI.Extensions.BasicIO",
|
"FESI.Extensions.BasicIO",
|
||||||
"FESI.Extensions.FileIO",
|
"FESI.Extensions.FileIO",
|
||||||
"helma.xmlrpc.fesi.FesiRpcExtension",
|
"helma.xmlrpc.fesi.FesiRpcExtension",
|
||||||
"helma.framework.extensions.ImageExtension",
|
"helma.scripting.fesi.extensions.ImageExtension",
|
||||||
"helma.framework.extensions.FtpExtension",
|
"helma.scripting.fesi.extensions.FtpExtension",
|
||||||
"FESI.Extensions.JavaAccess",
|
"FESI.Extensions.JavaAccess",
|
||||||
"FESI.Extensions.OptionalRegExp"};
|
"FESI.Extensions.OptionalRegExp"};
|
||||||
|
|
||||||
|
@ -106,9 +108,9 @@ public class RequestEvaluator implements Runnable {
|
||||||
evaluator.addExtension (extensions[i]);
|
evaluator.addExtension (extensions[i]);
|
||||||
hopx = new HopExtension ();
|
hopx = new HopExtension ();
|
||||||
hopx.initializeExtension (this);
|
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);
|
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);
|
dbx.setApplication (this.app);
|
||||||
|
|
||||||
// fake a cache member like the one found in ESNodes
|
// fake a cache member like the one found in ESNodes
|
||||||
|
@ -142,6 +144,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
try {
|
try {
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
app.typemgr.checkPrototypes ();
|
||||||
IPathElement root, currentElement;
|
IPathElement root, currentElement;
|
||||||
// reset skinManager
|
// reset skinManager
|
||||||
skinmanagers = null;
|
skinmanagers = null;
|
||||||
|
@ -751,7 +754,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
if (proto == null)
|
if (proto == null)
|
||||||
return null;
|
return null;
|
||||||
// First check if the skin has been already used within the execution of this request
|
// 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);
|
Skin skin = (Skin) skincache.get (key);
|
||||||
if (skin != null) {
|
if (skin != null) {
|
||||||
return skin;
|
return skin;
|
||||||
|
@ -775,7 +778,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
// still not found. See if there is a parent prototype which might define the 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);
|
} while (proto != null);
|
||||||
// looked every where, nothing to be found
|
// looked every where, nothing to be found
|
||||||
return null;
|
return null;
|
||||||
|
@ -932,18 +935,18 @@ public class RequestEvaluator implements Runnable {
|
||||||
prototypes.put (protoName, op);
|
prototypes.put (protoName, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
final class CompositeKey {
|
final class SkinKey {
|
||||||
|
|
||||||
final String first, second;
|
final String first, second;
|
||||||
|
|
||||||
public CompositeKey (String first, String second) {
|
public SkinKey (String first, String second) {
|
||||||
this.first = first;
|
this.first = first;
|
||||||
this.second = second;
|
this.second = second;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals (Object other) {
|
public boolean equals (Object other) {
|
||||||
try {
|
try {
|
||||||
CompositeKey key = (CompositeKey) other;
|
SkinKey key = (SkinKey) other;
|
||||||
return first.equals (key.first) && second.equals (key.second);
|
return first.equals (key.first) && second.equals (key.second);
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
package helma.framework.core;
|
package helma.framework.core;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Hashtable;
|
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
import FESI.Exceptions.*;
|
import FESI.Exceptions.*;
|
||||||
|
import helma.scripting.*;
|
||||||
|
import helma.scripting.fesi.*;
|
||||||
import helma.objectmodel.INode;
|
import helma.objectmodel.INode;
|
||||||
import helma.objectmodel.ConcurrencyException;
|
import helma.objectmodel.ConcurrencyException;
|
||||||
import helma.util.HtmlEncoder;
|
import helma.util.HtmlEncoder;
|
||||||
|
@ -24,13 +25,19 @@ public class Skin {
|
||||||
Object[] parts;
|
Object[] parts;
|
||||||
Application app;
|
Application app;
|
||||||
String source;
|
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) {
|
public Skin (String content, Application app) {
|
||||||
this (content, app, null);
|
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.app = app;
|
||||||
this.sandbox = sandbox;
|
this.sandbox = sandbox;
|
||||||
parse (content);
|
parse (content);
|
||||||
|
@ -110,18 +117,23 @@ public class Skin {
|
||||||
for (int i=0; i<parts.length; i++) {
|
for (int i=0; i<parts.length; i++) {
|
||||||
if (parts[i] instanceof Macro) {
|
if (parts[i] instanceof Macro) {
|
||||||
Macro m = (Macro) parts[i];
|
Macro m = (Macro) parts[i];
|
||||||
String mname = null;
|
if (macroname.equals (m.getFullName ()))
|
||||||
if (m.handler == null)
|
|
||||||
mname = m.name;
|
|
||||||
else
|
|
||||||
mname = m.handler+"."+m.name;
|
|
||||||
if (macroname.equals (mname))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
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 HANDLER = 0;
|
||||||
static final int MACRO = 1;
|
static final int MACRO = 1;
|
||||||
static final int PARAMNAME = 2;
|
static final int PARAMNAME = 2;
|
||||||
|
@ -131,8 +143,8 @@ public class Skin {
|
||||||
|
|
||||||
String handler;
|
String handler;
|
||||||
String name;
|
String name;
|
||||||
|
String fullname;
|
||||||
Hashtable parameters;
|
Hashtable parameters;
|
||||||
boolean notallowed = false;
|
|
||||||
|
|
||||||
public Macro (String str) {
|
public Macro (String str) {
|
||||||
|
|
||||||
|
@ -219,24 +231,17 @@ public class Skin {
|
||||||
else if (state <= MACRO)
|
else if (state <= MACRO)
|
||||||
name = b.toString().trim();
|
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 {
|
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;
|
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;
|
return;
|
||||||
} else if ("response".equalsIgnoreCase (handler)) {
|
} else if ("response".equalsIgnoreCase (handler)) {
|
||||||
renderFromResponse (reval);
|
renderFromResponse (reval);
|
||||||
|
@ -305,7 +310,7 @@ public class Skin {
|
||||||
if (v != ESUndefined.theUndefined && v != ESNull.theNull)
|
if (v != ESUndefined.theUndefined && v != ESNull.theNull)
|
||||||
reval.res.write (v);
|
reval.res.write (v);
|
||||||
} else {
|
} else {
|
||||||
String msg = "[HopMacro unhandled: "+handler+"."+name+"]";
|
String msg = "[HopMacro unhandled: "+getFullName()+"]";
|
||||||
reval.res.write (" "+msg+" ");
|
reval.res.write (" "+msg+" ");
|
||||||
app.logEvent (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) {
|
public String encode (String text, String encoding) {
|
||||||
if (encoding == null || text == null)
|
if (encoding == null || text == null)
|
||||||
return text;
|
return text;
|
||||||
|
@ -367,8 +376,22 @@ public class Skin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString () {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,29 @@ public class User implements Serializable {
|
||||||
lastTouched = System.currentTimeMillis ();
|
lastTouched = System.currentTimeMillis ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long touched () {
|
public long lastTouched () {
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.*;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
|
import helma.scripting.*;
|
||||||
import helma.util.Updatable;
|
import helma.util.Updatable;
|
||||||
import helma.util.SystemProperties;
|
import helma.util.SystemProperties;
|
||||||
import helma.objectmodel.db.DbMapping;
|
import helma.objectmodel.db.DbMapping;
|
||||||
|
@ -35,7 +36,7 @@ public class ZippedAppFile implements Updatable {
|
||||||
* the file has been modified or deleted.
|
* the file has been modified or deleted.
|
||||||
*/
|
*/
|
||||||
public boolean needsUpdate () {
|
public boolean needsUpdate () {
|
||||||
return lastmod != file.lastModified () || !file.exists ();
|
return lastmod != file.lastModified ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue