ODMA Extension for Workflow

Version 1.0: 24-Apr-95

This purpose of this proposal is to enhance the ODMA specification beyond just document management and to add groupware capabilities in the form of Workflow. This would not only "document management-enable" applications, but "workflow-enable" them. Workflow enabling would be optional for the application vendor.

The benefits of this proposal are that it presents ODMA as not just a static view of the world, but as the basis for actively managing information within groups and enterprises. It allows users to work completely within their applications while collaborating on documents. It gives application vendors the hooks to groupware-enable their documents, not just document management-enable them. It allows the document management vendors to build cooperative solutions with workflow vendors with the application as the glue.

The form of this API follows the spirit of the ODMA specification, but does not assume that the workflow engine is the same as the document management engine. This would allow users to mix and match components to access the documents through a DMS and coordinate their efforts through a workflow package. This reflects how many packages are being integrated together today, but make the integration occur at the application level. Interpretation of how the workflow commands would work is left entirely up to the workflow engine.

Conceptually, the proposal is simple. It assumes that from within an application, there are three things that a user might want to do with the ID of a workflow or business process:

1.	Start or attach a workflow or business processs to my current document or documents. What this means is left entirely up to the workflow engine. It could start an electronic mail route or database oriented workflow. The user would be presented with some form of dialog for definition and starting the workflow.
	
2.	Find out what is waiting for me in my inbox or queue. All workflow engines have the notion of inboxes, queues or to-do lists. The user would be presented with their queue on this command. This command returns one or more tokens for a document that the application can open for the user.
	
3.	Process my current document(s). If the current document was opened from the inbox (the application should know this), then process this document. Depending on the capabilities of the workflow engine this may mean forward this document on to the next user, reject it, apply rules to it as to what happens next.

Implementing these features implies a user interface change. This could be left up to the application to decide where or when these are presented. These are appropriate menu items for these functions:

	Attach Workflow...
	Workflow Inbox...
	Process Document...
	Get Workflow Info...

The last call is related to the GetDMInfo call of ODMA that gets information on the DMS. This gets information on the Workflow engine.

Workflow IDs

All rules applying to document IDs in ODMA apply to Workflow IDs, with the exception that they are case sensitive due to the recommendation of the Workflow Management Coalition. They are case-sensitive, NULL terminated strings of printable ISO 8859-1 (Latin 1) characters. To distinguish these IDs from document IDs they are prefixed with a ::ODMAWF string. It is important to distinguish these document IDs so that the calling application can handle them appropriately without requiring an interpretation of the ODM_ID portion of the ID string. Their form is similar to the ODMA ID.

	::ODMAWF\WF_ID\WF_SPECIFIC_INFO

Constants

All constants of ODMA apply to this interface as well. All ID lengths and buffer lengths apply.

Error Handling

The Workflow Manager is responsible for displaying informational error messages. When the ODM_SILENT flag is used, the Workflow Manager will not display these messages. The exception is the ODMWFRegisterApp where the caller should assume that the error message has not been displayed (see ODMWFRegisterApp). All other caveats from ODMA apply.

Connections

The Workflow Manager API follows the same rules of connection that the ODMA interface follows. The connection however must be a separate one unless the ODMA ODMRegisterApp interface allows the for the return of information that the interface is a workflow interface. This is to accomodate interfaces that are workflow only and do not perform document management functions. 

Workflow Manager API

The workflow component would be similar to the ODMA interface in how it connects and is registered. It would use the same administration files. There are two pieces of information that are different.

ODMWFHANDLE pODMWFHandle
This is the handle of the workflow manager instance. It is retrieved from registering the workflow manager.
	
LPSTR lpszWorkflowID
Similar to the ID of a document within ODMA, the workflow ID identifies the workflow object being processed. This identifier must be distinct from a document ID because a workflow object may contain mutiple documents, and because there may be state associated with the workflow object that is not part of the state of any of its documents. This identifier is a string as in ODMA 1.0 because it is independent of the underlying workflow engine and can be transported as a string through alternate messaging systems.

Just as ODMA does not require the application to maintain document management information from the DMS, this workflow interface does not require the application to maintain workflow information. It is up to the workflow engine to maintain persistent information about the workflow and documents being worked on. No structures are to be maintained by the application.

Binding occurs the same as ODMA.DLL except that there is a ODMAWF.LIB and ODMAWF.DLL.

ODMWFRegisterApp
WORD ODMWFRegisterApp( ODMWFHANDLE FAR *pODMWFHandle, WORD version, LPSTR lpszAppId, DWORD dwEnvData, WORD pReserved )

ODMWFRegisterApp registers an application with the appropriate Workflow Management system (WMS) and returns a handle that can be used in calls to other ODMA Workflow functions. An application must call this function before calling any of the other ODMA Workflow functions. Contextual information about the user, security, etc. should be maintained internally by the WMS. Authentication and logon user interfaces are the responsibility of the WMS.

The caller of this function should assume that an error message has not been displayed in case of an error returned. This is due to the fact that the Workflow Manager may not be up and that the connection manager may not be able to translate the message appropriately.

Parameters:

pDmWorkHandle - out - If successful, a handle is returned here that can be used in calls to other ODMA Workflow functions. If the registration fails then 0 is returned here.

version - in - Specifies the version of the API required by the application. 100 should be passed to indicate version 1.0, 110 should be passed to indicate version 1.1, etc. All versions of the ODMA Workflow API will be downward compatible, so this should be interpreted as the minimum version number that the calling application expects the WMS to support. If the WMS does not support the specified version or a higher version then it should return an error.

lpszAppId - in - A unique identifier for the application. The maximum length for this string is 16 characters including the terminating NULL and it cannot begin with a digit. It is recommended that a Windows application use the File Manager ProgId for it primary document class, but this is not required.

dwEnvData - in - Environment data. On Windows platforms this is a Window handle for a parent window in the calling application. The WMS may use this winodw handle as the parent window for any dialogs or other windows it displays in response to ODMA Workflow calls. This handle must remain valid for the duration of the ODMA Workflow session (i.e. until ODMWFUnRegisterApp is called).

pReserved - in - Reserved for future use. Must be set to NULL.

Return Value: 0 is returned if successful. ODM_E_NOWMS is returned if no Workflow Management System has been registered for the calling application. ODM_E_CANTINIT is returned if a WMS is registered for the calling application but it fails to initialize itself. ODM_E_VERSION is returned if the WMS does not support the requested version of the API.

ODMWFUnRegisterApp
void ODMWFUnRegisterApp( ODMWFHANDLE pODMWFHandle )

An application that previously registered itself with a WMS via ODMWFRegisterApp should call this function when it is finished using the WMS. This would typically be done when the application is shutting down. After this call returns, the WMS handle is no longer valid and cannot be used for subsequent calls to ODMA Workflow functions.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

ODMWFNewObject
WORD ODMWFNewObject( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowID, LPDWORD pdwFlags )

This function calls the WMS to create a workflow object and associated ID. The calling application passes a buffer to contain the workflow ID. The application can then use the ODMWFInsertItem to attach documents and ODMWFProcessObject to initiate the workflow. The WMS has the option of presenting dialogs at any of these points to allow the user to select the workflow and confirm the documents to be attached.

The new workflow instance may be a brand new workflow object, an existing workflow object, or a copy of an existing workflow object. It may also be a mail message sent to a list of recipients. This is entirely up to the WMS.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflow - out - The id of the workflow object. The WMS uses this to track the specific instance of the workflow as it exists in the system. This buffer should be as large as the size determined for ODMA IDs.

pdwFlags - in/out - On input, 0 or a combination of 1 or more of the following values:

ODM_SILENT - The DMS should not require user interaction while satisfying the call.  If the call cannot be satisfied without user interaction then an error should be returned.

Return Value: 0 is returned if the workflow is successfully attached. ODM_E_NOATTACH is returned if the workflow could not attach this document. ODM_W_CANCEL is returned if the user canceled the operation.

ODMWFSelectObject
WORD ODMWFSelectObject( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowID, LPDWORD pdwFlags )

This is similar to the ODMWFSelectDoc call but is specifically designed to work with workflow. The users inbox is opened as interpreted by the WMS. The ids of any documents the workflow is routing can be obtained using the ODMWFGetItem calls. The documents are opened using the ODMA Open calls. After viewing, editing and/or saving the attached documents, the workflow id is then processed by ODMWFProcessObject call.

There can potentially be a number of ways that the WMS can present the user’s inbox. These are all WMS specific and it is left to the WMS to present these choices to the user. Any filtering of possible workflows is also left to the WMS.

Note: If there is a limited, universally accepted set of views that can be agreed, then those views should be exposed as part of the API and User Interface. Two possible choices are inbox and outbox.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowID - out - The ID of the workflow object. The WMS uses this to track the specific instance of the workflow.

pdwFlags - in/out - On input, 0 or a combination of 1 or more of the following values:

ODM_SILENT - The DMS should not require user interaction while satisfying the call.  If the call cannot be satisfied without user interaction then an error should be returned.

Return Value: 0 is returned if the workflow is successfully attached. ODM_E_BADWORKFLOW is returned if a workflow could not be fetched from the inbox. ODM_W_CANCEL is returned if the user canceled the operation.

ODMWFInsertItem
WORD ODMWFInsertItem( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowID, WORD wItemNumber, LPSTR lpszDocIdentifier )

ODMWFInsertItem allows the caller to insert a document to the collection of items attached to the workflow identified by the id. This collection is an ordered list and is inserted before the position indicated by the item number. A 0 value will put the new item at zero and force all the subsequent values down one. An item inserted at one past the last item will make the new item the last item. The attached item may either be identified by an ODMA ID or a simple file path. The ODMWFProcessObject should commit the changes made to the workflow.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowID - in - The ID of the workflow object. The WMS uses this to track the specific instance of the workflow.

wItemNumber - in - The index of the item to fetch from the collection of items attached to this workflow.

lpszDocIdentifier - in - A pointer to a ODMA-sized buffer to be filled in with the information required to fetch the document at the specified location. This buffer may be filled in with an ODMA Id or a file identifier. If this is an ODMA Id then this should be easily identified.

Return Value: 0 is returned if the workflow is successfully attached. ODM_E_BADINDEX is returned if the index value is out of bounds. ODM_E_NOPERMIT is returned if the user has no permission to modify the list of attachments to the workflow.

ODMWFRemoveItem
WORD ODMWFRemoveItem( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowID, WORD wItemNumber )

ODMWFRemoveItem allows the caller to remove a document from the collection of items attached to the workflow identified by the id. This collection is an ordered list and is removed from the position indicated by the item number. A 0 value will remove the first item and force all the subsequent values to move up one. This call only removes the item from the list and does not destroy the object. The ODMWFProcessObject should commit the changes made to the workflow.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowID - in - The ID of the workflow object. The WMS uses this to track the specific instance of the workflow.

wItemNumber - in - The index of the item to fetch from the collection of items attached to this workflow.

Return Value: 0 is returned if the workflow is successfully attached. ODM_E_BADINDEX is returned if the index value is out of bounds. ODM_E_NOPERMIT is returned if the user has no permission to modify the list of attachments to the workflow.

ODMWFGetItem
WORD ODMWFGetItem( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowID, WORD wItemNumber, LPSTR lpszDocIdentifier )

ODMWFGetItem allows the caller to enumerate through the collection of items attached to the workflow identified by the id. This collection is an ordered list and specified by the ODMWFInsertItem call. The WMS must return the documents in the same order the documents in which they were inserted. The attached item may either be identified by an ODMA ID or a simple file path.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowID - in - The ID of the workflow object. The WMS uses this to track the specific instance of the workflow.

wItemNumber - in - The index of the item to fetch from the collection of items attached to this workflow.

lpszDocIdentifier - out - A pointer to a ODMA-sized buffer to be filled in with the information required to fetch the document at the specified location. This buffer may be filled in with an ODMA Id or a file identifier. Based upon this string, the application should be able to determine if this is an ODMA ID or a filename.

Return Value: 0 is returned if the workflow is successfully attached. ODM_E_BADINDEX is returned if the index value is out of bounds.

ODMWFProcessObject
WORD ODMWFProcessDoc( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowID, LPDWORD pdwFlags )

This function calls the WMS to handle any forwarding action that may be required for this workflow. The workflow processed will have been retrieved using the ODMWFSelectObject or ODMWFNewObject. The semantics and context of this operation are up to the WMS and based upon the workflow ID. Based upon the values of the flags returned by this call the application should close the attached documents or leave them open. The function should not be called if the attached documents are dirty and have not been saved off to the DMS if they are identified by an ODMA ID.

Possible actions that may be involved in processing a workflow are:

1.	Start a new workflow. This is a workflow that has just been started by ODMWFNewObject.
	
2.	Forward the attached documents to the next user in the workflow or business process.
	
3.	Return the attached documents back to the previous user.
	
4.	Stop working on the current documents. (This may be called if the documents are dirty. It is up to the WMS to determine if documents may be dirty for a particular operation. It determines this with the appropriate ODMA call.)

The attached documents are managed using the ODMWFInsertItem, ODMWFRemoveItem and ODMWFGetItem.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowID - in - The ID of the workflow object. The WMS uses this to track the specific instance of the workflow.

pdwFlags - in/out - On input, 0 or a combination of 1 or more of the following values:

ODM_SILENT - The DMS should not require user interaction while satisfying the call.  If the call cannot be satisfied without user interaction then an error should be returned.

Upon return, one of the following flags will be set unless an error occurred:

ODM_CLOSEDOCS - The user or WMS indicated that the selected documents should be closed.

ODM_REOPENDOCS - This flag has been removed. Unless ODM_CLOSEDOCS has been returned, then documents should be left open.

Return Value: 0 is returned if the workflow is successfully attached.

ODMWFGetObjectInfo
ODMSTATUS ODMWFGetObjectInfo( ODMWFHANDLE pODMWFHandle, LPSTR lpszWorkflowId, WORD attribute, LPSTR lpszData, WORD dataLen )

An application can use this function to obtain information about a workflow from the WMS.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowId - in - A NULL-terminated Workflow ID.  This is typically obtained by a call to ODMWFSelectObject or ODMWFNewObject.

attribute - in - One of the following:

ODM_AUTHOR - Owner or Supervisor of the workflow.
ODM_NAME - Name of the workflow.  This is a descriptive name for the workflow and does not represent a filename.
ODM_STATUS - Status of the workflow.  This is typically an indication of the current status of the workflow such as Active, Late, Complete.
ODM_TITLETEXT - Suggested text to display in the workflow window's title bar.  This may include one or more fields from the workflow’s profile and possibly other information as well.
ODM_WMS_DEFINED - The lpszData parameter contains a WMS-specific indication of the data to be returned.  Note that an application must know which WMS it is talking to and must understand the data indications supported by that WMS in order to use this attribute name.
ODM_ITEMCOUNT - The lpszData parameter contains an ASCII-encoded value of the number of documents managed by this workflow. It is ASCII-encoded for consistency of results from the other parameters.
ODM_USERID - The lpszData parameter returns the ID of the user as understood by the WMS.
ODM_USERNAME - The lpszData parameter returns the full descriptive name of the user as understood by the WMS. Depending upon the implementation of the WMS, this may be the same value.

lpszData - in/out - On input, ignored if attribute is anything other than  ODM_WMS_DEFINED.  If attribute is ODM_WMS_DEFINED then lpszData contains an indication of the data to be returned.  On output, the requested data is returned in the buffer pointed to by lpszData.

dataLen - in - length of the output buffer pointed to by lpszData.  If the data to be returned is longer than this, it will be truncated.  In either case the returned data will always be terminated with a NULL character.

Return value:  0 if successful. ODM_E_ITEM if attribute is invalid or not supported by the workflow's WMS.  ODM_E_HANDLE if dmHandle was invalid.

ODMWFSetObjectInfo
ODMSTATUS ODMWFSetObjectInfo( ODMWFHANDLE pODMWFHandle, LPSTR lpszDocId, WORD attribute, LPSTR lpszData )

An application can use this function to pass information about the workflow to the WMS.  The WMS may or may not accept the information; most WMSs validate attributes like authors against predefined tables.

Parameters:

pODMWFHandle - in - An ODMA Workflow Handle obtained by a previous call to ODMWFRegisterApp().

lpszWorkflowId - in - A NULL-terminated Workflow ID.  This is typically obtained by a call to ODMWFSelectObject or ODMWFNewObject.

attribute - in - One of the following:

ODM_AUTHOR - Owner or Supervisor of the workflow.
ODM_NAME - Name of the workflow.  This is a descriptive name for the workflow and does not represent a filename.
ODM_WMS_DEFINED - The lpszData parameter contains a WMS-specific indication of the data to be returned.  Note that an application must know which DMS it is talking to and must understand the data indications supported by that DMS in order to use this attribute name.

lpszData - in - the data being passed to the WMS.  Must be NULL terminated.

Return value:  0 if successful. ODM_E_ITEM if attribute is invalid or not supported by the WMS.  ODM_E_HANDLE if pODMWFHandle was invalid.  ODM_E_FAIL if the specified data was invalid or the WMS was unable to accept it for other reasons.

ODMWFActivate
void ODMWFActivate( ODMWFHANDLE pODMWFHandle, WORD action, LPSTR lpszWorkflowID )

This function is called when the user chooses the “Get Workflow Info...” menu item. This assumes that the calling application has kept track of the current workflows. It presents information on the workflow and attached documents which have been opened as a result of ODMWFSelectObject and ODMWFGetItem calls. It may also be called from standard dialogs within the application. This function causes the WMS to perform actions that do not require cooperation from the calling application.  Control is returned to the calling application after the specified action has been completed.  Note that a WMS is not required to support all of these actions.

Parameters:

dmHandle - in - A Workflow handle obtained by a previous call to ODMWFRegisterApp.

action - in - One of the following action codes:

ODM_NONE - No specific is requested. The WMS should simply make itself visible and let the user select the action to be performed.

ODM_DELETE - The WMS should remove the workflow instance.

ODM_SHOWATTRIBUTES - The WMS should display the specified workflow’s history, profile and attributes.

ODM_EDITATTRIBUTES - The WMS should display the specified workflow’s attributes and the user should be put into edit mode. The WMS may not allow this operation while the workflow is active.

lpszWorkflowID - in - The ID of the workflow as identified by the WMS. If this value is NULL, then the WMS displays general information about the Workflow Management System.

ODMWFGetWMSInfo
void ODMWFGetWMSInfo( ODMWFHANDLE pODMWFHandle, LPSTR wmsId, LPWORD pwVerNo, LPDWORD pdwExtensions )

This function returns information to the application about the currently active WMS.

Parameters:

dmHandle - in - A Workflow handle obtained by a previous call to ODMWFRegisterApp.

wmsId - out - This should point to an area at least 9 bytes long. A NULL-terminated ID identifying the WMS is returned here. This is the same ID embedded in workflow IDs returned by this WMS.

pwVerNo - out - The version of the ODMA API supported by this WMS is returned here.

pdwExtensions - out - Indications of extensions to the base ODMA API that are supported by this WMS are returned here. No extensions have been defined yet, so currently 0 will always be returned here.