Introduction
For the wishlist item
Jira Legacy | ||||||
---|---|---|---|---|---|---|
|
Requirements
When executing a batch the new metadata of the item should be able to be determined by
The previous/current metadata of the item
Combinations of fields
Conditions
Textual operations
Solution
...
Introduced in version 23.1
Introduction
Using Metadata Expressions a new batch task is available and named BatchExpressionTemplatesTask
. It takes as an argument a list of metadata sidecar e.g.-like arguments. An example of such metadata sidecar is
Code Block |
---|
{ "Descriptive": { "Title": "Metadata Expression Analysis" },#{R('Descriptive.Title').toUpperCase()}", "Description": "#{R('Descriptive.Title') + ': ' + R('Dynamic.CustomDescription')}", "Dynamic "Keywords": {"Keyword": "#{R('Dynamic.CustomTag')}"} }, "CustomFieldDynamic": { "Some value" } } |
This metadata sidecar can now use a strict Spring Expression Language (Spel) subset to perform more complex operations. You can put one or more expressions #{...}
in the JSON or XML. Inside an expression, you can reference the metadata using R(<Dotted key>)
or record(<Dotted key>)
for example R('Descriptive.Title')
or record('Descriptive.Title')
.
Info |
---|
The system ensures the result after evaluating the expression it is correctly escaped |
Example input
"Orientation": "#{(R('Technical.Width') > R('Technical.Height')) ? 'Horizontal' : 'Vertical'}",
"AdditionalInformation": "My custom field"
}
} |
Merging
When the templated sidecar is evaluated against a record it will result for example in the following metadata sidecar
Code Block |
---|
{ "Descriptive": { "Title": "R('Descriptive.Title').toUpperCase()MY TEST FILE", "Description": "R('Descriptive.Title') + ': ' + R('Dynamic.CustomField')My test file: this is a test file", "Keywords": {"Keyword": "{R('Dynamic.CustomField')}"["My custom tag"]} }, "Dynamic": { "CustomFieldOrientation": "R('Dynamic.CustomField2') == 'X' ? 'Option A' : 'Option B'"Horizontal", "AdditionalInformation": "My custom field" } } |
Tip |
This metadata sidecar will then be merged against the record using the same rules as when MediaHaven Rest API - Updating a record.
Output after evaluating the expression
After evaluating all expressions in the input metadata sidecar, the result is a new metadata sidecar in JSON. The conversion follows the following rules
Output after evaluating the expression | Conversion into JSON |
---|---|
| JSON string |
| JSON boolean |
| JSON number |
| JSON array |
| JSON object |
|
...
JSON object containing JSON arrays |
All special characters are automatically escaped
The output of the metadata accessor
The output of the metadata accessor R
or record
is the following depending on which field type the dotted key refers to:
...
Level
...
Case
...
Effect
...
Example Expression
...
Example Output
...
Top
...
SimpleField
...
String
...
R('Descriptive.Title')
...
My title
...
Top
...
ListField
...
List of Strings
...
R('Descriptive.Keywords')
...
["A", "B", "C"]
...
Top
...
MapField
...
Map of Strings
...
R('Structural.Versioning')
...
{"Status": "HEAD", "Version": "2"}
...
Top
...
MultiItemField
...
Map of List of Strings
...
R('Descriptive.Authors')
...
{"Authors": ["Cedric"], "Director": ["Alice", "Bob"]}
...
Top
Others
...
Not allowed
...
Sub
...
Child of ListField
...
List of Strings
...
R('Descriptive.Keywords.Keyword')
...
["A", "B", "C"]
...
Sub
...
Child of MultiItemField
...
List of Strings
...
R('Descriptive.Authors.Director')
...
["Alice", "Bob"]
...
Sub
...
Child of MapField
...
String
...
R('Structural.Versioning.Status')
...
HEAD
...
Sub
...
Other
...
Not allowed
The R
takes an optional second argument, which is the default value. When it is not specified the default value is the empty string.
Security
The available features of SPel are described here: https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html. We must disable all features except
Literal expressions
Boolean and relational operators
Method invocationInline lists
Ternary operator
The method name “R” or “record”
...
Notice how the string "#{R('Dynamic.CustomTag')}"
is evaluated into an array ["My custom tag"]
. The end result is a valid metadata sidecar for “Keywords” namely "Keywords": {"Keyword": ["My custom tag"]}
whereas before evaluating the expression "Keywords": {"Keyword": "#{...}"}
is not a strictly valid metadata sidecar because the value of "Keyword"
must be an array and not a string.