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;
|
package helma.scripting.rhino;
|
||||||
|
|
||||||
|
import helma.scripting.rhino.extensions.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.framework.core.*;
|
import helma.framework.core.*;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.*;
|
import helma.objectmodel.db.*;
|
||||||
import org.mozilla.javascript.*;
|
import org.mozilla.javascript.*;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
@ -73,10 +74,39 @@ public class HopObject extends ScriptableObject {
|
||||||
*/
|
*/
|
||||||
public static Object hopObjectConstructor(Context cx, Object[] args,
|
public static Object hopObjectConstructor(Context cx, Object[] args,
|
||||||
Function ctorObj, boolean inNewExpr)
|
Function ctorObj, boolean inNewExpr)
|
||||||
throws ScriptingException {
|
throws JavaScriptException, ScriptingException {
|
||||||
RhinoEngine engine = (RhinoEngine) cx.getThreadLocal("engine");
|
RhinoEngine engine = (RhinoEngine) cx.getThreadLocal("engine");
|
||||||
RhinoCore c = engine.core;
|
RhinoCore c = engine.core;
|
||||||
String prototype = ((FunctionObject) ctorObj).getFunctionName();
|
String prototype = ((FunctionObject) ctorObj).getFunctionName();
|
||||||
|
|
||||||
|
// 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,
|
INode n = new helma.objectmodel.db.Node(prototype, prototype,
|
||||||
c.app.getWrappedNodeManager());
|
c.app.getWrappedNodeManager());
|
||||||
HopObject hobj = new HopObject(prototype);
|
HopObject hobj = new HopObject(prototype);
|
||||||
|
@ -90,6 +120,7 @@ public class HopObject extends ScriptableObject {
|
||||||
|
|
||||||
return hobj;
|
return hobj;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -111,6 +142,15 @@ public class HopObject extends ScriptableObject {
|
||||||
node = n;
|
node = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the INode wrapped by this HopObject.
|
||||||
|
*
|
||||||
|
* @return the wrapped INode instance
|
||||||
|
*/
|
||||||
|
public INode getNode() {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
|
@ -36,6 +36,20 @@ public class JavaObject extends NativeJavaObject {
|
||||||
RhinoCore core;
|
RhinoCore core;
|
||||||
Scriptable prototype;
|
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.
|
* Creates a new JavaObject wrapper.
|
||||||
*/
|
*/
|
||||||
|
@ -168,18 +182,16 @@ public class JavaObject extends NativeJavaObject {
|
||||||
|
|
||||||
public Object get(String name, Scriptable start) {
|
public Object get(String name, Scriptable start) {
|
||||||
// System.err.println ("GET: "+name);
|
// System.err.println ("GET: "+name);
|
||||||
Object obj = prototype.get(name, start);
|
Object obj = overload.get(name);
|
||||||
if (obj != null && obj != UniqueTag.NOT_FOUND)
|
if (obj != null) {
|
||||||
return obj;
|
return new FunctionObject(name, (Method) obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
Method[] m = JavaObject.class.getMethods();
|
obj = prototype.get(name, start);
|
||||||
for (int i=0; i<m.length; i++) {
|
if (obj != null && obj != UniqueTag.NOT_FOUND) {
|
||||||
if (name.equals(m[i].getName())) {
|
|
||||||
obj = new FunctionObject(name, m[i], this);
|
|
||||||
// System.err.println ("GOT: "+obj);
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return super.get(name, start);
|
return super.get(name, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package helma.scripting.rhino;
|
package helma.scripting.rhino;
|
||||||
|
|
||||||
|
import helma.scripting.rhino.extensions.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.framework.core.*;
|
import helma.framework.core.*;
|
||||||
import helma.main.Server;
|
import helma.main.Server;
|
||||||
|
@ -144,7 +145,7 @@ public final class RhinoCore {
|
||||||
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
|
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
|
||||||
(opp == null)) {
|
(opp == null)) {
|
||||||
if (app.isJavaPrototype(name)) {
|
if (app.isJavaPrototype(name)) {
|
||||||
opp = getRawPrototype("__javaobject__");
|
opp = null;
|
||||||
} else {
|
} else {
|
||||||
opp = getRawPrototype("hopobject");
|
opp = getRawPrototype("hopobject");
|
||||||
}
|
}
|
||||||
|
@ -177,9 +178,7 @@ public final class RhinoCore {
|
||||||
// the actual (scripted) constructor on it.
|
// the actual (scripted) constructor on it.
|
||||||
if (!"global".equalsIgnoreCase(name) && !"root".equalsIgnoreCase(name)) {
|
if (!"global".equalsIgnoreCase(name) && !"root".equalsIgnoreCase(name)) {
|
||||||
try {
|
try {
|
||||||
FunctionObject fp = new FunctionObject(name, HopObject.hopObjCtor, global);
|
installConstructor(name, op);
|
||||||
|
|
||||||
installConstructor(fp, op);
|
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
System.err.println("Error adding ctor for " + name + ": " + ignore);
|
System.err.println("Error adding ctor for " + name + ": " + ignore);
|
||||||
ignore.printStackTrace();
|
ignore.printStackTrace();
|
||||||
|
@ -213,7 +212,7 @@ public final class RhinoCore {
|
||||||
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
|
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
|
||||||
(opp == null)) {
|
(opp == null)) {
|
||||||
if (app.isJavaPrototype(name)) {
|
if (app.isJavaPrototype(name)) {
|
||||||
opp = getPrototype("__javaobject__");
|
opp = null;
|
||||||
} else {
|
} else {
|
||||||
opp = getPrototype("hopobject");
|
opp = getPrototype("hopobject");
|
||||||
}
|
}
|
||||||
|
@ -244,20 +243,6 @@ public final class RhinoCore {
|
||||||
op.setPrototype(opp);
|
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();) {
|
for (Iterator it = prototype.getZippedCode().values().iterator(); it.hasNext();) {
|
||||||
Object code = it.next();
|
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
|
* 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.
|
* 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);
|
ScriptRuntime.setFunctionProtoAndParent(global, fo);
|
||||||
fo.setImmunePrototypeProperty(prototype);
|
fo.setImmunePrototypeProperty(prototype);
|
||||||
|
|
||||||
prototype.setParentScope(fo);
|
prototype.setParentScope(fo);
|
||||||
|
|
||||||
String name = prototype.getClassName();
|
|
||||||
ScriptableObject.defineProperty(global, name, fo, ScriptableObject.DONTENUM);
|
ScriptableObject.defineProperty(global, name, fo, ScriptableObject.DONTENUM);
|
||||||
|
|
||||||
fo.setParentScope(global);
|
fo.setParentScope(global);
|
||||||
|
@ -563,7 +549,7 @@ public final class RhinoCore {
|
||||||
/**
|
/**
|
||||||
* Register an object prototype for a certain prototype name.
|
* 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)) {
|
if ((protoName != null) && (op != null)) {
|
||||||
prototypes.put(protoName, new TypeInfo(op, protoName));
|
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
|
* 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.
|
* 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);
|
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
|
* 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?
|
// FIXME: is this needed? should this return ESNull.theNull?
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
return 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 {
|
class TypeInfo {
|
||||||
Scriptable objectPrototype;
|
Scriptable objectPrototype;
|
||||||
long lastUpdate = 0;
|
long lastUpdate = 0;
|
||||||
|
@ -725,16 +721,18 @@ public final class RhinoCore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object wrapper class
|
||||||
|
*/
|
||||||
class Wrapper extends WrapFactory {
|
class Wrapper extends WrapFactory {
|
||||||
|
|
||||||
public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) {
|
public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) {
|
||||||
// System.err.println ("Wrapping: "+obj);
|
// System.err.println ("Wrapping: "+obj);
|
||||||
|
|
||||||
if (obj instanceof INode) {
|
if (obj instanceof INode) {
|
||||||
return getNodeWrapper((INode) obj);
|
return getNodeWrapper((INode) obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof IPathElement) {
|
if (obj != null && app.getPrototypeName(obj) != null) {
|
||||||
return getElementWrapper(obj);
|
return getElementWrapper(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +748,7 @@ public final class RhinoCore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject) {
|
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject) {
|
||||||
if (javaObject instanceof IPathElement) {
|
if (javaObject != null && app.getPrototypeName(javaObject) != null) {
|
||||||
return getElementWrapper(javaObject);
|
return getElementWrapper(javaObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +761,7 @@ public final class RhinoCore {
|
||||||
return getNodeWrapper((INode) obj);
|
return getNodeWrapper((INode) obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof IPathElement) {
|
if (obj != null && app.getPrototypeName(obj) != null) {
|
||||||
return getElementWrapper(obj);
|
return getElementWrapper(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.DbMapping;
|
import helma.objectmodel.db.DbMapping;
|
||||||
import helma.objectmodel.db.Relation;
|
import helma.objectmodel.db.Relation;
|
||||||
import helma.scripting.*;
|
import helma.scripting.*;
|
||||||
import helma.scripting.fesi.extensions.*;
|
|
||||||
import helma.util.CacheMap;
|
import helma.util.CacheMap;
|
||||||
import helma.util.Updatable;
|
import helma.util.Updatable;
|
||||||
import org.mozilla.javascript.*;
|
import org.mozilla.javascript.*;
|
||||||
|
@ -37,6 +36,7 @@ import java.util.*;
|
||||||
* This is the implementation of ScriptingEnvironment for the Mozilla Rhino EcmaScript interpreter.
|
* This is the implementation of ScriptingEnvironment for the Mozilla Rhino EcmaScript interpreter.
|
||||||
*/
|
*/
|
||||||
public final class RhinoEngine implements ScriptingEngine {
|
public final class RhinoEngine implements ScriptingEngine {
|
||||||
|
// map for Application to RhinoCore binding
|
||||||
static Map coreMap;
|
static Map coreMap;
|
||||||
|
|
||||||
// the application we're running in
|
// the application we're running in
|
||||||
|
@ -123,7 +123,7 @@ public final class RhinoEngine implements ScriptingEngine {
|
||||||
RhinoCore core = null;
|
RhinoCore core = null;
|
||||||
|
|
||||||
if (coreMap == null) {
|
if (coreMap == null) {
|
||||||
coreMap = new HashMap();
|
coreMap = new WeakHashMap();
|
||||||
} else {
|
} else {
|
||||||
core = (RhinoCore) coreMap.get(app);
|
core = (RhinoCore) coreMap.get(app);
|
||||||
}
|
}
|
||||||
|
@ -227,17 +227,17 @@ public final class RhinoEngine implements ScriptingEngine {
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|
||||||
// loop through previous globals and unset them, if necessary.
|
// loop through previous globals and unset them, if necessary.
|
||||||
/* if (lastGlobals != null) {
|
if (lastGlobals != null) {
|
||||||
for (Iterator i=lastGlobals.keySet().iterator(); i.hasNext(); ) {
|
for (Iterator i=lastGlobals.keySet().iterator(); i.hasNext(); ) {
|
||||||
String g = (String) i.next ();
|
String g = (String) i.next ();
|
||||||
try {
|
try {
|
||||||
global.deleteProperty (g, g.hashCode());
|
global.delete (g);
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
System.err.println ("Error resetting global property: "+g);
|
System.err.println ("Error resetting global property: "+g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastGlobals = null;
|
lastGlobals = null;
|
||||||
} */
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -298,10 +298,15 @@ public final class RhinoEngine implements ScriptingEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
// has the request timed out? If so, throw TimeoutException
|
// has the request timed out? If so, throw TimeoutException
|
||||||
// if (evaluator.thread != Thread.currentThread())
|
if (thread != Thread.currentThread())
|
||||||
// throw new TimeoutException ();
|
throw new TimeoutException ();
|
||||||
// create and throw a ScriptingException with the right message
|
// 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()) {
|
if (app.debug()) {
|
||||||
System.err.println("Error in Script: " + msg);
|
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() {
|
public ResponseTrans getResponse() {
|
||||||
return reval.res;
|
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() {
|
public RequestTrans getRequest() {
|
||||||
return reval.req;
|
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