Script Module
Version 9.1 by Vincent Massol on 2016/01/13 19:01
Scripting APIs, on top of JSR-223 |
Type | JAR |
Category | |
Developed by | |
Rating | |
License | GNU Lesser General Public License 2.1 |
Bundled With | XWiki Enterprise, XWiki Enterprise Manager |
Compatibility | XWiki > 2.3 |
Table of contents
Description
XWiki's scripting features are built on top of JSR-223.
The Script Module offers the following:
- Defines ScriptEvaluatedEvent and ScriptEvaluatingEvent events (see Observation Module) for being called before a script macro executes or just after it's been executed. The ScriptEvaluatedEvent event even allow to cancel the execution of the script macro.
- Provides a ScriptService component role allowing to expose APIs to script macros (see below)
Script Services
To expose an API to a script macro you simply need to implement the org.xwiki.script.service.ScriptService component role (see Component Module to know more about components).
For example:
@Component
@Named("my")
@Singleton
public class MyScriptService implements ScriptService
{
// Declare all java methods you wish to expose here. For example:
public void doSomething(String whatever)
{
...
}
}
@Named("my")
@Singleton
public class MyScriptService implements ScriptService
{
// Declare all java methods you wish to expose here. For example:
public void doSomething(String whatever)
{
...
}
}
Then to use this in a Velocity script macro for example you'll write:
{{velocity}}
$services.my.doSomething("something here")
{{/velocity}}
$services.my.doSomething("something here")
{{/velocity}}
Best Practices
- Script Service methods should not throw Exceptions. This rule is there so that it's easy to write scripts in Velocity. Instead they should return null in case of an error and the Script Service should provide a public Exception getLastError() method to get the last exception thrown. For example:public class ComponentScriptService implements ScriptService
{
/**
* The key under which the last encountered error is stored in the current execution context.
*/
private static final String ERROR_KEY = "scriptservice.component.error";
...
/**
* Provides access to the current context.
*/
@Inject
private Execution execution;
...
/**
* Get the error generated while performing the previously called action.
*
* @return the last exception or {@code null} if no exception was thrown
* @since 6.1M2
*/
public Exception getLastError()
{
return (Exception) this.execution.getContext().getProperty(ERROR_KEY);
}
/**
* Store a caught exception in the context, so that it can be later retrieved using {@link #getLastError()}.
*
* @param exception the exception to store, can be {@code null} to clear the previously stored exception
* @see #getLastError()
* @since 6.1M2
*/
private void setError(Exception exception)
{
this.execution.getContext().setProperty(ERROR_KEY, exception);
}
... Example of setting an exception...
public <T> T getInstance(Type roleType, String roleHint)
{
...
try {
result = cm.getInstance(roleType, roleHint);
} catch (ComponentLookupException e) {
setError(e);
}
...
}