Guido Casper wrote:
Johan,

thanks a lot for sharing your experiences.

As it happens I'm right now implementing workflow for a customer.

I have no knowledge about OSWorkflow (or any other commercial or non-commercial workflow engine) and having looked at Lenya's workflow package I couldn't quite get how to use it in my context (I would be grateful if Lenya people are listening and jumping into this discussion). However while implementing I quickly discovered I came up with with similar terms (what surprise :-)

It's interesting that you connected workflow directly at the repository (backend) level, which appears right to do so at first. But I believe we should try to do it at the "Cocoon level". TBH currently I'm only interested to do it at the Cocoon level since this would allow me to use it in different "Cocoon contextes". Whether that should read "Cocoon repository level" instead of "Cocoon level" I'm not sure since there might be other objects (like simple records in a SQL table) to be attached to workflow.


Yes, I think we should be as undiscriminating as possible regarding the types of objects that can be the subject of workflow. Even in document publishing it is often not only the physical document itself that is under workflow since it has secundary objects such as images or other type attachments. Or you may want to associate a whole set of documents as one entity with a workflow instance.


But to have a common ground (and terminology) I just talk about (Cocoon's) repository and documents (being resources or objects having workflow attached).

Our customer's repository is also a WebDAV repository and the current workflow state is captured as a WebDAV property of the document.

If the Repository interface within the repository block would be extended with get/setProperties (maybe we should simply have another one "RepoWithProps") I believe the same workflow engine could be connected to any repository implementation attached to that interface.


Currently property management in the repository block is implemented by the proxy-like RepositorySource. I *have* been thinking that this would be nicer to have directly on the Repository interface though. (I don't really like the inheritence model of all different Source enhancements and would only like to only resort to that in special cases such as WebDAV).


The drawback to that approach is that other access paths to the repo are not attached to the workflow (of course you can do things like routing your WebDAV traffic through Cocoon).


Well, going through a repository layer on the Cocoon side does not mean the actual workflow data cannot be persisted in the form of properties on the repository (WebDAV properties in Slide this case). So I don't see a big problem there.


On a side note, I believe in addition to components implementing the Repository interface we could/should come up with a set of components (like a WorkflowManager :-) sitting on top of that repository. But this gets too much offtopic.

The workflow our customer has goes roughly like this:

 ------------         -------------         --------
|tobereviewed|------>|beingreviewed|------>|released|
 ------------         -------------         --------
     /|\                    |                  |
      |                     |                  |
      |                    \|/                \|/
 --------------       -------------         ------
|beingprocessed|<--->|tobeprocessed|<------|online|
 --------------       -------------         ------
     /|\                    |                  |
      |                    \|/                 |
      |                 --------               |
       --------------->|archived|<-------------
                        --------

The boxes represent states a particular document might be in and the arrows are transitions allowed. Authorization is also taken into account in a sense that there are 2 globally valid roles (like user and editor :-) and each user must possess one of those. Some transistions are only allowed by one of those roles (all this looks very similar to your use cases - what surprise again :-). "tobeprocessed" might have a username attached to it and "beingprocessed" always has a username attached to it (the name of the user who put the document into the "beingprocessed" state) and only this user is allowed to edit this document and to transfer it into another state. There is another level of authorization (such as who might create/delete and edit docs at particular repo locations) implemented via WebDAV ACL.


Yay! :-)


We always capture the states as being properties of a document (that means there is no such thing as a workflow instance). So a pending task list for a user might simply be implemented by a DASL (or whatever query language the particular repository implementation might implement) query that goes like:
-give me all documents in "tobeprocessed" state
-give me all documents in "tobeprocessed" state with my name attached
-give me all documents in "tobereviewed" state



I like it.


and doesn't have to be a concern of the workflow engine at all.

So what might such a WorkflowManager look like? Our WorkflowManager (and I hereby propose to follow that path :-) is implemented as a Avalon component with the following interface:
-setState(docURI, requestedState, user, optionalObject)
-getState(docURI)
-getAllowedActions(docURI, user)
-setRepo(repo)


I hope the general meaning of the parameters is clear (and the details may be discussed later). "docURI" might be just an object identifier or an object carrying things like doctype information (so that your second precondition is met). "requestedState" might be a State object, an Action object, an Event object, simply a string or whatever. "optionalObject" in our case is string carrying a comment.



I think the repository is implementation specific and shouldn't be part of the interface. The user might also be regarded as an aspect of the manager's state but I am less sure of that.

--
Unico

Reply via email to