diff --git a/nifi-docs/src/main/asciidoc/expression-language-guide.adoc b/nifi-docs/src/main/asciidoc/expression-language-guide.adoc new file mode 100644 index 0000000000..5e010647ce --- /dev/null +++ b/nifi-docs/src/main/asciidoc/expression-language-guide.adoc @@ -0,0 +1,1401 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +Apache NiFi Expression Language Guide +===================================== +Apache NiFi Team +:homepage: http://nifi.incubator.apache.org + +[[overview]] +Overview +-------- +All data in Apache NiFi is represented by an abstraction called a FlowFile. +A FlowFile is comprised of two major pieces: content and attributes. +The content portion of the FlowFile represents the data on which to operate. +For instance, if a file is picked up from a local file system using the +GetFile Processor, the contents of the file will become the contents of the +FlowFile. + +The attributes portion of the FlowFile represents information about the data +itself, or metadata. Attributes are key-value pairs that represent what is +known about the data as well as information that is useful for routing and +processing the data appropriately. +Keeping with the example of a file that is picked up from +a local file system, the FlowFile would have an attribute called `filename` that +reflected the name of the file on the file system. Additionally, the FlowFile will +have a `path` attribute that reflects the directory on the file system that this +file lived in. The FlowFile will also have an attribute named `uuid`, which is a +unique identifier for this FlowFile. + +However, placing these attributes on a FlowFile do not provide much benefit +if the user is unable to make use of them. The NiFi Expression Language provides +the ability to reference these attributes, compare them to other values, +and manipulate their values. + + +[[structure]] +Structure of a NiFi Expression +------------------------------ + +The NiFi Expression Language always begins with the start delimiter `${` and ends +with the end delimiter `}`. Between the start and end delimiters is the text of the +Expression itself. In its most basic form, the Expression can consist of just an +attribute name. For example, `${filename}` will return the value of the ``filename'' +attribute. + +In a slightly more complex example, we can instead return a manipulation of this value. +We can, for example, return an all upper-case version of the filename by calling the +`toUpper` function: `${filename:toUpper()}`. In this case, we reference the ``filename'' +attribute and then manipulate this value by using the `toUpper` function. A function call +consists of 5 elements. First, there is a function call delimiter `:`. Second is the name +of the function - in this case, ``toUpper''. Next is an open parenthesis (`(`), followed +by the function arguments. The arguments necessary are dependent upon which function +is being called. In this example, we are using the `toUpper` function, which does not +have any arguments, so this element is omitted. Finally, the closing parenthesis (`)`) +indicates the end of the function call. There are many different functions that are supported +by the Expression Language to achieve many different goals. Some functions provide String (text) +manipulation, such as the `toUpper` function. Others, such as the `equals` and `matches` functions, +provide comparison functionality. Functions also exist for manipulating dates and times and +for performing mathematical operations. Each of these functions is described below, in the +< section, with an explanation of what the function does, the arguments that it +requires, and the type of information that it returns. + +When we perform a function call on an attribute, as above, we refer to the attribute as the +_subject_ of the function, as the attribute is the entity on which the function is operating. +We can then chain together multiple function calls, where the return value of the first function +becomes the subject of the second function and its return value becomes the subject of the third +function and so on. Continuing with our example, we can chain together multiple functions by using +the expression `${filename:toUpper():equals('HELLO.TXT')}`. There is no limit to the number of +functions that can be chained together. + +Any FlowFile attribute can be referenced using the Expression Language. However, if the attribute +name contains a ``special character,'' the attribute name must be escaped by quoting it. The following +characters are each considered ``special characters'': + +- $ (dollar sign) +- | (pipe) +- { (open brace) +- } (close brace) +- ( (open parenthesis) +- ) (close parenthesis) +- [ (open bracket) +- ] (close bracket) +- , (comma) +- : (colon) +- ; (semicolon) +- / (forward slash) +- * (asterisk) +- ' (single quote) +- (space) +- \t (tab) +- \r (carriage return) +- \n (new-line) + +Additionally, a number is considered a ``special character'' if it is the first character of the attribute name. +If any of these special characters is present in an attribute is quoted by using either single or double quotes. +The Expression Language allows single quotes and double quotes to be used interchangeably. For example, the following +can be used to escape an attribute named ``my attribute'': `${"my attribute"}` or `${'my attribute'}`. + +In this example, the value to be returned is the value of the "my attribute" value, if it exists. If that attribute +does not exist, the Expression Language will then look for a System Environment Variable named "my attribute." If +unable to find this, it will look for a JVM System Property named "my attribute." Finally, if none of these exists, +the Expression Language will return a `null` value. + +There also exist some functions that expect to have no subject. These functions are invoked simply +by calling the function at the beginning of the Expression, such as `${hostname()}`. These functions +can then be changed together, as well. For example, `${hostname():toUpper()}`. Attempting to +evaluate the function with subject will result in an error. In the <> +section below, these functions will clearly indicate in their descriptions that they do not +require a subject. + +Often times, we will need to compare the values of two different attributes to each other. +We are able to accomplish this by using embedded Expressions. We can, for example, check if +the ``filename'' attribute is the same as the ``uuid'' attribute: `${filename:equals( ${uuid} )}`. +Notice here, also, that we have a space between the opening parenthesis for the `equals` method and +the embedded Expression. This is not necessary and does not affect how the Expression is evaluated +in any way. Rather, it is intended to make the Expression easier to read. White space is ignored by +the Expression Language between delimiters. Therefore, we can use the Expression +`${ filename : equals(${ uuid}) }` or `${filename:equals(${uuid})}` and both Expressions +mean the same thing. We cannot, however, use `${file name:equals(${uuid})}`, because this results +in `file` and `name` being interpreted as different tokens, rather than a single token, `filename`. + + + +[[usage]] +== Expression Language in the Application + +The Expression Language is used heavily throughout the NiFi application for configuring Processor +properties. Not all Processor properties support the Expression Language, however. Whether or not +a Property supports the Expression Language is determined by the developer of the Processor when +the Processor is written. However, the application strives to clearly illustrate for each Property +whether or not the Expression Language is supported. + +In the application, when configuring a Processor property, the User Interface provides an Information +icon ( +image:iconInfo.png["Info"] +) next to the name of the Property. Hovering over this icon with the mouse will provide a tooltip that +provides helpful information about the Property. This information includes a description of the Property, +the default value (if any), historically configured values (if any), and whether or not this Property +supports the expression language. + + +[[editor]] +=== Expression Language Editor + +When configuring the value of a Processor property, the NiFi User Interface provides help with the +Expression Language using the Expression Language editor. Once an Expression is begin by typing `${`, +the editor begins to highlight parentheses and braces so that the user is easily able to tell which +opening parenthesis or brace matches which closing parenthesis or brace. + +The editor also supplies context-sensitive help by providing a list of all functions that can be used +at the current cursor position. To activate this feature, press Ctrl+Space on the keyboard. The user +is also able to type part of a function name and then press Ctrl+Space to see all functions that can +be used that start with the same prefix. For example, if we type into the editor `${filename:to` +and then press Ctrl+Space, we are provided a pop-up that lists six different functions: `toDate`, +`toLower`, `toNumber`, `toRadix`, `toString`, and `toUpper`. We can then continue typing to narrow +which functions are shown, or we can select one of the functions from the list by double-clicking +it with the mouse or using the arrow keys to highlight the desired function and pressing Enter. + + + +[[functions]] +== Functions + +Functions provide a convenient way to manipulate and compare values of attributes. The Expression Language +provides many different functions to meet the needs of a automated dataflow. Each function takes +zero or more arguments and returns a single value. These functions can then be chained together to create +powerful Expressions to evaluate conditions and manipulate values. See <> for more information +on how to call and chain functions together. + +[[types]] +=== Data Types + +Each argument to a function and each value returned from a function has a specific data type. The Expression +Language supports four different data types: + +- *String*: A String is a sequence of characters that can consist of numbers, letters, white space, and + special characters. +- *Number*: A Number is an integer comprised of one or more digits (`0` through `9`). The Expression Language + does not provide support for fractional numbers. Dates and times are represented in the + Expression Language as Numbers, representing the number of milliseconds since midnight GMT on January 1, 1970. +- *Boolean*: A Boolean is one of either `true` or `false`. + +All attributes are considered to be of type String. + +The Expression Language is generally able to automatically coerce a value of one data type to the appropriate +data type for a function. However, functions do exist to manually coerce a value into a specific data type. +See the <> section for more information. + + + + + + +[[boolean]] +== Boolean Logic + +One of the most powerful features of the Expression Language is the ability to compare an attribute value against +some other value. This is used often, for example, to configure how a Processor should route data. The following +functions are used for performing boolean logic, such as comparing two values. +Each of these functions returns a value of type Boolean. + + +=== *isNull* +*Description*: The `isNull` function returns `true` if the subject is null, `false` otherwise. This is typically used to determine + if an attribute exists. + +*Subject Type*: Any + +*Arguments*: No arguments + +*Return Type*: Boolean + +*Examples*: `${filename:isNull()}` returns `true` if the "filename" attribute does not exist. + It returns `true` if the attribute exists. + + + +=== *notNull* +*Description*:The `notNull` function returns the opposite value of the `isNull` function. That is, it will return `true` if the + subject exists and `false` otherwise. + +*Subject Type*: Any + +*Arguments*: No arguments + +*Return Type*: Boolean + +*Examples*: `${filename:notNull()}` returns `true` if the "filename" attribute exists. It returns "false" if the attribute + does not exist. + + + +=== *equals* +*Description*: The `equals` function is very widely used and determines if its subject is equal to another String value. + Note that the `equals` function performs a direct comparison of two String values. Take care not to confuse this + function with the <> function, which evaluates its subject against a Regular Expression. + +*Subject Type*: Any + +*Arguments*: The equals function takes a single argument. It is expected to be of the same type as the Subject. + +*Return Type*: Boolean + +*Examples*: +We can check if the filename of a FlowFile is "hello.txt" by using the expression `${filename:equals('hello.txt')}`, +or we could check if the value of the attribute `hello` is equal to the value of the `filename` attribute: +`${hello:equals( ${filename} )}`. + + + +=== *equalsIgnoreCase* +*Description*: Similar to the `equals` function, the `equalsIgnoreCase` function compares its subject against a String value but returns +`true` if the two values differ only by case (upper case vs. lower case). + +*Subject Type*: String + +*Arguments*: 1: String + +*Return Type*: Boolean + +*Examples*: `${filename:equalsIgnoreCase('hello.txt')}` will evaluate to `true` if filename is equal to "hello.txt" + or "HELLO.TXT" or "HeLLo.TxT". + + + + +=== *gt* +*Description*: The `gt` function is used for numeric comparison and returns `true` if the subject is Greater Than + its argument. If either the subject or the argument cannot be coerced into a Number, + this function returns `false`. + +*Subject Type*: Number + +*Arguments*: 1: Number + +*Return Type*: Boolean + +*Examples*: `${fileSize:gt( 1024 )}` will return `true` if the size of the FlowFile's content is more than 1 kilobyte + (1024 bytes). Otherwise, it will return `false`. + + + + +=== *ge* +*Description*: The `ge` function is used for numeric comparison and returns `true` if the subject is Greater Than + Or Equal To its argument. If either the subject or the argument cannot be coerced into a Number, + this function returns `false`. + +*Subject Type*: Number + +*Arguments*: 1: Number + +*Return Type*: Boolean + +*Examples*: `${fileSize:ge( 1024 )}` will return `true` if the size of the FlowFile's content is at least ( + is greater than or equal to) 1 kilobyte (1024 bytes). Otherwise, it will return `false`. + + +=== *lt* +*Description*: The `lt` function is used for numeric comparison and returns `true` if the subject is Less Than + its argument. If either the subject or the argument cannot be coerced into a Number, + this function returns `false`. + +*Subject Type*: Number + +*Arguments*: 1: Number + +*Return Type*: Boolean + +*Examples*: `${fileSize:lt( 1048576 )}` will return `true` if the size of the FlowFile's content is less than + 1 megabyte (1048576 bytes). Otherwise, it will return `false`. + + + + +=== *le* +*Description*: The `le` function is used for numeric comparison and returns `true` if the subject is Less Than + Or Equal To its argument. If either the subject or the argument cannot be coerced into a Number, + this function returns `false`. + +*Subject Type*: Number + +*Arguments*: 1: Number + +*Return Type*: Boolean + +*Examples*: `${fileSize:le( 1048576 )}` will return `true` if the size of the FlowFile's content is at most + (less than or equal to) 1 megabyte (1048576 bytes). Otherwise, it will return `false`. + + + + + + +=== *and* +*Description*: The `and` function takes as a single argument a Boolean value and returns `true` if both the Subject + and the argument are `true`. If either the subject or the argument is `false` or cannot be coerced into a Boolean, + the function returns `false`. Typically, this is used with an embedded Expression as the argument. + +*Subject Type*: Boolean + +*Arguments*: 1: Boolean + +*Return Type*: Boolean + +*Examples*: We can check if the filename is both all lower-case and has at least 5 characters by using the Expression +----------------------------------------------- +${filename:toLower():equals( ${filename} ):and( + ${filename:length():ge(5)} +)} +----------------------------------------------- + + + + + +=== *or* + +*Description*: The `or` function takes as a single argument a Boolean value and returns `true` if either the Subject + or the argument is `true`. If both the subject and the argument are `false`, the function returns `false`. If + either the Subject or the argument cannot be coerced into a Boolean value, this function will return `false`. + +*Subject Type*: Boolean + +*Arguments*: 1: Boolean + +*Return Type*: Boolean + +*Examples*: The following example will return `true` if either the filename has exactly 5 characters or if + the filename is all lower-case. +---------------------------------------------- +${filename:toLower():equals( ${filename} ):or( + ${filename:length():equals(5)} +)} +---------------------------------------------- + + + + +=== *not* + +*Description*: The `not` function returns the negation of the Boolean value of the subject. + +*Subject Type*: Boolean + +*Arguments*: No arguments + +*Return Type*: Boolean + +*Examples*: We can invert the value of another function by using the `not` function, as + `${filename:equals('hello.txt'):not()}`. This will return `true` if the filename is NOT equal to + "hello.txt" and will return `false` if the filename is "hello.txt." + + + + + + + +[[strings]] +== String Manipulation + +Each of the following functions manipulates a String in some way. + + + + +=== *toUpper* + +*Description*: This function converts the Subject into an all upper-case String. Said another way, it + replaces any lowercase letter with the uppercase equivalent. + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: If the "filename" attribute is "abc123.txt", then the Expression `${filename:toUpper()}` + will return "ABC123.TXT" + + + + + +=== *toLower* + +*Description*: This function converts the Subject into an all lower-case String. Said another way, + it replaces any uppercase letter with the lowercase equivalent. + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: If the "filename" attribute is "ABC123.TXT", then the Expression `${filename:toLower()}` + will return "abc123.txt" + + + + + +=== *trim* + +*Description*: The `trim` function will remove any leading or trailing white space from its subject. + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: If the attribute `attr` has the value " 1 2 3 ", then the Expression `${attr:trim()}` will + return the value "1 2 3". + + + + + +=== *urlEncode* + +*Description*: Returns a URL-friendly version of the Subject. This is useful, for instance, when using an + attribute value to indicate the URL of a website. + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: We can URL-Encode an attribute named "url" by using the Expression `${url:urlEncode()}`. If + the value of the "url" attribute is "https://nifi.incubator.apache.org/some value with spaces", this + Expression will then return "https://nifi.incubator.apache.org/some%20value%20with%20spaces". + + + + +=== *urlDecode* + +*Description*: Converts a URL-friendly version of the Subject into a human-readable form. + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: If we have a URL-Encoded attribute named "url" with the value + "https://nifi.incubator.apache.org/some%20value%20with%20spaces", then the Expression + `${url:urlDecode()}` will return "https://nifi.incubator.apache.org/some value with spaces". + + + + + +=== *substring* + +*Description*: + Returns a portion of the Subject, given a _starting index_ and an optional _ending index_. + If the _ending index_ is not supplied, it will return the portion of the Subject starting at the given + 'start index' and ending at the end of the Subject value. + + +The _starting index_ and _ending index_ are zero-based. That is, the first character is referenced by using + the value `0`, not `1`. + +If either the _starting index_ is or the _ending index_ is not a number, this function call will result + in an error. + +If the _starting index_ is larger than the _ending index_, this function call will result in an error. + +If the _starting index_ or the _ending index_ is greater than the length of the Subject or has a value + less than 0, this function call will result in an error. + + +*Subject Type*: String + +*Arguments*: + + - _starting index_ : Number + - _ending index_ : Number + +*Return Type*: String + +*Examples*: + +If we have an attribute named "filename" with the value "a brand new filename.txt", +then the following Expressions will result in the following values: + +.Substring Examples +|================================================================ +| Expression | Value +| `${filename:substring(0,1)}` | `a` +| `${filename:substring(2)}` | `brand new filename.txt` +| `${filename:substring(12)}` | `filename.txt` +| `${filename:substring( ${filename:length():minus(2)} )}` | `xt` +|================================================================ + + + + +=== *substringBefore* + +*Description*: Returns a portion of the Subject, starting with the first character of the Subject + and ending with the character immediately before the first occurrence of the argument. If + the argument is not present in the Subject, the entire Subject will be returned. + +*Subject Type*: String + +*Arguments*: 1: String: The String to search for in the Subject + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", + then the following Expressions will result in the following values: + +.SubstringBefore Examples +|====================================================================== +| Expression | Value +| `${filename:substringBefore('.')}` | `a brand new filename` +| `${filename:substringBefore(' ')}` | `a` +| `${filename:substringBefore(' n')}` | `a brand` +| `${filename:sbustringBefore('missing')}` | `a brand new filename.txt` +|====================================================================== + + + + + +=== *substringBeforeLast* + +*Description*: Returns a portion of the Subject, starting with the first character of the Subject + and ending with the character immediately before the last occurrence of the argument. If + the argument is not present in the Subject, the entire Subject will be returned. + +*Subject Type*: String + +*Arguments*: 1: String: The String to search for in the Subject + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", + then the following Expressions will result in the following values: + +.SubstringBeforeLast Examples +|========================================================================== +| Expression | Value +| `${filename:substringBeforeLast('.')}` | `a brand new filename` +| `${filename:substringBeforeLast(' ')}` | `a brand new` +| `${filename:substringBeforeLast(' n')}` | `a brand` +| `${filename:substringBeforeLast('missing')}` | `a brand new filename.txt` +|========================================================================== + + + + + + +=== *substringAfter* + +*Description*: Returns a portion of the Subject, starting with the character immediately after + the first occurrence of the argument and extending to the end of the Subject. If + the argument is not present in the Subject, the entire Subject will be returned. + +*Subject Type*: String + +*Arguments*: 1: String: The String to search for in the Subject + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", + then the following Expressions will result in the following values: + +.SubstringAfter Examples +|====================================================================== +| Expression | Value +| `${filename:substringAfter('.')}` | `txt` +| `${filename:substringAfter(' ')}` | `brand new filename.txt` +| `${filename:substringAfter(' n')}` | `ew filename.txt` +| `${filename:substringAfter('missing')}` | `a brand new filename.txt` +|====================================================================== + + + + + +=== *substringAfterLast* + +*Description*: Returns a portion of the Subject, starting with the character immediately after + the last occurrence of the argument and extending to the end of the Subject. If + the argument is not present in the Subject, the entire Subject will be returned. + +*Subject Type*: String + +*Arguments*: 1: String: The String to search for in the Subject + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", + then the following Expressions will result in the following values: + +.SubstringAfterLast Examples +|========================================================================= +| Expression | Value +| `${filename:substringAfterLast('.')}` | `txt` +| `${filename:substringAfterLast(' ')}` | `filename.txt` +| `${filename:substringAfterLast(' n')}` | `ew filename.txt` +| `${filename:substringAfterLast('missing')}` | `a brand new filename.txt` +|========================================================================= + + + + + + + +=== *append* + +*Description*: The `append` function returns the result of appending the argument to the value of + the Subject. If the Subject is null, returns the argument itself. + +*Subject Type*: String + +*Arguments*: 1: String + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the Expression + `${filename:append('.gz')}` will return "a brand new filename.txt.gz". + + + + + +=== *prepend* + +*Description*: The `prepend` function returns the result of prepending the argument to the value of + the Subject. If the subject is null, returns the argument itself. + +*Subject Type*: String + +*Arguments*: 1: String + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "filename.txt", then the Expression + `${filename:prepend('a brand new ')}` will return "a brand new filename.txt". + + + + + +=== *replace* + +*Description*: Replaces occurrences of one String within the Subject with another String. + +*Subject Type*: String + +*Arguments*: 2 + + _Search String_: The String to find within the Subject + _Replacement_: The value to replace _Search String_ with + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the following +Expressions will provide the following results: + + + +.Replace Examples +|=================================================================== +| Expression | Value +| `${filename:replace('.', '_')}` | `a brand new filename_txt` +| `${filename:replace(' ', '.')}` | `a.brand.new.filename.txt` +| `${filename:replace('XYZ', 'ZZZ')}` | `a brand new filename.txt` +| `${filename:replace('filename', 'book')}` | `a brand new book.txt` +|=================================================================== + + + + + +=== *replaceAll* + +*Description*: The `replaceAll` function takes two String arguments: a Regular Expression (NiFi uses the Java Pattern + syntax), and a replacement string. The return value is the result of substituting the replacement string for + all patterns within the Subject that match the Regular Expression. + +*Subject Type*: String + +*Arguments*: 2 + + _regular expression_: the Regular Expression (in Java syntax) to match in the Subject + _replacement_: The value to use for replacing matches in the Subject. If the _regular expression_ + argument uses Capturing Groups, back references are allowed in the _replacement_. + +*Return Type*: String + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the following +Expressions will provide the following results: + + + +.ReplaceAll Examples +|======================================================================================= +| Expression | Value +| `${filename:replaceAll('\..*', '')}` | `a brand new filename` +| `${filename:replaceAll('a brand (new)', '$1')}` | `new filename.txt` +| `${filename:replaceAll('XYZ', 'ZZZ')}` | `a brand new filename.txt` +| `${filename:replaceAll('brand (new)', 'somewhat $1')}` | `a somewhat new filename.txt` +|======================================================================================= + + + + + + +=== *replaceNull* + +*Description*: The `replaceNull` function returns the argument if the Subject is null. Otherwise, + returns the Subject. + +*Subject Type*: Any + +*Arguments*: 1: Any Type + +*Return Type*: Type of Subject if Subject is not null; else, type of Argument + +*Examples*: If the attribute "filename" has the value "a brand new filename.txt" and the attribute + "hello" does not exist, then the Expression `${filename:replaceNull('abc')}` will return + "a brand new filename.txt", while `${hello:replaceNull('abc')}` will return "abc". + + + + + +=== *length* + +*Description*: Returns the length of the Subject + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: Number + +*Examples*: If the attribute "filename" has a value of "a brand new filename.txt" and the attribute + "hello" does not exist, then the Expression `${filename:length()}` will return 24. `${hello:length()}` + will return 0. + + + + + + + + +[[searching]] +== Searching + +Each of the following functions is used to search its subject for some value. + + +=== *startsWith* + +*Description*: Returns `true` if the Subject starts with the String provided as the argument, + `false` otherwise. + +*Subject Type*: String + +*Arguments*: 1: String + +*Return Type*: Boolean + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the Expression + `${filename:startsWith('a brand')}` will return `true`. `${filename:startsWith('A BRAND')}` will + return `false`. `${filename:toUpper():startsWith('A BRAND')}` returns `true`. + + + + + +=== *endsWith* + +*Description*: Returns `true` if the Subject ends with the String provided as the argument, + `false` otherwise. + +*Subject Type*: String + +*Arguments*: 1: String + +*Return Type*: Boolean + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the Expression + `${filename:endsWith('txt')}` will return `true`. `${filename:endsWith('TXT')}` will + return `false`. `${filename:toUpper():endsWith('TXT')}` returns `true`. + + + + + +=== *contains* + +*Description*: Returns `true` if the Subject contains the value of the argument anywhere in the + value. + +*Subject Type*: String + +*Arguments*: 1: String + +*Return Type*: Boolean + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the Expression + `${filename:contains('new')}` will return `true`. `${filename:contains('NEW')}` will + return `false`. `${filename:toUpper():contains('NEW')}` returns `true`. + + + + + +=== *find* + +*Description*: Returns `true` if the Subject contains any sequence of characters that matches the + Regular Expression provided by the argument. + +*Subject Type*: String + +*Arguments*: 1: String: a Regular Expression (in the Java Pattern syntax) to search for in the Subject. + +*Return Type*: Boolean + +*Examples*: + +If the "filename" attribute has the value "a brand new filename.txt", then the following +Expressions will provide the following results: + + +.find Examples +|======================================================================================= +| Expression | Value +| `${filename:find('a [Bb]rand [Nn]ew')}` | `true` +| `${filename:find('Brand.*')}` | `false` +| `${filename:find('brand')}` | `true` +|======================================================================================= + + + + + +=== *matches* + +*Description*: Returns `true` if the Subject exactly matches the Regular Expression provided by the argument. + +*Subject Type*: String + +*Arguments*: 1: String: a Regular Expression (in the Java Pattern syntax) to match against the Subject. + +*Return Type*: Boolean + +*Examples*: + +If the "filename" attribute has the value "a brand new filename.txt", then the following +Expressions will provide the following results: + + +.matches Examples +|======================================================================================= +| Expression | Value +| `${filename:matches('a.*txt')}` | `true` +| `${filename:matches('brand')}` | `false` +| `${filename:matches('.+brand.+')}` | `true` +|======================================================================================= + + + + +=== *indexOf* + +*Description*: Returns the index of the first character in the Subject that matches the String value provided + as an argument. If the argument is found multiple times within the Subject, the value returned is the + starting index of the *first* occurrence. + If the argument cannot be found in the Subject, returns `-1`. The index is zero-based. This means that if + the search string is found at the beginning of the Subject, the value returned will be `0`, not `1`. + +*Subject Type*: String + +*Arguments*: String + +*Return Type*: Number + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the following +Expressions will provide the following results: + + + +.indexOf Examples +|======================================================================================= +| Expression | Value +| `${filename:indexOf('a.*txt')}` | `-1` +| `${filename:indexOf('.')}` | `20` +| `${filename:indexOf('a')}` | `0` +| `${filename:indexOf(' ')}` | `1` +|======================================================================================= + + + + +=== *lastIndexOf* + +*Description*: Returns the index of the first character in the Subject that matches the String value provided + as an argument. If the argument is found multiple times within the Subject, the value returned is the + starting index of the *last* occurrence. + If the argument cannot be found in the Subject, returns `-1`. The index is zero-based. This means that if + the search string is found at the beginning of the Subject, the value returned will be `0`, not `1`. + +*Subject Type*: String + +*Arguments*: String + +*Return Type*: Number + +*Examples*: If the "filename" attribute has the value "a brand new filename.txt", then the following +Expressions will provide the following results: + +.lastIndexOf Examples +|======================================================================================= +| Expression | Value +| `${filename:lastIndexOf('a.*txt')}` | `-1` +| `${filename:lastIndexOf('.')}` | `20` +| `${filename:lastIndexOf('a')}` | `17` +| `${filename:lastIndexOf(' ')}` | `11` +|======================================================================================= + + + + +[[numbers]] +== Mathematical Operations and Numeric Manipulation + + +=== *plus* + +*Description*: Adds a numeric value to the Subject. If either the argument or the Subject cannot be + coerced into a Number, returns `null`. + +*Subject Type*: Number + +*Arguments*: 1: Number + +*Return Type*: Number + +*Examples*: If the "fileSize" attribute has a value of 100, then the Expression `${fileSize:plus(1000)}` + will return the value `1100`. + + + + + +=== *minus* + +*Description*: Subtracts a numeric value from the Subject. + +*Subject Type*: Number + +*Arguments*: Number + +*Return Type*: Number + +*Examples*: If the "fileSize" attribute has a value of 100, then the Expression `${fileSize:minus(100)}` + will return the value `0`. + + + + + +=== *multiply* + +*Description*: Multiplies a numeric value by the Subject and returns the product. + +*Subject Type*: Number + +*Arguments*: Number + +*Return Type*: Number + +*Examples*: If the "fileSize" attribute has a value of 100, then the Expression `${fileSize:multiply(1024)}` + will return the value `102400`. + + + + +=== *divide* + +*Description*: Divides a numeric value by the Subject and returns the result, rounded down to the nearest integer. + +*Subject Type*: Number + +*Arguments*: Number + +*Return Type*: Number + +*Examples*: If the "fileSize" attribute has a value of 100, then the Expression `${fileSize:divide(12)}` + will return the value `8`. + + + + +=== *mod* + +*Description*: Performs a modular division of the Subject by the argument. That is, this function will divide + the Subject by the value of the argument and return not the quotient but rather the remainder. + +*Subject Type*: Number + +*Arguments*: Number + +*Return Type*: Number + +*Examples*: If the "fileSize" attribute has a value of 100, then the Expression `${fileSize:mod(12)}` + will return the value `4`. + + + + + +=== *toRadix* + +*Description*: Converts the Subject from a Base 10 number to a different Radix (or number base). An optional + second argument can be used to indicate the minimum number of characters to be used. If the converted value + has fewer than this number of characters, the number will be padded with leading zeroes. + +*Subject Type*: Number + +*Arguments*: 2 + + _Desired Base_: A Number between 2 and 36 (inclusive) + _Padding_: Optional argument that specifies the minimum number of characters in the converted output + +*Return Type*: String + +*Examples*: If the "fileSize" attributes has a value of 1024, then the following Expressions will yield + the following results: + + +.toRadix Examples +|======================================================================================= +| Expression | Value +| `${fileSize:toRadix(10)}` | `1024` +| `${fileSize:toRadix(10, 1)}` | `1024` +| `${fileSize:toRadix(10, 8)}` | `00001024` +| `${fileSize:toRadix(16)}` | `400` +| `${fileSize:toRadix(16, 8)}` | `00000400` +| `${fileSize:toRadix(2)}` | `10000000000` +| `${fileSize:toRadix(2, 16)}` | `0000010000000000` +|======================================================================================= + + + + +[[dates]] +== Date Manipulation + + + +[[format]] +=== *format* + +*Description*: Formats a number as a date/time according to the format specified by the argument. The argument + must be a String that is a valid Java SimpleDateFormat format. The Subject is expected to be a Number that + represents the number of milliseconds since Midnight GMT January 1, 1970. + +*Subject Type*: Number + +*Arguments*: 1: String: The format to output the date in. + +*Return Type*: String + +*Examples*: If the attribute "time" has the value "1420058163264", then the following Expressions will yield + the following results: + +.format Examples +|============================================================================ +| Expression | Value +| `${time:format("yyyy/MM/dd HH:mm:ss.SSS'Z'")}` | `2014/12/31 15:36:03.264Z` +| `${time:format("yyyy/MM/dd")}` | `2014/12/31` +| `${time:format("HH:mm:ss.SSS'Z'")}` | `15:36:03.264Z` +| `${time:format("2014")}` | `2014` +|============================================================================ + + + + + +=== *toDate* + +*Description*: Converts a String into a Number, based on the format specified by the argument. The argument + must be a String that is a valid Java SimpleDateFormat format. The Subject is expected to be a String + that is formatted according the argument. The return value is the numbr of milliseconds since + Midnight GMT January 1, 1979. + +*Subject Type*: String + +*Arguments*: String + +*Return Type*: Number + +*Examples*: If the attribute "year" has the value "2014" and the attribute "time" has the value "2014/12/31 15:36:03.264Z", + then the Expression `${year:toDate('yyyy')}` will return the number of milliseconds between Midnight GMT on January 1, 1970 + and Midnight GMT on January 1, 2014. The Expression `${time:toDate("yyyy/MM/dd HH:mm:ss.SSS'Z'")}` will result in the + number of milliseconds between Midnight GMT on January 1, 1970 and 15:36:03.264 GMT on December 31, 2014. + + Often, this function is used in conjunction with the <> function to change the format of a date/time. For example, + if the attribute "date" has the value "12-24-2014" and we want to change the format to "2014/12/24", we can do so by + chaining together the two functions: `${date:toDate('MM-dd-yyyy'):format('yyyy/MM/dd')}`. + + + + +=== *now* + +*Description*: The `now` function returns the current date and time as the number of milliseconds since Midnight GMT on + January 1, 1970. + +*Subject Type*: No Subject + +*Arguments*: No arguments + +*Return Type*: Number + +*Examples*: We can format the current date and time by using the `now` function in conjunction with the <> function: + `${now():format('yyyy/MM/dd HH:mm:ss')}`. + + + + + +[[type_cast]] +== Type Coercion + +=== *toString* + +*Description*: Coerces the Subject into a String + +*Subject Type*: Any type + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: The Expression `${fileSize:toNumber():toString()}` converts the value of "fileSize" attribute to a number and + back to a String. + + + + + +=== *toNumber* + +*Description*: Coerces the Subject into a Number + +*Subject Type*: String + +*Arguments*: No arguments + +*Return Type*: Number + +*Examples*: The Expression `${fileSize:toNumber()}` converts the String attribute value of "fileSize" to a number. + + + + + + +[[subjectless]] +== Subjectless Functions + +=== *ip* + +*Description*: Returns the IP address of the machine. + +*Subject Type*: No subject + +*Arguments*: No arguments + +*Return Type*: String + +*Examples*: ${ip()} + + + + + +=== *hostname* + +*Description*: Returns the Hostname of the machine. An optional argument of type Boolean can be provided + to specify whether or not the Fully Qualified Domain Name should be used. If `false`, or not specified, + the hostname will not be fully qualified. If the argument is `true` but the fully qualified hostname + cannot be resolved, the simple hostname will be returned. + +*Subject Type*: No subject + +*Arguments*: 1: Boolean: Optionally specify whether or not the hostname to return should be fully qualified, + if not specified, defaults to `false`. + +*Return Type*: String + +*Examples*: ${hostname(true)} + + + + + +=== *UUID* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + +=== *nextInt* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + + +[[multi]] +== Evaluating Multiple Attributes + +=== *anyAttribute* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + +=== *allAttributes* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + +=== *anyMatchingAttribute* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + +=== *allMatchingAttributes* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + +=== *anyDelineatedValue* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + +=== *allDelineatedValues* + +*Description*: + +*Subject Type*: + +*Arguments*: + +*Return Type*: + +*Examples*: + + + + + + +