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(
Method m = c.getMethod(classMapping.getProperty("root.factory.method"), 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) {
throw new RuntimeException("Error creating root object: " +
e.toString());
} }
} catch (Exception e) {
throw new RuntimeException("Error creating root object: " +
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
*/ */