Eazflow - Developer reference documentation

Overview

Introduction

The workflow is represented by a Process. During the lifetime of a Process, different Activities are performed on it. When an Activity requests user input, a form is presented to the user. The user enters required data into the form-fields. Form-field values are stored in Variables of the Process. When a particular Activity gets finished, a Transition to another Activity is made and the next Activity is started.

Availability of Processes, Activities, _Variables and Transitions to a User is controlled by Access-rights with Role-based rules. There are two types of user Roles: Global roles and Instance roles. Users authenticate themselves to the system (username/password). Each User has a set of Global roles assigned. In adition to these Global roles, a specific local Instance role set can be supplied on each instance of Process. This mechanism represents situations where a user has a special position within some processes, e.g. the initiator, assigned solver etc.

Definitions and Instances

Main types of entities (process, activity, transition, etc.) occur in definitions and instances.

Definition entities describe the model of the given workflow process, all of its possible activities, transitions, variables with their types, validation rules etc.

Typically, the administrators will instantiate new definition entities when adding a new process definition, or introducing an activity step to an already defined process. The developers may implement new definition entity classes to provide new variable types like e.g. a PDF report.

Instance entities represent individual process instances, performed activities and transitions and actual variable values as they are carried out.

Typically, the users will (mostly without realizing it) instantiate new instance entities when starting a new process, or following a transition to enter a new activity.

Internals

Main entities (domain classes)

Process-definition classes

  • DefProcess - main process-definition entity class
  • DefActivity - base class for all activity-definition classes
    • DefAStart - first activity type of the process, this type of activity is started by the system when a new process is created
    • DefAUserAction - activity type for user interaction - in this type of activity, users are filling in variable-fields and then choosing transition to the next activity
    • DefAFinish - last activity type of the process, process is finished when it reaches this type of activity
  • DefTransition - defines a possible transition from an activity definition into another

Variable (type) definition classes

  • TypeCompositeDef - defines a composite structure consisting of member fields (which may, recursively, also be composite, see below)
    • TypeProcessDef - subclass of !TypeCompositeDef, defines a root for the structure of process variables (each !DefProcess has a !TypeProcessDef assigned)
  • TypeMember - base composite-member class - defines a member field of a composite type (!TypeCompositeDef)

Process-instance classes

Variable-instance classes

  • Variable - acts as an interface for accessing all data-fields
  • ValueStorage - stores values of variables

Authentication & authorization (users, roles, access rights)

  • User - represents a user which can log-in to the system; a user may have roles (!RoleGlobal) assigned
  • RoleGlobal - global roles are assigned to users in the system globally (e.g. system.administrator, company.director), typically by the administrator
  • RoleInstance - instance roles are assigned per process-instance (e.g. process.author, process.supervisor), typically automatically by the system based on some process variable values
  • ProcessRoleUser - a materialized relation which assigns (for a particular process) an instance role directly to a user (e.g. for some process instance, user u1 has the instance role process.author)
  • ProcessRoleGlobal - a materialized relation which assigns (for a particular process) an instance role to a global role (e.g. all users having the global role company.director have for some process the instance role process.supervisor)
  • AccessRightDefProcess - access to process-definitions (NONE/EXECUTE)- who can start which processes
  • AccessRightProcess - access to process-instances (NONE/READONLY/WRITABLE)
  • AccessRightActivity - access to process per activity (NONE/READONLY/WRITABLE/DELETE)
  • AccessRightTransition - access to transitions (NONE/EXECUTE)
  • AccessRightVariable - access to process variables (NONE/READONLY/WRITABLE/MANDATORY)

    Access in each category is defined by a list of rules consisting of weight, patterns for matching role-code, process-code, activity-code, transition-code, variable-code (the set of codes depends on the category) and the access right (operation allowed). For a particular test, the rule matching all code-patterns and having the greatest weight defines the access right granted.

  • RenderConfigVariable - in a way similar to the access-right definitions, rendering of process-variables is configured by rules of code-patterns; each rule defines whether the corresponding variable is rendered in the main section (or in the details section only) and whether composite type containing the variable is rendered folded or unfolded

Services

Controllers

  • WorklistController - all main process-related functionality (list all, list TODO, search, view, edit, etc.)
  • UserController - user login/logout, welcome screen, user preferences setup

Rendering of variables

The most important part of a process display is the pane with process-variables. The rendering of the variables (i.e. their labels, values, edit-boxes etc.) is performed in the show action of WorklistController. Actually, all variables of a process are contained within one structure (tree) defined by TypeProcessDef assigned to the process and all variables are rendered as part of rendering this process-variable-structure.

Rendering of variables is handled by <eazf:renderNode> and related tags (of the EazflowTaglib tag library) with the help of templates named views/Type/_Type....gsp.

Variable and rendering logic

Basically, for a <some_typename> type, there is a Type<some_typename> class inheriting from TypeMember, which defines the special functionality of the type (type conversion for storage, validation, saving from the submitted form, etc.). Furthermore, there are views/Type/_Type<some_typename>.gsp, views/Type/_Type<some_typename>Label.gsp and views/Type/_Type<some_typename>Body.gsp templates, which define the rendering. When a particular template doesn't exist, a template for the superclass is used, so in most cases only the views/Type/_Type<some_typename>Body.gsp template (if any at all) has to be overridden when implementing a new variable type.

Templates present in the main grails-app views directory take precedence over plugin templates, so rendering of plugin-defined types can also be easily customized.

Look into TypeInteger (grails-app/domain/TypeInteger.groovy, views/Type/_TypeIntegerBody.gsp) and TypeSysuser (grails-app/domain/TypeSysuser.groovy, views/Type/_TypeSysuserBody.gsp) for examples of how new types should be defined.

Also available in: HTML TXT