5.7.1.2. Custom Functions
Besides the 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.
5.7.1.2.1. 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).
Example of function libraries in the codeinstruction XML file
1<?xml version="1.0" encoding="UTF-8"?>
2<code_instruction xmlns="https://metafactory.io/xsd/v1/codeinstruction"
3 xmlns:java="https://metafactory.io/xsd/v1/java-codeinstruction"
4 xmlns:ts="https://metafactory.io/xsd/v1/typescript-codeinstruction"
5 xmlns:xi="http://www.w3.org/2001/XInclude"
6 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7 xsi:schemaLocation="https://metafactory.io/xsd/v1/codeinstruction
8 https://metafactory.io/xsd/v1/codeinstruction.xsd
9 https://metafactory.io/xsd/v1/java-codeinstruction
10 https://metafactory.io/xsd/v1/java-codeinstruction.xsd
11 https://metafactory.io/xsd/v1/typescript-codeinstruction
12 https://metafactory.io/xsd/v1/typescript-codeinstruction.xsd">
13 <properties>
14 <java.main.directory>src/main/java</java.main.directory>
15 <java.test.directory>src/test/java</java.test.directory>
16 <java.package.base>io.metafactory.codecomposer_reference</java.package.base>
17 </properties>
18 <external_libraries>
19 <external_library name="libProject">
20 <path>./src</path>
21 <codeinstructions_folder>codeinstruction</codeinstructions_folder>
22 <snippets_folder>snippet</snippets_folder>
23 <function_library>codeinstruction/my-project-ci-functions.xml</function_library>
24 <function_library>codeinstruction/example-custom-functions.xml</function_library>
25 </external_library>
26 </external_libraries>
5.7.1.2.2. 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 <definition> element the result of the function can be defined.
Using function arguments
Custom functions can have zero to nine arguments. Arguments are named arg1, arg2, arg3, …, arg9.
5.7.1.2.3. 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:
1<?xml version="1.0" encoding="UTF-8"?>
2<functions xmlns="https://metafactory.io/xsd/v1/codeinstruction"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="https://metafactory.io/xsd/v1/codeinstruction https://metafactory.io/xsd/v1/codeinstruction.xsd">
5
6 <function name="createSimpleDtoClassName">
7 <!--Function must be called with 1 argument:
8 1) name of the model object
9 -->
10 <definition>${arg1}SimpleDto</definition>
11 </function>
12
13 <function name="createSimpleEntityClassName">
14 <!--Function must be called with 1 argument:
15 1) name of the model object
16 -->
17 <definition>${arg1}SimpleEntity</definition>
18 </function>
19
20 <function name="createSimpleServiceClassName">
21 <!--Function must be called with 1 argument:
22 1) name of the model object
23 -->
24 <definition>${arg1}SimpleService</definition>
25 </function>
26
27 <function name="createSpecialServiceClassName">
28 <!--Function must be called with 1 argument:
29 1) name of the model object
30 -->
31 <definition>${fmsnippet.examples.exampleSnippetToCreateSpecialServiceClassName}</definition>
32 </function>
33
34</functions>
Best practice
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:
1<#--stop if arg1 is null-->
2<#if !(arg1)??> <#stop "arg1 (model object name) not found in context" ></#if>
3
4<#--best practice: assign argument to a variable with a name that represents its contents -->
5<#assign modelObjectName = arg1/>
6
7${modelObjectName}SpecialService
Note
The example snippet shown is a rather simple one, but a snippet has the ability to implement more complex custom functions as well.
5.7.1.2.4. Usage of a custom function
Custom functions can be used in code instructions and in snippets.
5.7.1.2.5. 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.
1<?xml version="1.0" encoding="UTF-8"?>
2<java_package xmlns="https://metafactory.io/xsd/v1/java-codeinstruction"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="https://metafactory.io/xsd/v1/java-codeinstruction https://metafactory.io/xsd/v1/java-codeinstruction.xsd"
5 name="${pattern.property.java.package.base}.entities.simple"
6 path="${pattern.property.java.main.directory}"
7 package="domain_model">
8 <class name="${createSimpleEntityClassName(${object.name})}"
9 foreach="object">
10 </class>
11</java_package>
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.
1<?xml version="1.0" encoding="UTF-8"?>
2<model xmlns="https://metafactory.io/xsd/v1/model"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="https://metafactory.io/xsd/v1/model https://metafactory.io/xsd/v1/model.xsd">
5 <package name="domain_model">
6 <object name="ExampleObject1">
7 </object>
8 <object name="ExampleObject2">
9 </object>
10 <object name="ExampleObject3">
11 </object>
12 <object name="ExampleObject4">
13 </object>
14 </package>
15</model>
Output
1package io.metafactory.codecomposer_reference.entities.simple;
2
3public class ExampleObject1SimpleEntity {
4
5}
1package io.metafactory.codecomposer_reference.entities.simple;
2
3public class ExampleObject2SimpleEntity {
4
5}
1package io.metafactory.codecomposer_reference.entities.simple;
2
3public class ExampleObject3SimpleEntity {
4
5}
1package io.metafactory.codecomposer_reference.entities.simple;
2
3public class ExampleObject4SimpleEntity {
4
5}
5.7.1.2.6. 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.
1<#import "/library/custom_functions_libproject.ftl" as cf_libproject>
2
3<#if !(modelObject)??> <#stop "modelObject not found in context" ></#if>
4
5<#assign simpleEntityClassName= cf_libproject.createSimpleEntityClassName(modelObject.name)>
6
7<!-- use of the value returned by cf_libproject.createSimpleEntityClassName assigned to variable simpleEntityClassName -->
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.