From 76a91e0cc0b3b4470d286b2415599d4b67b335dc Mon Sep 17 00:00:00 2001 From: Scott Yuan Date: Tue, 3 Dec 2024 21:36:55 -0700 Subject: [PATCH 1/8] SLING-12519 - Remove Double-Checked Locking in ScriptableBase.java * Eliminated the use of double-checked locking in wrapper/ScriptableBase.java to improve code safety and readability. --- .../scripting/javascript/wrapper/ScriptableBase.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java index 95a330f..42edafc 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java @@ -34,7 +34,7 @@ public abstract class ScriptableBase extends ScriptableObject { public static final String JSFUNC_PREFIX = "jsFunction_"; - protected Object getNative(String name, Scriptable start) { + protected synchronized Object getNative(String name, Scriptable start) { final Object wrapped = getWrappedObject(); if(wrapped == null) { @@ -46,11 +46,7 @@ protected Object getNative(String name, Scriptable start) { } if(njo == null) { - synchronized (this) { - if(njo == null) { - njo = new NativeJavaObject(start, wrapped, getStaticType()); - } - } + njo = new NativeJavaObject(start, wrapped, getStaticType()); } return njo.get(name, start); From 22ce146824d1c6d549ba0e38e00791716b2bde98 Mon Sep 17 00:00:00 2001 From: Scott Yuan Date: Tue, 3 Dec 2024 21:36:55 -0700 Subject: [PATCH 2/8] SLING-12519 - Remove Double-Checked Locking in ScriptableBase.java * Eliminated the use of double-checked locking in wrapper/ScriptableBase.java to improve code safety and readability. --- .../scripting/javascript/wrapper/ScriptableBase.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java index 95a330f..42edafc 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java @@ -34,7 +34,7 @@ public abstract class ScriptableBase extends ScriptableObject { public static final String JSFUNC_PREFIX = "jsFunction_"; - protected Object getNative(String name, Scriptable start) { + protected synchronized Object getNative(String name, Scriptable start) { final Object wrapped = getWrappedObject(); if(wrapped == null) { @@ -46,11 +46,7 @@ protected Object getNative(String name, Scriptable start) { } if(njo == null) { - synchronized (this) { - if(njo == null) { - njo = new NativeJavaObject(start, wrapped, getStaticType()); - } - } + njo = new NativeJavaObject(start, wrapped, getStaticType()); } return njo.get(name, start); From 6f3a811ab3fabc9c98f919a7f7e04061a6fed3b5 Mon Sep 17 00:00:00 2001 From: Eric Norman Date: Tue, 17 Dec 2024 15:54:22 -0800 Subject: [PATCH 3/8] SLING-12492 bump org.apache.sling.api to 2.25.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5da6f58..bbb5073 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ org.apache.sling org.apache.sling.api - 2.21.0 + 2.25.4 provided From ffe719cc0ec1597d02cc35aab179ffba85c3a1b8 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Fri, 28 Mar 2025 16:59:44 +0100 Subject: [PATCH 4/8] SLING-12730 Update to Parent 62 --- .sling-module.json | 5 +++++ pom.xml | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .sling-module.json diff --git a/.sling-module.json b/.sling-module.json new file mode 100644 index 0000000..cfad4d2 --- /dev/null +++ b/.sling-module.json @@ -0,0 +1,5 @@ +{ + "jenkins": { + "jdks": [17, 21] + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index bbb5073..fbe22d3 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ org.apache.sling sling-bundle-parent - 48 + 62 @@ -89,6 +89,16 @@ org.osgi.service.metatype.annotations provided + + org.osgi + org.osgi.framework + provided + + + org.osgi + org.osgi.service.component + provided + org.apache.sling org.apache.sling.api From afa14fc1e201a695e011ffd6761ac608fc1fb1b5 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Fri, 28 Mar 2025 17:00:08 +0100 Subject: [PATCH 5/8] SLING-12730 apply spotless formatting --- pom.xml | 40 +- .../scripting/javascript/SlingWrapper.java | 7 +- .../javascript/helper/ExportsObject.java | 6 +- .../javascript/helper/ModuleObject.java | 22 +- .../javascript/helper/ModuleScope.java | 42 +- .../javascript/helper/SlingContext.java | 5 +- .../helper/SlingContextFactory.java | 14 +- .../javascript/helper/SlingGlobal.java | 570 +++++++++--------- .../javascript/helper/SlingRhinoDebugger.java | 26 +- .../javascript/helper/SlingWrapFactory.java | 10 +- .../internal/RhinoJavaScriptEngine.java | 77 +-- .../RhinoJavaScriptEngineFactory.java | 104 ++-- ...oJavaScriptEngineFactoryConfiguration.java | 15 +- .../scripting/javascript/io/EspReader.java | 68 +-- .../javascript/wrapper/ScriptableBase.java | 34 +- .../wrapper/ScriptableCalendar.java | 82 +-- .../javascript/wrapper/ScriptableItemMap.java | 11 +- .../javascript/wrapper/ScriptableMap.java | 28 +- .../javascript/wrapper/ScriptableNode.java | 82 ++- .../wrapper/ScriptablePrintWriter.java | 60 +- .../wrapper/ScriptableProperty.java | 11 +- .../wrapper/ScriptableResource.java | 38 +- .../javascript/wrapper/ScriptableVersion.java | 32 +- .../wrapper/ScriptableVersionHistory.java | 32 +- .../RepositoryScriptingTestBase.java | 4 +- .../scripting/javascript/TestSetupTest.java | 11 +- .../RhinoJavaScriptEngineFactoryTest.java | 57 +- .../internal/RhinoJavaScriptEngineTest.java | 3 +- .../internal/ScriptEngineHelper.java | 25 +- .../javascript/internal/TestPathRegexp.java | 33 +- .../javascript/io/EspReaderTest.java | 190 +++--- .../javascript/wrapper/ScriptableMapTest.java | 42 +- .../wrapper/ScriptableNodeTest.java | 174 ++---- .../wrapper/ScriptableResourceTest.java | 112 ++-- 34 files changed, 963 insertions(+), 1104 deletions(-) diff --git a/pom.xml b/pom.xml index fbe22d3..0db265e 100644 --- a/pom.xml +++ b/pom.xml @@ -37,30 +37,15 @@ scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-javascript.git scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-javascript.git + HEAD https://github.com/apache/sling-org-apache-sling-scripting-javascript.git - HEAD - + 1.7.7.1_1 8 - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - org.apache.sling.scripting.javascript - - - - - - @@ -207,9 +192,9 @@ org.apache.jackrabbit - oak-jackrabbit-api - 1.72.0 - test + oak-jackrabbit-api + 1.72.0 + test org.apache.jackrabbit @@ -220,8 +205,21 @@ org.apache.jackrabbit jackrabbit-core - 2.19.6 + 2.19.6 test + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.sling.scripting.javascript + + + + diff --git a/src/main/java/org/apache/sling/scripting/javascript/SlingWrapper.java b/src/main/java/org/apache/sling/scripting/javascript/SlingWrapper.java index e2899f4..23b0743 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/SlingWrapper.java +++ b/src/main/java/org/apache/sling/scripting/javascript/SlingWrapper.java @@ -29,12 +29,11 @@ public interface SlingWrapper extends Wrapper { * @return the class name */ String getClassName(); - + /** * The list of Java classes wrapped by this wrapper. * * @return the wrapped classes */ - Class [] getWrappedClasses(); - -} \ No newline at end of file + Class[] getWrappedClasses(); +} diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/ExportsObject.java b/src/main/java/org/apache/sling/scripting/javascript/helper/ExportsObject.java index 36dc935..b48b816 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/ExportsObject.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/ExportsObject.java @@ -26,7 +26,7 @@ public class ExportsObject extends NativeObject { private static final long serialVersionUID = 7608182741100799506L; public ExportsObject(Scriptable parent) { - this.setParentScope(parent); - this.setPrototype(getObjectPrototype(parent)); - } + this.setParentScope(parent); + this.setPrototype(getObjectPrototype(parent)); + } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleObject.java b/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleObject.java index 0ad0db6..ce68513 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleObject.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleObject.java @@ -27,17 +27,17 @@ public class ModuleObject extends NativeObject implements Scriptable { private final ModuleScope module; - ModuleObject(ModuleScope parent) { - setParentScope(parent); - setPrototype(getObjectPrototype(parent)); - this.module = parent; - } + ModuleObject(ModuleScope parent) { + setParentScope(parent); + setPrototype(getObjectPrototype(parent)); + this.module = parent; + } - @Override - protected Object equivalentValues(Object value) { - if (value instanceof String) { - return this.module.getModuleName().equals(value) ? Boolean.TRUE : Boolean.FALSE; - } - return NOT_FOUND; + @Override + protected Object equivalentValues(Object value) { + if (value instanceof String) { + return this.module.getModuleName().equals(value) ? Boolean.TRUE : Boolean.FALSE; } + return NOT_FOUND; + } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleScope.java b/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleScope.java index f6d62f2..fd6135f 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleScope.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/ModuleScope.java @@ -27,33 +27,33 @@ public class ModuleScope extends ImporterTopLevel { private static final long serialVersionUID = -6063613037620927512L; private ExportsObject exports; - private Scriptable module; - private String name; + private Scriptable module; + private String name; - public ModuleScope(Scriptable prototype, String moduleName) { - this.setParentScope(null); - this.setPrototype(prototype); - this.activatePrototypeMap(3); + public ModuleScope(Scriptable prototype, String moduleName) { + this.setParentScope(null); + this.setPrototype(prototype); + this.activatePrototypeMap(3); - this.name = moduleName; + this.name = moduleName; - this.reset(); - } + this.reset(); + } - public Scriptable getExports() { - return this.exports = (ExportsObject) get("exports", this); - } + public Scriptable getExports() { + return this.exports = (ExportsObject) get("exports", this); + } - public void reset() { - this.module = new ModuleObject(this); - int attr = READONLY | PERMANENT; + public void reset() { + this.module = new ModuleObject(this); + int attr = READONLY | PERMANENT; ScriptableObject.defineProperty(this.module, "id", this.getModuleName(), attr); - this.exports = new ExportsObject(this); - this.defineProperty("exports", this.exports, DONTENUM); - } + this.exports = new ExportsObject(this); + this.defineProperty("exports", this.exports, DONTENUM); + } - public String getModuleName() { - return this.name; - } + public String getModuleName() { + return this.name; + } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContext.java b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContext.java index f06c4cf..3a119c9 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContext.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContext.java @@ -30,15 +30,14 @@ public class SlingContext extends Context { @Override - public ScriptableObject initStandardObjects(ScriptableObject scope, - boolean sealed) { + public ScriptableObject initStandardObjects(ScriptableObject scope, boolean sealed) { ScriptableObject rootScope = super.initStandardObjects(scope, sealed); // prepare the ImporterToplevel host object because it will be // used as top level scope for the RhinoJavaScriptEngine but is // not initialized with the rest of the standard objects ImporterTopLevel.init(this, rootScope, sealed); - + // add Sling global objects SlingGlobal.init(rootScope, sealed); diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContextFactory.java b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContextFactory.java index 0ea3c47..82e2bdd 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContextFactory.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingContextFactory.java @@ -51,8 +51,8 @@ public class SlingContextFactory extends ContextFactory { 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, - Context.isValidLanguageVersion(languageVersion) ? languageVersion : Context.VERSION_DEFAULT)); + initGlobal(new SlingContextFactory( + sp, Context.isValidLanguageVersion(languageVersion) ? languageVersion : Context.VERSION_DEFAULT)); } } @@ -72,7 +72,7 @@ private SlingContextFactory(ScopeProvider sp, int languageVersion) { private void dispose() { // ensure the debugger is closed exitDebugger(); - + // reset the context factory class for future use ContextFactory newGlobal = new ContextFactory(); setField(newGlobal, "hasCustomGlobal", Boolean.FALSE); @@ -109,14 +109,12 @@ private void initDebugger(Context cx) { if (isDebugging()) { try { if (debugger == null) { - debugger = new SlingRhinoDebugger( - getClass().getSimpleName()); + debugger = new SlingRhinoDebugger(getClass().getSimpleName()); debugger.setScopeProvider(scopeProvider); debugger.attachTo(this); } } catch (Exception e) { - log.warn("initDebugger: Failed setting up the Rhino debugger", - e); + log.warn("initDebugger: Failed setting up the Rhino debugger", e); } } } @@ -129,7 +127,7 @@ public void exitDebugger() { debugger = null; } } - + void debuggerStopped() { debugger = null; } diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingGlobal.java b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingGlobal.java index 9609cf6..cb945e6 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingGlobal.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingGlobal.java @@ -63,300 +63,278 @@ * */ public class SlingGlobal implements Serializable, IdFunctionCall { - static final long serialVersionUID = 6080442165748707530L; - - private static final Object FTAG = new Object(); - - private static final int Id_load = 1; - - private static final int Id_print = 2; - - private static final int Id_require = 3; - - private static final int LAST_SCOPE_FUNCTION_ID = 3; - - /** default log */ - private static final Logger defaultLog = LoggerFactory.getLogger(SlingGlobal.class); - - public static void init(Scriptable scope, boolean sealed) { - SlingGlobal obj = new SlingGlobal(); - - for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) { - String name; - int arity = 1; - switch (id) { - case Id_load: - name = "load"; - break; - case Id_print: - name = "print"; - break; - case Id_require: - name = "require"; - break; - default: - throw Kit.codeBug(); - } - IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name, - arity, scope); - if (sealed) { - f.sealObject(); - } - f.exportAsScopeProperty(); - } - - } - - public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) { - if (f.hasTag(FTAG)) { - int methodId = f.methodId(); - switch (methodId) { - case Id_load: { - load(cx, thisObj, args); - return Context.getUndefinedValue(); - } - - case Id_print: { - print(cx, thisObj, args); - return Context.getUndefinedValue(); - } - - case Id_require: { - return require(cx, thisObj, args); - } - } - } - throw f.unknown(); - } - - private void print(Context cx, Scriptable thisObj, Object[] args) { - StringBuffer message = new StringBuffer(); - for (int i = 0; i < args.length; i++) { - if (i > 0) { - message.append(" "); - } - // Convert the arbitrary JavaScript value into a string form. - String s = ScriptRuntime.toString(args[i]); - - message.append(s); - } - - getLogger(cx, thisObj).info(message.toString()); - } - - private void load(Context cx, Scriptable thisObj, Object[] args) { - - SlingScriptHelper sling = getProperty(cx, thisObj, SlingBindings.SLING, - SlingScriptHelper.class); - if (sling == null) { - throw new NullPointerException(SlingBindings.SLING); - } - - Scriptable globalScope = ScriptableObject.getTopLevelScope(thisObj); - - Resource scriptResource = sling.getScript().getScriptResource(); - ResourceResolver resolver = scriptResource.getResourceResolver(); - - // the path of the current script to resolve realtive paths - String currentScript = sling.getScript().getScriptResource().getPath(); - String scriptParent = ResourceUtil.getParent(currentScript); - - for (Object arg : args) { - String scriptName = ScriptRuntime.toString(arg); - - Resource loadScript = null; - if (!scriptName.startsWith("/")) { - String absScriptName = scriptParent + "/" + scriptName; - loadScript = resolver.resolve(absScriptName); - } - - // not resolved relative to the current script - if (loadScript == null) { - loadScript = resolver.resolve(scriptName); - } - - if (loadScript == null) { - throw Context.reportRuntimeError("Script file " + scriptName - + " not found"); - } - - InputStream scriptStream = loadScript.adaptTo(InputStream.class); - if (scriptStream == null) { - throw Context.reportRuntimeError("Script file " + scriptName - + " cannot be read from"); - } - - try { - // reader for the stream - Reader scriptReader = new InputStreamReader(scriptStream, Charset.forName("UTF-8")); - - // check whether we have to wrap the basic reader - if (scriptName - .endsWith(RhinoJavaScriptEngineFactory.ESP_SCRIPT_EXTENSION)) { - scriptReader = new EspReader(scriptReader); - } - - // read the suff buffered for better performance - scriptReader = new BufferedReader(scriptReader); - - // now, let's go - cx.evaluateReader(globalScope, scriptReader, scriptName, 1, - null); - - } catch (IOException ioe) { - - throw Context.reportRuntimeError("Failure reading file " - + scriptName + ": " + ioe); - - } finally { - // ensure the script input stream is closed - try { - scriptStream.close(); - } catch (IOException ignore) { - } - } - } - } - - public Object require(Context cx, Scriptable thisObj, Object[] args) { - if (args.length != 1 || !(args[0] instanceof String)) { - throw Context - .reportRuntimeError("require() requires a String argument"); - } - String modulePath = (String) args[0]; - - ModuleScope moduleScope = null; - if (thisObj instanceof ModuleScope) { - moduleScope = (ModuleScope) thisObj; - } - - ModuleScope module = loadModule(cx, modulePath.trim(), moduleScope, - thisObj); - return module.getExports(); - } - - private ModuleScope loadModule(Context cx, String modulePath, - ModuleScope moduleScope, Scriptable thisObj) { - String absolutePath = modulePath; - if (modulePath.startsWith(".")) { - // relative - if (moduleScope == null) { - throw Context - .reportRuntimeError("Cannot resolve relative module name outside of a module scope."); - } - absolutePath = (moduleScope.getModuleName() + "/" + modulePath) - .replaceAll("[^/]*/\\./", ""); - while (absolutePath.matches("([^/]*/)?[^/]*/\\.\\./")) { - absolutePath = absolutePath - .replaceAll("([^/]*/)?[^/]*/\\.\\./", ""); - } - } - absolutePath = absolutePath + ".js"; - - SlingScriptHelper sling = getProperty(cx, thisObj, SlingBindings.SLING, - SlingScriptHelper.class); - if (sling == null) { - throw new NullPointerException(SlingBindings.SLING); - } - ResourceResolver resrev = sling.getScript().getScriptResource().getResourceResolver(); - - Resource script = null; - String scriptName = null; - for (String basepath : resrev.getSearchPath()) { - script = resrev.resolve(basepath + absolutePath); - if (script!=null&&!(script instanceof NonExistingResource)) { - scriptName = basepath + absolutePath; - break; - } - } - if (script==null) { - throw Context.reportRuntimeError("Unable to resolve module " + absolutePath + " in search path"); - } - - InputStream scriptStream = script.adaptTo(InputStream.class); - if (scriptStream == null) { - //try once again - scriptStream = resrev.resolve(scriptName).adaptTo(InputStream.class); - if (scriptStream==null) { - throw Context.reportRuntimeError("Script file " + script.getPath() - + " cannot be read"); - } - } - - - try { - // reader for the stream - Reader scriptReader = new InputStreamReader(scriptStream, Charset.forName("UTF-8")); - - // check whether we have to wrap the basic reader - if (scriptName - .endsWith(RhinoJavaScriptEngineFactory.ESP_SCRIPT_EXTENSION)) { - scriptReader = new EspReader(scriptReader); - } - - // read the suff buffered for better performance - scriptReader = new BufferedReader(scriptReader); - - //TODO: execute script with ModuleScope - // now, let's go - - ModuleScope scope = moduleScope; - if (scope==null) { - scope = new ModuleScope(thisObj, absolutePath.substring(0, absolutePath.length() - 3)); - } else { - scope.reset(); - } - - cx.evaluateReader(scope, scriptReader, scriptName, 1, - null); - - return scope; - - } catch (IOException ioe) { - - throw Context.reportRuntimeError("Failure reading file " - + scriptName + ": " + ioe); - - } finally { - // ensure the script input stream is closed - try { - scriptStream.close(); - } catch (IOException ignore) { - } - } - } - - /** - * Returns the script logger or the logger of this class as a fallback - * default if the global log variable is not accessible. - */ - private Logger getLogger(Context cx, Scriptable scope) { - Logger log = getProperty(cx, scope, SlingBindings.LOG, Logger.class); - if (log == null) { - log = this.defaultLog; - } - return log; - } - - /** - * Returns the named toplevel property converted to the requested - * type or null if no such property exists or the - * property is of the wrong type. - */ - @SuppressWarnings("unchecked") - private Type getProperty(Context cx, Scriptable scope, String name, - Class type) { - Object prop = ScriptRuntime.name(cx, scope, name); - - if (prop instanceof Wrapper) { - prop = ((Wrapper) prop).unwrap(); - } - - if (type.isInstance(prop)) { - return (Type) prop; // unchecked case - } - - return null; - } + static final long serialVersionUID = 6080442165748707530L; + + private static final Object FTAG = new Object(); + + private static final int Id_load = 1; + + private static final int Id_print = 2; + + private static final int Id_require = 3; + + private static final int LAST_SCOPE_FUNCTION_ID = 3; + + /** default log */ + private static final Logger defaultLog = LoggerFactory.getLogger(SlingGlobal.class); + + public static void init(Scriptable scope, boolean sealed) { + SlingGlobal obj = new SlingGlobal(); + + for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) { + String name; + int arity = 1; + switch (id) { + case Id_load: + name = "load"; + break; + case Id_print: + name = "print"; + break; + case Id_require: + name = "require"; + break; + default: + throw Kit.codeBug(); + } + IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name, arity, scope); + if (sealed) { + f.sealObject(); + } + f.exportAsScopeProperty(); + } + } + + public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { + if (f.hasTag(FTAG)) { + int methodId = f.methodId(); + switch (methodId) { + case Id_load: { + load(cx, thisObj, args); + return Context.getUndefinedValue(); + } + + case Id_print: { + print(cx, thisObj, args); + return Context.getUndefinedValue(); + } + + case Id_require: { + return require(cx, thisObj, args); + } + } + } + throw f.unknown(); + } + + private void print(Context cx, Scriptable thisObj, Object[] args) { + StringBuffer message = new StringBuffer(); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + message.append(" "); + } + // Convert the arbitrary JavaScript value into a string form. + String s = ScriptRuntime.toString(args[i]); + + message.append(s); + } + + getLogger(cx, thisObj).info(message.toString()); + } + + private void load(Context cx, Scriptable thisObj, Object[] args) { + + SlingScriptHelper sling = getProperty(cx, thisObj, SlingBindings.SLING, SlingScriptHelper.class); + if (sling == null) { + throw new NullPointerException(SlingBindings.SLING); + } + + Scriptable globalScope = ScriptableObject.getTopLevelScope(thisObj); + + Resource scriptResource = sling.getScript().getScriptResource(); + ResourceResolver resolver = scriptResource.getResourceResolver(); + + // the path of the current script to resolve realtive paths + String currentScript = sling.getScript().getScriptResource().getPath(); + String scriptParent = ResourceUtil.getParent(currentScript); + + for (Object arg : args) { + String scriptName = ScriptRuntime.toString(arg); + + Resource loadScript = null; + if (!scriptName.startsWith("/")) { + String absScriptName = scriptParent + "/" + scriptName; + loadScript = resolver.resolve(absScriptName); + } + + // not resolved relative to the current script + if (loadScript == null) { + loadScript = resolver.resolve(scriptName); + } + + if (loadScript == null) { + throw Context.reportRuntimeError("Script file " + scriptName + " not found"); + } + + InputStream scriptStream = loadScript.adaptTo(InputStream.class); + if (scriptStream == null) { + throw Context.reportRuntimeError("Script file " + scriptName + " cannot be read from"); + } + + try { + // reader for the stream + Reader scriptReader = new InputStreamReader(scriptStream, Charset.forName("UTF-8")); + + // check whether we have to wrap the basic reader + if (scriptName.endsWith(RhinoJavaScriptEngineFactory.ESP_SCRIPT_EXTENSION)) { + scriptReader = new EspReader(scriptReader); + } + + // read the suff buffered for better performance + scriptReader = new BufferedReader(scriptReader); + + // now, let's go + cx.evaluateReader(globalScope, scriptReader, scriptName, 1, null); + + } catch (IOException ioe) { + + throw Context.reportRuntimeError("Failure reading file " + scriptName + ": " + ioe); + + } finally { + // ensure the script input stream is closed + try { + scriptStream.close(); + } catch (IOException ignore) { + } + } + } + } + + public Object require(Context cx, Scriptable thisObj, Object[] args) { + if (args.length != 1 || !(args[0] instanceof String)) { + throw Context.reportRuntimeError("require() requires a String argument"); + } + String modulePath = (String) args[0]; + + ModuleScope moduleScope = null; + if (thisObj instanceof ModuleScope) { + moduleScope = (ModuleScope) thisObj; + } + + ModuleScope module = loadModule(cx, modulePath.trim(), moduleScope, thisObj); + return module.getExports(); + } + + private ModuleScope loadModule(Context cx, String modulePath, ModuleScope moduleScope, Scriptable thisObj) { + String absolutePath = modulePath; + if (modulePath.startsWith(".")) { + // relative + if (moduleScope == null) { + throw Context.reportRuntimeError("Cannot resolve relative module name outside of a module scope."); + } + absolutePath = (moduleScope.getModuleName() + "/" + modulePath).replaceAll("[^/]*/\\./", ""); + while (absolutePath.matches("([^/]*/)?[^/]*/\\.\\./")) { + absolutePath = absolutePath.replaceAll("([^/]*/)?[^/]*/\\.\\./", ""); + } + } + absolutePath = absolutePath + ".js"; + + SlingScriptHelper sling = getProperty(cx, thisObj, SlingBindings.SLING, SlingScriptHelper.class); + if (sling == null) { + throw new NullPointerException(SlingBindings.SLING); + } + ResourceResolver resrev = sling.getScript().getScriptResource().getResourceResolver(); + + Resource script = null; + String scriptName = null; + for (String basepath : resrev.getSearchPath()) { + script = resrev.resolve(basepath + absolutePath); + if (script != null && !(script instanceof NonExistingResource)) { + scriptName = basepath + absolutePath; + break; + } + } + if (script == null) { + throw Context.reportRuntimeError("Unable to resolve module " + absolutePath + " in search path"); + } + + InputStream scriptStream = script.adaptTo(InputStream.class); + if (scriptStream == null) { + // try once again + scriptStream = resrev.resolve(scriptName).adaptTo(InputStream.class); + if (scriptStream == null) { + throw Context.reportRuntimeError("Script file " + script.getPath() + " cannot be read"); + } + } + + try { + // reader for the stream + Reader scriptReader = new InputStreamReader(scriptStream, Charset.forName("UTF-8")); + + // check whether we have to wrap the basic reader + if (scriptName.endsWith(RhinoJavaScriptEngineFactory.ESP_SCRIPT_EXTENSION)) { + scriptReader = new EspReader(scriptReader); + } + + // read the suff buffered for better performance + scriptReader = new BufferedReader(scriptReader); + + // TODO: execute script with ModuleScope + // now, let's go + + ModuleScope scope = moduleScope; + if (scope == null) { + scope = new ModuleScope(thisObj, absolutePath.substring(0, absolutePath.length() - 3)); + } else { + scope.reset(); + } + + cx.evaluateReader(scope, scriptReader, scriptName, 1, null); + + return scope; + + } catch (IOException ioe) { + + throw Context.reportRuntimeError("Failure reading file " + scriptName + ": " + ioe); + + } finally { + // ensure the script input stream is closed + try { + scriptStream.close(); + } catch (IOException ignore) { + } + } + } + + /** + * Returns the script logger or the logger of this class as a fallback + * default if the global log variable is not accessible. + */ + private Logger getLogger(Context cx, Scriptable scope) { + Logger log = getProperty(cx, scope, SlingBindings.LOG, Logger.class); + if (log == null) { + log = this.defaultLog; + } + return log; + } + + /** + * Returns the named toplevel property converted to the requested + * type or null if no such property exists or the + * property is of the wrong type. + */ + @SuppressWarnings("unchecked") + private Type getProperty(Context cx, Scriptable scope, String name, Class type) { + Object prop = ScriptRuntime.name(cx, scope, name); + + if (prop instanceof Wrapper) { + prop = ((Wrapper) prop).unwrap(); + } + + if (type.isInstance(prop)) { + return (Type) prop; // unchecked case + } + + return null; + } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingRhinoDebugger.java b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingRhinoDebugger.java index 3c7b0cd..2e17d02 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingRhinoDebugger.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingRhinoDebugger.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.helper; diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java index 6510373..d6e29c4 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java +++ b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java @@ -47,8 +47,7 @@ public class SlingWrapFactory extends WrapFactory { */ @SuppressWarnings("unchecked") @Override - public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, - Object javaObject, Class staticType) { + public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class staticType) { Scriptable result = null; try { @@ -59,8 +58,7 @@ public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, } if (hostObjectName != null) { - result = cx.newObject(scope, hostObjectName, - new Object[] { javaObject }); + result = cx.newObject(scope, hostObjectName, new Object[] {javaObject}); } } catch (Exception e) { log.warn("Cannot Wrap " + javaObject, e); @@ -74,13 +72,13 @@ public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, } private String getHostObjectName(Class javaClass) { - if(javaClass==null || isExcluded(javaClass)) { + if (javaClass == null || isExcluded(javaClass)) { return null; } String hostObjectName = wrappers.get(javaClass); if (hostObjectName == null) { // before SLING-383 the superclass was tested first, - // but for Version and VersionHistory this would get + // but for Version and VersionHistory this would get // a Node wrapper, that's not what we want final Class[] javaInterfaces = javaClass.getInterfaces(); for (int i = 0; i < javaInterfaces.length && hostObjectName == null; i++) { diff --git a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java index fddce2b..b9ddcd7 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java +++ b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java @@ -1,28 +1,23 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.internal; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - import javax.script.Bindings; import javax.script.Compilable; import javax.script.CompiledScript; @@ -31,6 +26,13 @@ import javax.script.ScriptEngineFactory; import javax.script.ScriptException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + import org.apache.commons.io.IOUtils; import org.apache.sling.api.scripting.LazyBindings; import org.apache.sling.api.scripting.SlingBindings; @@ -94,7 +96,7 @@ public CompiledScript compile(Reader scriptReader) throws ScriptException { scriptReader = wrapReaderIfEspScript(scriptReader, scriptName); try { final Context rhinoContext = Context.enter(); - rhinoContext.setLanguageVersion(((RhinoJavaScriptEngineFactory)getFactory()).rhinoLanguageVersion()); + rhinoContext.setLanguageVersion(((RhinoJavaScriptEngineFactory) getFactory()).rhinoLanguageVersion()); rhinoContext.setOptimizationLevel(optimizationLevel()); if (!ScriptRuntime.hasTopCall(rhinoContext)) { @@ -126,7 +128,8 @@ public CompiledScript getCompiledScript() { LOGGER.debug("Added {} script to Script Cache.", scriptName); return slingCompiledScript; } catch (IOException e) { - final ScriptException se = new ScriptException("Failure running script " + scriptName + ": " + e.getMessage()); + final ScriptException se = + new ScriptException("Failure running script " + scriptName + ": " + e.getMessage()); se.initCause(e); throw se; } finally { @@ -140,7 +143,8 @@ public Object eval(Reader scriptReader, ScriptContext scriptContext) throws Scri Reader reader = wrapReaderIfEspScript(scriptReader, scriptName); if (!(scriptReader instanceof ScriptNameAware)) { if (NO_SCRIPT_NAME.equals(scriptName)) { - String script = (String) scriptContext.getBindings(ScriptContext.ENGINE_SCOPE).get(ScriptEngine.FILENAME); + String script = (String) + scriptContext.getBindings(ScriptContext.ENGINE_SCOPE).get(ScriptEngine.FILENAME); if (script != null) { for (String extension : getFactory().getExtensions()) { if (script.endsWith(extension)) { @@ -162,8 +166,7 @@ private Reader wrapReaderIfEspScript(Reader scriptReader, String scriptName) { return scriptReader; } - private Map setBoundProperties(Scriptable scope, - Bindings bindings) { + private Map setBoundProperties(Scriptable scope, Bindings bindings) { Map replacedProperties = new HashMap(); for (Object entryObject : bindings.entrySet()) { @@ -177,8 +180,7 @@ private Map setBoundProperties(Scriptable scope, if (value != null) { // get the current property value, if set if (ScriptableObject.hasProperty(scope, name)) { - replacedProperties.put(name, ScriptableObject.getProperty( - scope, name)); + replacedProperties.put(name, ScriptableObject.getProperty(scope, name)); } // wrap the new value and set it @@ -207,18 +209,16 @@ private void getBoundProperties(Scriptable scope, Bindings bindings) { } } - private void resetBoundProperties(Scriptable scope, - Map properties) { + private void resetBoundProperties(Scriptable scope, Map properties) { if (scope != null && properties != null && properties.size() > 0) { for (Entry entry : properties.entrySet()) { - ScriptableObject.putProperty(scope, entry.getKey(), - entry.getValue()); + ScriptableObject.putProperty(scope, entry.getKey(), entry.getValue()); } } } private int optimizationLevel() { - return ((RhinoJavaScriptEngineFactory)getFactory()).getOptimizationLevel(); + return ((RhinoJavaScriptEngineFactory) getFactory()).getOptimizationLevel(); } private class SlingCompiledScript extends CompiledScript { @@ -244,7 +244,7 @@ public Object eval(ScriptContext scriptContext) throws ScriptException { try { final Context rhinoContext = Context.enter(); - rhinoContext.setLanguageVersion(((RhinoJavaScriptEngineFactory)getFactory()).rhinoLanguageVersion()); + rhinoContext.setLanguageVersion(((RhinoJavaScriptEngineFactory) getFactory()).rhinoLanguageVersion()); rhinoContext.setOptimizationLevel(optimizationLevel()); if (ScriptRuntime.hasTopCall(rhinoContext)) { @@ -288,8 +288,7 @@ public Object eval(ScriptContext scriptContext) throws ScriptException { // prevent variables to be pushed back in case of errors isTopLevelCall = false; - final ScriptException se = new ScriptException(t.details(), - t.sourceName(), t.lineNumber()); + final ScriptException se = new ScriptException(t.details(), t.sourceName(), t.lineNumber()); // log the script stack trace ((Logger) bindings.get(SlingBindings.LOG)).error(t.getScriptStackTrace()); @@ -317,7 +316,8 @@ public Object eval(ScriptContext scriptContext) throws ScriptException { // prevent variables to be pushed back in case of errors isTopLevelCall = false; String scriptName = getScriptName(scriptContext); - 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; @@ -342,8 +342,9 @@ public Object eval(ScriptContext scriptContext) throws ScriptException { if (scope != null) { ClassCache classCache = ClassCache.get(scope); classCache.clearCaches(); - LOGGER.info("Detected dirty class loader on thread {}. Emptying Rhino's class cache.", Thread.currentThread() - .getName()); + LOGGER.info( + "Detected dirty class loader on thread {}. Emptying Rhino's class cache.", + Thread.currentThread().getName()); } } } @@ -358,7 +359,7 @@ public ScriptEngine getEngine() { } private String getScriptName(Reader scriptReader) { - if(scriptReader instanceof ScriptNameAware){ + if (scriptReader instanceof ScriptNameAware) { return ((ScriptNameAware) scriptReader).getScriptName(); } return NO_SCRIPT_NAME; diff --git a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java index d8b0198..f8f8435 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java +++ b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java @@ -18,6 +18,9 @@ */ package org.apache.sling.scripting.javascript.internal; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; + import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -30,9 +33,6 @@ 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; @@ -72,48 +72,50 @@ import org.slf4j.LoggerFactory; @Component( - service = ScriptEngineFactory.class, - property = { - Constants.SERVICE_DESCRIPTION + "=Apache Sling Rhino Javascript Engine Factory", - 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", - "names=ECMAScript" - }, - reference = @Reference( - name = "HostObjectProvider", - service = RhinoHostObjectProvider.class, - cardinality = ReferenceCardinality.MULTIPLE, - policy = ReferencePolicy.DYNAMIC, - bind = "addHostObjectProvider", - unbind = "removeHostObjectProvider" - ) -) -@Designate( - ocd = RhinoJavaScriptEngineFactoryConfiguration.class -) + service = ScriptEngineFactory.class, + property = { + Constants.SERVICE_DESCRIPTION + "=Apache Sling Rhino Javascript Engine Factory", + 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", + "names=ECMAScript" + }, + reference = + @Reference( + name = "HostObjectProvider", + service = RhinoHostObjectProvider.class, + cardinality = ReferenceCardinality.MULTIPLE, + policy = ReferencePolicy.DYNAMIC, + bind = "addHostObjectProvider", + unbind = "removeHostObjectProvider")) +@Designate(ocd = RhinoJavaScriptEngineFactoryConfiguration.class) public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory implements ScopeProvider { - public final static int DEFAULT_OPTIMIZATION_LEVEL = 9; + public static final int DEFAULT_OPTIMIZATION_LEVEL = 9; - public final static String ECMA_SCRIPT_EXTENSION = "ecma"; + public static final String ECMA_SCRIPT_EXTENSION = "ecma"; - public final static String ESP_SCRIPT_EXTENSION = "esp"; + public static final String ESP_SCRIPT_EXTENSION = "esp"; private static final Class[] HOSTOBJECT_CLASSES = { - ScriptableResource.class, ScriptableNode.class, - ScriptableProperty.class, ScriptableItemMap.class, - ScriptablePrintWriter.class, ScriptableVersionHistory.class, - ScriptableVersion.class, ScriptableCalendar.class, ScriptableMap.class + ScriptableResource.class, + ScriptableNode.class, + ScriptableProperty.class, + ScriptableItemMap.class, + ScriptablePrintWriter.class, + ScriptableVersionHistory.class, + ScriptableVersion.class, + ScriptableCalendar.class, + ScriptableMap.class }; /** @@ -127,7 +129,6 @@ public class RhinoJavaScriptEngineFactory extends AbstractScriptEngineFactory im private static final String LANGUAGE_VERSION = "partial ECMAScript 2015 support"; private static final String LANGUAGE_NAME = "ECMAScript"; - private SlingWrapFactory wrapFactory; private Scriptable rootScope; @@ -262,15 +263,18 @@ private void dropRootScope() { // ---------- SCR integration @Activate - protected void activate(final ComponentContext context, final RhinoJavaScriptEngineFactoryConfiguration configuration) { + protected void activate( + final ComponentContext context, final RhinoJavaScriptEngineFactoryConfiguration configuration) { Dictionary props = context.getProperties(); - boolean debugging = getProperty("org.apache.sling.scripting.javascript.debug", props, context.getBundleContext(), false); + 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 { - Enumeration resources = RhinoJavaScriptEngineFactory.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); + Enumeration resources = + RhinoJavaScriptEngineFactory.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { try { URL url = resources.nextElement(); @@ -398,8 +402,7 @@ private void addHostObjects(Scriptable scope, Class[] clas } } - private void addImportedClasses(Context cx, Scriptable scope, - Class[] classes) { + private void addImportedClasses(Context cx, Scriptable scope, Class[] classes) { if (classes != null && classes.length > 0) { NativeJavaClass[] np = new NativeJavaClass[classes.length]; for (int i = 0; i < classes.length; i++) { @@ -409,8 +412,7 @@ private void addImportedClasses(Context cx, Scriptable scope, } } - private void addImportedPackages(Context cx, Scriptable scope, - String[] packages) { + private void addImportedPackages(Context cx, Scriptable scope, String[] packages) { if (packages != null && packages.length > 0) { NativeJavaPackage[] np = new NativeJavaPackage[packages.length]; for (int i = 0; i < packages.length; i++) { @@ -420,16 +422,14 @@ private void addImportedPackages(Context cx, Scriptable scope, } } - private boolean getProperty(String name, Dictionary props, - BundleContext bundleContext, boolean defaultValue) { + private boolean getProperty( + String name, Dictionary props, BundleContext bundleContext, boolean defaultValue) { Object value = props.get(name); if (value == null) { value = bundleContext.getProperty(name); } - return (value != null) - ? Boolean.parseBoolean(String.valueOf(value)) - : defaultValue; + return (value != null) ? Boolean.parseBoolean(String.valueOf(value)) : defaultValue; } private int readOptimizationLevel(final RhinoJavaScriptEngineFactoryConfiguration configuration) { diff --git a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryConfiguration.java b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryConfiguration.java index dc41745..13c6f8d 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryConfiguration.java +++ b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryConfiguration.java @@ -22,15 +22,14 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition( - name = "Apache Sling Rhino JavaScript Engine Factory", - description = "JavaScript engine based on Rhino" -) + name = "Apache Sling Rhino JavaScript Engine Factory", + description = "JavaScript engine based on Rhino") @interface RhinoJavaScriptEngineFactoryConfiguration { @AttributeDefinition( - name = "Rhino optimization level", - description = "The level of optimization for the bytecode generated by Rhino. Provide values between 0-9, 9 being the most aggressive level of optimization. A value of -1 will run scripts in interpreted mode." - ) - int org_apache_sling_scripting_javascript_rhino_optLevel() default RhinoJavaScriptEngineFactory.DEFAULT_OPTIMIZATION_LEVEL; - + name = "Rhino optimization level", + description = + "The level of optimization for the bytecode generated by Rhino. Provide values between 0-9, 9 being the most aggressive level of optimization. A value of -1 will run scripts in interpreted mode.") + int org_apache_sling_scripting_javascript_rhino_optLevel() default + RhinoJavaScriptEngineFactory.DEFAULT_OPTIMIZATION_LEVEL; } diff --git a/src/main/java/org/apache/sling/scripting/javascript/io/EspReader.java b/src/main/java/org/apache/sling/scripting/javascript/io/EspReader.java index 38beb47..6cb1c12 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/io/EspReader.java +++ b/src/main/java/org/apache/sling/scripting/javascript/io/EspReader.java @@ -90,7 +90,7 @@ public class EspReader extends FilterReader { private static final byte PARSE_STATE_ECMA_EXPR = 3; /** - * Compact ESP expression syntax similar to JSP Expression Language notation + * Compact ESP expression syntax similar to JSP Expression Language notation */ private static final byte PARSE_STATE_ECMA_EXPR_COMPACT = 4; @@ -127,7 +127,7 @@ public class EspReader extends FilterReader { * comment is read (and completely returned). */ private static final byte PARSE_STATE_ECMA_COMMENTL = 9; - + /** * To work with lookahead and character insertion, we use a PushbackReader. */ @@ -183,13 +183,14 @@ public class EspReader extends FilterReader { * @see #startWrite(String) */ private boolean outUndefined = true; - + /** * Javascript statement that sets the "out" variable that's used * to output data. Automatically inserted by the reader in code, * where needed. */ - public static final String DEFAULT_OUT_INIT_STATEMENT = "out=response.writer;"; + public static final String DEFAULT_OUT_INIT_STATEMENT = "out=response.writer;"; + private String outInitStatement = DEFAULT_OUT_INIT_STATEMENT; /** @@ -212,7 +213,7 @@ public EspReader(Reader baseReader) { // Start in ESP (template text) state pushState(PARSE_STATE_ESP); } - + /** * Set the code fragment used to initialize the "out" variable * @@ -290,8 +291,7 @@ public int read(char[] cbuf, int off, int len) throws java.io.IOException { ensureOpen(); // Check lines (taken from InputStreamReader ;-) - if ((off < 0) || (off > cbuf.length) || (len < 0) - || ((off + len) > cbuf.length) || ((off + len) < 0)) { + if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; @@ -398,7 +398,7 @@ public void reset() throws IOException { private int doRead() throws IOException { // we return out of the loop, if we find a character passing the filter - for (;;) { + for (; ; ) { // Get a character from the input, which may well have been // injected using the unread() method @@ -421,15 +421,15 @@ private int doRead() throws IOException { // Do the finite state machine switch (state) { - // NOTE : - // - continue means ignore current character, read next - // - break means return current character + // NOTE : + // - continue means ignore current character, read next + // - break means return current character - // Template text state - text is wrapped in out.write() + // Template text state - text is wrapped in out.write() case PARSE_STATE_ESP: if (c == '$') { // might start EL-like ECMA expr - int c2 = input.read(); - if (c2 == '{') { + int c2 = input.read(); + if (c2 == '{') { // ECMA expression ${ ... } pushState(PARSE_STATE_ECMA_EXPR_COMPACT); startWrite(null); @@ -437,11 +437,11 @@ private int doRead() throws IOException { doVerbatim("\");"); } continue; - } - - input.unread(c2); + } - } else if (c == '<') { // might start ECMA code/expr, ESP comment or JSP comment + input.unread(c2); + + } else if (c == '<') { // might start ECMA code/expr, ESP comment or JSP comment int c2 = input.read(); int c3 = input.read(); @@ -467,7 +467,6 @@ private int doRead() throws IOException { continue; } input.unread(c4); - } // We only get here if we are sure about ECMA @@ -479,7 +478,6 @@ private int doRead() throws IOException { doVerbatim("\");"); } continue; - } // Nothing special, push back read ahead @@ -525,7 +523,6 @@ private int doRead() throws IOException { doVerbatim(String.valueOf((char) c)); c = '\\'; - } // If in template text at the beginning of a line @@ -537,10 +534,9 @@ private int doRead() throws IOException { break; - // Reading ECMA code or and ECMA expression + // Reading ECMA code or and ECMA expression case PARSE_STATE_ECMA_EXPR: case PARSE_STATE_ECMA: - if (c == '%') { // might return to PARSE_STATE_ESP @@ -556,7 +552,6 @@ private int doRead() throws IOException { lineStart = true; continue; - } // false alert, push back @@ -583,13 +578,12 @@ private int doRead() throws IOException { escape = false; // start unescaped quoteChar = (char) c; // to recognize the end pushState(PARSE_STATE_QUOTE); - } break; - // reading compact (EL-like) ECMA Expression + // reading compact (EL-like) ECMA Expression case PARSE_STATE_ECMA_EXPR_COMPACT: - if (c == '}') { //might be the end of a compact expression + if (c == '}') { // might be the end of a compact expression // An expression is wrapped in out.write() popState(); doVerbatim(");"); @@ -598,11 +592,10 @@ private int doRead() throws IOException { lineStart = true; continue; - } break; - // Reading a JSP comment, only returning line endings + // Reading a JSP comment, only returning line endings case PARSE_STATE_JSP_COMMENT: // JSP comments end complexly with --%> @@ -617,7 +610,6 @@ private int doRead() throws IOException { // we really reached the end ... popState(); continue; - } input.unread(c4); } @@ -656,7 +648,7 @@ private int doRead() throws IOException { break; - // Return characters unfiltered + // Return characters unfiltered case PARSE_STATE_VERBATIM: // Go back to previous state if all characters read @@ -666,7 +658,7 @@ private int doRead() throws IOException { break; - // Return an ECMA multiline comment, ending with */ + // Return an ECMA multiline comment, ending with */ case PARSE_STATE_ECMA_COMMENT: // Might be the end of the comment @@ -682,7 +674,7 @@ private int doRead() throws IOException { break; - // Return an ECMA single line comment, ending with end of line + // Return an ECMA single line comment, ending with end of line case PARSE_STATE_ECMA_COMMENTL: // CRLF recognition @@ -699,8 +691,8 @@ private int doRead() throws IOException { } break; - - // What ???!!! + + // What ???!!! default: // we warn and go back to default state @@ -708,14 +700,11 @@ private int doRead() throws IOException { state = PARSE_STATE_ESP; break; - } // switch // Exiting the switch normally we return the current character return c; - } // for(;;) - } /** @@ -804,5 +793,4 @@ private byte popState() { state = stateStack.isEmpty() ? PARSE_STATE_ESP : stateStack.pop(); return oldState; } - -} \ No newline at end of file +} diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java index 42edafc..6fe7c82 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; @@ -37,11 +39,11 @@ public abstract class ScriptableBase extends ScriptableObject { protected synchronized Object getNative(String name, Scriptable start) { final Object wrapped = getWrappedObject(); - if(wrapped == null) { + if (wrapped == null) { return Scriptable.NOT_FOUND; } - if(jsMethods.contains(name)) { + if (jsMethods.contains(name)) { return Scriptable.NOT_FOUND; } @@ -65,8 +67,8 @@ protected synchronized Object getNative(String name, Scriptable start) { private Set getJsMethodNames() { final Set result = new HashSet(); - for(Method m : getClass().getMethods()) { - if(m.getName().startsWith(JSFUNC_PREFIX)) { + for (Method m : getClass().getMethods()) { + if (m.getName().startsWith(JSFUNC_PREFIX)) { result.add(m.getName().substring(JSFUNC_PREFIX.length())); } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableCalendar.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableCalendar.java index 056c38b..dcdda76 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableCalendar.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableCalendar.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; @@ -29,8 +31,8 @@ @SuppressWarnings("serial") public class ScriptableCalendar extends ScriptableBase implements SlingWrapper { - public static final String CLASSNAME = "Calendar"; - private SimpleDateFormat calendarFormat; + public static final String CLASSNAME = "Calendar"; + private SimpleDateFormat calendarFormat; /** Used to format date values */ static final String ECMA_DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z"; @@ -38,19 +40,19 @@ public class ScriptableCalendar extends ScriptableBase implements SlingWrapper { /** The Locale used to format date values */ static final Locale DATE_FORMAT_LOCALE = Locale.US; - /** Calendar is a class, not an interface - so we need to enumerate possible implementations here */ - private static final Class [] WRAPPED_CLASSES = { Calendar.class, GregorianCalendar.class }; + /** Calendar is a class, not an interface - so we need to enumerate possible implementations here */ + private static final Class[] WRAPPED_CLASSES = {Calendar.class, GregorianCalendar.class}; /** * The wrapped Calendar. Will be {@code null} if the * {@link #jsConstructor(Object)} method is not called, which particularly * is the case for the Calendar host object prototype. */ - private Calendar calendar; + private Calendar calendar; public Class[] getWrappedClasses() { - return WRAPPED_CLASSES; - } + return WRAPPED_CLASSES; + } public void jsConstructor(Object o) { this.calendar = (Calendar) o; @@ -61,51 +63,51 @@ public Object get(String name, Scriptable start) { // builtin javascript properties (jsFunction_ etc.) have priority final Object fromSuperclass = super.get(name, start); - if(fromSuperclass != Scriptable.NOT_FOUND) { + if (fromSuperclass != Scriptable.NOT_FOUND) { return fromSuperclass; } - if(calendar == null) { + if (calendar == null) { return Undefined.instance; } - if("date".equals(name)) { - return ScriptRuntime.toObject(this, calendar.getTime()); + if ("date".equals(name)) { + return ScriptRuntime.toObject(this, calendar.getTime()); } return getNative(name, start); } - @Override - protected Class getStaticType() { - return Calendar.class; - } + @Override + protected Class getStaticType() { + return Calendar.class; + } - @Override - protected Object getWrappedObject() { - return calendar; - } + @Override + protected Object getWrappedObject() { + return calendar; + } - @Override - public String getClassName() { - return CLASSNAME; - } + @Override + public String getClassName() { + return CLASSNAME; + } - @Override - public String toString() { + @Override + public String toString() { if (calendarFormat == null) { calendarFormat = new SimpleDateFormat(ECMA_DATE_FORMAT, DATE_FORMAT_LOCALE); } return calendarFormat.format(calendar.getTime()); - } + } public Object unwrap() { return calendar; } @SuppressWarnings("unchecked") - @Override + @Override public Object getDefaultValue(Class typeHint) { - return toString(); + return toString(); } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java index 8ac96e6..36e3f99 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableItemMap.java @@ -18,13 +18,13 @@ */ package org.apache.sling.scripting.javascript.wrapper; +import javax.jcr.Item; +import javax.jcr.RepositoryException; + import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; -import javax.jcr.Item; -import javax.jcr.RepositoryException; - import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; @@ -49,8 +49,7 @@ public void jsConstructor(Object res) { try { items.put(item.getName(), item); } catch (RepositoryException re) { - log.error("ScriptableItemMap: Cannot get name of item " - + item, re); + log.error("ScriptableItemMap: Cannot get name of item " + item, re); } } } @@ -85,7 +84,7 @@ public Object get(int index, Scriptable start) { public Object get(String name, Scriptable start) { // special provision for the "length" property to simulate an array if ("length".equals(name)) { - return ScriptRuntime.toNumber(this.items.keySet().size()+""); + return ScriptRuntime.toNumber(this.items.keySet().size() + ""); } Item item = items.get(name); diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMap.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMap.java index d644e53..6e5a77a 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMap.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMap.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; @@ -30,7 +32,7 @@ public class ScriptableMap extends ScriptableBase implements SlingWrapper { public static final String CLASSNAME = "Map"; - private static final Class [] WRAPPED_CLASSES = { Map.class }; + private static final Class[] WRAPPED_CLASSES = {Map.class}; private Map map = new HashMap(); diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java index 009c570..1f636f0 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNode.java @@ -1,29 +1,23 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Property; @@ -34,6 +28,14 @@ import javax.jcr.ValueFormatException; import javax.jcr.nodetype.NodeType; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + import org.apache.sling.scripting.javascript.SlingWrapper; import org.mozilla.javascript.Context; import org.mozilla.javascript.NativeArray; @@ -51,7 +53,7 @@ public class ScriptableNode extends ScriptableBase implements SlingWrapper { public static final String CLASSNAME = "Node"; - private static final Class [] WRAPPED_CLASSES = { Node.class }; + private static final Class[] WRAPPED_CLASSES = {Node.class}; /** default log */ private final Logger log = LoggerFactory.getLogger(getClass()); @@ -73,7 +75,7 @@ public String getClassName() { } @Override - public Class [] getWrappedClasses() { + public Class[] getWrappedClasses() { return WRAPPED_CLASSES; } @@ -89,7 +91,7 @@ protected Object getWrappedObject() { public Object jsFunction_addNode(String path, String primaryType) throws RepositoryException { Node n = null; - if(primaryType == null || "undefined".equals(primaryType)) { + if (primaryType == null || "undefined".equals(primaryType)) { n = node.addNode(path); } else { n = node.addNode(path, primaryType); @@ -115,7 +117,7 @@ public Object jsFunction_getChildren() { public Object jsFunction_getNodes(String namePattern) { try { NodeIterator iter = null; - if(namePattern == null || "undefined".equals(namePattern)) { + if (namePattern == null || "undefined".equals(namePattern)) { iter = node.getNodes(); } else { iter = node.getNodes(namePattern); @@ -145,9 +147,8 @@ public Object jsFunction_getPrimaryItem() { } public Object jsFunction_getProperty(String name) throws RepositoryException { - Object[] args = { node.getProperty(name) }; - return ScriptRuntime.newObject(Context.getCurrentContext(), this, - ScriptableProperty.CLASSNAME, args); + Object[] args = {node.getProperty(name)}; + return ScriptRuntime.newObject(Context.getCurrentContext(), this, ScriptableProperty.CLASSNAME, args); } public String jsFunction_getUUID() { @@ -304,11 +305,11 @@ public Object get(String name, Scriptable start) { // builtin javascript properties (jsFunction_ etc.) have priority final Object fromSuperclass = super.get(name, start); - if(fromSuperclass != Scriptable.NOT_FOUND) { + if (fromSuperclass != Scriptable.NOT_FOUND) { return fromSuperclass; } - if(node == null) { + if (node == null) { return Undefined.instance; } @@ -321,7 +322,7 @@ public Object get(String name, Scriptable start) { items.add(ScriptRuntime.toObject(this, it.nextNode())); } } catch (RepositoryException e) { - log.debug("RepositoryException while collecting Node children",e); + log.debug("RepositoryException while collecting Node children", e); } // Add all matching properties to result @@ -344,10 +345,10 @@ public Object get(String name, Scriptable start) { log.debug("RepositoryException while collecting Node properties", e); } - if (items.size()==0) { + if (items.size() == 0) { return getNative(name, start); - } else if (items.size()==1 && !isMulti) { + } else if (items.size() == 1 && !isMulti) { return items.iterator().next(); } else { @@ -358,8 +359,7 @@ public Object get(String name, Scriptable start) { } /** Wrap JCR Values in a simple way */ - private Scriptable wrap(Value value) throws ValueFormatException, - IllegalStateException, RepositoryException { + private Scriptable wrap(Value value) throws ValueFormatException, IllegalStateException, RepositoryException { Object javaObject; if (value.getType() == PropertyType.REFERENCE) { @@ -407,14 +407,14 @@ private static Object toJavaObject(Value value) throws RepositoryException { @Override public Object[] getIds() { Collection ids = new ArrayList(); - if(node != null) { + if (node != null) { try { PropertyIterator pit = node.getProperties(); while (pit.hasNext()) { ids.add(pit.nextProperty().getName()); } } catch (RepositoryException e) { - //do nothing, just do not list properties + // do nothing, just do not list properties } try { NodeIterator nit = node.getNodes(); @@ -422,7 +422,7 @@ public Object[] getIds() { ids.add(nit.nextNode().getName()); } } catch (RepositoryException e) { - //do nothing, just do not list child nodes + // do nothing, just do not list child nodes } } return ids.toArray(); @@ -469,12 +469,11 @@ public Object unwrap() { return node; } - //---------- Helper ------------------------------------------------------- + // ---------- Helper ------------------------------------------------------- private Object toScriptableItemMap(Iterator iter) { - Object[] args = (iter != null) ? new Object[] { iter } : null; - return ScriptRuntime.newObject(Context.getCurrentContext(), this, - ScriptableItemMap.CLASSNAME, args); + Object[] args = (iter != null) ? new Object[] {iter} : null; + return ScriptRuntime.newObject(Context.getCurrentContext(), this, ScriptableItemMap.CLASSNAME, args); } /** @@ -563,6 +562,5 @@ private InputStream getStream() throws IOException { } return delegatee; } - } } diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptablePrintWriter.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptablePrintWriter.java index 41389ff..27196eb 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptablePrintWriter.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptablePrintWriter.java @@ -1,26 +1,28 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; +import javax.servlet.http.HttpServletRequest; + import java.io.PrintWriter; import java.util.Locale; -import javax.servlet.http.HttpServletRequest; - import org.apache.sling.api.scripting.SlingBindings; import org.apache.sling.scripting.javascript.SlingWrapper; import org.mozilla.javascript.Context; @@ -33,15 +35,14 @@ public class ScriptablePrintWriter extends ScriptableObject implements SlingWrapper { public static final String CLASSNAME = "PrintWriter"; - private static final Class [] WRAPPED_CLASSES = { PrintWriter.class }; + private static final Class[] WRAPPED_CLASSES = {PrintWriter.class}; private PrintWriter writer; // the locale to use for printf private Locale locale; - public ScriptablePrintWriter() { - } + public ScriptablePrintWriter() {} public ScriptablePrintWriter(PrintWriter writer) { this.writer = writer; @@ -56,21 +57,19 @@ public String getClassName() { return CLASSNAME; } - public Class [] getWrappedClasses() { + public Class[] getWrappedClasses() { return WRAPPED_CLASSES; } - + // print args to writer if any // this method supports write(Object) - public static void jsFunction_write(Context cx, Scriptable thisObj, - Object[] args, Function funObj) { + public static void jsFunction_write(Context cx, Scriptable thisObj, Object[] args, Function funObj) { print(thisObj, args); } // print args to writer if any // this method supports print(Object) - public static void jsFunction_print(Context cx, Scriptable thisObj, - Object[] args, Function funObj) { + public static void jsFunction_print(Context cx, Scriptable thisObj, Object[] args, Function funObj) { print(thisObj, args); } @@ -79,8 +78,7 @@ public static void jsFunction_print(Context cx, Scriptable thisObj, // format string followed by format arguments. // This method supports printf(Locale, String, Object...) and // printf(String, Object...) - public static void jsFunction_printf(Context cx, Scriptable thisObj, - Object[] args, Function funObj) { + public static void jsFunction_printf(Context cx, Scriptable thisObj, Object[] args, Function funObj) { if (args.length > 0) { @@ -112,8 +110,7 @@ public static void jsFunction_printf(Context cx, Scriptable thisObj, // arguments starting after that are formatting arguments nextIdx++; Object[] formatArgs = new Object[args.length - nextIdx]; - System.arraycopy(args, nextIdx, formatArgs, 0, - formatArgs.length); + System.arraycopy(args, nextIdx, formatArgs, 0, formatArgs.length); // now get the writer and call printf PrintWriter writer = ((ScriptablePrintWriter) thisObj).writer; @@ -124,8 +121,7 @@ public static void jsFunction_printf(Context cx, Scriptable thisObj, // print args to the writer (if any) and append a line feed // this method supports println(Object) - public static void jsFunction_println(Context cx, Scriptable thisObj, - Object[] args, Function funObj) { + public static void jsFunction_println(Context cx, Scriptable thisObj, Object[] args, Function funObj) { print(thisObj, args).println(); } @@ -153,11 +149,10 @@ private static PrintWriter print(Object thisObj, Object[] args) { // - Otherwise or if getLocale returns null, we use the platform default private Locale getLocale() { if (locale == null) { - + try { // check whether we have a request object which has the locale - Object reqObj = ScriptRuntime.name(Context.getCurrentContext(), - this, SlingBindings.REQUEST); + Object reqObj = ScriptRuntime.name(Context.getCurrentContext(), this, SlingBindings.REQUEST); if (reqObj instanceof Wrapper) { Object wrapped = ((Wrapper) reqObj).unwrap(); if (wrapped instanceof HttpServletRequest) { @@ -172,7 +167,6 @@ private Locale getLocale() { if (locale == null) { locale = Locale.getDefault(); } - } return locale; diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java index ce6bce7..93529d2 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableProperty.java @@ -33,7 +33,7 @@ public class ScriptableProperty extends ScriptableBase implements SlingWrapper { public static final String CLASSNAME = "Property"; - private static final Class[] WRAPPED_CLASSES = { Property.class }; + private static final Class[] WRAPPED_CLASSES = {Property.class}; /** * The wrapped JCR Property instance. Will be {@code null} if the @@ -42,8 +42,7 @@ public class ScriptableProperty extends ScriptableBase implements SlingWrapper { */ private Property property; - public ScriptableProperty() { - } + public ScriptableProperty() {} public void jsConstructor(Object res) { this.property = (Property) res; @@ -263,11 +262,11 @@ public Object jsFunction_valueOf(String hint) { @Override public Object get(String name, Scriptable start) { final Object fromSuperclass = super.get(name, start); - if(fromSuperclass != Scriptable.NOT_FOUND) { + if (fromSuperclass != Scriptable.NOT_FOUND) { return fromSuperclass; } - if(property == null) { + if (property == null) { return Undefined.instance; } @@ -306,4 +305,4 @@ protected Class getStaticType() { protected Object getWrappedObject() { return property; } -} \ No newline at end of file +} diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResource.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResource.java index cf6e88c..957847e 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResource.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResource.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; @@ -55,20 +57,18 @@ *
  • [Object] properties
  • * */ -public class ScriptableResource extends ScriptableObject implements - SlingWrapper { +public class ScriptableResource extends ScriptableObject implements SlingWrapper { private static final Logger LOGGER = LoggerFactory.getLogger(ScriptableResource.class); public static final String CLASSNAME = "Resource"; - private static final Class[] WRAPPED_CLASSES = { Resource.class }; + private static final Class[] WRAPPED_CLASSES = {Resource.class}; private Resource resource; private ValueMap properties; - public ScriptableResource() { - } + public ScriptableResource() {} public ScriptableResource(Resource resource) { this.resource = resource; @@ -271,8 +271,7 @@ public Object jsFunction_getObject() { * the resource does not adapt to the required type or if the * argument is of the wrong type or missing. */ - public static Object jsFunction_adaptTo(Context cx, Scriptable thisObj, - Object[] args, Function funObj) { + public static Object jsFunction_adaptTo(Context cx, Scriptable thisObj, Object[] args, Function funObj) { // get and unwrap the argument Object arg = (args.length > 0) ? args[0] : null; @@ -299,7 +298,6 @@ public static Object jsFunction_adaptTo(Context cx, Scriptable thisObj, } catch (Exception e) { LOGGER.error("Unable to adapt object.", e); } - } if (adapter != null) { diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersion.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersion.java index 3a5944d..6adda82 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersion.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersion.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; @@ -23,14 +25,14 @@ public class ScriptableVersion extends ScriptableNode { public static final String CLASSNAME = "Version"; - private static final Class [] WRAPPED_CLASSES = { Version.class }; + private static final Class[] WRAPPED_CLASSES = {Version.class}; private Version version; @Override public void jsConstructor(Object res) { super.jsConstructor(res); - version = (Version)res; + version = (Version) res; } @Override @@ -52,4 +54,4 @@ public Class[] getWrappedClasses() { protected Object getWrappedObject() { return version; } -} \ No newline at end of file +} diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersionHistory.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersionHistory.java index 267a348..142ebb1 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersionHistory.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableVersionHistory.java @@ -1,18 +1,20 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; @@ -23,14 +25,14 @@ public class ScriptableVersionHistory extends ScriptableNode { public static final String CLASSNAME = "VersionHistory"; - private static final Class [] WRAPPED_CLASSES = { VersionHistory.class }; + private static final Class[] WRAPPED_CLASSES = {VersionHistory.class}; private VersionHistory versionHistory; @Override public void jsConstructor(Object res) { super.jsConstructor(res); - versionHistory = (VersionHistory)res; + versionHistory = (VersionHistory) res; } @Override @@ -52,4 +54,4 @@ public Class[] getWrappedClasses() { protected Object getWrappedObject() { return versionHistory; } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/sling/scripting/javascript/RepositoryScriptingTestBase.java b/src/test/java/org/apache/sling/scripting/javascript/RepositoryScriptingTestBase.java index 0318332..e630f28 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/RepositoryScriptingTestBase.java +++ b/src/test/java/org/apache/sling/scripting/javascript/RepositoryScriptingTestBase.java @@ -27,13 +27,12 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; - /** Base class for tests which need a Repository * and scripting functionality */ public class RepositoryScriptingTestBase extends RepositoryTestBase { protected ScriptEngineHelper script; private int counter; - + @Override @BeforeEach protected void setUp() throws Exception { @@ -50,5 +49,4 @@ protected void tearDown() throws Exception { protected Node getNewNode() throws RepositoryException, NamingException { return getTestRootNode().addNode("test-" + (++counter)); } - } diff --git a/src/test/java/org/apache/sling/scripting/javascript/TestSetupTest.java b/src/test/java/org/apache/sling/scripting/javascript/TestSetupTest.java index 673b611..710881b 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/TestSetupTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/TestSetupTest.java @@ -21,27 +21,26 @@ import org.apache.sling.scripting.javascript.internal.ScriptEngineHelper; import org.junit.jupiter.api.Test; - /** Verify that our test environment works */ class TestSetupTest extends RepositoryScriptingTestBase { - + /** Test our test repository setup */ @Test void testRootNode() throws Exception { assertNotNull(getTestRootNode()); } - + /** Test our script engine setup */ @Test void testScripting() throws Exception { - assertEquals("something",script.evalToString("out.print('something')")); + assertEquals("something", script.evalToString("out.print('something')")); } - + @Test void testScriptingWithData() throws Exception { final ScriptEngineHelper.Data data = new ScriptEngineHelper.Data(); data.put("a", "A"); data.put("b", "B"); - assertEquals("A1",script.evalToString("out.print(a + b.length)", data)); + assertEquals("A1", script.evalToString("out.print(a + b.length)", data)); } } diff --git a/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryTest.java b/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryTest.java index 218e1c6..d590351 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactoryTest.java @@ -1,33 +1,33 @@ -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~ Licensed to the Apache Software Foundation (ASF) under one - ~ or more contributor license agreements. See the NOTICE file - ~ distributed with this work for additional information - ~ regarding copyright ownership. The ASF licenses this file - ~ to you under the Apache License, Version 2.0 (the - ~ "License"); you may not use this file except in compliance - ~ with the License. You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, - ~ software distributed under the License is distributed on an - ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - ~ KIND, either express or implied. See the License for the - ~ specific language governing permissions and limitations - ~ under the License. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.sling.scripting.javascript.internal; -import java.util.Arrays; - import javax.script.ScriptEngineFactory; +import java.util.Arrays; + import org.apache.sling.commons.classloader.DynamicClassLoaderManager; import org.apache.sling.scripting.api.ScriptCache; import org.apache.sling.testing.mock.osgi.junit5.OsgiContext; import org.apache.sling.testing.mock.osgi.junit5.OsgiContextExtension; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -42,15 +42,20 @@ class RhinoJavaScriptEngineFactoryTest { @Test void testRegistrationProperties() { DynamicClassLoaderManager dynamicClassLoaderManager = mock(DynamicClassLoaderManager.class); - when(dynamicClassLoaderManager.getDynamicClassLoader()).thenReturn(RhinoJavaScriptEngineFactoryTest.class.getClassLoader()); + when(dynamicClassLoaderManager.getDynamicClassLoader()) + .thenReturn(RhinoJavaScriptEngineFactoryTest.class.getClassLoader()); context.registerService(DynamicClassLoaderManager.class, dynamicClassLoaderManager); context.registerService(ScriptCache.class, mock(ScriptCache.class)); context.registerInjectActivateService(new RhinoJavaScriptEngineFactory()); - RhinoJavaScriptEngineFactory instance = (RhinoJavaScriptEngineFactory) context.getService(ScriptEngineFactory.class); - assertEquals(Arrays.asList("rhino", "Rhino", "javascript", "JavaScript", "ecmascript", "ECMAScript"), instance.getNames()); + RhinoJavaScriptEngineFactory instance = + (RhinoJavaScriptEngineFactory) context.getService(ScriptEngineFactory.class); + assertEquals( + Arrays.asList("rhino", "Rhino", "javascript", "JavaScript", "ecmascript", "ECMAScript"), + instance.getNames()); assertEquals("ECMAScript", instance.getLanguageName()); assertEquals("partial ECMAScript 2015 support", instance.getLanguageVersion()); - assertTrue( instance.getEngineName() != null && instance.getEngineName().contains("Rhino 1.7.7.1_1"), "Unexpected engine name" ); + assertTrue( + instance.getEngineName() != null && instance.getEngineName().contains("Rhino 1.7.7.1_1"), + "Unexpected engine name"); } - } diff --git a/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java b/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java index 88c1508..577b052 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java @@ -26,12 +26,12 @@ import org.apache.sling.api.scripting.LazyBindings; import org.apache.sling.scripting.api.ScriptCache; import org.apache.sling.scripting.javascript.helper.SlingWrapFactory; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.mozilla.javascript.Context; import org.mozilla.javascript.ImporterTopLevel; import org.mozilla.javascript.Scriptable; -import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -105,5 +105,4 @@ SlingWrapFactory getWrapFactory() { return wrapFactory; } } - } diff --git a/src/test/java/org/apache/sling/scripting/javascript/internal/ScriptEngineHelper.java b/src/test/java/org/apache/sling/scripting/javascript/internal/ScriptEngineHelper.java index 045eb9f..98fcb62 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/internal/ScriptEngineHelper.java +++ b/src/test/java/org/apache/sling/scripting/javascript/internal/ScriptEngineHelper.java @@ -18,11 +18,6 @@ */ package org.apache.sling.scripting.javascript.internal; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.HashMap; -import java.util.Map; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; @@ -30,6 +25,12 @@ import javax.script.SimpleBindings; import javax.script.SimpleScriptContext; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; + import org.apache.sling.commons.testing.osgi.MockBundle; import org.apache.sling.commons.testing.osgi.MockComponentContext; import org.apache.sling.scripting.api.ScriptCache; @@ -61,13 +62,12 @@ public ScriptEngineHelper() { MockitoAnnotations.openMocks(this); } - public static class Data extends HashMap { - } + public static class Data extends HashMap {} private ScriptEngine getEngine() { if (engine == null) { synchronized (ScriptEngineHelper.class) { - factory.activate( new RhinoMockComponentContext(), factoryConfiguration); + factory.activate(new RhinoMockComponentContext(), factoryConfiguration); engine = factory.getScriptEngine(); } } @@ -78,20 +78,17 @@ public String evalToString(String javascriptCode) throws ScriptException { return evalToString(javascriptCode, null); } - public Object eval(String javascriptCode, Map data) - throws ScriptException { + public Object eval(String javascriptCode, Map data) throws ScriptException { return eval(javascriptCode, data, new StringWriter()); } - public String evalToString(String javascriptCode, Map data) - throws ScriptException { + public String evalToString(String javascriptCode, Map data) throws ScriptException { final StringWriter sw = new StringWriter(); eval(javascriptCode, data, sw); return sw.toString(); } - public Object eval(String javascriptCode, Map data, - final StringWriter sw) throws ScriptException { + public Object eval(String javascriptCode, Map data, final StringWriter sw) throws ScriptException { final PrintWriter pw = new PrintWriter(sw, true); ScriptContext ctx = new SimpleScriptContext(); diff --git a/src/test/java/org/apache/sling/scripting/javascript/internal/TestPathRegexp.java b/src/test/java/org/apache/sling/scripting/javascript/internal/TestPathRegexp.java index 691369c..ed423d9 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/internal/TestPathRegexp.java +++ b/src/test/java/org/apache/sling/scripting/javascript/internal/TestPathRegexp.java @@ -19,25 +19,26 @@ package org.apache.sling.scripting.javascript.internal; import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertEquals; class TestPathRegexp { - @Test - void testParentPath() { - String regexp = "([^/]*/)?[^/]*/\\.\\./"; - assertEquals("math", "/../math".replaceAll(regexp, "")); - assertEquals("math", "increment/../math".replaceAll(regexp, "")); - assertEquals("math", "foo/increment/../math".replaceAll(regexp, "")); - assertEquals("foo/math", "foo/bar/increment/../math".replaceAll(regexp, "")); - } + @Test + void testParentPath() { + String regexp = "([^/]*/)?[^/]*/\\.\\./"; + assertEquals("math", "/../math".replaceAll(regexp, "")); + assertEquals("math", "increment/../math".replaceAll(regexp, "")); + assertEquals("math", "foo/increment/../math".replaceAll(regexp, "")); + assertEquals("foo/math", "foo/bar/increment/../math".replaceAll(regexp, "")); + } - @Test - void testCurrentPath() { - String regexp = "[^/]*/\\./"; - assertEquals("math", "/./math".replaceAll(regexp, "")); - assertEquals("math", "increment/./math".replaceAll(regexp, "")); - assertEquals("foo/math", "foo/increment/./math".replaceAll(regexp, "")); - assertEquals("foo/bar/math", "foo/bar/increment/./math".replaceAll(regexp, "")); - } + @Test + void testCurrentPath() { + String regexp = "[^/]*/\\./"; + assertEquals("math", "/./math".replaceAll(regexp, "")); + assertEquals("math", "increment/./math".replaceAll(regexp, "")); + assertEquals("foo/math", "foo/increment/./math".replaceAll(regexp, "")); + assertEquals("foo/bar/math", "foo/bar/increment/./math".replaceAll(regexp, "")); + } } diff --git a/src/test/java/org/apache/sling/scripting/javascript/io/EspReaderTest.java b/src/test/java/org/apache/sling/scripting/javascript/io/EspReaderTest.java index c10acdf..d8c9e77 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/io/EspReaderTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/io/EspReaderTest.java @@ -18,12 +18,13 @@ */ package org.apache.sling.scripting.javascript.io; +import javax.script.ScriptException; + import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.stream.Stream; -import javax.script.ScriptException; import org.apache.sling.scripting.javascript.internal.ScriptEngineHelper; import org.junit.jupiter.api.Named; import org.junit.jupiter.api.Test; @@ -112,20 +113,20 @@ void testTemplate() throws IOException { assertEquals("out=response.writer;out.write(\"test\");", parse("test")); assertEquals("out=response.writer;out.write(\"test\\n\");\nout.write(\"test2\");", parse("test\ntest2")); } - + /** Test with a custom "out" initialization */ @Test void testOutInit() throws IOException { final String input = "test"; final String expected = "out=getOut();out.write(\"test\");"; - + StringBuffer buf = new StringBuffer(); EspReader r = new EspReader(new StringReader(input)); r.setOutInitStatement("out=getOut();"); int c; - while ( (c=r.read()) >= 0) { - buf.append( (char) c); + while ((c = r.read()) >= 0) { + buf.append((char) c); } assertEquals(expected, buf.toString()); @@ -142,7 +143,9 @@ void testCode() throws IOException { @Test void testExpr() throws IOException { assertEquals("out=response.writer;out.write( x + 1 );", parse("<%= x + 1 %>")); - assertEquals("out=response.writer;out.write(\"\");", parse("")); + assertEquals( + "out=response.writer;out.write(\"\");", + parse("")); } /** Test JavaScript comment */ @@ -154,77 +157,68 @@ void testComment() throws IOException { @ParameterizedTest @MethodSource("CompactExpressionCases") void testCompactExpressions(final String input, final String expected) throws IOException { - final String actual = parse(input); + final String actual = parse(input); assertEquals(flatten(expected), flatten(actual)); } static Stream CompactExpressionCases() { - return Stream.of( - Arguments.of( - // input - Named.of("testCompactExpressionsDouble", "\n"), - // expected - "out=response.writer;out.write(\"\\n\");\n" - ), - Arguments.of( - // input - Named.of("testCompactExpressionsDoubleNegative", "\n"), - // expected - "out=response.writer;out.write(\"\\n\");\n" - ), - Arguments.of( - // input - Named.of("testCompactExpressionsSingle", "\n"), - // expected - "out=response.writer;out.write(\"\\n\");\n" - ), - Arguments.of( - // input - Named.of("testCompactExpressionsSingleNegative", "\n"), - // expected - "out=response.writer;out.write(\"\\n\");\n" - ) - ); + return Stream.of( + Arguments.of( + // input + Named.of("testCompactExpressionsDouble", "\n"), + // expected + "out=response.writer;out.write(\"\\n\");\n"), + Arguments.of( + // input + Named.of("testCompactExpressionsDoubleNegative", "\n"), + // expected + "out=response.writer;out.write(\"\\n\");\n"), + Arguments.of( + // input + Named.of("testCompactExpressionsSingle", "\n"), + // expected + "out=response.writer;out.write(\"\\n\");\n"), + Arguments.of( + // input + Named.of("testCompactExpressionsSingleNegative", "\n"), + // expected + "out=response.writer;out.write(\"\\n\");\n")); } /** Test a complete template, using all features */ @Test void testCompleteTemplate() throws IOException { - final String input = - "\n" - + "<%= someExpr %>\n" - + "\n" - + "<-- some ESP comment -->\n" - + "// some javascript comment\n" - + "/* another javascript comment /*\n" - + "<%\n" - + "expr on\n" - + "two lines\n" - + "%>\n" - + "xyz\n" - + "xx\n" - + "\n" - + "" - ; - - final String expected = - "out=response.writer;out.write(\"\\n\");\n" - + "out.write(\"\");out.write( someExpr );out.write(\"\\n\");\n" - + "out.write(\"\\n\");\n" - + "out.write(\"<-- some ESP comment -->\\n\");\n" - + "out.write(\"// some javascript comment\\n\");\n" - + "out.write(\"/* another javascript comment /*\\n\");\n" - + "\n" - + "expr on\n" - + "two lines\n" - + "out.write(\"\\n\");\n" - + "out.write(\"xyz\\n\");\n" - + "out.write(\"xx\\n\");\n" - + "out.write(\"\\n\");\n" - + "out.write(\"\");" - ; - + final String input = "\n" + + "<%= someExpr %>\n" + + "\n" + + "<-- some ESP comment -->\n" + + "// some javascript comment\n" + + "/* another javascript comment /*\n" + + "<%\n" + + "expr on\n" + + "two lines\n" + + "%>\n" + + "xyz\n" + + "xx\n" + + "\n" + + ""; + + final String expected = "out=response.writer;out.write(\"\\n\");\n" + + "out.write(\"\");out.write( someExpr );out.write(\"\\n\");\n" + + "out.write(\"\\n\");\n" + + "out.write(\"<-- some ESP comment -->\\n\");\n" + + "out.write(\"// some javascript comment\\n\");\n" + + "out.write(\"/* another javascript comment /*\\n\");\n" + + "\n" + + "expr on\n" + + "two lines\n" + + "out.write(\"\\n\");\n" + + "out.write(\"xyz\\n\");\n" + + "out.write(\"xx\\n\");\n" + + "out.write(\"\\n\");\n" + + "out.write(\"\");"; + final String actual = parse(input); assertEquals(flatten(expected), flatten(actual)); } @@ -236,23 +230,23 @@ void testNumericExpression() throws IOException { String expected = "out=response.writer;out.write( 1 );"; String actual = parse(input); assertEquals(expected, actual); - + input = "<%= \"1\" %>"; expected = "out=response.writer;out.write( \"1\" );"; actual = parse(input); assertEquals(expected, actual); - + input = "<%= '1' %>"; expected = "out=response.writer;out.write( '1' );"; actual = parse(input); assertEquals(expected, actual); } - + /** Test a complete template, using all features */ @Test void testNumericExpressionOutput() throws ScriptException { ScriptEngineHelper script = new ScriptEngineHelper(); - + String input = "out.write( 1 );"; String actual = script.evalToString(input); String expected = "1"; @@ -268,57 +262,47 @@ void testNumericExpressionOutput() throws ScriptException { expected = "1"; assertEquals(expected, actual); } - + @Test void testColon() throws IOException { final String input = "currentNode.text:<%= currentNode.text %>"; - final String expected = - "out=response.writer;" - + "out.write(\"currentNode.text:\");" - + "out.write( currentNode.text );" - ; + final String expected = + "out=response.writer;" + "out.write(\"currentNode.text:\");" + "out.write( currentNode.text );"; final String actual = parse(input); assertEquals(expected, actual); } - + @Test void testEqualSigns() throws IOException { final String input = "currentNode.text=<%= currentNode.text %>"; - final String expected = - "out=response.writer;" - + "out.write(\"currentNode.text=\");" - + "out.write( currentNode.text );" - ; + final String expected = + "out=response.writer;" + "out.write(\"currentNode.text=\");" + "out.write( currentNode.text );"; final String actual = parse(input); assertEquals(expected, actual); } - + @Test void testSingleQuoted() throws IOException { final String input = "currentNode.text='<%= currentNode.text %>'"; - final String expected = - "out=response.writer;" - + "out.write(\"currentNode.text='\");" - + "out.write( currentNode.text );" - + "out.write(\"'\");" - ; + final String expected = "out=response.writer;" + + "out.write(\"currentNode.text='\");" + + "out.write( currentNode.text );" + + "out.write(\"'\");"; final String actual = parse(input); assertEquals(expected, actual); } - + @Test void testDoubleQuoted() throws IOException { final String input = "currentNode.text=\"<%= currentNode.text %>\""; - final String expected = - "out=response.writer;" - + "out.write(\"currentNode.text=\\\"\");" - + "out.write( currentNode.text );" - + "out.write(\"\\\"\");" - ; + final String expected = "out=response.writer;" + + "out.write(\"currentNode.text=\\\"\");" + + "out.write( currentNode.text );" + + "out.write(\"\\\"\");"; final String actual = parse(input); assertEquals(expected, actual); } - + /** Helper to pass an ESP text through the EspReader and return the result */ private String parse(String text) throws IOException { StringBuffer buf = new StringBuffer(); @@ -326,16 +310,16 @@ private String parse(String text) throws IOException { Reader r = new EspReader(new StringReader(text)); try { int c; - while ( (c=r.read()) >= 0) { - buf.append( (char) c); + while ((c = r.read()) >= 0) { + buf.append((char) c); } return buf.toString(); } finally { r.close(); - } + } } - + /** Replace \n with . in strings to make it easier to compare visually for testing */ private static String flatten(String str) { return str.replace('\n', '.'); diff --git a/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMapTest.java b/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMapTest.java index 3f05d14..5cb4bd1 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMapTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableMapTest.java @@ -1,24 +1,27 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.apache.sling.scripting.javascript.wrapper; -import java.util.HashMap; import javax.script.ScriptException; +import java.util.HashMap; + import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.scripting.javascript.RepositoryScriptingTestBase; @@ -27,7 +30,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - class ScriptableMapTest extends RepositoryScriptingTestBase { private ValueMap valueMap; @@ -37,10 +39,12 @@ class ScriptableMapTest extends RepositoryScriptingTestBase { @BeforeEach public void setUp() throws Exception { super.setUp(); - valueMap = new ValueMapDecorator(new HashMap() {{ - put("a", "a"); - put("b", 1); - }}); + valueMap = new ValueMapDecorator(new HashMap() { + { + put("a", "a"); + put("b", 1); + } + }); data = new ScriptEngineHelper.Data(); data.put("properties", valueMap); } @@ -65,4 +69,4 @@ void testPropertyAccess() throws ScriptException { void testJavaMethods() throws ScriptException { assertEquals(2, script.eval("properties.size()", data)); } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNodeTest.java b/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNodeTest.java index 6372add..08ba279 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNodeTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableNodeTest.java @@ -18,19 +18,18 @@ */ package org.apache.sling.scripting.javascript.wrapper; -import java.text.SimpleDateFormat; -import java.util.Calendar; - import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.Value; +import java.text.SimpleDateFormat; +import java.util.Calendar; + import org.apache.sling.scripting.javascript.RepositoryScriptingTestBase; import org.apache.sling.scripting.javascript.internal.ScriptEngineHelper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - /** Test the ScriptableNode class "live", by retrieving * Nodes from a Repository and executing javascript code * using them. @@ -76,114 +75,76 @@ protected void setUp() throws Exception { void testDefaultValue() throws Exception { final ScriptEngineHelper.Data data = new ScriptEngineHelper.Data(); data.put("node", getTestRootNode()); - assertEquals( - getTestRootNode().getPath(), - script.evalToString("out.print(node)", data) - ); + assertEquals(getTestRootNode().getPath(), script.evalToString("out.print(node)", data)); } @Test void testPrimaryNodeType() throws Exception { final ScriptEngineHelper.Data data = new ScriptEngineHelper.Data(); data.put("node", getTestRootNode()); - assertEquals( - "nt:unstructured", - script.evalToString("out.print(node.getPrimaryNodeType().getName())", data) - ); + assertEquals("nt:unstructured", script.evalToString("out.print(node.getPrimaryNodeType().getName())", data)); } @Test void testPrimaryNodeTypeProperty() throws Exception { final ScriptEngineHelper.Data data = new ScriptEngineHelper.Data(); data.put("node", getTestRootNode()); - assertEquals( - "nt:unstructured", - script.evalToString("out.print(node['jcr:primaryType'])", data) - ); + assertEquals("nt:unstructured", script.evalToString("out.print(node['jcr:primaryType'])", data)); } @Test void testViaPropertyNoWrappers() throws Exception { - assertEquals( - testText, - script.evalToString("out.print(property.value.string)", data) - ); + assertEquals(testText, script.evalToString("out.print(property.value.string)", data)); } @Test void testViaPropertyWithWrappers() throws Exception { - assertEquals( - textProperty.getString(), - script.evalToString("out.print(property)", data) - ); + assertEquals(textProperty.getString(), script.evalToString("out.print(property)", data)); } @Test void testViaNodeDirectPropertyAccess() throws Exception { - assertEquals( - testText, - script.evalToString("out.print(node.text)", data) - ); + assertEquals(testText, script.evalToString("out.print(node.text)", data)); } @Test void testViaPropertyNoWrappersNum() throws Exception { - assertEquals( - testNum, - script.eval("numProperty.value.getDouble()", data) - ); + assertEquals(testNum, script.eval("numProperty.value.getDouble()", data)); } @Test void testViaPropertyWithWrappersNum() throws Exception { - assertEquals( - testNum, - script.eval("0+numProperty", data) - ); + assertEquals(testNum, script.eval("0+numProperty", data)); } @Test void testViaNodeDirectPropertyAccessNum() throws Exception { - assertEquals( - testNum, - script.eval("node.num", data) - ); + assertEquals(testNum, script.eval("node.num", data)); } @Test void testViaPropertyNoWrappersCal() throws Exception { - assertEquals( - testCal.getTimeInMillis(), - script.eval("calProperty.value.getDate().getTimeInMillis()", data) - ); + assertEquals(testCal.getTimeInMillis(), script.eval("calProperty.value.getDate().getTimeInMillis()", data)); } @Test void testViaNodeDirectPropertyAccessCal() throws Exception { - final SimpleDateFormat f = new SimpleDateFormat(ScriptableCalendar.ECMA_DATE_FORMAT, ScriptableCalendar.DATE_FORMAT_LOCALE); - final String expected = f.format(testCal.getTime()); - assertEquals( - expected, - script.evalToString("out.print(node.cal)", data) - ); + final SimpleDateFormat f = + new SimpleDateFormat(ScriptableCalendar.ECMA_DATE_FORMAT, ScriptableCalendar.DATE_FORMAT_LOCALE); + final String expected = f.format(testCal.getTime()); + assertEquals(expected, script.evalToString("out.print(node.cal)", data)); } @Test void testCalDateClass() throws Exception { - assertEquals( - "number", - script.evalToString("out.print(typeof node.cal.date.time)", data) - ); + assertEquals("number", script.evalToString("out.print(typeof node.cal.date.time)", data)); } @Test void testPropertyParent() throws Exception { // need to use node.getProperty('num') to have a ScriptableProperty, // node.num only returns a wrapped value - assertEquals( - "nt:unstructured", - script.eval("node.getProperty('num').parent['jcr:primaryType']", data) - ); + assertEquals("nt:unstructured", script.eval("node.getProperty('num').parent['jcr:primaryType']", data)); } @Test @@ -191,21 +152,16 @@ void testPropertyAncestor() throws Exception { // call getAncestor which is not explicitly defined in ScriptableProperty, // to verify that all Property methods are available and that we get a // correctly wrapped result (SLING-397) - assertEquals( - "rep:root", - script.eval("node.getProperty('num').getAncestor(0)['jcr:primaryType']", data) - ); + assertEquals("rep:root", script.eval("node.getProperty('num').getAncestor(0)['jcr:primaryType']", data)); } @Test void testPropertiesIterationNoWrapper() throws Exception { final String code = - "var props = node.getProperties();" - + " for(i in props) { out.print(props[i].name); out.print(' '); }" - ; + "var props = node.getProperties();" + " for(i in props) { out.print(props[i].name); out.print(' '); }"; final String result = script.evalToString(code, data); - final String [] names = { "text", "otherProperty" }; - for(String name : names) { + final String[] names = {"text", "otherProperty"}; + for (String name : names) { assertTrue("result (" + result + ") contains '" + name + "'", result.contains(name)); } } @@ -213,10 +169,7 @@ void testPropertiesIterationNoWrapper() throws Exception { @Test void testAddNodeDefaultType() throws Exception { final String path = "subdt_" + System.currentTimeMillis(); - final String code = - "var n = node.addNode('" + path + "');\n" - + "out.print(n['jcr:primaryType']);\n" - ; + final String code = "var n = node.addNode('" + path + "');\n" + "out.print(n['jcr:primaryType']);\n"; assertEquals("nt:unstructured", script.evalToString(code, data)); } @@ -224,20 +177,16 @@ void testAddNodeDefaultType() throws Exception { void testAddNodeSpecificType() throws Exception { final String path = "subst_" + System.currentTimeMillis(); final String code = - "var n = node.addNode('" + path + "', 'nt:folder');\n" - + "out.print(n['jcr:primaryType']);\n" - ; + "var n = node.addNode('" + path + "', 'nt:folder');\n" + "out.print(n['jcr:primaryType']);\n"; assertEquals("nt:folder", script.evalToString(code, data)); } @Test void testGetNode() throws Exception { final String path = "subgn_" + System.currentTimeMillis(); - final String code = - "node.addNode('" + path + "', 'nt:resource');\n" - + "var n=node.getNode('" + path + "');\n" - + "out.print(n['jcr:primaryType']);\n" - ; + final String code = "node.addNode('" + path + "', 'nt:resource');\n" + + "var n=node.getNode('" + path + "');\n" + + "out.print(n['jcr:primaryType']);\n"; assertEquals("nt:resource", script.evalToString(code, data)); } @@ -250,37 +199,31 @@ void testGetProperty() throws Exception { @Test void testGetNodesNoPattern() throws Exception { final String path = "subgnnp_" + System.currentTimeMillis(); - final String code = - "node.addNode('" + path + "_A');\n" - + "node.addNode('" + path + "_B');\n" - + "var nodes = node.getNodes();\n" - + "for (i in nodes) { out.print(nodes[i].getName() + ' '); }\n" - ; + final String code = "node.addNode('" + path + "_A');\n" + + "node.addNode('" + path + "_B');\n" + + "var nodes = node.getNodes();\n" + + "for (i in nodes) { out.print(nodes[i].getName() + ' '); }\n"; assertEquals(path + "_A " + path + "_B ", script.evalToString(code, data)); } @Test void testGetNodesWithPattern() throws Exception { final String path = "subgnnp_" + System.currentTimeMillis(); - final String code = - "node.addNode('1_" + path + "_A');\n" - + "node.addNode('1_" + path + "_B');\n" - + "node.addNode('2_" + path + "_C');\n" - + "var nodes = node.getNodes('1_*');\n" - + "for (i in nodes) { out.print(nodes[i].getName() + ' '); }\n" - ; + final String code = "node.addNode('1_" + path + "_A');\n" + + "node.addNode('1_" + path + "_B');\n" + + "node.addNode('2_" + path + "_C');\n" + + "var nodes = node.getNodes('1_*');\n" + + "for (i in nodes) { out.print(nodes[i].getName() + ' '); }\n"; assertEquals("1_" + path + "_A 1_" + path + "_B ", script.evalToString(code, data)); } @Test void testRemoveNode() throws Exception { - final String code = - "node.addNode('toremove');\n" - + "out.print(node.hasNode('toremove'))\n" - + "out.print(' ')\n" - + "node.getNode('toremove').remove()\n" - + "out.print(node.hasNode('toremove'))\n" - ; + final String code = "node.addNode('toremove');\n" + + "out.print(node.hasNode('toremove'))\n" + + "out.print(' ')\n" + + "node.getNode('toremove').remove()\n" + + "out.print(node.hasNode('toremove'))\n"; assertEquals("true false", script.evalToString(code, data)); } @@ -294,14 +237,12 @@ void testForCurrentNode() throws Exception { @Test void testChildNodeAccess() throws Exception { final String path = "subtcna_" + System.currentTimeMillis(); - final String code = - "node.addNode('" + path + "');\n" - + "var n=node.getNode('" + path + "');\n" - + "out.print(n['jcr:primaryType']);\n" - + "out.print(' ');\n" - + "var n2=node['" + path + "'];\n" - + "out.print(n2['jcr:primaryType']);\n" - ; + final String code = "node.addNode('" + path + "');\n" + + "var n=node.getNode('" + path + "');\n" + + "out.print(n['jcr:primaryType']);\n" + + "out.print(' ');\n" + + "var n2=node['" + path + "'];\n" + + "out.print(n2['jcr:primaryType']);\n"; assertEquals("nt:unstructured nt:unstructured", script.evalToString(code, data)); } @@ -323,26 +264,20 @@ void testGetAncestor() throws Exception { @Test void testIsNodeType() throws Exception { - final String code = - "out.print(node.isNodeType('nt:unstructured'));\n" - + "out.print(' ');\n" - + "out.print(node.isNodeType('nt:file'));" - ; + final String code = "out.print(node.isNodeType('nt:unstructured'));\n" + + "out.print(' ');\n" + + "out.print(node.isNodeType('nt:file'));"; assertEquals("true false", script.evalToString(code, data)); } @Test void testGetSession() throws Exception { assertEquals( - "Root node found via node.session", - "/", - script.eval("node.session.getRootNode().getPath()", data) - ); + "Root node found via node.session", "/", script.eval("node.session.getRootNode().getPath()", data)); assertEquals( "Root node found via node.getSession()", "/", - script.eval("node.getSession().getRootNode().getPath()", data) - ); + script.eval("node.getSession().getRootNode().getPath()", data)); } /** @@ -359,7 +294,8 @@ void testMultiValReferencePropLookup() throws Exception { node.setProperty("singleRef", refNode1); node.setProperty("multiRef", new Value[] { session.getValueFactory().createValue(refNode1), - session.getValueFactory().createValue(refNode2) }); + session.getValueFactory().createValue(refNode2) + }); String code = "node['singleRef']"; assertTrue(script.eval(code, data) instanceof Node); diff --git a/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResourceTest.java b/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResourceTest.java index c627459..b03e80a 100644 --- a/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResourceTest.java +++ b/src/test/java/org/apache/sling/scripting/javascript/wrapper/ScriptableResourceTest.java @@ -18,13 +18,6 @@ */ package org.apache.sling.scripting.javascript.wrapper; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; import javax.jcr.Item; import javax.jcr.NamespaceException; import javax.jcr.Node; @@ -35,6 +28,14 @@ import javax.jcr.RepositoryException; import javax.jcr.Value; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + import org.apache.jackrabbit.JcrConstants; import org.apache.sling.api.SlingConstants; import org.apache.sling.api.resource.Resource; @@ -46,18 +47,17 @@ import org.apache.sling.jcr.resource.api.JcrResourceConstants; import org.apache.sling.scripting.javascript.RepositoryScriptingTestBase; import org.apache.sling.scripting.javascript.internal.ScriptEngineHelper; -import org.apache.sling.testing.mock.sling.junit5.SlingContextExtension; -import org.apache.sling.testing.mock.sling.junit5.SlingContext; import org.apache.sling.testing.mock.sling.ResourceResolverType; +import org.apache.sling.testing.mock.sling.junit5.SlingContext; +import org.apache.sling.testing.mock.sling.junit5.SlingContextExtension; import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mozilla.javascript.Wrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - @ExtendWith(SlingContextExtension.class) class ScriptableResourceTest extends RepositoryScriptingTestBase { @@ -81,9 +81,10 @@ protected void setUp() throws Exception { node = getNewNode(); try { - node.getSession().getWorkspace().getNamespaceRegistry().registerNamespace( - SlingConstants.NAMESPACE_PREFIX, - JcrResourceConstants.SLING_NAMESPACE_URI); + node.getSession() + .getWorkspace() + .getNamespaceRegistry() + .registerNamespace(SlingConstants.NAMESPACE_PREFIX, JcrResourceConstants.SLING_NAMESPACE_URI); } catch (NamespaceException ne) { // don't care, might happen if already registered } @@ -95,8 +96,7 @@ void testDefaultValuePath() throws Exception { data.put("resource", new TestResource(node)); // the path of the resource - assertEquals(node.getPath(), script.evalToString("out.print(resource)", - data)); + assertEquals(node.getPath(), script.evalToString("out.print(resource)", data)); assertEquals(node.getPath(), script.eval("resource.path", data)); assertEquals(node.getPath(), script.eval("resource.getPath()", data)); } @@ -104,11 +104,8 @@ void testDefaultValuePath() throws Exception { @Test void testResourceType() throws Exception { // set resource and resource super type - node.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, - RESOURCE_TYPE); - node.setProperty( - JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY, - RESOURCE_SUPER_TYPE); + node.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, RESOURCE_TYPE); + node.setProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY, RESOURCE_SUPER_TYPE); final ScriptEngineHelper.Data data = new ScriptEngineHelper.Data(); data.put("resource", new TestResource(node)); @@ -116,8 +113,7 @@ void testResourceType() throws Exception { // the resourceType of the resource assertEquals(RESOURCE_TYPE, script.eval("resource.type", data)); assertEquals(RESOURCE_TYPE, script.eval("resource.resourceType", data)); - assertEquals(RESOURCE_TYPE, script.eval("resource.getResourceType()", - data)); + assertEquals(RESOURCE_TYPE, script.eval("resource.getResourceType()", data)); } @Test @@ -186,20 +182,15 @@ void testIsResourceType() throws Exception { @Test void testResourceSuperType() throws Exception { // set resource and resource super type - node.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, - RESOURCE_TYPE); - node.setProperty( - JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY, - RESOURCE_SUPER_TYPE); + node.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, RESOURCE_TYPE); + node.setProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY, RESOURCE_SUPER_TYPE); final ScriptEngineHelper.Data data = new ScriptEngineHelper.Data(); data.put("resource", new TestResource(node)); // the resourceType of the resource - assertEquals(RESOURCE_SUPER_TYPE, script.eval( - "resource.resourceSuperType", data)); - assertEquals(RESOURCE_SUPER_TYPE, script.eval( - "resource.getResourceSuperType()", data)); + assertEquals(RESOURCE_SUPER_TYPE, script.eval("resource.resourceSuperType", data)); + assertEquals(RESOURCE_SUPER_TYPE, script.eval("resource.getResourceSuperType()", data)); } @Test @@ -209,8 +200,7 @@ void testResourceMetadata() throws Exception { // official API assertResourceMetaData(script.eval("resource.resourceMetadata", data)); - assertResourceMetaData(script.eval("resource.getResourceMetadata()", - data)); + assertResourceMetaData(script.eval("resource.getResourceMetadata()", data)); // deprecated mappings assertResourceMetaData(script.eval("resource.meta", data)); @@ -223,10 +213,8 @@ void testResourceResolver() throws Exception { data.put("resource", new TestResource(node)); // official API - assertEquals(RESOURCE_RESOLVER, script.eval( - "resource.resourceResolver", data)); - assertEquals(RESOURCE_RESOLVER, script.eval( - "resource.getResourceResolver()", data)); + assertEquals(RESOURCE_RESOLVER, script.eval("resource.resourceResolver", data)); + assertEquals(RESOURCE_RESOLVER, script.eval("resource.getResourceResolver()", data)); } @Test @@ -235,10 +223,8 @@ void testAdaptToNode() throws Exception { data.put("resource", new TestResource(node)); // the node to which the resource adapts - assertEquals(node, script.eval("resource.adaptTo('javax.jcr.Node')", - data)); - assertEquals(node, script.eval( - "resource.adaptTo(Packages.javax.jcr.Node)", data)); + assertEquals(node, script.eval("resource.adaptTo('javax.jcr.Node')", data)); + assertEquals(node, script.eval("resource.adaptTo(Packages.javax.jcr.Node)", data)); } @Test @@ -261,7 +247,9 @@ void testProperties() throws Exception { node.setProperty("test", "testProperties"); node.getSession().save(); data.put("resource", new TestResource(node)); - assertEquals(date.getTimeInMillis(), script.eval("(resource.properties['jcr:lastModified']).getTimeInMillis()", data)); + assertEquals( + date.getTimeInMillis(), + script.eval("(resource.properties['jcr:lastModified']).getTimeInMillis()", data)); assertEquals("testProperties", script.eval("resource.properties.test", data)); } @@ -415,37 +403,33 @@ public String getName() { } public Resource getChild(String relPath) { - try - { - Node childNode = node.getNode( relPath ); - if ( childNode != null ) { - return new TestResource( childNode ); + try { + Node childNode = node.getNode(relPath); + if (childNode != null) { + return new TestResource(childNode); } else { return null; } - } catch ( RepositoryException re ) - { + } catch (RepositoryException re) { return null; } } public Resource getParent() { - try - { + try { Node parentNode = node.getParent(); - if ( parentNode != null ) { - return new TestResource( parentNode ); + if (parentNode != null) { + return new TestResource(parentNode); } else { return null; } - } catch ( RepositoryException re ) - { + } catch (RepositoryException re) { return null; } } public boolean isResourceType(String resourceType) { - return getResourceType().equals( resourceType ); + return getResourceType().equals(resourceType); } public Iterator listChildren() { @@ -454,23 +438,17 @@ public Iterator listChildren() { @Override public @NotNull Iterable getChildren() { - try - { + try { List childList = new ArrayList(); NodeIterator it = node.getNodes(); - while ( it.hasNext() ) - { + while (it.hasNext()) { Node nextNode = it.nextNode(); - childList.add( new TestResource( nextNode ) ); + childList.add(new TestResource(nextNode)); } return childList; - } catch ( RepositoryException re ) - { + } catch (RepositoryException re) { return null; } } - - } - } From dc8df0f54a837c4bcd0064a1223e7186c64b750e Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Fri, 28 Mar 2025 17:14:14 +0100 Subject: [PATCH 6/8] SLING-12730 ignore spotless code reformatting commit in git blame --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..e0b9529 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +d14439c92f5c52d11ac3aee53de2e08243b0e34f \ No newline at end of file From 782cdd543c23d8e601a13d46a7550dcc4bab12ab Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Fri, 28 Mar 2025 17:14:14 +0100 Subject: [PATCH 7/8] SLING-12730 ignore spotless code reformatting commit in git blame --- .git-blame-ignore-revs | 1 + .../sling/scripting/javascript/wrapper/ScriptableBase.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..e0b9529 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +d14439c92f5c52d11ac3aee53de2e08243b0e34f \ No newline at end of file diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java index 6fe7c82..2c5ef07 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java @@ -47,7 +47,7 @@ protected synchronized Object getNative(String name, Scriptable start) { return Scriptable.NOT_FOUND; } - if(njo == null) { + if (njo == null) { njo = new NativeJavaObject(start, wrapped, getStaticType()); } From ed4e92d9d816494632386b629c612e5de1f0f865 Mon Sep 17 00:00:00 2001 From: sscottyuancoc Date: Mon, 4 Aug 2025 09:21:14 -0600 Subject: [PATCH 8/8] SLING-12519 - Remove Double-Checked Locking in ScriptableBase.java * Replaced with a simpler, non-thread-safe version to improve readability, as current acccess is already confined to a single thread. --- .../sling/scripting/javascript/wrapper/ScriptableBase.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java index 2c5ef07..b3674a0 100644 --- a/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java +++ b/src/main/java/org/apache/sling/scripting/javascript/wrapper/ScriptableBase.java @@ -36,7 +36,8 @@ public abstract class ScriptableBase extends ScriptableObject { public static final String JSFUNC_PREFIX = "jsFunction_"; - protected synchronized Object getNative(String name, Scriptable start) { + /** Not thread-safe: designed for use in single-threaded environments only. */ + protected Object getNative(String name, Scriptable start) { final Object wrapped = getWrappedObject(); if (wrapped == null) {