Added code for Rhino scripting engine.

This commit is contained in:
hns 2003-06-10 13:41:11 +00:00
parent 78411bea50
commit 1ea945f82a
8 changed files with 2822 additions and 0 deletions

View file

@ -0,0 +1,283 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.framework.*;
import helma.framework.core.*;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import helma.util.HtmlEncoder;
import org.mozilla.javascript.*;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class GlobalObject extends ScriptableObject {
Application app;
RhinoCore core;
/**
* Creates a new GlobalObject object.
*
* @param core ...
* @param app ...
*
* @throws PropertyException ...
*/
public GlobalObject(RhinoCore core, Application app)
throws PropertyException {
this.core = core;
this.app = app;
String[] globalFuncs = {
"renderSkin", "renderSkinAsString", "getProperty",
"authenticate", "createSkin", "format", "encode",
"encodeXml", "encodeForm", "stripTags"
};
defineFunctionProperties(globalFuncs, GlobalObject.class, 0);
put("app", this, new ApplicationBean(app));
put("Xml", this, new XmlObject(core));
}
/**
*
*
* @return ...
*/
public String getClassName() {
return "GlobalObject";
}
/**
*
*
* @param skin ...
* @param param ...
*
* @return ...
*/
public boolean renderSkin(Object skin, Object param) {
// System.err.println ("RENDERSKIN CALLED WITH PARAM "+param);
Context cx = Context.getCurrentContext();
RequestEvaluator reval = (RequestEvaluator) cx.getThreadLocal("reval");
Skin s;
if (skin instanceof Skin) {
s = (Skin) skin;
} else {
s = core.app.getSkin(null, skin.toString(), null);
}
Map p = null;
if ((param != null) && (param != Undefined.instance)) {
p = new HashMap();
if (param instanceof Scriptable) {
Scriptable sp = (Scriptable) param;
Object[] ids = sp.getIds();
for (int i = 0; i < ids.length; i++) {
Object obj = sp.get(ids[i].toString(), sp);
if (obj instanceof NativeJavaObject) {
p.put(ids[i], ((NativeJavaObject) obj).unwrap());
} else {
p.put(ids[i], obj);
}
}
}
}
if (s != null) {
s.render(reval, null, p);
}
return true;
}
/**
*
*
* @param skin ...
* @param param ...
*
* @return ...
*/
public String renderSkinAsString(Object skin, Object param) {
Context cx = Context.getCurrentContext();
RequestEvaluator reval = (RequestEvaluator) cx.getThreadLocal("reval");
Skin s;
if (skin instanceof Skin) {
s = (Skin) skin;
} else {
s = core.app.getSkin(null, skin.toString(), null);
}
Map p = null;
if ((param != null) && (param != Undefined.instance)) {
p = new HashMap();
if (param instanceof Scriptable) {
Scriptable sp = (Scriptable) param;
Object[] ids = sp.getIds();
for (int i = 0; i < ids.length; i++) {
Object obj = sp.get(ids[i].toString(), sp);
if (obj instanceof NativeJavaObject) {
p.put(ids[i], ((NativeJavaObject) obj).unwrap());
} else {
p.put(ids[i], obj);
}
}
}
}
if (s != null) {
reval.res.pushStringBuffer();
s.render(reval, null, p);
return reval.res.popStringBuffer();
}
return "";
}
/**
*
*
* @param propname ...
*
* @return ...
*/
public String getProperty(String propname) {
return app.getProperty(propname);
}
/**
*
*
* @param user ...
* @param pwd ...
*
* @return ...
*/
public boolean authenticate(String user, String pwd) {
return app.authenticate(user, pwd);
}
/**
*
*
* @param str ...
*
* @return ...
*/
public Skin createSkin(String str) {
return new Skin(str, app);
}
/**
*
*
* @param str ...
*
* @return ...
*/
public String encode(String str) {
return HtmlEncoder.encodeAll(str);
}
/**
*
*
* @param str ...
*
* @return ...
*/
public String encodeXml(String str) {
return HtmlEncoder.encodeXml(str);
}
/**
*
*
* @param str ...
*
* @return ...
*/
public String encodeForm(String str) {
return HtmlEncoder.encodeFormValue(str);
}
/**
*
*
* @param str ...
*
* @return ...
*/
public String format(String str) {
return HtmlEncoder.encode(str);
}
/**
*
*
* @param str ...
*
* @return ...
*/
public String stripTags(String str) {
if (str == null) {
return null;
}
char[] c = str.toCharArray();
boolean inTag = false;
int i;
int j = 0;
for (i = 0; i < c.length; i++) {
if (c[i] == '<') {
inTag = true;
}
if (!inTag) {
if (i > j) {
c[j] = c[i];
}
j++;
}
if (c[i] == '>') {
inTag = false;
}
}
if (i > j) {
return new String(c, 0, j);
}
return str;
}
}

View file

@ -0,0 +1,738 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.framework.*;
import helma.framework.core.*;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import org.mozilla.javascript.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class HopObject extends ScriptableObject {
static Method hopObjCtor;
static {
Method[] methods = HopObject.class.getMethods();
for (int i = 0; i < methods.length; i++) {
if ("hopObjectConstructor".equals(methods[i].getName())) {
hopObjCtor = methods[i];
break;
}
}
}
String className;
INode node;
RhinoCore core;
/**
* Creates a new HopObject object.
*/
public HopObject() {
className = "HopObject";
}
/**
* Creates a new HopObject object.
*
* @param cname ...
*/
public HopObject(String cname) {
className = cname;
}
// public void jsConstructor () {
/* Context cx = Context.getCurrentContext ();
RhinoEngine engine = (RhinoEngine) cx.getThreadLocal ("engine");
core = engine.core;
node = new helma.objectmodel.db.Node (null, null, core.app.getWrappedNodeManager ()); */
// }
public static Object hopObjectConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr) {
RhinoEngine engine = (RhinoEngine) cx.getThreadLocal("engine");
RhinoCore c = engine.core;
String prototype = ((FunctionObject) ctorObj).getFunctionName();
INode n = new helma.objectmodel.db.Node(prototype, prototype,
c.app.getWrappedNodeManager());
HopObject hobj = new HopObject(prototype);
hobj.init(c, n);
return hobj;
}
/**
*
*
* @return ...
*/
public String getClassName() {
return className;
}
/**
*
*
* @param c ...
* @param n ...
*/
public void init(RhinoCore c, INode n) {
core = c;
node = n;
}
/**
*
*
* @return ...
*/
public Object jsGet_cache() {
if (node == null) {
return null;
}
return node.getCacheNode();
}
/**
*
*
* @param skin ...
* @param param ...
*
* @return ...
*/
public boolean jsFunction_renderSkin(Object skin, Object param) {
// System.err.println ("RENDERSKIN CALLED WITH PARAM "+param);
Context cx = Context.getCurrentContext();
RequestEvaluator reval = (RequestEvaluator) cx.getThreadLocal("reval");
Skin s;
if (skin instanceof Skin) {
s = (Skin) skin;
} else {
s = core.app.getSkin(node, skin.toString(), null);
}
Map p = null;
if ((param != null) && (param != Undefined.instance)) {
p = new HashMap();
if (param instanceof Scriptable) {
Scriptable sp = (Scriptable) param;
Object[] ids = sp.getIds();
for (int i = 0; i < ids.length; i++) {
Object obj = sp.get(ids[i].toString(), sp);
if (obj instanceof NativeJavaObject) {
p.put(ids[i], ((NativeJavaObject) obj).unwrap());
} else {
p.put(ids[i], obj);
}
}
}
}
if (s != null) {
s.render(reval, node, p);
}
return true;
}
/**
*
*
* @param skin ...
* @param param ...
*
* @return ...
*/
public String jsFunction_renderSkinAsString(Object skin, Object param) {
// System.err.println ("RENDERSKIN CALLED WITH PARAM "+param);
Context cx = Context.getCurrentContext();
RequestEvaluator reval = (RequestEvaluator) cx.getThreadLocal("reval");
Skin s;
if (skin instanceof Skin) {
s = (Skin) skin;
} else {
s = core.app.getSkin(node, skin.toString(), null);
}
Map p = null;
if ((param != null) && (param != Undefined.instance)) {
p = new HashMap();
if (param instanceof Scriptable) {
Scriptable sp = (Scriptable) param;
Object[] ids = sp.getIds();
for (int i = 0; i < ids.length; i++) {
Object obj = sp.get(ids[i].toString(), sp);
if (obj instanceof NativeJavaObject) {
p.put(ids[i], ((NativeJavaObject) obj).unwrap());
} else {
p.put(ids[i], obj);
}
}
}
}
if (s != null) {
reval.res.pushStringBuffer();
s.render(reval, node, p);
return reval.res.popStringBuffer();
}
return "";
}
/**
*
*
* @param action ...
*
* @return ...
*/
public Object jsFunction_href(Object action) {
if (node == null) {
return null;
}
String act = null;
if (action != null) {
if (action instanceof NativeJavaObject) {
act = ((NativeJavaObject) action).unwrap().toString();
} else if (!(action instanceof Undefined)) {
act = action.toString();
}
}
return core.app.getNodeHref(node, act);
}
/**
*
*
* @param id ...
*
* @return ...
*/
public Object jsFunction_get(Object id) {
if ((node == null) || (id == null)) {
return null;
}
Context cx = Context.getCurrentContext();
Object n = null;
if (id instanceof Number) {
n = node.getSubnodeAt(((Number) id).intValue());
} else {
n = node.getChildElement(id.toString());
}
if (n == null) {
return null;
} else {
return cx.toObject(n, core.global);
}
}
/**
*
*
* @return ...
*/
public int jsFunction_count() {
if (node == null) {
return 0;
}
return node.numberOfNodes();
}
/**
*
*
* @return ...
*/
public int jsFunction_size() {
return jsFunction_count();
}
/**
* Prefetch child objects from (relational) database.
*/
public void jsFunction_prefetchChildren() {
jsFunction_prefetchChildren(0, 1000);
}
/**
* Prefetch child objects from (relational) database.
*/
public void jsFunction_prefetchChildren(int start, int length) {
if (!(node instanceof helma.objectmodel.db.Node)) {
return;
}
try {
((helma.objectmodel.db.Node) node).prefetchChildren(start, length);
} catch (Exception x) {
}
}
/**
*
*
* @return ...
*/
public Object[] jsFunction_list() {
int l = node.numberOfNodes();
Enumeration e = node.getSubnodes();
ArrayList a = new ArrayList();
while ((e != null) && e.hasMoreElements()) {
a.add(e.nextElement());
}
return a.toArray();
}
/**
*
*
* @param child ...
*
* @return ...
*/
public boolean jsFunction_add(Object child) {
if ((node == null) || (child == null)) {
return false;
}
if (child instanceof HopObject) {
INode added = node.addNode(((HopObject) child).node);
return true;
} else if (child instanceof INode) {
INode added = node.addNode((INode) child);
return true;
}
return false;
}
/**
*
*
* @param index ...
* @param child ...
*
* @return ...
*/
public boolean jsFunction_addAt(int index, Object child) {
if (child == null) {
return false;
}
if (child instanceof HopObject) {
INode added = node.addNode(((HopObject) child).node, index);
return true;
} else if (child instanceof INode) {
INode added = node.addNode((INode) child, index);
return true;
}
return false;
}
/**
* Remove node itself or one or more subnodes.
*/
public boolean jsFunction_remove(Object child) {
// semantics: if called without arguments, remove self.
// otherwise, remove given subnodes.
if (child == null) {
return node.remove();
} else if (node != null) {
try {
if (child instanceof HopObject) {
HopObject hobj = (HopObject) child;
if (hobj.node != null) {
node.removeNode(hobj.node);
return true;
}
}
} catch (Exception x) {
System.err.println("XXX: " + x);
x.printStackTrace();
}
}
return false;
}
/**
* Invalidate the node itself or a subnode
*/
public boolean jsFunction_invalidate(String childId) {
if (node instanceof helma.objectmodel.db.Node) {
if (childId == null) {
((helma.objectmodel.db.Node) node).invalidate();
} else {
((helma.objectmodel.db.Node) node).invalidateNode(childId);
}
}
return true;
}
/**
* Check if node is contained in subnodes
*/
public int jsFunction_contains(Object obj) {
if ((node != null) && (obj != null) && obj instanceof HopObject) {
return node.contains(((HopObject) obj).node);
}
return -1;
}
/**
*
*
* @param name ...
* @param start ...
* @param value ...
*/
public void put(String name, Scriptable start, Object value) {
if (node == null) {
super.put(name, start, value);
} else {
if (value instanceof NativeJavaObject) {
value = ((NativeJavaObject) value).unwrap();
}
if ((value == null) || (value == Undefined.instance)) {
node.unset(name);
} else if (value instanceof Scriptable) {
Scriptable s = (Scriptable) value;
if ("Date".equals(s.getClassName())) {
node.setDate(name, new Date((long) ScriptRuntime.toNumber(s)));
} else {
node.setString(name, s.toString());
}
} else if (value instanceof String) {
node.setString(name, value.toString());
} else if (value instanceof Boolean) {
node.setBoolean(name, ((Boolean) value).booleanValue());
} else if (value instanceof Number) {
node.setFloat(name, ((Number) value).doubleValue());
} else if (value instanceof Date) {
node.setDate(name, (Date) value);
} else if (value instanceof INode) {
node.setNode(name, (INode) value);
} else if (value instanceof HopObject) {
node.setNode(name, ((HopObject) value).node);
} else {
node.setJavaObject(name, value);
}
}
}
/**
*
*
* @param name ...
* @param start ...
*
* @return ...
*/
public boolean has(String name, Scriptable start) {
if (super.has(name, start)) {
return true;
}
if ((prototype != null) && prototype.has(name, start)) {
return true;
}
if ((node != null) && (node.get(name) != null)) {
return true;
}
return false;
}
/**
*
*
* @param name ...
*/
public void delete(String name) {
if ((node != null)) {
node.unset(name);
}
}
/**
*
*
* @param name ...
* @param start ...
*
* @return ...
*/
public Object get(String name, Scriptable start) {
// System.err.println ("GET from "+node+": "+name);
Object retval = super.get(name, start);
if (retval != ScriptableObject.NOT_FOUND) {
return retval;
}
if (prototype != null) {
retval = prototype.get(name, start);
}
if (retval != ScriptableObject.NOT_FOUND) {
return retval;
}
if (node != null) {
// Everything starting with an underscore is interpreted as internal property
if (name.startsWith("_")) {
return getInternalProperty(name);
}
IProperty p = node.get(name);
if (p != null) {
if (p.getType() == IProperty.STRING) {
return p.getStringValue();
}
if (p.getType() == IProperty.BOOLEAN) {
return p.getBooleanValue() ? Boolean.TRUE : Boolean.FALSE;
}
if (p.getType() == IProperty.INTEGER) {
return new Long(p.getIntegerValue());
}
if (p.getType() == IProperty.FLOAT) {
return new Double(p.getFloatValue());
}
Context cx = Context.getCurrentContext();
if (p.getType() == IProperty.DATE) {
Date d = p.getDateValue();
if (d == null) {
return NOT_FOUND;
} else {
Object[] args = { new Long(d.getTime()) };
try {
return cx.newObject(core.global, "Date", args);
} catch (PropertyException px) {
return NOT_FOUND;
} catch (NotAFunctionException nafx) {
return NOT_FOUND;
} catch (JavaScriptException nafx) {
return NOT_FOUND;
}
}
}
if (p.getType() == IProperty.NODE) {
INode n = p.getNodeValue();
if (n == null) {
return NOT_FOUND;
} else {
return cx.toObject(n, core.global);
}
}
if (p.getType() == IProperty.JAVAOBJECT) {
Object obj = p.getJavaObjectValue();
if (obj == null) {
return NOT_FOUND;
} else {
return cx.toObject(obj, core.global);
}
}
}
// as last resort, try to get property as anonymous subnode
Object anon = node.getChildElement(name);
if (anon != null) {
return anon;
}
}
return NOT_FOUND;
}
private Object getInternalProperty(String name) {
if ("__id__".equals(name) || "_id".equals(name)) {
return node.getID();
}
if ("__prototype__".equals(name) || "_prototype".equals(name)) {
return node.getPrototype();
}
if ("__parent__".equals(name) || "_parent".equals(name)) {
return core.getNodeWrapper(node.getParent());
}
// some more internal properties
if ("__name__".equals(name)) {
return node.getName();
}
if ("__fullname__".equals(name)) {
return node.getFullName();
}
if ("__hash__".equals(name)) {
return Integer.toString(node.hashCode());
}
if ("__node__".equals(name)) {
return node;
}
if ("__created__".equalsIgnoreCase(name)) {
return new Date(node.created());
}
if ("__lastmodified__".equalsIgnoreCase(name)) {
return new Date(node.lastModified());
}
return NOT_FOUND;
}
/**
*
*
* @return ...
*/
public Object[] getIds() {
if (node == null) {
return new Object[0];
}
Enumeration enum = node.properties();
ArrayList list = new ArrayList();
while (enum.hasMoreElements())
list.add(enum.nextElement());
return list.toArray();
}
/**
*
*
* @param name ...
* @param start ...
*
* @return ...
*/
public boolean has(int idx, Scriptable start) {
if (node != null) {
return (0 <= idx && idx < node.numberOfNodes());
}
return false;
}
/**
*
*
* @param name ...
* @param start ...
*
* @return ...
*/
public Object get(int idx, Scriptable start) {
if (node != null) {
INode n = node.getSubnodeAt(idx);
if (n == null) {
return NOT_FOUND;
} else {
Context cx = Context.getCurrentContext();
return cx.toObject(n, core.global);
}
}
return NOT_FOUND;
}
/**
*
*
* @param hint ...
*
* @return ...
*/
public Object getDefaultValue(Class hint) {
return (className != null) ? ("[HopObject " + className + "]") : "[HopObject]";
}
/**
*
*
* @return ...
*/
public String toString() {
return (className != null) ? ("[HopObject " + className + "]") : "[HopObject]";
}
}

View file

@ -0,0 +1,176 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.framework.*;
import helma.framework.core.*;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import org.mozilla.javascript.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class JavaObject extends NativeJavaObject {
RhinoCore core;
Scriptable prototype;
/**
* Creates a new JavaObject wrapper.
*/
public JavaObject(Scriptable scope, Object obj, Scriptable prototype) {
this.parent = scope;
this.javaObject = obj;
this.prototype = prototype;
staticType = obj.getClass();
initMembers();
}
/**
*
*
* @param skin ...
* @param param ...
*
* @return ...
*/
public boolean jsFunction_renderSkin(Object skin, Object param) {
// System.err.println ("RENDERSKIN CALLED WITH PARAM "+param);
Context cx = Context.getCurrentContext();
RequestEvaluator reval = (RequestEvaluator) cx.getThreadLocal("reval");
Skin s;
if (skin instanceof Skin) {
s = (Skin) skin;
} else {
s = core.app.getSkin(javaObject, skin.toString(), null);
}
Map p = null;
if ((param != null) && (param != Undefined.instance)) {
p = new HashMap();
if (param instanceof Scriptable) {
Scriptable sp = (Scriptable) param;
Object[] ids = sp.getIds();
for (int i = 0; i < ids.length; i++)
p.put(ids[i], sp.get(ids[i].toString(), sp));
}
}
if (s != null) {
s.render(reval, javaObject, p);
}
return true;
}
/**
*
*
* @param skin ...
* @param param ...
*
* @return ...
*/
public String jsFunction_renderSkinAsString(Object skin, Object param) {
// System.err.println ("RENDERSKIN CALLED WITH PARAM "+param);
Context cx = Context.getCurrentContext();
RequestEvaluator reval = (RequestEvaluator) cx.getThreadLocal("reval");
Skin s;
if (skin instanceof Skin) {
s = (Skin) skin;
} else {
s = core.app.getSkin(javaObject, skin.toString(), null);
}
Map p = null;
if ((param != null) && (param != Undefined.instance)) {
p = new HashMap();
if (param instanceof Scriptable) {
Scriptable sp = (Scriptable) param;
Object[] ids = sp.getIds();
for (int i = 0; i < ids.length; i++)
p.put(ids[i], sp.get(ids[i].toString(), sp));
}
}
if (s != null) {
reval.res.pushStringBuffer();
s.render(reval, javaObject, p);
return reval.res.popStringBuffer();
}
return "";
}
/**
*
*
* @param action ...
*
* @return ...
*/
public Object jsFunction_href(Object action) {
if (javaObject == null) {
return null;
}
String act = null;
if (action != null) {
if (action instanceof NativeJavaObject) {
act = ((NativeJavaObject) action).unwrap().toString();
} else if (!(action instanceof Undefined)) {
act = action.toString();
}
}
return core.app.getNodeHref(javaObject, act);
}
public boolean has(String name, Scriptable start) {
System.err.println ("HAS: "+name);
if (prototype.has(name, start))
return true;
return super.has(name, start);
}
public Object get(String name, Scriptable start) {
System.err.println ("GET: "+name);
Object obj = prototype.get(name, start);
if (obj != null && obj != Undefined.instance)
return obj;
return super.get(name, start);
}
}

View file

@ -0,0 +1,139 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.NativeJavaObject;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class MapWrapper extends ScriptableObject {
Map map;
RhinoCore core;
/**
* Creates a new MapWrapper object.
*/
public MapWrapper() {
map = null;
}
/**
* Creates a new MapWrapper object.
*
* @param map ...
* @param core ...
*/
public MapWrapper(Map map, RhinoCore core) {
this.map = map;
this.core = core;
}
/**
*
*
* @param name ...
* @param start ...
* @param value ...
*/
public void put(String name, Scriptable start, Object value) {
if (map == null) {
map = new HashMap();
}
if (value instanceof NativeJavaObject) {
map.put(name, ((NativeJavaObject) value).unwrap());
} else {
map.put(name, value);
}
}
/**
*
*
* @param name ...
* @param start ...
*
* @return ...
*/
public Object get(String name, Scriptable start) {
if (map == null) {
return null;
}
Object obj = map.get(name);
if (obj != null) {
Context cx = Context.getCurrentContext();
return cx.toObject(obj, core.global);
}
return null;
}
/**
*
*
* @param name ...
* @param start ...
*
* @return ...
*/
public boolean has(String name, Scriptable start) {
return (map != null) && map.containsKey(name);
}
/**
*
*
* @param name ...
*/
public void delete(String name) {
if (map != null) {
map.remove(name);
}
}
/**
*
*
* @return ...
*/
public Object[] getIds() {
if (map == null) {
return new Object[0];
}
return map.keySet().toArray();
}
/**
*
*
* @return ...
*/
public String getClassName() {
return "[MapWrapper]";
}
}

View file

@ -0,0 +1,84 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.scripting.*;
// import java.util.Vector;
// import java.util.Iterator;
import java.io.*;
// import helma.framework.*;
// import helma.framework.core.*;
// import helma.util.Updatable;
/**
* An class that updates fesi interpreters with actionfiles and templates.
*/
public class RhinoActionAdapter {
String sourceName;
String function;
String functionAsString;
/**
* Creates a new RhinoActionAdapter object.
*
* @param action ...
*/
public RhinoActionAdapter(ActionFile action) {
String content = action.getContent();
String functionName = action.getFunctionName();
sourceName = action.toString();
function = composeFunction(functionName,
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
content);
// check if this is a template and we need to generate an "_as_string" variant
if (action instanceof Template) {
functionAsString = composeFunction(functionName + "_as_string",
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
"res.pushStringBuffer(); " + content +
"\r\nreturn res.popStringBuffer();\r\n");
} else {
functionAsString = null;
}
}
protected String composeFunction(String funcname, String params, String body) {
if ((body == null) || "".equals(body.trim())) {
body = ";\r\n";
} else {
body = body + "\r\n";
}
if (params == null) {
params = "";
}
StringBuffer f = new StringBuffer("function ");
f.append(funcname);
f.append(" (");
f.append(params);
f.append(") {\n");
f.append(body);
f.append("\n}");
return f.toString();
}
}

View file

@ -0,0 +1,686 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.framework.*;
import helma.framework.core.*;
import helma.main.Server;
import helma.objectmodel.*;
import helma.objectmodel.db.DbMapping;
import helma.objectmodel.db.Relation;
import helma.scripting.*;
import helma.util.CacheMap;
import helma.util.Updatable;
import org.mozilla.javascript.*;
import java.io.*;
import java.util.*;
/**
* This is the implementation of ScriptingEnvironment for the Mozilla Rhino EcmaScript interpreter.
*/
public final class RhinoCore implements WrapHandler {
// the application we're running in
public final Application app;
// the global object
Scriptable global;
// caching table for JavaScript object wrappers
CacheMap wrappercache;
// table containing JavaScript prototypes
Hashtable prototypes;
long lastUpdate = 0;
/**
* Create a Rhino evaluator for the given application and request evaluator.
*/
public RhinoCore(Application app) {
this.app = app;
wrappercache = new CacheMap(500, .75f);
prototypes = new Hashtable();
Context context = Context.enter();
context.setCompileFunctionsWithDynamicScope(true);
context.setWrapHandler(this);
int optLevel = 0;
try {
optLevel = Integer.parseInt(app.getProperty("rhino.optlevel"));
} catch (Exception ignore) {
}
// System.err.println("Setting Rhino optlevel to " + optLevel);
context.setOptimizationLevel(optLevel);
try {
GlobalObject g = new GlobalObject(this, app);
global = context.initStandardObjects(g);
ScriptableObject.defineClass(global, HopObject.class);
putPrototype("hopobject",
ScriptableObject.getClassPrototype(global, "HopObject"));
putPrototype("global", global);
initialize();
} catch (Exception e) {
System.err.println("Cannot initialize interpreter");
System.err.println("Error: " + e);
e.printStackTrace();
throw new RuntimeException(e.getMessage());
} finally {
context.exit();
}
}
/**
* Initialize the evaluator, making sure the minimum type information
* necessary to bootstrap the rest is parsed.
*/
private synchronized void initialize() {
Collection protos = app.getPrototypes();
for (Iterator i = protos.iterator(); i.hasNext();) {
Prototype proto = (Prototype) i.next();
initPrototype(proto);
}
// always fully initialize global prototype, because
// we always need it and there's no chance to trigger
// creation on demand.
getPrototype("global");
}
/**
* Initialize a prototype without fully parsing its script files.
*/
synchronized void initPrototype(Prototype prototype) {
// System.err.println ("FESI INIT PROTO "+prototype);
Scriptable op = null;
String name = prototype.getName();
// get the prototype's prototype if possible and necessary
Scriptable opp = null;
Prototype parent = prototype.getParentPrototype();
if (parent != null) {
// see if parent prototype is already registered. if not, register it
opp = getRawPrototype(parent.getName());
if (opp == null) {
initPrototype(parent);
opp = getRawPrototype(parent.getName());
}
}
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
(opp == null)) {
if (app.isJavaPrototype(name)) {
opp = getRawPrototype("__javaobject__");
} else {
opp = getRawPrototype("hopobject");
}
}
// if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it.
op = getRawPrototype(name);
if (op == null) {
try {
Context context = Context.getCurrentContext();
op = new HopObject(name); // context.newObject (global /*, "HopObject" */);
op.setPrototype(opp);
op.setParentScope(global);
op.put("prototypename", op, name);
} catch (Exception ignore) {
System.err.println("Error creating prototype: " + ignore);
ignore.printStackTrace();
}
putPrototype(name, op);
} else {
// set parent prototype just in case it has been changed
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);
fp.addAsConstructor(global, op);
} catch (Exception ignore) {
System.err.println("Error adding ctor for " + name + ": " + ignore);
ignore.printStackTrace();
}
}
}
/**
* Set up a prototype, parsing and compiling all its script files.
*/
synchronized void evaluatePrototype(Prototype prototype) {
// System.err.println ("FESI EVALUATE PROTO "+prototype+" FOR "+this);
Scriptable op = null;
// get the prototype's prototype if possible and necessary
Scriptable opp = null;
Prototype parent = prototype.getParentPrototype();
if (parent != null) {
// see if parent prototype is already registered. if not, register it
opp = getPrototype(parent.getName());
if (opp == null) {
evaluatePrototype(parent);
opp = getPrototype(parent.getName());
}
}
String name = prototype.getName();
if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) &&
(opp == null)) {
if (app.isJavaPrototype(name)) {
opp = getPrototype("__javaobject__");
} else {
opp = getPrototype("hopobject");
}
}
// if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it.
op = getPrototype(name);
if (op == null) {
try {
Context context = Context.getCurrentContext();
op = new HopObject(name); // context.newObject (global /*, "HopObject" */);
op.setPrototype(opp);
op.setParentScope(global);
op.put("prototypename", op, name);
} catch (Exception ignore) {
System.err.println("Error creating prototype: " + ignore);
ignore.printStackTrace();
}
putPrototype(name, op);
} else {
// reset prototype to original state
resetPrototype(op);
// set parent prototype just in case it has been changed
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);
fp.addAsConstructor(global, 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();
evaluate(prototype, code);
}
for (Iterator it = prototype.getCode().values().iterator(); it.hasNext();) {
Object code = it.next();
evaluate(prototype, code);
}
}
/**
* Return an object prototype to its initial state, removing all application specific
* functions.
*/
synchronized void resetPrototype(Scriptable op) {
Object[] ids = op.getIds();
for (int i = 0; i < ids.length; i++) {
/* String prop = en.nextElement ().toString ();
try {
ESValue esv = op.getProperty (prop, prop.hashCode ());
if (esv instanceof ConstructedFunctionObject || esv instanceof FesiActionAdapter.ThrowException)
op.deleteProperty (prop, prop.hashCode());
} catch (Exception x) {} */
}
}
/**
* This method is called before an execution context is entered to let the
* engine know it should update its prototype information.
*/
public synchronized void updatePrototypes() {
if ((System.currentTimeMillis() - lastUpdate) < 1000L) {
return;
}
Collection protos = app.getPrototypes();
for (Iterator i = protos.iterator(); i.hasNext();) {
Prototype proto = (Prototype) i.next();
TypeInfo info = (TypeInfo) prototypes.get(proto.getName());
if (info == null) {
// a prototype we don't know anything about yet. Init local update info.
initPrototype(proto);
info = (TypeInfo) prototypes.get(proto.getName());
}
// only update prototype if it has already been initialized.
// otherwise, this will be done on demand
// System.err.println ("CHECKING PROTO "+proto+": "+info);
if (info.lastUpdate > 0) {
Prototype p = app.typemgr.getPrototype(info.protoName);
if (p != null) {
// System.err.println ("UPDATING PROTO: "+p);
app.typemgr.updatePrototype(p);
if (p.getLastUpdate() > info.lastUpdate) {
evaluatePrototype(p);
info.lastUpdate = p.getLastUpdate();
}
}
}
}
lastUpdate = System.currentTimeMillis();
}
/**
* Check if an object has a function property (public method if it
* is a java object) with that name.
*/
public boolean hasFunction(String protoname, String fname) {
// System.err.println ("HAS_FUNC: "+fname);
try {
Scriptable op = getPrototype(protoname);
// if this is an untyped object return false
if (op == null) {
return false;
}
Object func = ScriptableObject.getProperty(op, fname);
if ((func != null) && func instanceof Function) {
return true;
}
} catch (Exception esx) {
// System.err.println ("Error in hasFunction: "+esx);
return false;
}
return false;
}
/**
* Convert an input argument from Java to the scripting runtime
* representation.
*/
/* public static ESValue processXmlRpcArgument (Object what, Evaluator evaluator) throws Exception {
if (what == null)
return ESNull.theNull;
if (what instanceof Vector) {
Vector v = (Vector) what;
ArrayPrototype retval = new ArrayPrototype (evaluator.getArrayPrototype (), evaluator);
int l = v.size ();
for (int i=0; i<l; i++)
retval.putProperty (i, processXmlRpcArgument (v.elementAt (i), evaluator));
return retval;
}
if (what instanceof Hashtable) {
Hashtable t = (Hashtable) what;
ESObject retval = new ObjectPrototype (evaluator.getObjectPrototype (), evaluator);
for (Enumeration e=t.keys(); e.hasMoreElements(); ) {
String next = (String) e.nextElement ();
retval.putProperty (next, processXmlRpcArgument (t.get (next), evaluator), next.hashCode ());
}
return retval;
}
if (what instanceof String)
return new ESString (what.toString ());
if (what instanceof Number)
return new ESNumber (new Double (what.toString ()).doubleValue ());
if (what instanceof Boolean)
return ESBoolean.makeBoolean (((Boolean) what).booleanValue ());
if (what instanceof Date)
return new DatePrototype (evaluator, (Date) what);
return ESLoader.normalizeValue (what, evaluator);
} */
/**
* convert a JavaScript Object object to a generic Java object stucture.
*/
/* public static Object processXmlRpcResponse (ESValue what) throws EcmaScriptException {
if (what == null || what instanceof ESNull)
return null;
if (what instanceof ArrayPrototype) {
ArrayPrototype a = (ArrayPrototype) what;
int l = a.size ();
Vector v = new Vector ();
for (int i=0; i<l; i++) {
Object nj = processXmlRpcResponse (a.getProperty (i));
v.addElement (nj);
}
return v;
}
if (what instanceof ObjectPrototype) {
ObjectPrototype o = (ObjectPrototype) what;
Hashtable t = new Hashtable ();
for (Enumeration e=o.getProperties (); e.hasMoreElements (); ) {
String next = (String) e.nextElement ();
// We don't do deep serialization of HopObjects to avoid
// that the whole web site structure is sucked out with one
// object. Instead we return some kind of "proxy" objects
// that only contain the prototype and id of the HopObject property.
Object nj = null;
ESValue esv = o.getProperty (next, next.hashCode ());
if (esv instanceof ESNode) {
INode node = ((ESNode) esv).getNode ();
if (node != null) {
Hashtable nt = new Hashtable ();
nt.put ("id", node.getID());
if (node.getPrototype() != null)
nt.put ("prototype", node.getPrototype ());
nj = nt;
}
} else
nj = processXmlRpcResponse (esv);
if (nj != null) // can't put null as value in hashtable
t.put (next, nj);
}
return t;
}
if (what instanceof ESUndefined || what instanceof ESNull)
return null;
Object jval = what.toJavaObject ();
if (jval instanceof Byte || jval instanceof Short)
jval = new Integer (jval.toString ());
return jval;
} */
/**
* Return the application we're running in
*/
public Application getApplication() {
return app;
}
/**
* Get a raw prototype, i.e. in potentially unfinished state
* without checking if it needs to be updated.
*/
private Scriptable getRawPrototype(String protoName) {
if (protoName == null) {
return null;
}
TypeInfo info = (TypeInfo) prototypes.get(protoName);
return (info == null) ? null : info.objectPrototype;
}
/**
* Get the object prototype for a prototype name and initialize/update it
* if necessary.
*/
public Scriptable getPrototype(String protoName) {
if (protoName == null) {
return null;
}
TypeInfo info = (TypeInfo) prototypes.get(protoName);
if ((info != null) && (info.lastUpdate == 0)) {
Prototype p = app.typemgr.getPrototype(protoName);
if (p != null) {
app.typemgr.updatePrototype(p);
if (p.getLastUpdate() > info.lastUpdate) {
info.lastUpdate = p.getLastUpdate();
evaluatePrototype(p);
}
// set info.lastUpdate to 1 if it is 0 so we know we
// have initialized this prototype already, even if
// it is empty (i.e. doesn't contain any scripts/skins/actoins
if (info.lastUpdate == 0) {
info.lastUpdate = 1;
}
}
}
return (info == null) ? null : info.objectPrototype;
}
/**
* Register an object prototype for a certain prototype name.
*/
public void putPrototype(String protoName, Scriptable op) {
if ((protoName != null) && (op != null)) {
prototypes.put(protoName, new TypeInfo(op, protoName));
}
}
/**
*
*
* @param scope ...
* @param obj ...
* @param staticType ...
*
* @return ...
*/
public Object wrap(Scriptable scope, Object obj, Class staticType) {
if (obj instanceof INode) {
return getNodeWrapper((INode) obj);
}
if (obj instanceof IPathElement) {
return getElementWrapper(obj);
}
if (obj instanceof Map) {
return new MapWrapper((Map) obj, this);
}
return null;
}
/**
* 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 Scriptable getObjectWrapper(Object e) {
if (app.getPrototypeName(e) != null) {
return getElementWrapper(e);
}
/ else if (e instanceof INode)
return new ESNode ((INode) e, this); /
else {
return Context.getCurrentContext().toObject(e, global);
}
} */
/**
* 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 Scriptable getElementWrapper(Object e) {
// Gotta find out the prototype name to use for this object...
String prototypeName = app.getPrototypeName(e);
Scriptable op = getPrototype(prototypeName);
if (op == null) {
op = getPrototype("hopobject");
}
return new JavaObject(global, e, op);
}
/**
* Get a script wrapper for an instance of helma.objectmodel.INode
*/
public Scriptable getNodeWrapper(INode n) {
// FIXME: should this return ESNull.theNull?
if (n == null) {
return null;
}
HopObject esn = (HopObject) wrappercache.get(n);
if (esn == null) {
try {
String protoname = n.getPrototype();
Scriptable op = null;
// set the DbMapping of the node according to its prototype.
// this *should* be done on the objectmodel level, but isn't currently
// for embedded nodes since there's not enough type info at the objectmodel level
// for those nodes.
if ((protoname != null) && (protoname.length() > 0) &&
(n.getDbMapping() == null)) {
n.setDbMapping(app.getDbMapping(protoname));
}
op = getPrototype(protoname);
// no prototype found for this node?
if (op == null) {
op = getPrototype("hopobject");
}
esn = new HopObject();
esn.init(this, n);
esn.setPrototype(op);
wrappercache.put(n, esn);
// app.logEvent ("Wrapper for "+n+" created");
} catch (Exception x) {
System.err.println("Error creating node wrapper: " + x);
throw new RuntimeException(x.toString());
}
}
return esn;
}
/**
* Register a new Node wrapper with the wrapper cache. This is used by the
* Node constructor.
*/
public void putNodeWrapper(INode n, Scriptable esn) {
wrappercache.put(n, esn);
}
private synchronized void evaluate(Prototype prototype, Object code) {
if (code instanceof FunctionFile) {
FunctionFile funcfile = (FunctionFile) code;
File file = funcfile.getFile();
if (file != null) {
try {
FileReader fr = new FileReader(file);
updateEvaluator(prototype, fr, funcfile.getSourceName());
} catch (IOException iox) {
app.logEvent("Error updating function file: " + iox);
}
} else {
StringReader reader = new StringReader(funcfile.getContent());
updateEvaluator(prototype, reader, funcfile.getSourceName());
}
} else if (code instanceof ActionFile) {
ActionFile action = (ActionFile) code;
RhinoActionAdapter fa = new RhinoActionAdapter(action);
try {
updateEvaluator(prototype, new StringReader(fa.function),
action.getSourceName());
} catch (Exception esx) {
app.logEvent("Error parsing " + action + ": " + esx);
}
}
}
private synchronized void updateEvaluator(Prototype prototype, Reader reader,
String sourceName) {
// context = Context.enter(context);
try {
Scriptable op = getPrototype(prototype.getName());
// get the current context
Context cx = Context.getCurrentContext();
// do the update, evaluating the file
cx.evaluateReader(op, reader, sourceName, 1, null);
} catch (Throwable e) {
app.logEvent("Error parsing function file " + sourceName + ": " + e);
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ignore) {
}
}
}
}
class TypeInfo {
Scriptable objectPrototype;
long lastUpdate = 0;
String protoName;
public TypeInfo(Scriptable op, String name) {
objectPrototype = op;
protoName = name;
}
public String toString() {
return ("TypeInfo[" + protoName + "," + new Date(lastUpdate) + "]");
}
}
}

View file

@ -0,0 +1,442 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.extensions.ConfigurationException;
import helma.extensions.HelmaExtension;
import helma.framework.*;
import helma.framework.core.*;
import helma.main.Server;
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.*;
import java.io.*;
import java.util.*;
/**
* This is the implementation of ScriptingEnvironment for the Mozilla Rhino EcmaScript interpreter.
*/
public final class RhinoEngine implements ScriptingEngine {
static Map coreMap;
// the application we're running in
public Application app;
// The Rhino context
Context context;
// the global object
Scriptable global;
// the request evaluator instance owning this fesi evaluator
RequestEvaluator reval;
RhinoCore core;
// remember global variables from last invokation to be able to
// do lazy cleanup
Map lastGlobals = null;
// the global vars set by extensions
HashMap extensionGlobals;
/**
* Zero argument constructor.
*/
public RhinoEngine() {
}
/**
* Init the scripting engine with an application and a request evaluator
*/
public void init(Application app, RequestEvaluator reval) {
this.app = app;
this.reval = reval;
core = getRhinoCore(app);
context = Context.enter();
context.setCompileFunctionsWithDynamicScope(true);
try {
global = context.newObject(core.global);
global.setPrototype(core.global);
global.setParentScope(null);
// context.putThreadLocal ("reval", reval);
// context.putThreadLocal ("engine", this);
extensionGlobals = new HashMap();
Vector extVec = Server.getServer().getExtensions();
for (int i = 0; i < extVec.size(); i++) {
HelmaExtension ext = (HelmaExtension) extVec.get(i);
try {
HashMap tmpGlobals = ext.initScripting(app, this);
if (tmpGlobals != null) {
extensionGlobals.putAll(tmpGlobals);
}
} catch (ConfigurationException e) {
app.logEvent("Couldn't initialize extension " + ext.getName() + ": " +
e.getMessage());
}
}
// context.removeThreadLocal ("reval");
// context.removeThreadLocal ("engine");
} catch (Exception e) {
System.err.println("Cannot initialize interpreter");
System.err.println("Error: " + e);
e.printStackTrace();
throw new RuntimeException(e.getMessage());
} finally {
// Context.exit ();
}
}
static synchronized RhinoCore getRhinoCore(Application app) {
RhinoCore core = null;
if (coreMap == null) {
coreMap = new HashMap();
} else {
core = (RhinoCore) coreMap.get(app);
}
if (core == null) {
core = new RhinoCore(app);
coreMap.put(app, core);
}
return core;
}
/**
* This method is called before an execution context is entered to let the
* engine know it should update its prototype information.
*/
public void updatePrototypes() {
context = Context.enter(context);
context.setCompileFunctionsWithDynamicScope(true);
context.setWrapHandler(core);
int optLevel = 0;
try {
optLevel = Integer.parseInt(app.getProperty("rhino.optlevel"));
} catch (Exception ignore) {
}
context.setOptimizationLevel(optLevel);
core.updatePrototypes();
context.putThreadLocal("reval", reval);
context.putThreadLocal("engine", this);
}
/**
* This method is called when an execution context for a request
* evaluation is entered. The globals parameter contains the global values
* to be applied during this execution context.
*/
public void enterContext(HashMap globals) throws ScriptingException {
// set the thread filed in the FESI evaluator
// evaluator.thread = Thread.currentThread ();
// set globals on the global object
// context = Context.enter (context);
globals.putAll(extensionGlobals);
if ((globals != null) && (globals != lastGlobals)) {
// loop through global vars and set them
for (Iterator i = globals.keySet().iterator(); i.hasNext();) {
String k = (String) i.next();
Object v = globals.get(k);
Scriptable scriptable = null;
try {
// we do a lot of extra work to make access to global variables
// comfortable to EcmaScript coders, i.e. we use a lot of custom wrappers
// that expose properties and functions in a special way instead of just going
// with the standard java object wrappers.
if ("path".equals(k)) {
Scriptable arr = context.newObject(global, "Array");
List path = (List) v;
// register path elements with their prototype
for (int j = 0; j < path.size(); j++) {
Object pathElem = path.get(j);
Scriptable wrappedElement = context.toObject(pathElem, global);
arr.put(j, arr, wrappedElement);
String protoname = app.getPrototypeName(pathElem);
if (protoname != null) {
arr.put(protoname, arr, wrappedElement);
}
}
v = arr;
}
/* if (v instanceof Map) {
sv = new ESMapWrapper (this, (Map) v);
} else if ("path".equals (k)) {
ArrayPrototype parr = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator);
List path = (List) v;
// register path elements with their prototype
for (int j=0; j<path.size(); j++) {
Object pathElem = path.get (j);
ESValue wrappedElement = getElementWrapper (pathElem);
parr.putProperty (j, wrappedElement);
String protoname = app.getPrototypeName (pathElem);
if (protoname != null)
parr.putHiddenProperty (protoname, wrappedElement);
}
sv = parr;
} else if ("req".equals (k)) {
sv = new ESBeanWrapper (new RequestBean ((RequestTrans) v), this);
} else if ("res".equals (k)) {
sv = new ESBeanWrapper (new ResponseBean ((ResponseTrans) v), this);
} else if ("session".equals (k)) {
sv = new ESBeanWrapper (new SessionBean ((Session)v), this);
} else if ("app".equals (k)) {
sv = new ESBeanWrapper (new ApplicationBean ((Application)v), this);
} else if (v instanceof ESValue) {
sv = (ESValue)v;
} else {
sv = ESLoader.normalizeValue (v, evaluator);
} */
scriptable = context.toObject(v, global);
global.put(k, global, scriptable);
} catch (Exception x) {
app.logEvent("Error setting global variable " + k + ": " + x);
}
}
}
// remember the globals set on this evaluator
lastGlobals = globals;
}
/**
* This method is called to let the scripting engine know that the current
* execution context has terminated.
*/
public void exitContext() {
context.exit();
context.removeThreadLocal("reval");
context.removeThreadLocal("engine");
// unset the thread filed in the FESI evaluator
// evaluator.thread = null;
// loop through previous globals and unset them, if necessary.
/* if (lastGlobals != null) {
for (Iterator i=lastGlobals.keySet().iterator(); i.hasNext(); ) {
String g = (String) i.next ();
try {
global.deleteProperty (g, g.hashCode());
} catch (Exception x) {
System.err.println ("Error resetting global property: "+g);
}
}
lastGlobals = null;
} */
}
/**
* Invoke a function on some object, using the given arguments and global vars.
*/
public Object invoke(Object thisObject, String functionName, Object[] args,
boolean xmlrpc) throws ScriptingException {
Scriptable eso = null;
if (thisObject == null) {
eso = global;
} else {
eso = context.toObject(thisObject, global);
}
try {
for (int i = 0; i < args.length; i++) {
// XML-RPC requires special argument conversion
// if (xmlrpc)
// esv[i] = processXmlRpcArgument (args[i], evaluator);
// for java.util.Map objects, we use the special "tight" wrapper
// that makes the Map look like a native object
/* else if (args[i] instanceof Map)
esv[i] = new ESMapWrapper (this, (Map) args[i]);
else
esv[i] = ESLoader.normalizeValue (args[i], evaluator); */
args[i] = context.toObject(args[i], global);
}
Object f = ScriptableObject.getProperty(eso, functionName);
if ((f == ScriptableObject.NOT_FOUND) || !(f instanceof Function)) {
return null;
}
Object retval = ((Function) f).call(context, global, eso, args);
// if (xmlrpc)
// return processXmlRpcResponse (retval);
if ((retval == null) || (retval == Undefined.instance)) {
return null;
} else if (retval instanceof NativeJavaObject) {
return ((NativeJavaObject) retval).unwrap();
} else {
return retval;
}
} catch (RedirectException redirect) {
throw redirect;
} catch (TimeoutException timeout) {
throw timeout;
} catch (ConcurrencyException concur) {
throw concur;
} catch (Exception x) {
// check if this is a redirect exception, which has been converted by fesi
// into an EcmaScript exception, which is why we can't explicitly catch it
if (reval.res.getRedirect() != null) {
throw new RedirectException(reval.res.getRedirect());
}
// do the same for not-modified responses
if (reval.res.getNotModified()) {
throw new RedirectException(null);
}
// has the request timed out? If so, throw TimeoutException
// if (evaluator.thread != Thread.currentThread())
// throw new TimeoutException ();
// create and throw a ScriptingException with the right message
String msg = x.toString();
if (app.debug()) {
System.err.println("Error in Script: " + msg);
x.printStackTrace();
}
throw new ScriptingException(msg);
}
}
/**
* Let the evaluator know that the current evaluation has been
* aborted. This is done by setting the thread ref in the evaluator
* object to null.
*/
public void abort() {
// unset the thread filed in the FESI evaluator
// evaluator.thread = null;
}
/**
* Check if an object has a function property (public method if it
* is a java object) with that name.
*/
public boolean hasFunction(Object obj, String fname) {
// System.err.println ("HAS_FUNC: "+fname);
return core.hasFunction(app.getPrototypeName(obj), fname);
}
/**
* Check if an object has a defined property (public field if it
* is a java object) with that name.
*/
public Object get(Object obj, String propname) {
if ((obj == null) || (propname == null)) {
return null;
}
String prototypeName = app.getPrototypeName(obj);
if ("user".equalsIgnoreCase(prototypeName) &&
"password".equalsIgnoreCase(propname)) {
return "[macro access to password property not allowed]";
}
// if this is a HopObject, check if the property is defined
// in the type.properties db-mapping.
if (obj instanceof INode) {
DbMapping dbm = app.getDbMapping(prototypeName);
if (dbm != null) {
Relation rel = dbm.propertyToRelation(propname);
if ((rel == null) || !rel.isPrimitive()) {
return "[property \"" + propname + "\" is not defined for " +
prototypeName + "]";
}
}
}
Scriptable so = context.toObject(obj, global);
try {
Object prop = so.get(propname, so);
if (prop != Undefined.instance) {
return prop;
}
} catch (Exception esx) {
// System.err.println ("Error in getProperty: "+esx);
return null;
}
return null;
}
/**
* Get an introspector to this engine. FIXME: not yet implemented for the rhino engine.
*/
public IPathElement getIntrospector() {
return null;
}
/**
* Return the application we're running in
*/
public Application getApplication() {
return app;
}
/**
* Return the RequestEvaluator owning and driving this FESI evaluator.
*/
public RequestEvaluator getRequestEvaluator() {
return reval;
}
/**
* 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.
*/
public RequestTrans getRequest() {
return reval.req;
}
}

View file

@ -0,0 +1,274 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.scripting.rhino;
import helma.framework.core.Application;
import helma.framework.core.RequestEvaluator;
import helma.objectmodel.INode;
import helma.objectmodel.db.Node;
import helma.objectmodel.dom.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
/**
*
*/
public class XmlObject {
RhinoCore core;
/**
* Creates a new XmlObject object.
*
* @param core ...
*/
public XmlObject(RhinoCore core) {
this.core = core;
}
/**
*
*
* @param hopObject ...
* @param file ...
*
* @return ...
*
* @throws IOException ...
* @throws RuntimeException ...
*/
public boolean write(Object hopObject, String file)
throws IOException {
INode node = null;
if (hopObject instanceof HopObject) {
node = ((HopObject) hopObject).node;
}
// we definitly need a node
if (node == null) {
throw new RuntimeException("First argument in Xml.write() is not an hopobject");
}
if (file == null) {
throw new RuntimeException("Second argument file name must not be null");
}
File tmpFile = new File(file + ".tmp." + XmlWriter.generateID());
XmlWriter writer = new XmlWriter(tmpFile, "UTF-8");
writer.setDatabaseMode(false);
boolean result = writer.write(node);
writer.close();
File finalFile = new File(file);
tmpFile.renameTo(finalFile);
core.getApplication().logEvent("wrote xml to " + finalFile.getAbsolutePath());
return true;
}
/**
* Xml.create() is used to get a string containing the xml-content.
* Useful if Xml-content should be made public through the web.
*/
public String writeToString(Object hopObject) throws IOException {
INode node = null;
if (hopObject instanceof HopObject) {
node = ((HopObject) hopObject).node;
}
// we definitly need a node
if (node == null) {
throw new RuntimeException("First argument in Xml.write() is not an hopobject");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
XmlWriter writer = new XmlWriter(out, "UTF-8");
// in case we ever want to limit serialization depth...
// if (arguments.length > 1 && arguments[1] instanceof ESNumber)
// writer.setMaxLevels(arguments[1].toInt32());
writer.setDatabaseMode(false);
boolean result = writer.write(node);
writer.flush();
return out.toString("UTF-8");
}
/**
*
*
* @param file ...
*
* @return ...
*
* @throws RuntimeException ...
*/
public Object read(String file) throws RuntimeException {
return read(file, null);
}
/**
*
*
* @param file ...
* @param hopObject ...
*
* @return ...
*
* @throws RuntimeException ...
*/
public Object read(String file, Object hopObject) throws RuntimeException {
if (file == null) {
throw new RuntimeException("Missing arguments in Xml.read()");
}
INode node = null;
if (hopObject instanceof HopObject) {
node = ((HopObject) hopObject).node;
}
if (node == null) {
// make sure we have a node, even if 2nd arg doesn't exist or is not a node
node = new Node((String) null, (String) null,
core.getApplication().getWrappedNodeManager());
}
try {
XmlReader reader = new XmlReader();
INode result = reader.read(new File(file), node);
return core.getNodeWrapper(result);
} catch (NoClassDefFoundError e) {
throw new RuntimeException("Can't load XML parser:" + e);
} catch (Exception f) {
throw new RuntimeException(f.toString());
}
}
/**
*
*
* @param str ...
*
* @return ...
*
* @throws RuntimeException ...
*/
public Object readFromString(String str) throws RuntimeException {
return readFromString(str, null);
}
/**
*
*
* @param str ...
* @param hopObject ...
*
* @return ...
*
* @throws RuntimeException ...
*/
public Object readFromString(String str, Object hopObject)
throws RuntimeException {
if (str == null) {
throw new RuntimeException("Missing arguments in Xml.read()");
}
INode node = null;
if (hopObject instanceof HopObject) {
node = ((HopObject) hopObject).node;
}
if (node == null) {
// make sure we have a node, even if 2nd arg doesn't exist or is not a node
node = new Node((String) null, (String) null,
core.getApplication().getWrappedNodeManager());
}
try {
XmlReader reader = new XmlReader();
INode result = reader.read(new StringReader(str), node);
return core.getNodeWrapper(result);
} catch (NoClassDefFoundError e) {
throw new RuntimeException("Can't load XML parser:" + e);
} catch (Exception f) {
throw new RuntimeException(f.toString());
}
}
/* class XmlGet extends BuiltinFunctionObject {
XmlGet(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if ( arguments==null || arguments.length==0 )
throw new EcmaScriptException("Xml.get() needs a location as an argument");
try {
XmlConverter converter;
if ( arguments.length>1 ) {
converter = new XmlConverter (arguments[1].toString());
} else {
converter = new XmlConverter ();
}
INode node = new helma.objectmodel.db.Node ( (String)null, (String)null, this.evaluator.engine.getApplication().getWrappedNodeManager() );
INode result = converter.convert (arguments[0].toString(),node);
return this.evaluator.engine.getNodeWrapper(result);
} catch ( NoClassDefFoundError e ) {
throw new EcmaScriptException("Can't load dom-capable xml parser.");
} catch ( RuntimeException f ) {
throw new EcmaScriptException(f.toString());
}
}
}
class XmlGetFromString extends BuiltinFunctionObject {
XmlGetFromString(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if ( arguments==null || arguments.length==0 )
throw new EcmaScriptException("Xml.getFromString() needs an XML string as parameter");
try {
XmlConverter converter;
if ( arguments.length>1 ) {
converter = new XmlConverter (arguments[1].toString());
} else {
converter = new XmlConverter ();
}
INode node = new helma.objectmodel.db.Node ( (String)null, (String)null, this.evaluator.engine.getApplication().getWrappedNodeManager() );
INode result = converter.convertFromString (arguments[0].toString(),node);
return this.evaluator.engine.getNodeWrapper(result);
} catch ( NoClassDefFoundError e ) {
throw new EcmaScriptException("Can't load dom-capable xml parser.");
} catch ( RuntimeException f ) {
throw new EcmaScriptException(f.toString());
}
}
} */
}