This documentation focuses on the MVEL expression language, used in automation chains. For a broader look on that subject, have a look at the Understand Expression and Scripting Languages Used in Nuxeo page.
How to Use Scripting Features in Parameters Values
Values you put in operations parameters are provided with scripting capability.
When filling in a parameter value (like "value" parameter of "update property" in the case we want to update the title of the a document), there are three options:
Title
: there is no interpretation (default behavior), the parameter is taken "as is", which means that the title will be "Title".expr:Title
starts with a "expr:
". The system will interpret the value "Title" as a scripting expression. In that case it means that the value of the title will be updated with the content of the variable Titleexpr:The real @{Title}
: When there is the use of@{my_variable_name}
in a script expression, the expression between bracket is considered as a variable name and resolved as a string, and the whole expression is evaluated as the concatenation of the various substrings (included the one interpreted). In our case, if theTitle
variable contains the string literal "Story", the title value will be "The real Story".
When the script is evaluated, you can use both contextual objects and embedded functions.
Scripting Context
Document: The Document object represents the input document, when the operation takes a document as input. You can use it to get a property value of it:
expr:Document["dc:title"]
You can also use methods provided by the Document Wrapper, see below.variable_name: if you set a context variable in a previous operation, you can access it in the parameter value by just referring to its name. In the following sample, if there was a
SetVariable
before in the operation flow that put the path of a document in the variablepath_of_the_workspace
, the parameter's value will be this path.expr:path_of_the_workspace
Do not use "-" character in the variable name. Prefer the use of
_
.Relative paths: each time you need to use a path expression (whether it is as a direct parameter of an operation, such as move, or in a an NXQL query, for STARTSWITH operator, you can leverage relative path capability:
- "." will be replaced by path of input document;
- ".." will be replaced by path of parent of input document.
CurrentDate: you can use the
CurrentDate
object, that will provide various utility methods to get the current date value, see below.Context.principal.model.getPropertyValue("schema:field"): gets the current user property. By default users implements user.xsd schema. So if you want for instance the company name,
Context.principal.model.getPropertyValue("user:company")
. But if your users implements other schemas, you choose your "schema prefix (or name if don't set) : field name"CurrentUser.actingUser: in a workflow context, all the automation operations executed by the workflow engine are executed using a temporary unrestricted session (if the current user is not an administrator, this is a session with the user "system"). This variable allows you to fetch the current user. This can also be useful when the operation "Users and groups > Login as" has been used in order to retrieve the current username.
Note that
currentUser
is an alias forCurrentUser
.- Event: in an event handler context, the Event object can be used to access some of the event's properties. For instance
@{Event.getName()}
will return the event name.
Document Wrapper
The Document wrapper, used by the system for any document put in scripting context (whether under a variable name, or as the input document ("Document") provides several utility methods:
Document.parent
: returns a document wrapper of the parent of the document;Document.workspace
: returns a document wrapper of the parent workspace of the document;Document.domain
: returns a document wrapper of the parent domain of the document;Document.path
: returns a string representing the value of the path of the document, like "/default-domain/workspaces/my-workspace";Document.title
: returns the title of the document;Document.description
: returns the description of the document;Document.type
: returns the Nuxeo EP Document type of the document (like "File", "Folder", ...);Document.lifeCycle
: returns the current lifecycle state of the document;Document.name
: returns the name of the document (last part of the path);Document.versionLabel
: returns the version name of the document (like "1.1"...).
Note that currentDocument
is an alias for Document
.
Date Wrapper
The Date wrapper is useful to update documents' date properties and to build time-relative NXQL queries.
CurrentDate.date
: returns the date. It is the method to use to update a document date field, likedc:valid
, or whatever custom date field.
Some other methods are provided to display the current date as a string:
CurrentDate.format("_java formatting expression_
")
: returns the current date in the specified format;CurrentDate.time
: returns the date in milliseconds;CurrentDate.day
: returns the day of the current time;CurrentDate.month
: returns the month of the current time;CurrentDate.year
: returns the year of the current time;CurrentDate.hour
: returns the hour of the current time;CurrentDate.minut
: returns the minutes of the current time;CurrentDate.second
: returns the seconds of the current time;CurrentDate.week
: returns the week of the current time.
Some others can be used when building an NXQL query to express dates relatively to the current date:
CurrentDate.days(-3)
: returns the current date minus three days;CurrentDate.years(10)
: returns the current date plus ten years;CurrentDate.months(-5).weeks(2).seconds(23)
: returns the current date minus five months plus two weeks and 23 seconds;...
• If you want to work on a date that is held by a property of your document, you first need to get a
DateWrapper
object, by using:@{Fn.calendar(Document["dc:created"])}
. Ex:@{Fn.calendar(Document["dc:created"]).format("yyyy-MM-dd")}
• To set a date property based on the current date, use the
CurrentDate
object, and ends the expression with thedate
wrapper. So for example, to set up the a field to...today:
@{CurrentDate.date}
...in 7 days:
@{CurrentDate.days(7).date}
• To create a date that you can set on a date property from a string, you can use...
@{new java.text.SimpleDateFormat("yyyy-MM-dd").parse(date_str)}
...wheredate_str
is a Context variable containing a value such as "2013-09-26": You must pass toSimpleDateFormat
the format of this date, so the parse() method will work.
Functions
The Functions object is providing a set of useful functions. This object is named _Fn_ and provide the following functions:
Fn.getNextId(String key)
: gets a unique value for the given key. Each time this function is called using the same key a different string will be returned.Fn.getVocabularyLabel(String vocabularyName, String key)
: gets a value from the named vocabulary that is associated with the given key.Fn.getPrincipal(String userName)
: gets a Nuxeo principal object for the given username string.Fn.getEmail(String userName)
: gets the e-mail of the given username.Fn.getEmails(List<String> userNames)
: gets a list of e-mails for the given user name list.Fn.getPrincipalEmails(List<NuxeoPrincipal> principals)
: the same as above but the input object is a list of Nuxeo principals.Fn.concatenateIntoList(List<T> list, Object... values)
: adds the values to the list. If a value is itself an array or a collection, each of its members are added to the list. The list is returned.Fn.concatenateValuesAsNewList(Object... values)
: likeconcatenateIntoList
but using a newly-created list.Fn.htmlEscape(String string)
: gets an escaped version of the string suitable for HTML inclusion.Fn.nxqlEscape(String string)
: gets an escaped version of the string suitable for NXQL inclusion inside single quotes (since Nuxeo 7.10).
Nuxeo Environment Properties
Nuxeo environment properties are accessible in scripts using the Env
map object. All the properties defined in Nuxeo property files located in Nuxeo conf
directory are available through the Env
map. This is very useful when you want to parametrize your operations using values that can be modified later on a running server.
For example let's say you want to make an operation that is creating a document and initialize its description from a Nuxeo property named automation.document.description
.
In order to do this you should:
- Fetch the property using the
Env
map in your operation parameter:Env["automation.document.description"]
. - And then on the target server to create a property file inside the Nuxeo
conf
directory that defines the variable you are using in the operation chain: automation.document.description = My Description
MVEL
The scripting language used is MVEL. See the MVEL language guide. You can use all the features of the scripting language itself.
For instance, you can use the substring method, when dealing with paths:
expr: Document.path.substring(26)
.
Testing if a variable is null:
@{WorkflowVariables["mail"] == empty?"VoidChain":"MyChain"}
Usage of empty
variable allows user to evaluate expression to empty string. For instance to set a property of a document to "" (empty string), you can define the value with empty:
@{empty}
Date Management Example
Operation | Destination field | Source value | Expression Example |
---|---|---|---|
Services > Create Task | due date | Current Date |
@{CurrentDate.date}
|
Next Month |
@{CurrentDate.month(1).date}
| ||
Given Date | 2012-03-15T00:00:00Z | ||
Date Property from the input Document |
@{Document.getProperty("dc:expired")}
| ||
Date Property from the input Document |
@{Document.getProperty("dc:expired")}
| ||
Document > Update property | value | Current Date |
@{CurrentDate.date}
|
Next Month |
@{CurrentDate.month(1).date}
| ||
Document > Update property | value | Current Date |
@{CurrentDate.date}
|
If you have an error like that in your logs:
No type adapter found for input: class org.nuxeo.ecm.automation.core.scripting.DateWrapper and output class java.util.Date
This means that you are presenting a DateWrapper value type into a field that waits for ajava.util.Date
object. |
User and Group Management Example
Operation | Destination field | Source value | Expression Example | Remark |
---|---|---|---|---|
Document > Update property | value | String | Administrator | |
Document > Update property | value | Static value | Current User | |
Services > Create task | additional list of actors prefixed ids | String |
user:Administrator
| |
String |
group:administrators
| |||
variable name for actors prefixed ids | In Context | variable | This variable can be set by the "User & Group > Get Users and Groups" with "prefix identifiers" checked. | |
Current User |
user:@{CurrentUser.name}
| |||
User & Group > Get Users and Groups |
Numbers Management example
Operation | Destination field | Source value | Expression Example | Remark |
---|---|---|---|---|
Conversion > Resize a picture | maxHeight/maxWidth | integer | 10 |
Document management example
Field management
Operation | Destination field | Source value | Expression Example | Remark |
---|---|---|---|---|
Document > Copy | target | String |
/default-domain/workspaces
| Here is specified the path of the container where the document is to be created. The path is given by the names of ancestors of the document (can be different from the title and stored into a different field of the document). |
Document > Copy | target | from context |
@{Context["documentStored"].name}
|
This will work if you have previously added the Execution Context > Set Context Variable into your automation chain to store the document into this documentStored variable.
|
name | String | name-of-my-document | This field is a technical one and used to create the notion of path (see above). This is not the title. This is also used for URL generation. Look at the URL after navigating to a document and you will see his path based on the names of the document's ancestor and its name. | |
Document > Create | type | String | File | Here you must use the name of the document type (not the label). |
Referencing Automation Chain Parameters
@{ChainParameters['parameterName']}
More Advanced Scripts
In this section, we will gather useful scripts so as to share experience on using scripting in automation, especially in the Run Script operation.
new ArrayList(Arrays.asList(WorkflowVariables["contributors"])); x.add(Context["workflowInitiator"]); WorkflowVariables["contributors"]=x;
// This works for workflow variables, (NodeVariables and WorkflowVariables) but would also work for a list property of a document, see this question on answers (http://answers.nuxeo.com/questions/4240/add-string-to-a-list-string-property-in-pure-studioautomation-for-prototypes)
@{org.nuxeo.runtime.api.Framework.getService(org.nuxeo.business.days.management.service.BusinessDaysService).getLimitDate("myRule",CurrentDate.date)}