Forum OpenACS Q&A: Re: Status of Workflow - Using it with Project-Manager?

Collapse
Posted by Frank Bergmann on
Hi,

<blockquote> exceeded my (skill) to (time available) ratio
</blockquote>

I guess the same is happening to me.

I've been working in the past with the Java "State Pattern" from the "Gang of Five" book (for example: http://home.earthlink.net/~huston2/dp/state.html), and I understand that "Workflow" is really an implementation of the state pattern as oposed to the old "ACS Workflow" which aimed to be a full-fledged workflow more similar to Lotus Notes etc...

Basicly, the GoF architecture maps a number of states to a number of classes (or subclasses in the case of hierarchical states and state-inheritance). These classes implement a number of methods, defined by the superclass or by an interface. These methods usually include access permission checks, a pretty name, GUI output etc. It's pretty generic, so you can add new methods to the states.

In contrast, Workflow is relatively specific with its roles system etc. and its way on how to interact with the environment (callbacks and contracts), probably because TCL doesn't allow for objects and inheritance the way Java does. To me it seems that this specificity makes it more difficult to understand the module.

What I really like about the workflow is the Lisp-style definition and the concept of a prototype-workflow that is cloned to get the actual case instances. I think that's a much more elegant way to describe the states and to deal with their properties, compared to Java etc.

Maybe what we'd need is more a "convention" then a specific piece of code to facilitate the use of the state pattern in applications and to avoid a deadlock in this area because the current workflow is difficult to learn, but nobody dares to implement his own code.

Just thinking loudly:

- Maybe I could reuse the Lisp-style definition scheme of the workflow
- Ignore roles and define "guard conditions" for actions based on privileges. This would be compatible with the role-based authentication used in P/O and the OpenACS permission system in general
- Use the Lisp-style definition to define constant values for states that could be queried with a simple get_attribute(object, state, attribute_name) method
- Use TCL's functional capabilities and use lambda-style functions to model state-specific code

This way we would get a straightforward implementation for the most important question in any workflow: "What actions can the current user perform at the current state?":

set workflow {
    ...
    states {...}
    actions {
        resubmit {
            pretty_name "Resubmit"
            privileges { resubmit_priv }
            new_state resubmitted
            from_states { resolved closed }
        }
        ...
    }
}

ad_proc sp_next_actions {workflow user_id cur_state} {
    Returns the list of actions that user_id can perform
    in the specific state. The "sp_" prefix stands for
    "State Pattern".
} {
    # get the list of all user privileges
    set user_privs [sp_user_privs $user_id]

    # get the list of _all_ workflow actions
    set all_actions [sp_all_actions $workflow]

    # Eliminate all unsuitable and restricted actions
    set allowed_actions [list]
    foreach action $all_actions {
        # Check if the action is appropriate for cur_state by checking from_states
        if {![sp_action_appropriate $workflow $action $cur_state]} {
            next
        }
        # Check that the user has the required privilege (only one!)
        set action_priv [sp_action_get_priv $action]
        if {[lsearch $users_privs $action_priv] < 0} {
            next
        }
        lappend allowed_actions $action
    }
    return $allowed_actions
}

However, there are several potential issues with this algorithms:
- It has a O(m*n) complexity with the number of actions and the number of privileges. However N and M are small..
- Maybe it is difficult for some application to get the list of all user privileges (I remember some comment in the OpenACS permissions tutorial that you shouldn't ask certain questions).
- The complexity of roles definition and maintenance is shifted to the permissions system. Is this positive or negative? It's positive in the case of Project/Open, because is features a role-based permission system anyway.

Positive:
- Very simple and easy to understand how it works
- Low entry barrier for people who want to "just add some states" to their objects
- No need for a SQL data model
- It's extensible by "copy-paste-modify", so users can cover even untypical requirements with it. However, this may lead to duplicated code

Just thinking loudly. I'm sure I've overlooked some serious issues...

Frank

mailto:frank_dot_bergmann_at_project_dash_open_dot_com
http://www.project-open.com/