Better fix for bug #684: Retrieve ScriptingEngine if necessary in Application.getDataRoot(), and make sure root objects set via Application.setDataRoot() are actually used.

This commit is contained in:
hns 2009-11-05 10:15:53 +00:00
parent 989ce36da0
commit 784e374f78

View file

@ -25,6 +25,7 @@ import helma.objectmodel.*;
import helma.objectmodel.db.*; import helma.objectmodel.db.*;
import helma.util.*; import helma.util.*;
import helma.scripting.ScriptingEngine; import helma.scripting.ScriptingEngine;
import helma.scripting.ScriptingException;
import java.io.*; import java.io.*;
import java.lang.reflect.*; import java.lang.reflect.*;
@ -841,52 +842,65 @@ public final class Application implements Runnable {
* This method returns the root object of this application's object tree. * This method returns the root object of this application's object tree.
*/ */
public Object getDataRoot() throws Exception { public Object getDataRoot() throws Exception {
return getDataRoot(getCurrentRequestEvaluator().getScriptingEngine()); return getDataRoot(null);
} }
/** /**
* This method returns the root object of this application's object tree. * This method returns the root object of this application's object tree.
*/ */
public Object getDataRoot(ScriptingEngine scriptingEngine) throws Exception { protected Object getDataRoot(ScriptingEngine engine) throws Exception {
if (rootObject != null) {
return rootObject;
}
// check if we have a custom root object class // check if we have a custom root object class
if (rootObjectClass != null) { if (rootObjectClass != null) {
// create custom root element. // create custom root element.
if (rootObject == null) {
try { try {
if (classMapping.containsKey("root.factory.class") && if (classMapping.containsKey("root.factory.class") &&
classMapping.containsKey("root.factory.method")) { classMapping.containsKey("root.factory.method")) {
String rootFactory = classMapping.getProperty("root.factory.class"); String rootFactory = classMapping.getProperty("root.factory.class");
Class c = typemgr.getClassLoader().loadClass(rootFactory); Class c = typemgr.getClassLoader().loadClass(rootFactory);
Method m = c.getMethod(classMapping.getProperty("root.factory.method"), Method m = c.getMethod(
classMapping.getProperty("root.factory.method"),
(Class[]) null); (Class[]) null);
rootObject = m.invoke(c, (Object[]) null); rootObject = m.invoke(c, (Object[]) null);
} else { } else {
String rootClass = classMapping.getProperty("root"); String rootClass = classMapping.getProperty("root");
Class c = typemgr.getClassLoader().loadClass(rootClass); Class c = typemgr.getClassLoader().loadClass(rootClass);
rootObject = c.newInstance(); rootObject = c.newInstance();
} }
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Error creating root object: " + throw new RuntimeException("Error creating root object: " +
e.toString()); e.toString());
} }
}
return rootObject; return rootObject;
} else if (rootObjectPropertyName != null) { } else if (rootObjectPropertyName != null || rootObjectFunctionName != null) {
// get root object from a global scripting engine property // get root object from a global scripting engine property or function
return scriptingEngine.getGlobalProperty(rootObjectPropertyName); if (engine == null) {
} else if (rootObjectFunctionName != null) { RequestEvaluator reval = getEvaluator();
// get root object from a global script engine function try {
return scriptingEngine.invoke(null, rootObjectFunctionName, return getDataRootFromEngine(reval.getScriptingEngine());
RequestEvaluator.EMPTY_ARGS, ScriptingEngine.ARGS_WRAP_DEFAULT, true); } finally {
releaseEvaluator(reval);
}
} else {
return getDataRootFromEngine(engine);
}
} else { } else {
// no custom root object is defined - use standard helma objectmodel // no custom root object is defined - use standard helma objectmodel
return nmgr.getRootNode(); return nmgr.getRootNode();
} }
} }
private Object getDataRootFromEngine(ScriptingEngine engine)
throws ScriptingException {
return rootObjectPropertyName != null ?
engine.getGlobalProperty(rootObjectPropertyName) :
engine.invoke(null, rootObjectFunctionName,
RequestEvaluator.EMPTY_ARGS,
ScriptingEngine.ARGS_WRAP_DEFAULT, true);
}
/** /**
* Return the prototype of the object to be used as this application's root object * Return the prototype of the object to be used as this application's root object
*/ */