Further improvments regarding the "everything is scriptable"

philosophy. Scriptable Java classes are now defined in a
file called scriptable.properties.
This commit is contained in:
hns 2001-09-09 18:08:24 +00:00
parent 18f20ac807
commit 33c7eda08c
2 changed files with 35 additions and 20 deletions

View file

@ -98,6 +98,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
// password file to use for authenticate() function
private CryptFile pwfile;
// Map of java class names to object prototypes
Properties scriptables;
// a cache for parsed skin objects
CacheMap skincache = new CacheMap (100, 0.75f);
@ -174,6 +177,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
pwf = new File (appDir, "passwd");
pwfile = new CryptFile (pwf, parentpwfile);
// the properties that map java class names to prototype names
scriptables = new SystemProperties (new File (appDir, "scriptable.properties").getAbsolutePath ());
// character encoding to be used for responses
charset = props.getProperty ("charset", "ISO-8859-1");
@ -646,7 +652,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
/**
* Return a path to be used in a URL pointing to the given element and action
*/
public String getNodeHref (IPathElement elem, String actionName) {
public String getNodeHref (Object elem, String actionName) {
// FIXME: will fail for non-node roots
Object root = getDataRoot ();
INode users = getUserRoot ();
@ -733,7 +739,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// The following methods minic the IPathElement interface. This allows as
/// The following methods mimic the IPathElement interface. This allows as
/// to script any Java object: If the object implements IPathElement (as does
/// the Node class in Helma's internal objectmodel) then the corresponding
/// method is called in the object itself. Otherwise, a corresponding script function
@ -785,7 +791,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
return ((IPathElement) obj).getPrototype ();
else
// use java class name as prototype name
return obj.getClass ().getName ();
return scriptables.getProperty (obj.getClass ().getName ());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -653,12 +653,16 @@ public class RequestEvaluator implements Runnable {
}
protected Object invokeDirectFunction (Object obj, String functionName, Object[] args) throws Exception {
ESObject eso = getElementWrapper (obj);
ESObject eso = null;
if (obj == null)
eso = global;
else
eso = getElementWrapper (obj);
ESValue[] esv = args == null ? new ESValue[0] : new ESValue[args.length];
for (int i=0; i<esv.length; i++)
esv[i] = ESLoader.normalizeValue (args[i], evaluator);
ESValue retval = eso.doIndirectCall (evaluator, eso, functionName, esv);
return retval.toJavaObject ();
return retval == null ? null : retval.toJavaObject ();
}
public synchronized Object invokeFunction (Object node, String functionName, Object[] args)
@ -761,12 +765,8 @@ public class RequestEvaluator implements Runnable {
if (thisObject == null)
proto = app.typemgr.getPrototype ("global");
else {
try {
IPathElement elem = (IPathElement) thisObject.toJavaObject ();
Object elem = thisObject.toJavaObject ();
proto = app.getPrototype (elem);
} catch (ClassCastException wrongClass) {
throw new RuntimeException ("Can't render a skin on something that is not a path element: "+wrongClass);
}
}
return getSkin (proto, skinname);
}
@ -867,7 +867,24 @@ public class RequestEvaluator implements Runnable {
return (ESNode) objectcache.get (n);
}
/**
* Get a Script wrapper for an object. In contrast to getElementWrapper, this is called for
* any Java object, not just the ones in the request path which we know are scripted.
* So what we do is check if the object belongs to a scripted class. If so, we call getElementWrapper()
* with the object, otherwise we return a generic unscripted object wrapper.
*/
public ESValue getObjectWrapper (Object e) {
if (app.getPrototypeName (e) != null)
return getElementWrapper (e);
else
return new ESWrapper (e, evaluator);
}
/**
* Get a Script wrapper for any given object. If the object implements the IPathElement
* interface, the getPrototype method will be used to retrieve the name of the prototype
* to use. Otherwise, a Java-Class-to-Script-Prototype mapping is consulted.
*/
public ESObject getElementWrapper (Object e) {
// check if e is an instance of a helma objectmodel node.
@ -875,18 +892,10 @@ public class RequestEvaluator implements Runnable {
return getNodeWrapper ((INode) e);
// Gotta find out the prototype name to use for this object...
String prototypeName = null;
// check if e implements the IPathElement interface
if (e instanceof IPathElement)
// e implements the getPrototype() method
prototypeName = ((IPathElement) e).getPrototype ();
else
// use java class name as prototype name
prototypeName = e.getClass ().getName ();
String prototypeName = app.getPrototypeName (e);
ObjectPrototype op = getPrototype (prototypeName);
if (op == null)
op = esNodePrototype;