summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/JsEngineProvider.java4
-rw-r--r--modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapter.java32
-rw-r--r--modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/EngineTest.java19
-rw-r--r--modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/InitializerTest.java4
-rw-r--r--modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapterTest.java117
-rw-r--r--modules/enterprise/scripting/javascript/src/test/resources/nest.js9
-rw-r--r--modules/enterprise/scripting/javascript/src/test/resources/nested/deep-nest.js8
7 files changed, 175 insertions, 18 deletions
diff --git a/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/JsEngineProvider.java b/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/JsEngineProvider.java
index 63c5023..af89772 100644
--- a/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/JsEngineProvider.java
+++ b/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/JsEngineProvider.java
@@ -30,6 +30,8 @@ import org.rhq.scripting.ScriptEngineProvider;
*/
public class JsEngineProvider implements ScriptEngineProvider {
+ public static final String SCRIPT_FILE_EXTENSION = "js";
+
@Override
public String getSupportedLanguage() {
return "javascript";
@@ -37,7 +39,7 @@ public class JsEngineProvider implements ScriptEngineProvider {
@Override
public String getScriptFileExtension() {
- return "js";
+ return SCRIPT_FILE_EXTENSION;
}
@Override
diff --git a/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapter.java b/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapter.java
index fb3926b..9a02210 100644
--- a/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapter.java
+++ b/modules/enterprise/scripting/javascript/src/main/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapter.java
@@ -25,47 +25,55 @@ import java.net.URI;
import java.net.URISyntaxException;
import org.mozilla.javascript.commonjs.module.provider.ModuleSource;
+import org.mozilla.javascript.commonjs.module.provider.ModuleSourceProvider;
import org.mozilla.javascript.commonjs.module.provider.ModuleSourceProviderBase;
import org.rhq.scripting.ScriptSourceProvider;
+import org.rhq.scripting.javascript.JsEngineProvider;
/**
+ * This is an adapter that acts as a {@link ModuleSourceProvider} for Rhino
+ * but uses RHQ's {@link ScriptSourceProvider} to load the scripts.
*
- *
* @author Lukas Krejci
*/
public class ScriptSourceToModuleSourceProviderAdapter extends ModuleSourceProviderBase {
private static final long serialVersionUID = 1L;
-
+
+ private static final String SUFFIX = "." + JsEngineProvider.SCRIPT_FILE_EXTENSION;
+
private ScriptSourceProvider scriptSourceProvider;
-
+
public ScriptSourceToModuleSourceProviderAdapter(ScriptSourceProvider provider) {
scriptSourceProvider = provider;
}
-
+
@Override
protected ModuleSource loadFromPrivilegedLocations(String moduleId, Object validator) throws IOException,
URISyntaxException {
- //if the URI is absolute, we make sure to define the ModuleSource as sandboxed.
- //this is done by making the URI a "subpath" of the base.
URI uri = new URI(moduleId);
- URI base = null;
- if (uri.isAbsolute()) {
- base = uri;
+ if (!uri.isAbsolute()) {
+ return null;
}
- return loadFromUri(uri, base, validator);
+ return loadFromUri(uri, null, validator);
}
@Override
protected ModuleSource loadFromUri(URI uri, URI base, Object validator) throws IOException, URISyntaxException {
URI fullUri = uri;
if (base != null) {
- fullUri = uri.resolve(base);
+ fullUri = base.resolve(uri);
+ }
+
+ if (!fullUri.getSchemeSpecificPart().endsWith(SUFFIX)) {
+ fullUri =
+ new URI(fullUri.getScheme(), fullUri.getAuthority(), fullUri.getPath() + SUFFIX, fullUri.getQuery(),
+ fullUri.getFragment());
}
Reader sourceReader = scriptSourceProvider.getScriptSource(fullUri);
-
+
if (sourceReader == null) {
return null;
} else {
diff --git a/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/EngineTest.java b/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/EngineTest.java
index 6aa9355..6ed5757 100644
--- a/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/EngineTest.java
+++ b/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/EngineTest.java
@@ -63,8 +63,8 @@ public class EngineTest {
public void modulesCanBeLoaded() throws Exception {
String script = "" +
- "var m1 = require('target/test-classes/test-module1.js'); \n" +
- "var m2 = require('target/test-classes/test-module2.js'); \n" +
+ "var m1 = require('target/test-classes/test-module1'); \n" +
+ "var m2 = require('target/test-classes/test-module2'); \n" +
"println(typeof(m1.func1));\n" +
"println(typeof(m1.func2));\n" +
"println(typeof(m2.func3));\n" +
@@ -85,7 +85,7 @@ public class EngineTest {
+ "var test2 = \"strstr\"\n"
+ "var test3 = new java.lang.String(\"strstr\")\n";
- ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
+ ScriptEngine engine = getScriptEngine();
engine.eval(script);
@@ -104,6 +104,19 @@ public class EngineTest {
assertEquals(ret, 12, "Engine failed to pass a concatenated string as a string parameter.");
}
+ public void relativeModuleAddressingWorks() throws Exception {
+ String script = "var n = require('target/test-classes/nest');";
+
+ ScriptEngine engine = getScriptEngine();
+
+ Object ret = engine.eval(script + "n.nest()");
+ assertEquals(ret, "Deep nest", "A module could not be loaded using a relative path.");
+
+ ret = engine.eval(script + "n.maze()");
+ assertEquals(ret, "func1", "A module could not be loaded using a relative path.");
+
+ }
+
private ScriptEngine getScriptEngine() {
ScriptEngineManager manager = new ScriptEngineManager();
return manager.getEngineByName("rhino-nonjdk");
diff --git a/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/InitializerTest.java b/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/InitializerTest.java
index e71155b..36bfbb9 100644
--- a/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/InitializerTest.java
+++ b/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/InitializerTest.java
@@ -100,7 +100,7 @@ public class InitializerTest {
public void scriptSourceProviderApplied() throws Exception {
- String script = "var m = require('rhq://test-module1.js'); m.func1();";
+ String script = "var m = require('rhq:/test-module1'); m.func1();";
//first let's try to find the scripts with the default source provider...
ScriptEngine eng = new JsEngineInitializer().instantiate(Collections.<String>emptySet(), null);
@@ -118,7 +118,7 @@ public class InitializerTest {
if (!"rhq".equals(location.getScheme())) {
return null;
}
- String scriptName = location.getSchemeSpecificPart().substring(2); //remove the '//'
+ String scriptName = location.getPath().substring(1); //remove the '/'
InputStream src = getClass().getClassLoader().getResourceAsStream(scriptName);
return new InputStreamReader(src);
}
diff --git a/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapterTest.java b/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapterTest.java
new file mode 100644
index 0000000..72b6d25
--- /dev/null
+++ b/modules/enterprise/scripting/javascript/src/test/java/org/rhq/scripting/javascript/util/ScriptSourceToModuleSourceProviderAdapterTest.java
@@ -0,0 +1,117 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.scripting.javascript.util;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URI;
+import java.util.Collections;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.testng.annotations.Test;
+
+import org.rhq.scripting.ScriptSourceProvider;
+import org.rhq.scripting.javascript.JsEngineInitializer;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class ScriptSourceToModuleSourceProviderAdapterTest {
+
+ private JsEngineInitializer initializer = new JsEngineInitializer();
+
+ private static class ClasspathScriptSourceProvider implements ScriptSourceProvider {
+ private ClassLoader cl;
+
+ public ClasspathScriptSourceProvider() {
+ this(ClasspathScriptSourceProvider.class.getClassLoader());
+ }
+
+ public ClasspathScriptSourceProvider(ClassLoader cl) {
+ this.cl = cl;
+ }
+
+ private static final String SCHEME = "classpath";
+ @Override
+ public Reader getScriptSource(URI uri) {
+ if (!SCHEME.equals(uri.getScheme())) {
+ return null;
+ }
+
+ String path = uri.getPath().substring(1); //remove the leading /
+
+ return new InputStreamReader(cl.getResourceAsStream(path));
+ }
+ }
+
+ private ScriptEngine getScriptEngine() throws ScriptException {
+ ScriptEngine engine = initializer.instantiate(Collections.<String>emptySet(), null);
+ initializer.installScriptSourceProvider(engine, new ClasspathScriptSourceProvider());
+
+ return engine;
+ }
+
+ public void simpleModuleLoad() throws Exception {
+ String script = "var m = require('classpath:/nested/deep-nest'); m.nest();";
+
+ Object ret = getScriptEngine().eval(script);
+
+ assertEquals(ret, "Deep nest", "deep-nest.js#nest() returned unexpected value");
+ }
+
+ public void relativePathsInRequire() throws Exception {
+ String script = "var m = require('classpath:/nest'); m.maze();";
+
+ Object ret = getScriptEngine().eval(script);
+
+ assertEquals(ret, "func1", "nest.js#maze() returned unexpected value");
+ }
+
+ public void urisWithAuthorityDontConfuseResolution() throws Exception {
+ String script = "var m = require('classpath://authority/nest'); m.maze();";
+
+ Object ret = getScriptEngine().eval(script);
+
+ assertEquals(ret, "func1", "nest.js#maze() returned unexpected value");
+ }
+
+ public void urisWithQueryDontConfuseResolution() throws Exception {
+ String script = "var m = require('classpath:/nest?query'); m.maze();";
+
+ Object ret = getScriptEngine().eval(script);
+
+ assertEquals(ret, "func1", "nest.js#maze() returned unexpected value");
+ }
+
+ public void urisWithFragmentDontConfuseResolution() throws Exception {
+ String script = "var m = require('classpath:/nest#fragment'); m.maze();";
+
+ Object ret = getScriptEngine().eval(script);
+
+ assertEquals(ret, "func1", "nest.js#maze() returned unexpected value");
+ }
+}
diff --git a/modules/enterprise/scripting/javascript/src/test/resources/nest.js b/modules/enterprise/scripting/javascript/src/test/resources/nest.js
new file mode 100644
index 0000000..e9ea75e
--- /dev/null
+++ b/modules/enterprise/scripting/javascript/src/test/resources/nest.js
@@ -0,0 +1,9 @@
+var dn = require('./nested/deep-nest');
+
+exports.nest = function() {
+ return dn.nest();
+}
+
+exports.maze = function() {
+ return dn.maze();
+} \ No newline at end of file
diff --git a/modules/enterprise/scripting/javascript/src/test/resources/nested/deep-nest.js b/modules/enterprise/scripting/javascript/src/test/resources/nested/deep-nest.js
new file mode 100644
index 0000000..25110cd
--- /dev/null
+++ b/modules/enterprise/scripting/javascript/src/test/resources/nested/deep-nest.js
@@ -0,0 +1,8 @@
+exports.nest = function() {
+ return "Deep nest";
+}
+
+exports.maze = function() {
+ var m1 = require('../test-module1');
+ return m1.func1();
+}