SLING-7305 - The org.apache.sling.scripting.javascript bundle should add more specifi...
authorRadu Cotescu <radu@apache.org>
Wed, 13 Dec 2017 13:35:59 +0000 (14:35 +0100)
committerRadu Cotescu <radu@apache.org>
Wed, 13 Dec 2017 13:35:59 +0000 (14:35 +0100)
* enhanced the list of names with which the RhinoScriptEngineFactory is registered
* defined the language version, by making sure Rhino is always initialised with the
ES6 features
* added information about what Rhino version is actually used

pom.xml
src/main/java/org/apache/sling/scripting/javascript/helper/SlingContextFactory.java
src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java
src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java

diff --git a/pom.xml b/pom.xml
index c272bd7..4666d1d 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-scripting-javascript.git</url>
     </scm>
 
+    <properties>
+        <rhino.version>1.7.7.1_1</rhino.version>
+    </properties>
+
     <build>
         <plugins>
             <plugin>
@@ -63,7 +67,7 @@
                             org.apache.sling.commons.osgi;inline="org/apache/sling/commons/osgi/PropertiesUtil.*"
                         </Embed-Dependency>
                         <Provide-Capability>
-                            osgi.implementation;osgi.implementation="org.apache.sling.scripting.javascript.rhinoscriptengine";version:Version="1.7.7.1"
+                            osgi.implementation;osgi.implementation="org.apache.sling.scripting.javascript.rhinoscriptengine";version:Version="${rhino.version}"
                         </Provide-Capability>
                         <_removeheaders>
                           Embed-Dependency,
@@ -72,6 +76,7 @@
                         </_removeheaders>
                         <ScriptEngine-Name>${project.name}</ScriptEngine-Name>
                         <ScriptEngine-Version>${project.version}</ScriptEngine-Version>
+                        <Rhino-Version>${rhino.version}</Rhino-Version>
                     </instructions>
                 </configuration>
             </plugin>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.mozilla</groupId>
-            <artifactId>rhino</artifactId>
-            <version>1.7.7.1</version>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.rhino</artifactId>
+            <version>${rhino.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
index b2c694c..0ea3c47 100644 (file)
@@ -43,13 +43,16 @@ public class SlingContextFactory extends ContextFactory {
 
     private boolean debuggerActive;
 
+    private int languageVersion;
+
     // conditionally setup the global ContextFactory to be ours. If
     // a global context factory has already been set, we have lost
     // and cannot set this one.
-    public static void setup(ScopeProvider sp) {
+    public static void setup(ScopeProvider sp, int languageVersion) {
         // TODO what do we do in the other case? debugger won't work
         if (!hasExplicitGlobal()) {
-            initGlobal(new SlingContextFactory(sp));
+            initGlobal(new SlingContextFactory(sp,
+                    Context.isValidLanguageVersion(languageVersion) ? languageVersion : Context.VERSION_DEFAULT));
         }
     }
 
@@ -61,8 +64,9 @@ public class SlingContextFactory extends ContextFactory {
     }
 
     // private as instances of this class are only used by setup()
-    private SlingContextFactory(ScopeProvider sp) {
+    private SlingContextFactory(ScopeProvider sp, int languageVersion) {
         scopeProvider = sp;
+        this.languageVersion = languageVersion;
     }
 
     private void dispose() {
@@ -81,7 +85,9 @@ public class SlingContextFactory extends ContextFactory {
 
     @Override
     protected Context makeContext() {
-        return new SlingContext();
+        Context context = new SlingContext();
+        context.setLanguageVersion(languageVersion);
+        return context;
     }
 
     @Override
index 158ff22..f49a661 100644 (file)
@@ -93,6 +93,7 @@ public class RhinoJavaScriptEngine extends AbstractSlingScriptEngine implements
             scriptReader = wrapReaderIfEspScript(scriptReader, scriptName);
             try {
                 final Context rhinoContext = Context.enter();
+                rhinoContext.setLanguageVersion(((RhinoJavaScriptEngineFactory)getFactory()).rhinoLanguageVersion());
                 rhinoContext.setOptimizationLevel(optimizationLevel());
 
                 if (!ScriptRuntime.hasTopCall(rhinoContext)) {
@@ -239,6 +240,7 @@ public class RhinoJavaScriptEngine extends AbstractSlingScriptEngine implements
             try {
 
                 final Context rhinoContext = Context.enter();
+                rhinoContext.setLanguageVersion(((RhinoJavaScriptEngineFactory)getFactory()).rhinoLanguageVersion());
                 rhinoContext.setOptimizationLevel(optimizationLevel());
 
                 if (ScriptRuntime.hasTopCall(rhinoContext)) {
index acd7bd1..c870df7 100644 (file)
  */
 package org.apache.sling.scripting.javascript.internal;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineFactory;
 
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
+import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
 import org.apache.sling.scripting.api.ScriptCache;
 import org.apache.sling.scripting.javascript.RhinoHostObjectProvider;
@@ -68,9 +74,12 @@ import org.slf4j.LoggerFactory;
         Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
         "extensions=" + RhinoJavaScriptEngineFactory.ECMA_SCRIPT_EXTENSION,
         "extensions=" + RhinoJavaScriptEngineFactory.ESP_SCRIPT_EXTENSION,
+        "mimeTypes=text/ecmascript",
         "mimeTypes=text/javascript",
         "mimeTypes=application/ecmascript",
         "mimeTypes=application/javascript",
+        "names=rhino",
+        "names=Rhino",
         "names=javascript",
         "names=JavaScript",
         "names=ecmascript",
@@ -110,7 +119,10 @@ public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory im
 
     private int optimizationLevel;
 
-    private String languageVersion;
+    private static final int RHINO_LANGUAGE_VERSION = Context.VERSION_ES6;
+    private static final String LANGUAGE_VERSION = "partial ECMAScript 2015 support";
+    private static final String LANGUAGE_NAME = "ECMAScript";
+
 
     private SlingWrapFactory wrapFactory;
 
@@ -129,11 +141,11 @@ public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory im
     }
 
     public String getLanguageName() {
-        return "ECMAScript";
+        return LANGUAGE_NAME;
     }
 
     public String getLanguageVersion() {
-        return languageVersion;
+        return LANGUAGE_VERSION;
     }
 
     /**
@@ -143,10 +155,14 @@ public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory im
      * @return an integer from 0-9 with 9 being the most aggressive optimization, or
      * -1 if interpreted mode is to be used
      */
-    public int getOptimizationLevel() {
+    int getOptimizationLevel() {
         return optimizationLevel;
     }
 
+    int rhinoLanguageVersion() {
+        return Context.VERSION_ES6;
+    }
+
     public Object getParameter(String name) {
         if ("THREADING".equals(name)) {
             return "MULTITHREADED";
@@ -170,6 +186,7 @@ public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory im
             final Context rhinoContext = Context.enter();
             try {
                 rhinoContext.setOptimizationLevel(optimizationLevel);
+                rhinoContext.setLanguageVersion(RHINO_LANGUAGE_VERSION);
                 Scriptable tmpScope = rhinoContext.initStandardObjects(new ImporterTopLevel(rhinoContext), false);
 
                 // default classes
@@ -215,22 +232,40 @@ public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory im
         Dictionary<?, ?> props = context.getProperties();
         boolean debugging = getProperty("org.apache.sling.scripting.javascript.debug", props, context.getBundleContext(), false);
 
+        // try to get the manifest
+        String rhinoVersion = null;
+        InputStream ins = null;
+        try {
+            ins = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
+            if (ins != null) {
+                Manifest manifest = new Manifest(ins);
+                Attributes attrs = manifest.getMainAttributes();
+                rhinoVersion = attrs.getValue("Rhino-Version");
+            }
+        } catch (IOException ioe) {
+            log.warn("Unable to read Rhino version.", ioe);
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+
         optimizationLevel = readOptimizationLevel(configuration);
 
         // setup the wrap factory
         wrapFactory = new SlingWrapFactory();
 
         // initialize the Rhino Context Factory
-        SlingContextFactory.setup(this);
+        SlingContextFactory.setup(this, RHINO_LANGUAGE_VERSION);
 
-        Context cx = Context.enter();
-        setEngineName(getEngineName() + " (" + cx.getImplementationVersion() + ")");
-        languageVersion = String.valueOf(cx.getLanguageVersion());
-        Context.exit();
+        setEngineName(getEngineName() + " (Rhino " + (rhinoVersion != null ? rhinoVersion : "unknown") + ")");
 
-        setExtensions(ECMA_SCRIPT_EXTENSION, ESP_SCRIPT_EXTENSION);
-        setMimeTypes("text/javascript", "application/ecmascript", "application/javascript");
-        setNames("javascript", ECMA_SCRIPT_EXTENSION, ESP_SCRIPT_EXTENSION);
+        setExtensions(PropertiesUtil.toStringArray(props.get("extensions")));
+        setMimeTypes(PropertiesUtil.toStringArray(props.get("mimeTypes")));
+        setNames(PropertiesUtil.toStringArray(props.get("names")));
 
         final ContextFactory contextFactory = ContextFactory.getGlobal();
         if (contextFactory instanceof SlingContextFactory) {