Server

Use of MVEL in Automation Chains

This page is scheduled for review and update. Check back soon for updated content!

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 Title

  • expr: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 the Title 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 variable path_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"): Returns 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 for CurrentUser.

  • 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.

Also note that we listed here the main accessors. Document is a DocumentWrapper and you can also check the code to see all the available accessors.
For example, you can also use hasFacet(String facet), hasSchema(String schemaName), etc. Make sure to select the branch corresponding to the version of Nuxeo you are using.

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, like dc: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"])}
    For example: @{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 the calendar wrapper.
    For example, to set up a field to:

    • today: @{CurrentDate.days(0).calendar}
    • in 7 days: @{CurrentDate.days(7).calendar}
  • 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)} where date_str is a Context variable containing a value such as "2019-09-26". You must pass to SimpleDateFormat the format of this date, so the parse() method work.

Functions

The Functions object is providing a set of useful functions. This object is named Fn and it provides the following functions (the full list can also be checked in the code, make sure to select the branch of your version):

  • Fn.getNextId(String key): Returns a unique value for the given key using the default sequencer. Each time this function is called using the same key a different string will be returned.

  • Fn.getNextId(String key, String sequencerName): Same as Fn.getNextId(String key) but allows for using a specific sequencer.

  • Fn.getVocabularyLabel(String vocabularyName, String key): Returns a value from the named vocabulary that is associated with the given key.

  • Fn.getPrincipal(String userName): Returns a Java NuxeoPrincipal object for the given username string.

  • Fn.getPrincipalsFromGroup(String group): Returns a Java Set of NuxeoPrincipal for the given group. Also returns the subgroups.

  • Fn.getPrincipalsFromGroup(String group, boolean ignoreGroups): Returns a Java Set of NuxeoPrincipal for the given group. Only the users are returned, not subgroups.

  • Fn.getEmail(String userName): Returns the e-mail of the given username.

  • Fn.getEmails(List<String> userNames): Returns a list of e-mails for the given user name list.

  • Fn.getEmails(List<String> userNames, boolean usePrefix): Returns a list of e-mails for the given user name list. If userPrefix is true, each item is prefixed with user:.

  • Fn.getPrincipalEmails(List<NuxeoPrincipal> principals): Same as above but the input object is a list of Nuxeo principals.

  • Fn.getEmailsFromGroup(String groupName): Returns a list of e-mails of all the users of the group.

  • 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): Same as concatenateIntoList but using a newly-created list.

  • Fn.htmlEscape(String string): Returns an escaped version of the string suitable for HTML inclusion.

  • Fn.nxqlEscape(String string): Returns an escaped version of the string suitable for NXQL inclusion inside single quotes.

  • Fn.documentExists(CoreSession session, String idOrPath): Returns true if the document exists in the repository.

  • Fn.getDirService(): Returns the DirectoryService. Requires administration privileges.

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 configure 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:

  1. Fetch the property using the Env map in your operation parameter: Env["automation.document.description"].
  2. 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.

Working with a list of properties

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)

Calling a Nuxeo service

 @{org.nuxeo.runtime.api.Framework.getService(org.nuxeo.business.days.management.service.BusinessDaysService).getLimitDate("myRule",CurrentDate.date)}

We'd love to hear your thoughts!

All fields required