-
Notifications
You must be signed in to change notification settings - Fork 5
Script Registry
Dynamic imports allow developers to reference scripts that have been "registered" into a global script registry or a specific named registry (for a particular use-case). Such scripts can then be imported via the importScript API.
importScript("registry", "my-global-script");
importScript("registry", "my-script@my-sub-registry");
In the Alfresco Repository, the Spring bean javaScriptProcessor.scriptRegistry is that global registry. New scripts can be registered programmatically via the Java API or by using one of the pre-defined bootstrap options.
The class ScriptBootstrap can be used to configure a Spring bean that registers a single script with the script registry at the startup of the Repository or Share.
A trivial use to register a classpath-based script in the Repository would look like this:
<bean class="org.nabucco.alfresco.enhScriptEnv.common.script.registry.ScriptBootstrap">
<property name="registry" ref="javaScriptProcessor.scriptRegistry" />
<property name="name=" value="my-script" />
<!-- This is optional -->
<property name="subRegistry" value="my-sub-registry" />
<property name="script">
<bean class="org.nabucco.alfresco.enhScriptEnv.common.script.registry.ClasspathRegisterableScript">
<property name="scriptResource" value="classpath:path/to/my-script.js" />
</bean>
</property>
</bean>
Of course a developer could have just imported a classpath-baesd script using importScript and the classpath locator. The major benefit we get is by decoupling the import from how a script is located / loaded. We can also use custom implementations of RegisterableScript to define how scripts are loaded.
The module also provides an extended VersionRegisterableScript interface that allows us to configure versions for registered scripts. This can then be used to selectively import specific versions of a script or pick the latest version in an allowed range.
An import with restriction to version can look something like this:
// import a script that "applies to" a specific version
importScript("registry", "my-global-script", true, {
version : "1.0",
// only get the script if it is specific to "Enterprise"
// note: if not provided, defaults to "true" / "false" based on the Alfresco edition
// note: developer defines meaning via script registration and use - does not always have to refer to Alfresco edition
community : false
});
// import a script that "falls into" a specific version range
importScript("registry", "my-global-script", true, {
// get the most current version in the range from 1.0 (inclusive) to 2.0 (exclusive)
appliesFrom : "1.0",
appliesTo : "2.0",
appliesToExclusive : true,
// don't care about "Community" / "Enterprise" distinction
community : null
});
// import a script that combines "falls into" and "applies to" into a composite condition
importScript("registry", "my-global-script", true, {
conditions : [
{ version : "1.0", community : null},
{ appliesTo : "1.0", appliesFrom: "2.0", community : null}
]
});
There is a built-in flexibility to how versions may be used.
- a script can be registered with a specific script version and (optionally) a range of covered versions (from/to)
- the script version is used for a natural ordering of scripts and selecting the most recent version that matches the falls into style resolution condition
- the covered version range can be used to delineate abstract (arbitrary) versions, e.g. the version of a workflow, and to select the most recent version that matches the applies to style resolution condition
We can register a version-aware script in the following way:
<bean class="org.nabucco.alfresco.enhScriptEnv.common.script.registry.ScriptBootstrap">
<property name="registry" ref="javaScriptProcessor.scriptRegistry" />
<property name="name=" value="my-script" />
<!-- This is optional -->
<property name="subRegistry" value="my-sub-registry" />
<property name="script">
<bean class="org.nabucco.alfresco.enhScriptEnv.common.script.registry.VersionRegisterableScriptAdapter">
<property name="adaptedScript">
<bean class="org.nabucco.alfresco.enhScriptEnv.common.script.registry.ClasspathRegisterableScript">
<property name="scriptResource" value="classpath:path/to/my-script.js" />
</bean>
</property>
<property name="version" value="1.0" /> <!-- Version of the script itself -->
<property name="appliesFrom" value="54.1" /> <!-- Minimal abstract (e.g. workflow) version this script *applies to* -->
</bean>
</property>
</bean>
The more scripts a developer wants to expose via the registry with or without version information, the more frustrating will it be to do this via Spring configuration. For this reason, the module provides at least a basic utility for bootstrap automation, the VersionRegisterableScriptClasspathScanner. This utility allows us to define a collection of classpaths that will be scanned for any scripts to bootstrap into the script registry.
The Repository patch project defines a single scanner to bootstrap all of the versioned scripts relevant for the "pluggable document library filters" use case.
<bean id="${project.artifactId}-repo-webScriptFragmentsBootstrap" class="org.nabucco.alfresco.enhScriptEnv.repo.script.registry.RepositoryVersionRegisterableScriptClasspathScanner">
<property name="scriptRegistry" ref="javaScriptProcessor.scriptRegistry" />
<property name="rootResourcePatterns">
<list>
<value>classpath*:alfresco/module/${project.artifactId}/registeredScripts</value>
<value>classpath*:alfresco/module/*/registeredScripts</value>
<value>classpath*:alfresco/extension/registeredScripts</value>
</list>
</property>
<property name="resourcePatternResolver" ref="resourceFinder" />
</bean>
This scanner will look for any files with the suffix ".js" and bootstrap them into the registry based on their paths below the configured root resources. By organising "*.js" files into different paths below the root, the developer can populate all the parameters that are available in Spring.
- the first folder in a path named "enterprise", "community" or "general" will cause scripts therein to be registered for Enterprise-/Community-only or without restriction
- the first folder in a path that is a valid version number (e.g. "1.0" or "1.4.1") will define the version of the scripts therein (e.g. group all scripts of a specific module release)
- the first folder in a path that is a valid version range (e.g. "[1.0-2.0)", "-2.0]", "(1.0-") will define the range of applicable abstract versions for the scripts therein (a square bracket defines an exclusive, a parenthesis an inclusive version)
- the first folder in a path that does not define any other aspect (see previous points) will define the name of the sub-registry scripts therein will be registered with
- the name of the script file (without ".js" suffix) will define the name the script is registered with
The repository patch project defines and bootstraps two sub-registries with document library and document library filter scripts for various versions of Alfresco Community and Enterprise editions, including scripts that apply to both editions. Using the classpath scanner, any developer can add a new or adapted document library filter script by placing it in the correct resource path without having to override / duplicate any configuration or out-of-the-box script.