Functions

Table of Contents

Overview

Actifsource functions might be called from templates (see ChapterTemplate Editor), from other functions, or from selector relations (see Chapter 4.4.7 SelectorRelation). There are different supported types of functions (see Chapter 9.3 Function types).

Function Space

The function space is the resource where functions are living. We know two different types of functions spaces, both derived from AbstractFunctionSpace.

FunctionSpace is the place where you can place any function. Template is a code template where you can place functions in the scope of the template.

image256 image256

Functions are grouped by a FunctionContext. By the typeRef, the FunctionContext is bound to a Class or an Enum. Functions in the function context are applicable on instances of types referenced by typeRef.

image273 image273

Info

Note that Actifsource prohibits more than one function context with the same typeRef in the same function space.

Function Parameters

A function might define a set of parameters. If calling a function from a template, Actifsource automatically tries to match with the context path (see Chapter 8.3.17).

Function parameters are defined in the model of the specific function type (see Chapter 9.3 Function types).

image265 image265

Using function parameters in a template function (see Chapter 9.3.6 TemplateFunction) leads to the corresponding super contexts (see Chapter 8.3.5 SuperContext).

image274 image274

Using function parameters in a java function (see Chapter 9.3.3 SelectorFunction)

Selector functions allow you to navigate the model by using the selector syntax. Starting from a Class defined by FunctionContext.typeRef you may navigate via the resource properties.

Selectors might be used in Templates to select a context. But selectors might also be called from within selectors – even recursively.

  • Forward navigation Consider the following meta-model.

    image275 image275

    We like to define a selector function named getSubChild on Parent which returns all sub-children in all children of the parent. The return type when navigating along a property is given by the range of the property, i.e, in our example the expected return type is a list of elements of type SubChild To navigate from Parent via child to subChild just assemble a selector Parent.child.subChild Make sure to use content assist (Ctrl+Space) when writing selector functions.

image276 image276

This is what a selector function could look like.

image277 image277

  • Backward navigation Consider the following meta-model.

image275 image275

To get the Parent instance for a SubChild instance we have to navigate backwards via the subChild and child relation. The selector allows backward navigation via the minus relation.

image278 image278

  • List operators Actifsource provides you with the following operators which are defined on lists (where the lists are given by Selector expressions):\
Operator Description
A union B The result is the concatenation of the two lists A and B. For example, [a1,a2] union [a3,a1] is equal to [a1,a2,a3,a1].
A intersect B Only elements found in A and in B where duplicates are preserved and the resulting order is given by A. For example, [a1,a1,a2,a2] intersect [a2,a1,a1] is equal to [a1,a1,a2].
A except B For all elements b in B, the first occurrence of b in A is removed from A. For example, [a2,a1,a3,a2,a1] except [a1,a2,a1] is equal to [a3,a2]
A else B All elements in A if a is empty, otherwise all elements in B. For example, [a1, a2] else [b1,b2] is equal to [a1,a2] and [] else [b1,b2] is equal to [b1,b2].
A then B All element in B if A is not empty else empty list (i.e (A then B else C)).
A excludefilterA.c All elements from the set A with the exception of the elements for which A.c is evaluated to empty or boolean true.
A includefilterA.c where the expression A.c must be evaluated as not empty or Boolean true.
A getindexi Selects the element at position i ($i \in \mathbb{Z}_{0}^{+}$) from the list of elements of A. For example [a2,a1,a3,a2,a1] getindex 2 selects a3.
Info

Note that you can use brackets to control precedence (i.e. (A.x union A.y) intersect A.z). The result type of the union, intersect and else operator is the most concrete supertype of the type of the two operands (e.g. if A is of type NamedResource and B is of type Resource, then A intersect B A union B and A else B are all of type Resource). After brackets you can continue the selector (i.e (A.x union A.y).typeOf).

  • Down Cast Consider the following meta-model.
    image279 image279

If you only like to get Leaf components from the Client, just use the type cast operator (colon).

image280 image280

  • Up Cast It is always possible to use an upcast to a base class (i.e. Resource or NamedResource) if needed.

  • Self Cast If your selector has to return the typeRef instance itself, use the self-cast. Consider the following selector function for Component returning the component instance itself.

image281 image281

  • Recursive navigation The diagram below shows a composite pattern as presented in the book Design Patterns from Erich Gamma et al. The composite pattern allows you to recursively instantiate Composite instances, which might aggregate other components of type Leaf or again – of type Composite.

image282 image282

There is an easy way to find the Client of this recursive model using selectors. First, we collect all components including the own component and all parent components.

For that reason we write a selector function for Component which returns the component itself and also all parent components which are reachable by going backwards via the component relation.

image283 image283

To get the Client which is parent of all component just collect all component first by using the above selector functions. From all this components in the collected set there is only one instance aggregated by Client. Let’s write a selector function for that.

Please take extra care because there are two relations named component. One is Composite.component the other one is Client.component Make sure to use Composite.component in allComponent and Client.component in getClient

image284 image284

  • Calling selectors with parameters

[TBD]

JavaFunction

leads to the corresponding java function arguments.

image285 image285

Polymorphic calls

Function calls are polymorphic if a function has the same name, the same parameters and a typeRef to a sub class.

image286 image286

In the following example, the function identify is defined for MyClass and MySubClass. There will be a polymorphic call to MyClass.identify dependent on the type of the instance.

image287 image287

Non-Polymorphic calls

There are situations where polymorphic calls are not desired. You have to disable polymorphic calls on every caller. Use the context menu Change to non-virtual call on the function.

image288 image288

A small arrow indicates the non-polymorphic call.

image289 image289

Extends

Polymorphic calls are supported in the same function space by default. Extending another function space enables polymorphic calls over functions spaces.

image290 image290

Function types

Actifsource supports different types of functions.

image291 image291

Abstract Function

Abstract functions shall only be defined on types with an abstract modifier (see Chapter 4.6.1 ch.actifsource.core.Class).

For an abstract function, there must be non-abstract function for any non-abstract subclass in the same function space or in a function space that extends it.

image292 image292

SelectorFunction

Selector functions allow you to navigate the model by using the selector syntax. Starting from a Class defined by FunctionContext.typeRef you may navigate via the resource properties.

Selectors might be used in Templates to select a context. But selectors might also be called from within selectors – even recursively.

  • Forward navigation Consider the following meta-model.
    image275 image275

We like to define a selector function named getSubChild on Parent which returns all sub-children in all children of the parent. The return type when navigating along a property is given by the range of the property, i.e, in our example the expected return type is a list of elements of type SubChild

To navigate from Parent via child to subChild just assemble a selector Parent.child.subChild Make sure to use content assist (Ctrl+Space) when writing selector functions.

image276 image276

This is what a selector function could look like.

image277 image277

  • Backward navigation Consider the following meta-model.

image275 image275

To get the Parent instance for a SubChild instance we have to navigate backwards via the subChild and child relation. The selector allows backward navigation via the minus relation.

image278 image278

  • List operators Actifsource provides you with the following operators which are defined on lists (where the lists are given by Selector expressions):
Operator Description
A union B The result is the concatenation of the two lists A and B. For example, [a1,a2] union [a3,a1] is equal to [a1,a2,a3,a1].
A intersect B Only elements found in A and in B where duplicates are preserved and the resulting order is given by A. For example, [a1,a1,a2,a2] intersect [a2,a1,a1] is equal to [a1,a1,a2].
A except B For all elements b in B, the first occurrence of b in A is removed from A. For example, [a2,a1,a3,a2,a1] except [a1,a2,a1] is equal to [a3,a2]
A else B All elements in A if a is not empty, otherwise all elements in B. For example, [a1, a2] else [b1,b2] is equal to [a1,a2] and [] else [b1,b2] is equal to [b1,b2].
A then B All element in B if A is not empty else empty list (i.e (A then B else C)).
Info

Note that you can use brackets to control precedence (i.e. (A.x union A.y) intersect A.z). The result type of the union, intersect and else operator is the most concrete supertype of the type of the two operands (e.g. if A is of type NamedResource and B is of type Resource, then A intersect B A union B and A else B are all of type Resource).

  • Down Cast Consider the following meta-model.

image279 image279

If you only like to get Leaf components from the Client, just use the type cast operator (colon).

image280 image280

  • Up Cast It is always possible to use an upcast to a base class (i.e. Resource or NamedResource) if needed.

  • Self Cast If your selector has to return the typeRef instance itself, use the self-cast. Consider the following selector function for Component returning the component instance itself.

image281 image281

  • Recursive navigation The diagram below shows a composite pattern as presented in the book Design Patterns from Erich Gamma et al. The composite pattern allows you to recursively instantiate Composite instances, which might aggregate other components of type Leaf or again – of type Composite.

image282 image282

There is an easy way to find the Client of this recursive model using selectors. First, we collect all components including the own component and all parent components.

For that reason we write a selector function for Component which returns the component itself and also all parent components which are reachable by going backwards via the component relation. $

image283 image283

To get the Client which is parent of all component just collect all component first by using the above selector functions. From all this components in the collected set there is only one instance aggregate by Client. Let’s write a selector function for that.

Please take extra care because there are two relations named component. One is Composite.component the other one is Client.component Make sure to use Composite.component in allComponent and Client.component in getClient

image284 image284

  • Calling selectors with parameters

[TBD]

JavaFunction

Actifsource supports user-implemented Java functions that make use of the very powerful Javamodel to access the Actifsource models from Java code (see also Section 9.5).

image293 image293

When you declare a Java function, Actifsource automatically generates a function skeleton in a file with the same name as your function space found in the folder src-gen.

image294 image294

You should only modify generated files within protected regions (see Chapter 2.12.5 Protected Regions). Take extra care that import statements are placed within the protected regions – especially if inserted automatically by the Java content assist.

image295 image295

As function arguments, an instance of type FunctionContext.typeRef and all parameters are passed. Use the Java content assist (Ctrl+Space) to display available functions. To access properties choose myClass.selectMyProperty(). For more information on how to access the Javamodel see Chapter 9.5.

  • Return Types
    image296 image296

A Java function has a return type which is either a Type or a TypeReference.

A Type is either a SimpleType or a ListType. A SimpleType can, in particular, be a ClassType, which references any Class, or a LiteralType, which references any Literal. For a LiteralType the return type of the generated Java function is the Java class given by the return value of the method getValueType() of the ILiteralAspect (e.g. in the example above the LiteralAspect of StringLiterals (ch.actifsource.core.model.aspects.impl.String.StringLiteralAspect) defines that java.lang.String represents StringLiterals and, therefore, the the return type of identify is java.lang.String). A ListType references either a Class or a Literal (more precisely, it actually references an AbstractType). The return type of the generated Java function is then a java.util.List<Class>, where Class is the Java class that corresponds to the Literal or the Class. Note that in the latter case the Java class is the wrapper Java class that corresponds to the Actifsource Class and is provided by the Javamodel (see also Chapter 2 and Section 9.5).

A TypeReference is either a GenericContextType or a GenericContextListType. In the first case, the return type of the generated Java function is <T extends C T where C is the Java class corresponding to the type of the element the function is called on (the this-instance). In the second case, the return type of the generated Java function is a <T extends C> java.util.List<T> where T is defined as before (see examples below).

Info

Note that function with a return type of GenericContextType or a GenericContextListType can be applied to elements of any sub-type of the type given by typeRef of the FunctionContext, i.e., the this-parameter of the generated Java function is <T extends Class> T where Class is the Java wrapper class corresponding to the typeRef of the FunctionContext.

image297 image297

image298 image298

image299 image299

image300 image300

image301 image301

JavaListFunction

Java list functions can be applied to a list of elements defined by a Selector expression, e.g. in the Selector expression Parent.child.myFunction@ChildFunctionSpace the function myFunction is called on the list of all Children reachable from Parent via the relation child (see example in Section 9.3.2). The this-parameter of the generated Java function is then of type java.util.List<\> where C is the Java class corresponding to the typeRef of the FunctionContext (respectively java.util.List<T extends C> if the returnType of the Java list function is GenericContext(List)Type). Consider the following example that is based on the meta-model from Section 9.3.5:

image302 image302

image303 image303

The return types of JavaListFunctions are determined in the same way as for JavaFunctions (see Section 9.3.3). A list of built-in (Java) list functions is presented in Section Fehler! Verweisquelle konnte nicht gefunden werden..

Consider an extended meta-model where Parent can be referenced by a ParentContainer via a relation parent:

image304 image304

In this case, the selector ParentContainer.parent.child.myFunction@MyFunctionSpace constructs for each Parent the list of Children reachable from this Parent and then applies the function myFunction to each of these lists. If the function should be applied to the list of Children reachable indirectly via parent we can write a (Selector)Function that returns a list of all these Children e.g. ParentContainer.getAllChildren@MyFunctionSpace where getAllChildren is a SelectorFunction with the selector ParentContainer.parent.child In the selector ParentContainer.getAllChildren@MyFunctionSpace.myFunction@MyFunctionSpace the function myFunction is only called once on the list of all Children reachable from ParentContainer.

JavaAspectFunction

[TBD]

TemplateFunction

A template function behaves in the same way as a template, but there are no files generated from a template function. Just think of a template function as a sub template which can be expanded in a template or in another template function (also recursively).

Consider the following meta-model:

image305 image305

Let us now write a template function for a component which writes the name and type of the component and, if the given component is a composite, also does the same recursively for all subcomponents.

First of all we have to define the template function in the model.

image306 image306

To open the template function with the template editor, just double click in the Project Explorer. Use the Link with Editor tool (see Chapter 2.10.1 Link with Editor) to easily locate the template function in the project explorer.

image307 image307

In line 1 we write out the component name and its type name. In line 2 we iterate over all aggregated components, but only if the component is of type Composite (type cast). In this context we call the template function asText recursively for all aggregated component.

Info

Note the indention of two spaces on line 2. Actifsource takes care of the indentions so that the whole content of the template function is indented.

image308 image308

We can now call our template function from a template. If there is a call to a function from another function space, the function space is explicitly stated using the notation myFunction@MyFunctionSpace.

image309 image309

Next, we create an instance of type Client containing composites and leaves. The output from the above template might look as follows.

Info

Note that the indention is applied recursively.

image310 image310

TemplateLineFunction

The template line function behaves like a template but without the possibility to set contexts (see Chapter 8.3.9 Line Context, Column Context, Protected Context). The template line allows you to create simple single line texts as for name aspects (see Chapter 4.6.1 ch.actifsource.core.Class).

Consider a resource Person with two string literals firstName and LastName

image311 image311

Write a template function for person, which prints out the person's last name and first name.

image312 image312

Simply use the template line function as name aspect in the class Person.

image313 image313

Please not that it is also possible that the selector of the name aspect can be used directly as template line.

image314 image314

Info

Note that Person is only a Resource but not a NamedResource. The attributes firstName and lastName are therefore just normal properties.

image315 image315

Defining the name aspect as seen above synthesizes the name.

image316 image316

Built-in functions

Actifsource provides lots of useful built-in functions.

Built-in functions on Any

Actifsource provides the following built-in functions on Any.

Function Return type Description
guid Literal Gets the unique identifier of any Resource or Literal. (For Resources it is a GUID, for Literals it is the Literal itself.)

Built-in functions on Any List

Actifsource provides the following built-in functions on List of Any.

Function Return type Description
count IntegerLiteral Counts the number of elements in the list
isEmpty BooleanLiteral Returns true if and only if the list is empty.
isSet BooleanLiteral Returns true if and only if the list contains no duplicates.
first T Returns the first element in the list.
last T Returns the last element in the list.
count IntegerLiteral Counts the number of elements in the list.
reverse List of T Reverses the elements in the list.
distinct List of T Remove duplicates from a list, first to last.

Built-in functions on Resource

Actifsource provides the following built-in functions on Resource.

Function Return type Description
package String Returns the package of the resource as string.
guid String Returns the GUID of the resource as string.
simpleName String Returns the Resource’s name as defined by its NameAspect. If the resource extends NamedResource, the NameAspect returns the value of the name attribute. If no NameAspect is defined, the GUID of the resource is returned.

Built-in functions on List of Resource

Actifsource provides the following built-in functions on List of Resource.

Function Return type Description
sortByGuid List of T Sorts the list of resources by their GUIDs.
sortBySimpleName List of T Sorts the list of resources by their names.

Built-in functions on Literal

Actifsource provides the following built-in functions on Literal.

Function Return type Description
guid T Gets the identifier of the Literal value.

Built-in functions on IntegerLiteral

Actifsource provides the following built-in functions on IntegerLiteral.

Function Return type Description
increment Integer Increments an integer number.
decrement Integer Decrements an integer number.
notZero Integer Returns the number unless it is zero.

Built-in functions on IntegerLiteralList

Actifsource provides the following built-in functions on List of IntegerLiteral.

Function Return type Description
sum Integer Calculates the sum of a list of integer numbers.
minimum Integer Returns the minimum integer in a list.
maximum Integer Returns the maximum integer in a list.

Built-in functions on BooleanLiteral

Actifsource provides the following built-in functions on BooleanLiteral.

Function Return type Description
isFalse Boolean Returns true if the Boolean value is false.

Built-in functions on List of Character

Actifsource provides the following built-in functions on List of Character.

Function Return type Description
string Boolean Builds a string from characters.

Built-in functions on List of Letter

Actifsource provides the following built-in functions on List of Letter.

Function Return type Description
string Word Builds a word from letters.

Built-in functions on TextLiteral

Actifsource provides the following built-in functions on TextLiteral.

Function Return type Description
suppressIndent Text Sets the current intent mode to ‘suppress indent’: All lines after the first line start at the very beginning of the line. If applied in a template function, the setting of the outer template is not affected. The return value is the text itself.
indent Text Sets the indent mode to ‘indent’ (=default). All lines will start at the same position as the first line. (The preceding characters in the first line are copied, non-whitespace characters replaced by whitespaces.) If applied in a template function, the setting of the outer template is not affected. The return value is the text itself.
prefix Text Sets the indent mode to ‘prefix’. All lines will repeat the preceding characters in of the first line. If applied in a template function, the setting of the outer template is not affected. The return value is the text itself.
splitLines List<String> Splits text at line breaks into a list of strings.
split80 List<String> Splits text into a list of strings of maximum 80 characters. Words are considered atomic, if possible.
split100 List<String> Splits text into a list of strings of maximum 100 characters. Words are considered atomic, if possible.
escapedString String Escapes the text such that it can be embedded into C, C++ or Java source code. Escaping for C/C++ only works for ASCII characters.
notEmpty Text Returns the text unless it is empty.

Built-in functions on StringLiteral

Actifsource provides the following built-in functions on StringLiteral.

Function Return type Description
character List of Character Gets the characters in the string.
length Integer Gets the number of characters in the string.
toFirstUpper String Gets the same string with capital first letter.
toFirstLower String Gets the same string with small first letter.
toAllUpper String Gets the string in all capital letters.
toAllLower String Gets the string in all small letters.
camelcapToUnderscore String Inserts an underscore before every uppercase letter unless it is the first letter in the string.
whitespaceToCamelcap String Replaces letters behind one or many whitespace characters by their uppercase counterparts, replacing those whitespace
characters.
whitespaceToUnderscore String Replaces all whitespace characters by underscore characters.
split80 List of String Splits the string into a list of strings of maximally 80 characters.
split100 List of String Splits the string into a list of strings of maximally 100 characters.
packageToDirectory String Replaces '.' by '/'.
isNotEmpty Boolean Returns true if and only if the string is not an empty string.
escapedString String Escapes the string such that it can be embedded into C, C++ or Java source code. Escaping for C/C++ only works for ASCII characters.
part List of Literal Parses the string into words, natural numbers and special characters, removing whitespaces.

Built-in functions on Word

Actifsource provides the following built-in functions on Build.

Function Return type Description
character Letter Gets the letters in the word.

Built-in functions on Guid

Actifsource provides the following built-in functions on Build.

Function Return type Description
timestamp Long Returns the GUID's timestamp in nanoseconds starting from Oct 15, 1582.
time Time Returns the GUID's time.
identify Resource Returns the Resource identified by the GUID.

Built-in functions on Build

Actifsource provides the following built-in functions on Build.

Function Return type Description
once Build Used in the selector of the template. Build.once means a template is not based on a resource but only built once.

Built-in functions on LinkSelector

Actifsource provides the following built-in functions on LinkSelector.

Function Return type Description
selectorText String Converts a selector to simple text string.
selectorResultType AbstractType Calculates a selectors result type.

Built-in functions on File

Actifsource provides the following built-in functions on File.

Function Return type Description
contents Text Returns a file's contents.

Accessing the model from within Java function

It is possible to access the model, other functions (see chapter 9.3 Function types), or even built-in functions (see chapter Fehler! Verweisquelle konnte nicht gefunden werden. Fehler! Verweisquelle konnte nicht gefunden werden.) from within Java functions.

Consider the following meta-model for the subsequent examples:

image317 image317

Model forward access

Let’s write a Java Function for Parent which returns only instances of type Child with names beginning with “A”.

Start by declaring a Java Function named filterChild as seen in Chapter 9.3.3.

image318 image318

For the model forward access use the selectProperty() function on the given resource where property is the property to select.

The subsequent filter function iterates over the relation Parent.child in the for-Statement via parent.selectChild(). Then we check if Child.name starts with “A” via child.selectName(). If the condition is fulfilled we add the filtered child to the child list. At the end we return the child list with the filtered children.

image319 image319

You might use the filter function in the selector of a template or in any other function. The following template only prints children with names starting with “A”.

image320 image320

Model backward access

Using the selector syntax accessing the model backwards is quite easy (see chapter 9.3.2 SelectorFunction) by the minus sign. Accessing the model backwards is also possible in the Java code.

For the model backward access use the static function selectToMeProperty() on the class which defines the relation.

Since we want to access the relation Parent.child backwards we have to choose the static method Parent.selectToMeChild() providing the actual child as parameter. As a result we get the parent of the given child.

image321 image321

Function access

Use the extension mechanism to access any of your functions from within Java Code.

Info

Note that the extension mechanism also supports polymorphic calls (see chapter Fehler! Verweisquelle konnte nicht gefunden werden. Fehler! Verweisquelle konnte nicht gefunden werden.).

Let’s assume that we have a function filterChild as shown in chapter 9.5.1 Model forward access. Let’s write a Java function filterChildReverse which returns a reverse list of the filtered children based on filterChild.

For the function access use the extension() function on the given resource with FunctionSpace.ITypeRefFunctions.class as parameter. FunctionSpace is the function space where your function is defined. TypeRef is FunctionContext.typeRef. The static property .class is given from Java and represents a class as an object.

image322 image322

Built-in function access

Use the extension mechanism to access built-in functions on resources (see chapter 9.4.1 Built-in functions on Any

Actifsource provides the following built-in functions on Any.

Function Return type Description
guid Literal Gets the unique identifier of any Resource or Literal. (For Resources it is a GUID, for Literals it is the Literal itself.)

Built-in functions on Any List

Actifsource provides the following built-in functions on List of Any.

Function Return type Description
count IntegerLiteral Counts the number of elements in the list.
isEmpty BooleanLiteral Returns true if and only if the list is empty.
isSet BooleanLiteral Returns true if and only if the list contains no duplicates.
first T Returns the first element in the list.
last T Returns the last element in the list.
count IntegerLiteral Counts the number of elements in the list.
reverse List of T Reverses the elements in the list.
distinct List of T Remove duplicates from a list, first to last.

Built-in functions on Resource) from within Java Code. Accessing built-in functions is done the same way as seen in the above chapter 9.5.3 Function access.

To write a function which returns the package and the simpleName of a child we can reuse the built-in functions package() and simpleName() For the built-in function access use the extension() function on the given resource with BuiltinResourceFunctions.class as parameter.

image323 image323

Info

Note that you cannot access built-in functions for literals via the extension mechanism.