Difference between revisions of "Architecture - Available transformation functions"

From wiki.gpii
Jump to: navigation, search
Line 11: Line 11:
 
These transformations takes an input which can be defined in two ways:
 
These transformations takes an input which can be defined in two ways:
  
*''value'': As a constant defined in the expander using the key ''value''
+
*''value'': As a constant defined in the transform using the key ''value''
 
*''inputPath'': As a path reference to the input (model) by using the key ''inputPath''.
 
*''inputPath'': As a path reference to the input (model) by using the key ''inputPath''.
  
If both keys are used in an ''expander'' declaration, the value found at the ''inputPath'' will be used if something is found there. If not, the transformer will default to using the value defined by ''value''. Besides this input, the transformation might require an arbitrary number of constants given in the expander declaration.
+
If both keys are used in an ''transform'' declaration, the value found at the ''inputPath'' will be used if something is found there. If not, the transformer will default to using the value defined by ''value''. Besides this input, the transformation might require an arbitrary number of constants given in the transform declaration.
  
 
== standardOutputTransformationFunction: ==
 
== standardOutputTransformationFunction: ==
Line 22: Line 22:
 
*''outputPath'': An EL path to where the transformation should output it's value to.
 
*''outputPath'': An EL path to where the transformation should output it's value to.
  
In case the expander is nested within other expanders (eg. a valuemapper), the outputPath specified will be relative to the outputPaths specified in the outer levels as well as to the location of the outermost expander.
+
In case the transform is nested within other transforms (eg. a valuemapper), the outputPath specified will be relative to the outputPaths specified in the outer levels as well as to the location of the outermost transform.
  
 
== standardTransformationFunction: ==
 
== standardTransformationFunction: ==
Line 30: Line 30:
 
== multiInputTransformationFunction: ==
 
== multiInputTransformationFunction: ==
  
These transformations allows for multiple inputs. In their default blocks, besides the gradename, they require an "inputVariables" key. The value of this should be a hash of key-value pairs, where the key is the variable name and the value is the default value to assign to the variable in case no matching constant or path is found. For each of the variables declared, the system will look up the source-model path defined by <variable>Path in the expander and the <variable> declared in the expander. The path takes priority. Example:
+
These transformations allows for multiple inputs. In their default blocks, besides the gradename, they require an "inputVariables" key. The value of this should be a hash of key-value pairs, where the key is the variable name and the value is the default value to assign to the variable in case no matching constant or path is found. For each of the variables declared, the system will look up the source-model path defined by <variable>Path in the transform and the <variable> declared in the transform. The path takes priority. Example:
 
<pre>fluid.defaults("fluid.transforms.scaleValue", {
 
<pre>fluid.defaults("fluid.transforms.scaleValue", {
 
     gradeNames: [ "fluid.multiInputTransformFunction" ],
 
     gradeNames: [ "fluid.multiInputTransformFunction" ],
Line 40: Line 40:
 
});
 
});
 
</pre>
 
</pre>
The above declaration defines three input variables; value, factor and offset. Taking as an example the factor, the first thing that will be looked up in the expander is the value of "factorPath". If it is defined, this path will be looked up in the source-model and this will be assigned to factor if found. If it's not found, the value (expanded if necessary) of the "factor" key of the expander will be used if found. If neither is found, the default value of 1 will be assigned to factor.
+
The above declaration defines three input variables; value, factor and offset. Taking as an example the factor, the first thing that will be looked up in the transform is the value of "factorPath". If it is defined, this path will be looked up in the source-model and this will be assigned to factor if found. If it's not found, the value (expanded if necessary) of the "factor" key of the transform will be used if found. If neither is found, the default value of 1 will be assigned to factor.
  
 
The inputVariables will be available to fluid.transforms.scaleValue as the first argument in the form of an object keyed by variable names with the values as described above.
 
The inputVariables will be available to fluid.transforms.scaleValue as the first argument in the form of an object keyed by variable names with the values as described above.
Line 57: Line 57:
  
 
'''Syntax:'''
 
'''Syntax:'''
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.literalValue",
 
     type: "fluid.transforms.literalValue",
 
     input: <constant value>
 
     input: <constant value>
 
}
 
}
 
</pre>
 
</pre>
=== <br/> ===
+
 
  
 
=== Example 1: You can user literal value if you have some constant that you want to output to the document ===
 
=== Example 1: You can user literal value if you have some constant that you want to output to the document ===
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.literalValue",
 
     type: "fluid.transforms.literalValue",
 
     input: "some constant"
 
     input: "some constant"
Line 75: Line 75:
  
 
=== Example 2: The content of literal value will need be transformed further ===
 
=== Example 2: The content of literal value will need be transformed further ===
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.literalValue",
 
     type: "fluid.transforms.literalValue",
 
     input: {
 
     input: {
Line 92: Line 92:
  
  
=== Example 3: Like all expanders - will fall back from path to direct value ===
+
=== Example 3: Like all transforms - will fall back from path to direct value ===
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.literalValue",
 
     type: "fluid.transforms.literalValue",
 
     input: "balloon",
 
     input: "balloon",
Line 101: Line 101:
 
'''Output:''' if anything is found at the path "some.path" the content of that will be output literally, else "balloon" will be output
 
'''Output:''' if anything is found at the path "some.path" the content of that will be output literally, else "balloon" will be output
  
== <br/> ==
 
  
== To Array ==
 
  
Type: standardTransformation Inputs:
+
== To Array (fluid.transforms.arrayValue) ==
 +
 
 +
'''description''': This transformation will turn its value into an array if it's not already an array.
 +
 
 +
'''Type''': standardTransformation Inputs:
  
 
*input / inputPath
 
*input / inputPath
  
Syntax:
+
'''Syntax:'''
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.arrayValue",
 
     type: "fluid.transforms.arrayValue",
     value: <constant value>
+
     input: <constant value>
 
}
 
}
 
</pre>
 
</pre>
This transformation will turn its value into an array if it's not already an array.
 
  
Example:
+
=== Example 1: Passing a single value will wrap it in an array ===
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.arrayValue",
 
     type: "fluid.transforms.arrayValue",
     value: "some constant"
+
     input: "some constant"
 
}
 
}
 
</pre>
 
</pre>
The above would give us: [ "some constant" ]. If the ''value'' had been an array already, it would just had been passed as is (so in the case - value: [ "some constant "] - we would have got the same output.
+
'''output''':  
 +
<pre>
 +
[ "some constant" ]
 +
</pre>
 +
 
 +
If the ''value'' had been an array already, it would just had been passed as is (so in the case - value: [ "some constant "] - we would have got the same output).
 +
 
 +
 
 +
== Count length of array (fluid.transforms.count) ==
  
== Count length of array ==
 
  
 
Type: standardTransformation Inputs:
 
Type: standardTransformation Inputs:
 +
 +
'''Description:''' If the input is an array, the lenght of the array will be the output of this function. If the input is a primitive or object, 1 will be returned.
  
 
*input / inputPath
 
*input / inputPath
Line 135: Line 145:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.count",
 
     type: "fluid.transforms.count",
 
     value: <constant value>
 
     value: <constant value>
 
}
 
}
 
</pre>
 
</pre>
If the input is an array, the lenght of the array will be the output of this function. If the input is a primitive or object, 1 will be returned.
 
  
 
Example:
 
Example:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.arrayValue",
 
     type: "fluid.transforms.arrayValue",
 
     value: [ "foo", "bar" ]
 
     value: [ "foo", "bar" ]
Line 157: Line 166:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.firstValue",
 
     type: "fluid.transforms.firstValue",
 
     value: <constant of array type>
 
     value: <constant of array type>
Line 166: Line 175:
 
Example:
 
Example:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.firstValue",
 
     type: "fluid.transforms.firstValue",
 
     value: [ "foo", "bar" ]
 
     value: [ "foo", "bar" ]
Line 179: Line 188:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.delete",
 
     type: "fluid.transforms.delete",
 
     outputPath: <the output path to delete>
 
     outputPath: <the output path to delete>
Line 190: Line 199:
 
{
 
{
 
     "": ""
 
     "": ""
     expander: {
+
     transform: {
 
         type: "fluid.transforms.delete",
 
         type: "fluid.transforms.delete",
 
         outputPath: foo
 
         outputPath: foo
Line 196: Line 205:
 
}
 
}
 
</pre>
 
</pre>
Given the model as input: { hello: "world", foo: "bar" }, the above would give the value { hello: "world" }. The "": "" in the expander would normally mean that the entire input model is copied without any transformations, but the delete expander ensures that the path "foo" is deleted.
+
Given the model as input: { hello: "world", foo: "bar" }, the above would give the value { hello: "world" }. The "": "" in the transform would normally mean that the entire input model is copied without any transformations, but the delete transform ensures that the path "foo" is deleted.
  
  
Line 204: Line 213:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.firstValue",
 
     type: "fluid.transforms.firstValue",
 
     value: <constant of array type>
 
     value: <constant of array type>
Line 213: Line 222:
 
Example:
 
Example:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.firstValue",
 
     type: "fluid.transforms.firstValue",
 
     value: [ "foo", "bar" ]
 
     value: [ "foo", "bar" ]
Line 228: Line 237:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.scaleValue",
 
     type: "fluid.transforms.scaleValue",
 
     value: <constant of array type>,
 
     value: <constant of array type>,
Line 239: Line 248:
 
Example:
 
Example:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.scaleValue",
 
     type: "fluid.transforms.scaleValue",
 
     value: 12,
 
     value: 12,
Line 250: Line 259:
  
 
Example:
 
Example:
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.scaleValue",
 
     type: "fluid.transforms.scaleValue",
 
     value: 12,
 
     value: 12,
Line 266: Line 275:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.binaryOp",
 
     type: "fluid.transforms.binaryOp",
 
     left: <constant of appropriate type>,
 
     left: <constant of appropriate type>,
Line 299: Line 308:
 
Example:
 
Example:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.binaryOp",
 
     type: "fluid.transforms.binaryOp",
 
     left: 100,
 
     left: 100,
Line 308: Line 317:
 
The above would give the sum (a number) of 100 and the value found in the input model at the path "some.path".
 
The above would give the sum (a number) of 100 and the value found in the input model at the path "some.path".
  
== Conditional Expander ==
+
== Conditional transform ==
  
 
type: multiInputTransformation (variables: true, false, condition)
 
type: multiInputTransformation (variables: true, false, condition)
Line 314: Line 323:
 
Syntax:
 
Syntax:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.condition",
 
     type: "fluid.transforms.condition",
 
     condition: <boolean value>
 
     condition: <boolean value>
     "true": <can be declared in the expander as variable or path - optional>,
+
     "true": <can be declared in the transform as variable or path - optional>,
     "false": <can be declared in the expander as variable or path - optional>
+
     "false": <can be declared in the transform as variable or path - optional>
 
}
 
}
 
</pre>
 
</pre>
Based on the boolean ''condition'' constant (or the path to the inputModel ''conditionPath'') either the value or ''true'' or ''false'' (truePath/falsePath, respectively) will be the result of the expander. The condition is required and either true or false (or both) - or their path equivalents - should be set.
+
Based on the boolean ''condition'' constant (or the path to the inputModel ''conditionPath'') either the value or ''true'' or ''false'' (truePath/falsePath, respectively) will be the result of the transform. The condition is required and either true or false (or both) - or their path equivalents - should be set.
  
 
Example:
 
Example:
 
<pre>  
 
<pre>  
expander: {
+
transform: {
 
     type: "fluid.transforms.binaryOp",
 
     type: "fluid.transforms.binaryOp",
 
     conditionPath: "some.path",
 
     conditionPath: "some.path",
Line 335: Line 344:
  
 
Syntax:
 
Syntax:
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.arrayToObject",
 
     type: "fluid.transforms.arrayToObject",
 
     inputPath: "some input path pointing to an array",
 
     inputPath: "some input path pointing to an array",
 
     key: "the variable from array to use as key"
 
     key: "the variable from array to use as key"
     innerValue: [ (...inner expanders...) ]
+
     innerValue: [ (...inner transforms...) ]
 
}
 
}
 
</pre>
 
</pre>
As the name suggests, the arrayToObject expander changes an array into an object. This can be useful to be able to refer to a certain EL path of an input by a key which unlike reference to an array index does not depend on the order of the array. The expander requires a key - one that is present in each of the array-entries and unique - this will be used to key the resulting object. For example:
+
As the name suggests, the arrayToObject transform changes an array into an object. This can be useful to be able to refer to a certain EL path of an input by a key which unlike reference to an array index does not depend on the order of the array. The transform requires a key - one that is present in each of the array-entries and unique - this will be used to key the resulting object. For example:
  
 
If we have the input model:
 
If we have the input model:
Line 352: Line 361:
 
}
 
}
 
</pre>
 
</pre>
And the expander
+
And the transform
 
<pre>{
 
<pre>{
     expander: {
+
     transform: {
 
         type: "fluid.transforms.arrayToObject",
 
         type: "fluid.transforms.arrayToObject",
 
         inputPath: "foo.bar",
 
         inputPath: "foo.bar",
Line 367: Line 376:
 
}
 
}
 
</pre>
 
</pre>
An optional variable to the expander is the "innerValue". Any variable or expander that needs to refer to the content of the array should be declared here. The input paths within the innerValue block will be relative to the original array entry. (This behavior will be changed later with FLUID-XYZ).
+
An optional variable to the transform is the "innerValue". Any variable or transform that needs to refer to the content of the array should be declared here. The input paths within the innerValue block will be relative to the original array entry. (This behavior will be changed later with FLUID-XYZ).
  
 
As an example:
 
As an example:
Line 377: Line 386:
 
}
 
}
 
</pre>
 
</pre>
And the expander
+
And the transform
 
<pre>{
 
<pre>{
     expander: {
+
     transform: {
 
         type: "fluid.transforms.arrayToObject",
 
         type: "fluid.transforms.arrayToObject",
 
         inputPath: "foo.bar",
 
         inputPath: "foo.bar",
 
         key: "product",
 
         key: "product",
 
         inputPath: [{
 
         inputPath: [{
             expander: {
+
             transform: {
 
                 type: "fluid.transforms.value",
 
                 type: "fluid.transforms.value",
 
                 inputPath: "info.healthy",
 
                 inputPath: "info.healthy",
Line 402: Line 411:
  
 
Syntax:
 
Syntax:
<pre>expander: {
+
<pre>transform: {
 
     type: "fluid.transforms.arrayToOutputs",
 
     type: "fluid.transforms.arrayToOutputs",
 
     inputPath: "some input path pointing to an array",
 
     inputPath: "some input path pointing to an array",
Line 414: Line 423:
 
}
 
}
 
</pre>
 
</pre>
This expander can be used when one wants to create a set based on values available in an array. TODO: Add example and further descriptions. presentValue and missingValue are optional. If not defined, they'll default to true and false, respectively
+
This transform can be used when one wants to create a set based on values available in an array. TODO: Add example and further descriptions. presentValue and missingValue are optional. If not defined, they'll default to true and false, respectively

Revision as of 11:30, 16 September 2013

Introduction to transformations

Outputting

Direct value vs. reading from path

Grades of transformations

standardInputTransformationFunction:

These transformations takes an input which can be defined in two ways:

  • value: As a constant defined in the transform using the key value
  • inputPath: As a path reference to the input (model) by using the key inputPath.

If both keys are used in an transform declaration, the value found at the inputPath will be used if something is found there. If not, the transformer will default to using the value defined by value. Besides this input, the transformation might require an arbitrary number of constants given in the transform declaration.

standardOutputTransformationFunction:

These transformations only outputs a single value. The value of the output depends on the transformation, but the path to output to can be defined by:

  • outputPath: An EL path to where the transformation should output it's value to.

In case the transform is nested within other transforms (eg. a valuemapper), the outputPath specified will be relative to the outputPaths specified in the outer levels as well as to the location of the outermost transform.

standardTransformationFunction:

These transformations satisfy the requirements of both standardInputTransformation and standardOutputTransformation (see above)

multiInputTransformationFunction:

These transformations allows for multiple inputs. In their default blocks, besides the gradename, they require an "inputVariables" key. The value of this should be a hash of key-value pairs, where the key is the variable name and the value is the default value to assign to the variable in case no matching constant or path is found. For each of the variables declared, the system will look up the source-model path defined by <variable>Path in the transform and the <variable> declared in the transform. The path takes priority. Example:

fluid.defaults("fluid.transforms.scaleValue", {
    gradeNames: [ "fluid.multiInputTransformFunction" ],
    inputVariables: { 
        value: null, 
        factor: 1,
        offset: 0
    }
});

The above declaration defines three input variables; value, factor and offset. Taking as an example the factor, the first thing that will be looked up in the transform is the value of "factorPath". If it is defined, this path will be looked up in the source-model and this will be assigned to factor if found. If it's not found, the value (expanded if necessary) of the "factor" key of the transform will be used if found. If neither is found, the default value of 1 will be assigned to factor.

The inputVariables will be available to fluid.transforms.scaleValue as the first argument in the form of an object keyed by variable names with the values as described above.


Transformers

Literal Value (fluid.transforms.literalValue)

Description: Returns the value given as input (or via inputPath), without attempting to do further transformations for that value. This transformation is basically an identity function - it will output the constant value given as input.

Type: standardTransformation Inputs:

  • input / inputPath 

Syntax:

transform: {
    type: "fluid.transforms.literalValue",
    input: <constant value>
}


Example 1: You can user literal value if you have some constant that you want to output to the document

transform: {
    type: "fluid.transforms.literalValue",
    input: "some constant"
}

Output: The output in this case would be:

"some constant"


Example 2: The content of literal value will need be transformed further

transform: {
    type: "fluid.transforms.literalValue",
    input: {
       transform: {
          type: "fluid.transforms.helloworld",
          value: "I'm not interpreted"
       }
    }
}

Output: The content of value will just be output literally:

transform: {
    type: "fluid.transforms.helloworld",
    input: "I'm not interpreted"
}


Example 3: Like all transforms - will fall back from path to direct value

transform: {
    type: "fluid.transforms.literalValue",
    input: "balloon",
    inputPath: "some.path"
}

Output: if anything is found at the path "some.path" the content of that will be output literally, else "balloon" will be output


To Array (fluid.transforms.arrayValue)

description: This transformation will turn its value into an array if it's not already an array.

Type: standardTransformation Inputs:

  • input / inputPath

Syntax:

 
transform: {
    type: "fluid.transforms.arrayValue",
    input: <constant value>
}

Example 1: Passing a single value will wrap it in an array

 
transform: {
    type: "fluid.transforms.arrayValue",
    input: "some constant"
}

output:

[ "some constant" ]

If the value had been an array already, it would just had been passed as is (so in the case - value: [ "some constant "] - we would have got the same output).


Count length of array (fluid.transforms.count)

Type: standardTransformation Inputs:

Description: If the input is an array, the lenght of the array will be the output of this function. If the input is a primitive or object, 1 will be returned.

  • input / inputPath

Syntax:

 
transform: {
    type: "fluid.transforms.count",
    value: <constant value>
}

Example:

 
transform: {
    type: "fluid.transforms.arrayValue",
    value: [ "foo", "bar" ]
}

The above would give the value 2


Get first value of array

Syntax:

 
transform: {
    type: "fluid.transforms.firstValue",
    value: <constant of array type>
}

Will return the first entry (that does not evaluate to undefined) of the array. The input is required to be of type array.

Example:

 
transform: {
    type: "fluid.transforms.firstValue",
    value: [ "foo", "bar" ]
}

The above would give the value "foo".


Delete path from the output

Syntax:

 
transform: {
    type: "fluid.transforms.delete",
    outputPath: <the output path to delete>
}

Will delete the given path from the output.

Example:

 
{
    "": ""
    transform: {
        type: "fluid.transforms.delete",
        outputPath: foo
    }
}

Given the model as input: { hello: "world", foo: "bar" }, the above would give the value { hello: "world" }. The "": "" in the transform would normally mean that the entire input model is copied without any transformations, but the delete transform ensures that the path "foo" is deleted.


Get first value of array

Syntax:

 
transform: {
    type: "fluid.transforms.firstValue",
    value: <constant of array type>
}

Will return the first entry (that does not evaluate to undefined) of the array. The input is required to be of type array.

Example:

 
transform: {
    type: "fluid.transforms.firstValue",
    value: [ "foo", "bar" ]
}

The above would give the value "foo".


Scale value with optional offset

type: multiInputTransformation (variables: value, factor offset)

Syntax:

 
transform: {
    type: "fluid.transforms.scaleValue",
    value: <constant of array type>,
    factor: <the scaling factor>,
    offset: <the offset to use for the scaling>
}

This will scale the input value using the equation: value * factor + offset. If factor is unspecified it will be interpreted as 1 and if offset is unspecified it will be interpreted as 0. Both factor and offset can references to the input model by using: factorPath and offsetPath, respectively. If both the path and constant for any of these values is defined, first the path is looked up, and if a value is found it will be used. Else the constant will be used.

Example:

 
transform: {
    type: "fluid.transforms.scaleValue",
    value: 12,
    factor: 10,
    offsetPath: "some.path"
    offset: 100
}

In this example, if no value is found at some.path, the output will be 12*10+100 = 220. If the value 1000 is found at some.path the result would be 12*10+1000=1120.

Example:

transform: {
    type: "fluid.transforms.scaleValue",
    value: 12,
    factorPath: "some.path"
}

In this example, if no value is found at some.path, the factor will default to 1, outputting 12*1+0=12. If a value is found (say, 12) the output will be 12*12+0=144


Binary operation

type: multiInputTransformation (variables: left, right)

Syntax:

 
transform: {
    type: "fluid.transforms.binaryOp",
    left: <constant of appropriate type>,
    right: <constant of appropriate type>,
    operator: <the operator to use>
}

This will do a binary operation given the two operands (left and right) and the operator. You can reference to the input model for both left and right by using leftPath and rightPath. If both rightPath and right is given, a lookup will be done of rightPath first, and if nothing is found the constant from right will be used. Same goes for left and leftPath. Both the left and right operands are required (either in their path or constant form). The operator is also required. The result of the expansion will be the result of the binary operation. Valid operands are:

Arithmetic Operators (operands are required to be numbers, output will be a number):

  • +: (Addition) Adds 2 numbers.
  • -: (subtraction) As a unary operator, negates the value of its argument. As a binary operator, subtracts 2 numbers.
    • (Multiplication) Multiplies 2 numbers.
  • /: (Division) Divides 2 numbers.
  •  %: (Modulus) Computes the integer remainder of dividing 2 numbers.

Comparison Operators: (operands are required to be numbers, output will be boolean)

  • ===: Returns true if the operands are equal.
  •  !==: Returns true if the operands are not equal.
  • >: Returns true if left operand is greater than right operand.
  • >=: Returns true if left operand is greater than or equal to right operand.
  • <: Returns true if left operand is less than right operand.
  • <=: Returns true if left operand is less than or equal to right operand.

Logical Operators: (both operands are required to be booleans, output will be boolean)

  • &&: (Logical AND) Returns true if both logical operands are true. Otherwise, returns false.
  • ||: (Logical OR) Returns true if either logical expression is true. If both are false, returns false.

Example:

 
transform: {
    type: "fluid.transforms.binaryOp",
    left: 100,
    rightPath: "some.path",
    operator: "+"
}

The above would give the sum (a number) of 100 and the value found in the input model at the path "some.path".

Conditional transform

type: multiInputTransformation (variables: true, false, condition)

Syntax:

 
transform: {
    type: "fluid.transforms.condition",
    condition: <boolean value>
    "true": <can be declared in the transform as variable or path - optional>,
    "false": <can be declared in the transform as variable or path - optional>
}

Based on the boolean condition constant (or the path to the inputModel conditionPath) either the value or true or false (truePath/falsePath, respectively) will be the result of the transform. The condition is required and either true or false (or both) - or their path equivalents - should be set.

Example:

 
transform: {
    type: "fluid.transforms.binaryOp",
    conditionPath: "some.path",
    "true": "It was true",
    "false": "It was false"
}

Changing an array into an object

Syntax:

transform: {
    type: "fluid.transforms.arrayToObject",
    inputPath: "some input path pointing to an array",
    key: "the variable from array to use as key"
    innerValue: [ (...inner transforms...) ]
}

As the name suggests, the arrayToObject transform changes an array into an object. This can be useful to be able to refer to a certain EL path of an input by a key which unlike reference to an array index does not depend on the order of the array. The transform requires a key - one that is present in each of the array-entries and unique - this will be used to key the resulting object. For example:

If we have the input model:

foo: {
    bar: [ 
        { product: "salad", price: 10, healthy: "yes" },
        { product: "candy", price: 18, healthy: "no" }
    ]
}

And the transform

{
    transform: {
        type: "fluid.transforms.arrayToObject",
        inputPath: "foo.bar",
        key: "product"
    }
}

We are saying that we want the array found on inputPath and return an object where where the key will be the value of product and the content will be the remainder of the array entry. So the above would return:

{
    salad: { price: 10, healthy: "yes" },
    candy: { price: 18, healthy: "no" }
}

An optional variable to the transform is the "innerValue". Any variable or transform that needs to refer to the content of the array should be declared here. The input paths within the innerValue block will be relative to the original array entry. (This behavior will be changed later with FLUID-XYZ).

As an example:

foo: {
    bar: [ 
        { product: "salad", info: { price: 10, healthy: "yes" }},
        { product: "candy", info: { price: 18, healthy: "no", tasty: "yes" }}
    ]
}

And the transform

{
    transform: {
        type: "fluid.transforms.arrayToObject",
        inputPath: "foo.bar",
        key: "product",
        inputPath: [{
            transform: {
                type: "fluid.transforms.value",
                inputPath: "info.healthy",
            }

        }]
    }
}

In the second (innermost) inputPath, we refer to info.healthy, which is relative to the path defined by our outer inputPath.

{
    salad: "yes",
    candy: "no"
}

Changing an array to a set

Syntax:

transform: {
    type: "fluid.transforms.arrayToOutputs",
    inputPath: "some input path pointing to an array",
    presentValue: "The value that the entry in the set should have if present in array",
    missingValue: "That value that the entry should have if not present in the array",
    options: {
        "expectedArrayEntry1": "Key of set1",
        (...)
        "expectedArrayEntryN": "Key of setN",
    }
}

This transform can be used when one wants to create a set based on values available in an array. TODO: Add example and further descriptions. presentValue and missingValue are optional. If not defined, they'll default to true and false, respectively