.. ******************************************************************************* * MetaFactory.io R2 * Technical Documentation * * File name : CustomFunctions.rst * * MetaFactory BV Amsterdam ******************************************************************************* .. include:: /inline-images.txt .. _CustomFunctions: Custom Functions ================ Besides the :ref:`built-in functions ` in the expression language of the CodeComposer you can define your own **custom functions** for use in code instructions and snippets. This can be achieved by adding **function libraries** with custom functions to the code instructions XML. Adding a function library with custom functions to the code instructions ------------------------------------------------------------------------ **Function libraries** with custom functions can be added to the code instruction XML file for each external library. Multiple function libraries can be added per external library (see lines 23 and 24 in the example code instructions XML file below). .. rubric:: Example of function libraries in the codeinstruction XML file .. code-block:: xml :caption: codecomposer-reference-input/src/codeinstruction/codeinstruction.xml :name: CusFunc_codeinstruction :linenos: :emphasize-lines: 23,24 src/main/java src/test/java io.metafactory.codecomposer_reference ./src codeinstruction snippet codeinstruction/my-project-ci-functions.xml codeinstruction/example-custom-functions.xml .. admonition:: Best practice :class: bestpractice |BestPractice L| You should group functions that belong together in a separate function library file. Defining a custom function -------------------------- A **custom function** can be defined by adding a <**function**> element to the <**functions**> element in the XML file of the function library. The custom function must be given a unique name and contain a <**definition**> element. In the element the result of the function can be defined. .. rubric:: Using function arguments Custom functions can have zero to nine arguments. Arguments are named arg1, arg2, arg3, …, arg9. Example of custom functions --------------------------- In the following custom functions XML file an example is shown of 4 custom functions: - createSimpleDtoClassName - createSimpleEntityClassName - createSimpleServiceClassName and - createSpecialServiceClassName, each having the name of the model object as argument: .. code-block:: xml :caption: codecomposer-reference-input/src/codeinstruction/example-custom-functions.xml :name: CusFunc_example01 :linenos: :emphasize-lines: 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30 ,31, 32 ${arg1}SimpleDto ${arg1}SimpleEntity ${arg1}SimpleService ${fmsnippet.examples.exampleSnippetToCreateSpecialServiceClassName} .. admonition:: Best practice :class: bestpractice |BestPractice L| You should add a comment for each argument describing what the argument is. .. admonition:: Best practice :class: bestpractice |BestPractice L| You should **not** use **modelPackage, modelObject, modelAttribute** or **modelReference** in custom functions: Only use arg1 t/m arg9. The first three functions found in the example define the result of the function directly in the definition, while the fourth function uses a snippet to define the result of the function: .. literalinclude:: /../codecomposer-reference-input/src/snippet/examples/exampleSnippetToCreateSpecialServiceClassName.ftl :caption: codecomposer-reference-input/src/snippet/examples/exampleSnippetToCreateSpecialServiceClassName.ftl :linenos: .. note:: The example snippet shown is a rather simple one, but a snippet has the ability to implement more complex custom functions as well. .. admonition:: Best practice :class: bestpractice |BestPractice L| You should assign any argument of the snippet that implements a custom function to a variable with a name that represents the content of the variable at the start of the snippet and use the variable instead of the numbered argument in the rest of the snippet. Usage of a custom function -------------------------- Custom functions can be used in code instructions and in snippets. Usage of a custom function in a code instruction ------------------------------------------------ A custom function can be used in a code instruction. The following code instruction shows an example of the use of a custom function named *createSimpleEntityClassName* which has the object name as argument. .. code-block:: xml :caption: codecomposer-reference-input/src/codeinstruction/examples/example-code-instruction-simple-entity-foreach-object.xml :name: CusFunc_example02 :linenos: :emphasize-lines: 8 .. rubric:: Input Given the code instruction XML in **codecomposer-reference-input/src/codeinstruction/codeinstruction.xml**, the code instruction in **codecomposer-reference-input/src/codeinstruction/examples/example-code-instruction-simple-entity-foreach-object.xml**, the custom function library in **codecomposer-reference-input/src/codeinstruction/example-custom-functions.xml** and the model in **codecomposer-reference-input/src/model/model.xml** shown below, CodeComposer will produce the files shown in the output in the following section. .. code-block:: xml :caption: codecomposer-reference-input/src/model/model.xml :name: CusFunc_model :linenos: :emphasize-lines: 6, 8, 10, 12 .. rubric:: Output .. code-block:: java :caption: codecomposer-reference-output/src/main/java/io/metafactory/codecomposer_reference/entities/simple/ExampleObject1SimpleEntity.java :name: CusFunc_Output01 :linenos: :emphasize-lines: 3 package io.metafactory.codecomposer_reference.entities.simple; public class ExampleObject1SimpleEntity { } .. code-block:: java :caption: codecomposer-reference-output/src/main/java/io/metafactory/codecomposer_reference/entities/simple/ExampleObject2SimpleEntity.java :name: CusFunc_Output02 :linenos: :emphasize-lines: 3 package io.metafactory.codecomposer_reference.entities.simple; public class ExampleObject2SimpleEntity { } .. code-block:: java :caption: codecomposer-reference-output/src/main/java/io/metafactory/codecomposer_reference/entities/simple/ExampleObject3SimpleEntity.java :name: CusFunc_Output03 :linenos: :emphasize-lines: 3 package io.metafactory.codecomposer_reference.entities.simple; public class ExampleObject3SimpleEntity { } .. code-block:: java :caption: codecomposer-reference-output/src/main/java/io/metafactory/codecomposer_reference/entities/simple/ExampleObject4SimpleEntity.java :name: CusFunc_Output04 :linenos: :emphasize-lines: 3 package io.metafactory.codecomposer_reference.entities.simple; public class ExampleObject4SimpleEntity { } Usage of a custom function in a snippet --------------------------------------- A custom function can be used in a snippet by importing the function library in which the custom function is defined (see line 1 of the example snippet below) and assigning it to a variable. A call of the custom function starts with the variable chosen in the import statement followed by a dot and the name of the function (see line 5). After assigning the return value of the function to a variable, the variable can be used in other statements in the snippet to produce the desired output of the snippet. .. code-block:: :caption: codecomposer-reference-input/src/snippet/examples/exampleSnippetUsingCustomFunction.ftl :name: CusFunc_InSnippet :linenos: :emphasize-lines: 1, 5 <#import "/library/custom_functions_libproject.ftl" as cf_libproject> <#if !(modelObject)??> <#stop "modelObject not found in context" > <#assign simpleEntityClassName= cf_libproject.createSimpleEntityClassName(modelObject.name)> .. note:: Multiple function libraries within a external library are combined by the CodeComposer in one single .ftl file named after the external library and placed in the /library directory. In the example the two function libraries in the external library *libProject* are combined by the CodeComposer into */library/custom_functions_libproject.ftl*.