Fabasoft Folio supports different types of actions that can be invoked on an object:
For more information on public, private and obsolete see chapter “Public, private, secured, obsolete”.
This section describes the definition of use cases using the app.ducx use case language of Fabasoft app.ducx.
Syntax |
usecase reference(parameter, ...) { |
The usecase keyword is used to declare a use case. It must be followed by the reference and by parentheses, holding the list of parameters or the prototype. Use cases define the public interface of the software component.
Note: An action is declared the same way, using the optional action keyword. Actions are ment to be private.
Note: The general data type aggregate cannot be used as argument type, please use interface instead,
Parameters must be separated by commas. For each parameter, the data type must be specified. For objects, use the object keyword or the reference of an object class when denoting the data type. For specifying an arbitrary data type, use the any keyword. Square brackets can be used to denote lists.
By default, parameters are treated as input parameters. Output parameters must be prefixed with the keyword out. For input/output parameters, the prefix ref must be used. The keywords retval out (out may be omitted) and retval ref denote parameters that are used as default return values. The keyword optional can be used to mark optional parameters. unique specifies unique lists in parameters.
“…“ can be used to mark an unspecified number of optional parameters at the end of the parameter list. The interface coometh.GetParameter() provides access to these arguments.
Example |
usecases APPDUCXSAMPLE@200.200 usecase CalcOrderPosValue(integer quantity, currency unitprice, usecase CalcOrderTotal(OrderPosition[] positions, boolean includetax, usecase ValidateOrderPositions(ref unique OrderPosition[] positions) { usecase CreateCollectiveInvoice(Order[] orders, retval Invoice invoice) { usecase MyPrint(string format, …) { } |
Note: Even if you mark a parameter with retval it is not allowed to use return with a value in a method implementation. The only way to provide a return value of a method is by assigning a value to the corresponding parameter.
Prototypes are component objects containing predefined sets of parameters. Certain use cases – such as property triggers described in chapter “Assigning triggers to a property” – require predefined prototypes in order to function correctly.
For assigning a prototype to a use case instead of specifying a list of parameters you can use the parameters as keywords followed by the reference of the prototype.
Example |
usecases APPDUCXSAMPLE@200.200 // Skeleton of a get value trigger action // Skeleton of a set value trigger action |
The accexec keyword is used to assign an access type to a use case.
If protected by an access type, a use case can only be invoked if the user trying to invoke it is granted the access type by the object’s ACL. However, it is not mandatory to protect a use case with an access type. Please refer to chapter “Defining an access type” for further information on how to define access types.
In order to be able to invoke a use case, you have to provide an implementation for one or more object classes. You may also provide different implementations of the same use case for different object classes just as in an object-oriented programming language, Fabasoft app.ducx allows an object class to provide a more specific implementation of a use case that is already implemented by one of its base classes. In this case, the implementation in the subclass overrides the implementation in the base class.
The Fabasoft Folio Kernel returns an error message if a use case is invoked on an object where no implementation is found in the object class of the object or in one of its base classes.
The variant keyword is used to denote the object classes for which an implementation of a use case is provided. There are various types of implementations:
In a variant block, you may also define optional use case hints to describe the behavior of the use case implementation. To define use case hints use the hints keyword, followed by curly braces and a list of use case hints as described by the next table.
Hint | Description |
MH_CHANGESOBJ | The use case implementation changes the current object. |
MH_NEEDSSERVER | The use case implementation requires a connection to the server. |
MH_NEEDSARCHIVE | The use case implementation requires an archive implementation. |
MH_NEEDSLOCALGUI | The use case implementation requires interaction with the graphical user interface. |
MH_CHANGESVIEW | The use case implementation changes the current view. |
MH_CREATESOBJ | The use case implementation creates a new object in the currently selected object pointer or object list. |
MH_NEEDSEXPLORER | The use case implementation requires explore mode. |
MH_NEEDSTREE | The use case implementation requires the tree view |
MH_NEEDSPLUGIN | The use case implementation requires the client plugin |
MH_NEEDSSINGLESEL | The use case implementation requires a single selection |
MH_NEEDSMULTISEL | The use case implementation requires a multiple selection |
MH_NEEDSDESKTOPORTABLET | The use case implementation requires at least a Desktop or a Tablet. |
MH_NEEDSCURRENTVERSION | The use case implementation requires the object in the current version, not a historic version. |
The app.ducx expression language can be used for implementing a use case. When implementing a use case as expression, the current object – that is the object on which the use case has been invoked – can be accessed using the cooobj variable. Additionally, the coort interface object can be used to access the Fabasoft Folio Runtime, and the cootx variable contains an interface to the current transaction. Parameter names can be used to access the parameters declared in the use case signature.
Note: The app.ducx compiler verifies the syntax of expressions, but it cannot completely verify semantic correctness.
In the following example, the use case CreateInvoice is implemented in object class APPDUCXSAMPLE@200.200:Order as an expression. The expression creates a new instance of object class APPDUCXSAMPLE@200.200:Invoice, initializes some of its properties, passes back the invoice object in parameter invoice, and references the new invoice in the APPDUCXSAMPLE@200.200:invoice property of the order.
Example |
usecases APPDUCXSAMPLE@200.200 usecase CreateInvoice(out Invoice invoice) { |
If a use case overrides one of its superclass's use cases, you can invoke the overridden use case through the use of the keyword super. Calling super is only allowed when coometh (holds the so-called method context) is available. in or ref parameters that are changed before the call of super are passed in the changed state. out or ref parameters are written to the local scope after the call of super.
Example |
usecases APPDUCXSAMPLE@200.200 usecase CallSuper(integer inx, retval string name) { |
Fabasoft app.ducx allows you to store the actual expression code in a separate app.ducx expression language file.
Example |
app.ducx Use Case Language usecases APPDUCXSAMPLE@200.200 usecase CreateInvoice(out Invoice invoice) { app.ducx Expression Language (CreateInvoice.ducx-xp) #APPDUCXSAMPLE@200.200:Invoice.ObjectCreate(null, &invoice); |
Note: Using this way to specify an expression implementation is discouraged since there is no context available to perform compiler features like type checking. Additionally all identifiers must be fully qualified.
Syntax |
menu usecase reference on selected { menu usecase reference on selected or container { menu usecase reference on container { menu usecase reference dynamic { get = CalculateMenu; |
A menu use case is a special type of use case that is usually invoked by a user selecting a menu item in the user interface.
There are a few optional options available, specified by using keywords after the reference:
To enable this functionality, a number of elements are required. These are generated automatically by the app.ducx compiler:
The following example shows the definition of a menu use case for setting the state of an instance of object class APPDUCXSAMPLE@200.200:Order to OS_SHIPPED. This menu use case is invoked on each of the order objects selected by the user. For this menu use case, the Fabasoft app.ducx compiler also generates a menu object with the reference APPDUCXSAMPLE@200.200:MenuMarkOrderAsShipped. In the example, this menu object is added to context menu APPDUCXSAMPLE@200.200:MenuRootOrderContext to allow users to invoke the use case from the context menu of an order to change the state of the order to OS_SHIPPED.
Note: Objects must be locked before they may be changed. To lock an object, COOSYSTEM@1.1:ObjectLock must be invoked on the object.
Example |
app.ducx Use Case Language usecases APPDUCXSAMPLE@200.200 menu usecase MarkOrderAsShipped on selected { app.ducx User Interface Language userinterface APPDUCXSAMPLE@200.200 // Assign the use case to the context menu of APPDUCXSAMPLE@200.200:Order MenuMarkOrderAsShipped; } } |
Note: Menu use cases can also be implemented in Java or as a virtual application. If implemented as virtual application, a predefined prototype is assigned to the virtual application:
For menu use cases employing the on selected or on selected or container clause the FSCVENV@1.1001:MenuPrototype prototype is assigned to the virtual application, and the parameters described in the next table are passed to it.
Variable | Description |
venv_object | The variable venv_object stores the object the use case was invoked on. |
venv_parent | The variable venv_parent stores the container from which the use case was executed. |
venv_index | The variable venv_index stores the index of the object in the property from which the use case was executed. |
venv_view | The variable venv_view stores the property from which the use case was executed. |
venv_action | The variable venv_action stores the use case that is executed. |
Table 21: Parameters of FSCVENV@1.1001:MenuPrototype
Variable | Description |
sys_object | The variable sys_object stores the object the use case was invoked on. |
sys_action | The variable sys_action stores the use case that is executed. |
sys_view | The variable sys_view stores the property from which the use case was executed. |
sys_selobjects | The variable sys_selobjects stores the objects selected in the property stored in variable sys_view. |
sys_selindices | The variable sys_selindices stores the index of each selected object in the property stored in variable sys_view. |
sys_dynkey | The variable sys_dynkey stores the key of the dynamic menu and is only available when the use case was executed from a dynamic menu. |