From 807c4193184d070514649c21b86b6160f9a922bc Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Tue, 14 Sep 2010 13:00:57 +0000 Subject: [PATCH] Merged V3.3-BUG-FIX to HEAD 22496: Merged V3.3 to V3.3-BUG-FIX 22383: *Record only* Merged HEAD to V3.3 22381: Fixes FTL syntax error in Calendar view webscript 22404: *Record only* Merged HEAD to V3.3 22403: Fixed ALF-4669: Delete Links (app:filelink) in Share deletes destination 22409: Fixed ALF-2857: Links broken for updated discussions [Contribution] 22449: Fix for ALF-3698 - Need to re-enable request-scoped javascript scopes for webscripts - Improvements to repo and web-tier JS script processsor config to allow "shared scope" feature to be disabled - Sealed shared scopes are used between script executions - processor config can now disabled this feature and ensure that a new scope is created for each executed script. Allows core JS objects to be extended in scripts. 22454: ALF-3803 Fix for ISO8601 Date Format parser - milliseconds are optional. 22455: Fix to handle non-200 status code in some Share dashlets. Missing I18N string in site profile dashlet. 22456: SpringSurf contrib of ALF-3803 Fix for ISO8601 Date Format parser - milliseconds are optional. 22457: SESURF-66 - Remote Client improvements 22458: Merged BRANCHES/DEV/BELARUS/V3.3-2010_06_08 to BRANCHES/V3.3: 20585: ALF-1861: Shortcut parent-child association path should align with the actual 'cm:name' property of the shortcut 22464: ALF-1518 - Added support for Java System property "http.nonProxyHosts" in Remote Client - specifies a list of hosts that should *not* be proxied if the associated http.proxyHost property is set 22475: Fix for SESURF-76 - contributed by Ooi Leng Chye. 22484: Fix for ALF-4674 - added "max-age=0" to cache-control header for Download servlet to fix issues with content not always being re-requested after an update - brings the Download servlet inline with the ContentGet webscript that already does this git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22502 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/script-services-context.xml | 11 ++- .../repo/jscript/RhinoScriptProcessor.java | 86 ++++++++++++++----- 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/config/alfresco/script-services-context.xml b/config/alfresco/script-services-context.xml index 2ed0a034c4..dad6620db4 100644 --- a/config/alfresco/script-services-context.xml +++ b/config/alfresco/script-services-context.xml @@ -18,7 +18,16 @@ js - + + + + true + + + + + true + diff --git a/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java b/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java index 9071cae12b..4a0244ec87 100644 --- a/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java +++ b/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java @@ -21,7 +21,6 @@ package org.alfresco.repo.jscript; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -89,6 +88,9 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess /** Flag to enable or disable runtime script compliation */ private boolean compile = true; + /** Flag to enable the sharing of sealed root scopes between scripts executions */ + private boolean shareSealedScopes = true; + /** Cache of runtime compiled script instances */ private final Map scriptCache = new ConcurrentHashMap(256); @@ -119,6 +121,15 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess this.compile = compile; } + /** + * @param shareSealedScopes true to allow sharing of sealed scopes between script executions - set to + * false to disable this feature and ensure that a new scope is created for each executed script. + */ + public void setShareSealedScopes(boolean shareSealedScopes) + { + this.shareSealedScopes = shareSealedScopes; + } + /** * @see org.alfresco.service.cmr.repository.ScriptProcessor#reset() */ @@ -414,10 +425,18 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess // Create a thread-specific scope from one of the shared scopes. // See http://www.mozilla.org/rhino/scopes.html cx.setWrapFactory(wrapFactory); - Scriptable sharedScope = secure ? this.nonSecureScope : this.secureScope; - Scriptable scope = cx.newObject(sharedScope); - scope.setPrototype(sharedScope); - scope.setParentScope(null); + Scriptable scope; + if (this.shareSealedScopes) + { + Scriptable sharedScope = secure ? this.nonSecureScope : this.secureScope; + scope = cx.newObject(sharedScope); + scope.setPrototype(sharedScope); + scope.setParentScope(null); + } + else + { + scope = initScope(cx, secure, false); + } // there's always a model, if only to hold the util objects if (model == null) @@ -531,7 +550,7 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess } } - + /** * Pre initializes two scope objects (one secure and one not) with the standard objects preinitialised. * This saves on very expensive calls to reinitialize a new scope on every web script execution. See @@ -541,38 +560,65 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess */ public void afterPropertiesSet() throws Exception { - // Initialise the secure scope + // Initialize the secure scope Context cx = Context.enter(); try { cx.setWrapFactory(wrapFactory); - this.secureScope = cx.initStandardObjects(null, true); - - // remove security issue related objects - this ensures the script may not access - // unsecure java.* libraries or import any other classes for direct access - only - // the configured root host objects will be available to the script writer - this.secureScope.delete("Packages"); - this.secureScope.delete("getClass"); - this.secureScope.delete("java"); + this.secureScope = initScope(cx, false, true); } finally { Context.exit(); } - // Initialise the non-secure scope + // Initialize the non-secure scope cx = Context.enter(); try { cx.setWrapFactory(wrapFactory); - - // allow access to all libraries and objects, including the importer - // @see http://www.mozilla.org/rhino/ScriptingJava.html - this.nonSecureScope = new ImporterTopLevel(cx, true); + this.nonSecureScope = initScope(cx, true, true); } finally { Context.exit(); } } + + /** + * Initializes a scope for script execution. The easiest way to embed Rhino is just to create a new scope this + * way whenever you need one. However, initStandardObjects() is an expensive method to call and it allocates a + * fair amount of memory. + * + * @param cx the thread execution context + * @param secure Do we consider the script secure? When false this ensures the script may not + * access insecure java.* libraries or import any other classes for direct access - only the + * configured root host objects will be available to the script writer. + * @param sealed Should the scope be sealed, making it immutable? This should be true if a scope + * is to be reused. + * @return the scope object + */ + protected Scriptable initScope(Context cx, boolean secure, boolean sealed) + { + Scriptable scope; + if (secure) + { + // Initialise the non-secure scope + // allow access to all libraries and objects, including the importer + // @see http://www.mozilla.org/rhino/ScriptingJava.html + scope = new ImporterTopLevel(cx, sealed); + } + else + { + // Initialise the secure scope + scope = cx.initStandardObjects(null, sealed); + // remove security issue related objects - this ensures the script may not access + // unsecure java.* libraries or import any other classes for direct access - only + // the configured root host objects will be available to the script writer + scope.delete("Packages"); + scope.delete("getClass"); + scope.delete("java"); + } + return scope; + } } \ No newline at end of file