You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/09/26 17:26:41 UTC
svn commit: r699367 - in
/incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal:
./ RhinoJavaScriptEngine.java
Author: fmeschbe
Date: Fri Sep 26 08:26:40 2008
New Revision: 699367
URL: http://svn.apache.org/viewvc?rev=699367&view=rev
Log:
SLING-677 share the top level scope for the complete
request processing and move the engine to an internal
package to enable export of the SPI interfaces
(see SLING-634)
Added:
incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/
incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java
- copied, changed from r688978, incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/RhinoJavaScriptEngine.java
Copied: incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java (from r688978, incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/RhinoJavaScriptEngine.java)
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java?p2=incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java&p1=incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/RhinoJavaScriptEngine.java&r1=688978&r2=699367&rev=699367&view=diff
==============================================================================
--- incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/RhinoJavaScriptEngine.java (original)
+++ incubator/sling/trunk/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java Fri Sep 26 08:26:40 2008
@@ -14,9 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sling.scripting.javascript;
+package org.apache.sling.scripting.javascript.internal;
import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.Map.Entry;
import javax.script.Bindings;
@@ -30,11 +33,12 @@
import org.apache.sling.scripting.javascript.helper.SlingWrapFactory;
import org.apache.sling.scripting.javascript.io.EspReader;
import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.JavaScriptException;
-import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.WrapFactory;
import org.slf4j.Logger;
/**
@@ -45,7 +49,8 @@
private Scriptable rootScope;
- public RhinoJavaScriptEngine(ScriptEngineFactory factory, Scriptable rootScope) {
+ public RhinoJavaScriptEngine(ScriptEngineFactory factory,
+ Scriptable rootScope) {
super(factory);
this.rootScope = rootScope;
}
@@ -56,7 +61,7 @@
String scriptName = "NO_SCRIPT_NAME";
{
SlingScriptHelper helper = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
- if(helper != null) {
+ if (helper != null) {
scriptName = helper.getScript().getScriptResource().getPath();
}
}
@@ -66,31 +71,42 @@
scriptReader = new EspReader(scriptReader);
}
+ // container for replaced properties
+ Map<String, Object> replacedProperties = null;
+ Scriptable scope = null;
+
// create a rhino Context and execute the script
try {
-
+
final Context rhinoContext = Context.enter();
- final ScriptableObject scope = new NativeObject();
- // Set the global scope to be our prototype
- scope.setPrototype(rootScope);
+ if (ScriptRuntime.hasTopCall(rhinoContext)) {
- // We want "scope" to be a new top-level scope, so set its parent
- // scope to null. This means that any variables created by assignments
- // will be properties of "scope".
- scope.setParentScope(null);
+ // reuse the top scope if we are included
+ scope = ScriptRuntime.getTopCallScope(rhinoContext);
- // setup the context for use
- rhinoContext.setWrapFactory(SlingWrapFactory.INSTANCE);
+ } else {
- // add initial properties to the scope
- for (Object entryObject : bindings.entrySet()) {
- Entry<?, ?> entry = (Entry<?, ?>) entryObject;
- Object wrapped = ScriptRuntime.toObject(scope, entry.getValue());
- ScriptableObject.putProperty(scope, (String) entry.getKey(),
- wrapped);
+ // create the request top scope, use the ImporterToplevel here
+ // to support the importPackage and importClasses functions
+ scope = new ImporterTopLevel(); // new NativeObject();
+
+ // Set the global scope to be our prototype
+ scope.setPrototype(rootScope);
+
+ // We want "scope" to be a new top-level scope, so set its
+ // parent scope to null. This means that any variables created
+ // by assignments will be properties of "scope".
+ scope.setParentScope(null);
+
+ // setup the context for use
+ WrapFactory wrapFactory = ((RhinoJavaScriptEngineFactory) getFactory()).getWrapFactory();
+ rhinoContext.setWrapFactory(wrapFactory);
}
+ // add initial properties to the scope
+ replacedProperties = setBoundProperties(scope, bindings);
+
final int lineNumber = 1;
final Object securityDomain = null;
@@ -98,26 +114,61 @@
lineNumber, securityDomain);
} catch (JavaScriptException t) {
-
+
final ScriptException se = new ScriptException(t.details(),
t.sourceName(), t.lineNumber());
((Logger) bindings.get(SlingBindings.LOG)).error(t.getScriptStackTrace());
se.setStackTrace(t.getStackTrace());
throw se;
-
+
} catch (Throwable t) {
-
- final ScriptException se = new ScriptException("Failure running script " + scriptName
- + ": " + t.getMessage());
+
+ final ScriptException se = new ScriptException(
+ "Failure running script " + scriptName + ": " + t.getMessage());
se.initCause(t);
throw se;
-
+
} finally {
-
+
+ // if properties have been replaced, reset them
+ resetBoundProperties(scope, replacedProperties);
+
Context.exit();
-
+
+ }
+ }
+
+ private Map<String, Object> setBoundProperties(Scriptable scope,
+ Bindings bindings) {
+ Map<String, Object> replacedProperties = new HashMap<String, Object>();
+
+ for (Object entryObject : bindings.entrySet()) {
+ Entry<?, ?> entry = (Entry<?, ?>) entryObject;
+ String name = (String) entry.getKey();
+
+ // get the current property value, if set
+ if (ScriptableObject.hasProperty(scope, name)) {
+ replacedProperties.put(name, ScriptableObject.getProperty(
+ scope, name));
+ }
+
+ // wrap the new value and set it
+ Object wrapped = ScriptRuntime.toObject(scope, entry.getValue());
+ ScriptableObject.putProperty(scope, (String) entry.getKey(),
+ wrapped);
}
+
+ return replacedProperties;
}
+ private void resetBoundProperties(Scriptable scope,
+ Map<String, Object> properties) {
+ if (scope != null && properties != null && properties.size() > 0) {
+ for (Entry<String, Object> entry : properties.entrySet()) {
+ ScriptableObject.putProperty(scope, entry.getKey(),
+ entry.getValue());
+ }
+ }
+ }
}