Lots of fixes and cleanup.
This commit is contained in:
parent
4236304e84
commit
052b847c7a
5 changed files with 128 additions and 61 deletions
|
@ -16,6 +16,7 @@
|
|||
|
||||
package helma.scripting.rhino;
|
||||
|
||||
import helma.scripting.rhino.extensions.*;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.objectmodel.*;
|
||||
|
|
|
@ -23,6 +23,7 @@ import helma.objectmodel.*;
|
|||
import helma.objectmodel.db.*;
|
||||
import org.mozilla.javascript.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
|
@ -73,22 +74,52 @@ public class HopObject extends ScriptableObject {
|
|||
*/
|
||||
public static Object hopObjectConstructor(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
throws ScriptingException {
|
||||
throws JavaScriptException, ScriptingException {
|
||||
RhinoEngine engine = (RhinoEngine) cx.getThreadLocal("engine");
|
||||
RhinoCore c = engine.core;
|
||||
String prototype = ((FunctionObject) ctorObj).getFunctionName();
|
||||
INode n = new helma.objectmodel.db.Node(prototype, prototype,
|
||||
|
||||
// if this is a java object prototype, create a new java object
|
||||
// of the given class instead of a HopObject.
|
||||
if (c.app.isJavaPrototype(prototype)) {
|
||||
String classname = c.app.getJavaClassForPrototype(prototype);
|
||||
try {
|
||||
Class clazz = Class.forName(classname);
|
||||
Constructor[] cnst = clazz.getConstructors();
|
||||
// brute force loop through constructors -
|
||||
// alas, this isn't very pretty.
|
||||
for (int i=0; i<cnst.length; i++) try {
|
||||
FunctionObject fo = new FunctionObject("ctor", cnst[i], engine.global);
|
||||
Object obj = fo.call(cx, engine.global, null, args);
|
||||
return cx.toObject(obj, engine.global);
|
||||
} catch (JavaScriptException x) {
|
||||
Object value = x.getValue();
|
||||
if (value instanceof Throwable) {
|
||||
((Throwable) value).printStackTrace();
|
||||
}
|
||||
throw new JavaScriptException("Error in Java constructor: "+value);
|
||||
} catch (Exception ignore) {
|
||||
// constructor arguments didn't match
|
||||
}
|
||||
throw new ScriptingException("No matching Java Constructor found in "+clazz);
|
||||
} catch (Exception x) {
|
||||
System.err.println("Error in Java constructor: "+x);
|
||||
throw new JavaScriptException(x);
|
||||
}
|
||||
} else {
|
||||
INode n = new helma.objectmodel.db.Node(prototype, prototype,
|
||||
c.app.getWrappedNodeManager());
|
||||
HopObject hobj = new HopObject(prototype);
|
||||
HopObject hobj = new HopObject(prototype);
|
||||
|
||||
hobj.init(c, n);
|
||||
Scriptable p = c.getPrototype(prototype);
|
||||
if (p != null) {
|
||||
hobj.setPrototype(p);
|
||||
engine.invoke(hobj, "constructor", args, false);
|
||||
hobj.init(c, n);
|
||||
Scriptable p = c.getPrototype(prototype);
|
||||
if (p != null) {
|
||||
hobj.setPrototype(p);
|
||||
engine.invoke(hobj, "constructor", args, false);
|
||||
}
|
||||
|
||||
return hobj;
|
||||
}
|
||||
|
||||
return hobj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,6 +142,15 @@ public class HopObject extends ScriptableObject {
|
|||
node = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the INode wrapped by this HopObject.
|
||||
*
|
||||
* @return the wrapped INode instance
|
||||
*/
|
||||
public INode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
|
|
|
@ -29,13 +29,27 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class JavaObject extends NativeJavaObject {
|
||||
|
||||
RhinoCore core;
|
||||
Scriptable prototype;
|
||||
|
||||
static HashMap overload;
|
||||
|
||||
static {
|
||||
overload = new HashMap();
|
||||
Method[] m = JavaObject.class.getMethods();
|
||||
for (int i=0; i<m.length; i++) {
|
||||
if ("href".equals(m[i].getName()) ||
|
||||
"renderSkin".equals(m[i].getName()) ||
|
||||
"renderSkinAsString".equals(m[i].getName())) {
|
||||
overload.put(m[i].getName(), m[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new JavaObject wrapper.
|
||||
*/
|
||||
|
@ -168,19 +182,17 @@ public class JavaObject extends NativeJavaObject {
|
|||
|
||||
public Object get(String name, Scriptable start) {
|
||||
// System.err.println ("GET: "+name);
|
||||
Object obj = prototype.get(name, start);
|
||||
if (obj != null && obj != UniqueTag.NOT_FOUND)
|
||||
return obj;
|
||||
|
||||
Method[] m = JavaObject.class.getMethods();
|
||||
for (int i=0; i<m.length; i++) {
|
||||
if (name.equals(m[i].getName())) {
|
||||
obj = new FunctionObject(name, m[i], this);
|
||||
// System.err.println ("GOT: "+obj);
|
||||
return obj;
|
||||
}
|
||||
Object obj = overload.get(name);
|
||||
if (obj != null) {
|
||||
return new FunctionObject(name, (Method) obj, this);
|
||||
}
|
||||
return super.get(name, start);
|
||||
|
||||
obj = prototype.get(name, start);
|
||||
if (obj != null && obj != UniqueTag.NOT_FOUND) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
return super.get(name, start);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package helma.scripting.rhino;
|
||||
|
||||
import helma.scripting.rhino.extensions.*;
|
||||
import helma.framework.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.main.Server;
|
||||
|
@ -144,7 +145,7 @@ public final class RhinoCore {
|
|||
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
|
||||
(opp == null)) {
|
||||
if (app.isJavaPrototype(name)) {
|
||||
opp = getRawPrototype("__javaobject__");
|
||||
opp = null;
|
||||
} else {
|
||||
opp = getRawPrototype("hopobject");
|
||||
}
|
||||
|
@ -177,9 +178,7 @@ public final class RhinoCore {
|
|||
// the actual (scripted) constructor on it.
|
||||
if (!"global".equalsIgnoreCase(name) && !"root".equalsIgnoreCase(name)) {
|
||||
try {
|
||||
FunctionObject fp = new FunctionObject(name, HopObject.hopObjCtor, global);
|
||||
|
||||
installConstructor(fp, op);
|
||||
installConstructor(name, op);
|
||||
} catch (Exception ignore) {
|
||||
System.err.println("Error adding ctor for " + name + ": " + ignore);
|
||||
ignore.printStackTrace();
|
||||
|
@ -213,7 +212,7 @@ public final class RhinoCore {
|
|||
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
|
||||
(opp == null)) {
|
||||
if (app.isJavaPrototype(name)) {
|
||||
opp = getPrototype("__javaobject__");
|
||||
opp = null;
|
||||
} else {
|
||||
opp = getPrototype("hopobject");
|
||||
}
|
||||
|
@ -244,20 +243,6 @@ public final class RhinoCore {
|
|||
op.setPrototype(opp);
|
||||
}
|
||||
|
||||
// Register a constructor for all types except global.
|
||||
// This will first create a new prototyped hopobject and then calls
|
||||
// the actual (scripted) constructor on it.
|
||||
/* if (!"global".equalsIgnoreCase(name) && !"root".equalsIgnoreCase(name)) {
|
||||
try {
|
||||
FunctionObject fp = new FunctionObject(name, HopObject.hopObjCtor, global);
|
||||
|
||||
installConstructor(fp, op);
|
||||
} catch (Exception ignore) {
|
||||
System.err.println("Error adding ctor for " + name + ": " + ignore);
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
} */
|
||||
|
||||
for (Iterator it = prototype.getZippedCode().values().iterator(); it.hasNext();) {
|
||||
Object code = it.next();
|
||||
|
||||
|
@ -276,13 +261,14 @@ public final class RhinoCore {
|
|||
* that does not set the constructor property in the prototype. This is because
|
||||
* we want our own scripted constructor function to prevail, if it is defined.
|
||||
*/
|
||||
private void installConstructor(FunctionObject fo, Scriptable prototype) {
|
||||
private void installConstructor(String name, Scriptable prototype) {
|
||||
FunctionObject fo = new FunctionObject(name, HopObject.hopObjCtor, global);
|
||||
|
||||
ScriptRuntime.setFunctionProtoAndParent(global, fo);
|
||||
fo.setImmunePrototypeProperty(prototype);
|
||||
|
||||
prototype.setParentScope(fo);
|
||||
|
||||
String name = prototype.getClassName();
|
||||
ScriptableObject.defineProperty(global, name, fo, ScriptableObject.DONTENUM);
|
||||
|
||||
fo.setParentScope(global);
|
||||
|
@ -563,7 +549,7 @@ public final class RhinoCore {
|
|||
/**
|
||||
* Register an object prototype for a certain prototype name.
|
||||
*/
|
||||
public void putPrototype(String protoName, Scriptable op) {
|
||||
private void putPrototype(String protoName, Scriptable op) {
|
||||
if ((protoName != null) && (op != null)) {
|
||||
prototypes.put(protoName, new TypeInfo(op, protoName));
|
||||
}
|
||||
|
@ -575,7 +561,7 @@ public final class RhinoCore {
|
|||
* 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.
|
||||
*/
|
||||
protected Scriptable getElementWrapper(Object e) {
|
||||
public Scriptable getElementWrapper(Object e) {
|
||||
|
||||
Scriptable w = (Scriptable) wrappercache.get(e);
|
||||
|
||||
|
@ -600,7 +586,7 @@ public final class RhinoCore {
|
|||
/**
|
||||
* Get a script wrapper for an instance of helma.objectmodel.INode
|
||||
*/
|
||||
protected Scriptable getNodeWrapper(INode n) {
|
||||
public Scriptable getNodeWrapper(INode n) {
|
||||
// FIXME: is this needed? should this return ESNull.theNull?
|
||||
if (n == null) {
|
||||
return null;
|
||||
|
@ -710,6 +696,16 @@ public final class RhinoCore {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the global scope of this RhinoCore.
|
||||
*/
|
||||
public Scriptable getScope() {
|
||||
return global;
|
||||
}
|
||||
|
||||
/**
|
||||
* TypeInfo helper class
|
||||
*/
|
||||
class TypeInfo {
|
||||
Scriptable objectPrototype;
|
||||
long lastUpdate = 0;
|
||||
|
@ -725,16 +721,18 @@ public final class RhinoCore {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Object wrapper class
|
||||
*/
|
||||
class Wrapper extends WrapFactory {
|
||||
|
||||
public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) {
|
||||
// System.err.println ("Wrapping: "+obj);
|
||||
|
||||
if (obj instanceof INode) {
|
||||
return getNodeWrapper((INode) obj);
|
||||
}
|
||||
|
||||
if (obj instanceof IPathElement) {
|
||||
if (obj != null && app.getPrototypeName(obj) != null) {
|
||||
return getElementWrapper(obj);
|
||||
}
|
||||
|
||||
|
@ -750,7 +748,7 @@ public final class RhinoCore {
|
|||
}
|
||||
|
||||
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject) {
|
||||
if (javaObject instanceof IPathElement) {
|
||||
if (javaObject != null && app.getPrototypeName(javaObject) != null) {
|
||||
return getElementWrapper(javaObject);
|
||||
}
|
||||
|
||||
|
@ -763,7 +761,7 @@ public final class RhinoCore {
|
|||
return getNodeWrapper((INode) obj);
|
||||
}
|
||||
|
||||
if (obj instanceof IPathElement) {
|
||||
if (obj != null && app.getPrototypeName(obj) != null) {
|
||||
return getElementWrapper(obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import helma.objectmodel.*;
|
|||
import helma.objectmodel.db.DbMapping;
|
||||
import helma.objectmodel.db.Relation;
|
||||
import helma.scripting.*;
|
||||
import helma.scripting.fesi.extensions.*;
|
||||
import helma.util.CacheMap;
|
||||
import helma.util.Updatable;
|
||||
import org.mozilla.javascript.*;
|
||||
|
@ -37,6 +36,7 @@ import java.util.*;
|
|||
* This is the implementation of ScriptingEnvironment for the Mozilla Rhino EcmaScript interpreter.
|
||||
*/
|
||||
public final class RhinoEngine implements ScriptingEngine {
|
||||
// map for Application to RhinoCore binding
|
||||
static Map coreMap;
|
||||
|
||||
// the application we're running in
|
||||
|
@ -123,7 +123,7 @@ public final class RhinoEngine implements ScriptingEngine {
|
|||
RhinoCore core = null;
|
||||
|
||||
if (coreMap == null) {
|
||||
coreMap = new HashMap();
|
||||
coreMap = new WeakHashMap();
|
||||
} else {
|
||||
core = (RhinoCore) coreMap.get(app);
|
||||
}
|
||||
|
@ -227,17 +227,17 @@ public final class RhinoEngine implements ScriptingEngine {
|
|||
thread = null;
|
||||
|
||||
// loop through previous globals and unset them, if necessary.
|
||||
/* if (lastGlobals != null) {
|
||||
if (lastGlobals != null) {
|
||||
for (Iterator i=lastGlobals.keySet().iterator(); i.hasNext(); ) {
|
||||
String g = (String) i.next ();
|
||||
try {
|
||||
global.deleteProperty (g, g.hashCode());
|
||||
global.delete (g);
|
||||
} catch (Exception x) {
|
||||
System.err.println ("Error resetting global property: "+g);
|
||||
}
|
||||
}
|
||||
lastGlobals = null;
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,10 +298,15 @@ public final class RhinoEngine implements ScriptingEngine {
|
|||
}
|
||||
|
||||
// has the request timed out? If so, throw TimeoutException
|
||||
// if (evaluator.thread != Thread.currentThread())
|
||||
// throw new TimeoutException ();
|
||||
if (thread != Thread.currentThread())
|
||||
throw new TimeoutException ();
|
||||
// create and throw a ScriptingException with the right message
|
||||
String msg = x.toString();
|
||||
String msg;
|
||||
if (x instanceof JavaScriptException) {
|
||||
msg = ((JavaScriptException) x).getValue().toString();
|
||||
} else {
|
||||
msg = x.toString();
|
||||
}
|
||||
|
||||
if (app.debug()) {
|
||||
System.err.println("Error in Script: " + msg);
|
||||
|
@ -416,16 +421,27 @@ public final class RhinoEngine implements ScriptingEngine {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the Response object of the current evaluation context. Proxy method to RequestEvaluator.
|
||||
* Return the Response object of the current evaluation context.
|
||||
* Proxy method to RequestEvaluator.
|
||||
*/
|
||||
public ResponseTrans getResponse() {
|
||||
return reval.res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Request object of the current evaluation context. Proxy method to RequestEvaluator.
|
||||
* Return the Request object of the current evaluation context.
|
||||
* Proxy method to RequestEvaluator.
|
||||
*/
|
||||
public RequestTrans getRequest() {
|
||||
return reval.req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RhinoCore object for the application this engine belongs to.
|
||||
*
|
||||
* @return this engine's RhinoCore instance
|
||||
*/
|
||||
public RhinoCore getCore() {
|
||||
return core;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue