Copyright © 1997 AIIM International
HTML EDITION 2.0-3 Review Draft last updated 2001-09-04-12:49 -0700 (pdt)
For the latest information on ODMA and the ODMA Specifications, consult the ODMA section of the AIIM DMware Development Site. Current locations of development sites can be found through AIIM DMware. The current status of ODMA and its support, including current status of ODMA 2.0, is reported in the ODMA Support section.
Specification History
1.1 Document IDs
1.2 Constants
1.3 Error Handling
1.4 Connections and the ODMA Connection Manager
1.5 Document Format Names
1.6 DMS or Native File System Dialogs - Which to Display First
1.7 Character Sets
1.8 Application Interfaces
1.9 Query Syntax
1.10 Query Examples
2.1
ODMActivate
2.2ODMCloseDoc
2.3ODMCloseDocEx
2.4ODMGetAlternateContent
2.5ODMGetDMS
2.6ODMGetDMSCount
2.7ODMGetDMSInfo
2.8ODMGetDMSList
2.9ODMGetDocInfo
2.10ODMGetDocRelation
2.11ODMGetLeadMoniker
2.12ODMNewDoc
2.13ODMOpenDoc
2.14ODMQueryCapability
2.15ODMQueryClose
2.16ODMQueryExecute
2.17ODMQueryGetResults
2.18ODMQueryInterface
2.19ODMRegisterApp
2.20ODMSaveAs
2.21ODMSaveAsEx
2.22ODMSaveDoc
2.23ODMSaveDocEx
2.24ODMSelectDoc
2.25ODMSelectDocEx
2.26ODMSetAlternateContent
2.27ODMSetDMS
2.28ODMSetDocEvent
2.29ODMSetDocInfo
2.30ODMSetDocRelation
2.31ODMUnRegisterApp
3.1
ODMGetODMInterface
3.2IODMDocManInterface
3.3IODMQueryInterface
3.4IODMDocMan2Interface
ODM_E_INUSE as a valid return code in ODMActivate.ODMQuery* functions and
the IODMQuery COM interface. Also added a clarification to the expected
behavior of an application when calling ODMSaveAs and an empty string is
returned for lpszNewDocId. IODMDocMan2 interface. Defined several items to help provide better
out-of-the-box integration between desktop applications and DMS. Also added
clarifications to the existing specification and arranged the functions
alphabetically.The original impetus for the Open Document Management API (ODMA) was the recognition that there was no standard method for a client application to integrate with a Document Management System (DMS). Each DMS vendor wrote separate integration code for each of the major client applications they supported. Applications that did not have integrations written for them by the DMS vendors would have to write and support a separate integration for each DMS that was supported. This required a complete matrix of integrations, each with its own set of bugs, limitations and reliability issues. It seemed obvious that a high level standard for connecting applications and document management systems was a natural fit.
A small group of application and DMS vendors started working together to create an API that would allow applications and document management systems to inter-operate through a single high level API. This implied the creation of a standard, however, the creation of a standard has many pitfalls. Probably the biggest problem is that a lot of work can be put into the creation of the standard, and nobody uses it.
The industry is filled with examples of standards that were obsolete by the time they made it through the standardization process. By the time some standards make it through the standardization process, they are so large and unwieldy they are almost impossible to implement and maintain. Company politics and hidden agendas of the participants can play as big a role in the adoption of a standard as trying to solve the problem in the first place. The industry is also full of proprietary API’s that claim to be standards, but are not. The initial group of vendors that met and formed the ODMA consortium wanted to avoid as many of these problems as possible.
The working rules of the ODMA consortium are fairly simple.
It is difficult to express the importance the initial members of the consortium placed on wanting to create a useful API that is vendor and platform independent while still simple to implement. They recognized that they could solve 80 percent of the problem easily and were willing to live with having to solve another 10 percent over time and probably never being able to solve the final 10 percent.
The Open Document Management API (ODMA) is a standardized, high-level interface between desktop applications and document management systems (DMSs). Its purposes are:
ODMA specifies a set of interfaces that applications can use to initiate actions within a DMS. The API is intended to be relatively easy for application vendors to incorporate into updates of existing applications. It should not require major restructuring of an application to integrate it with ODMA. Note that this version of ODMA does not specify how DMSs may initiate actions within the applications.
The ODMA API is platform-independent. The associated data type definitions and binding information are platform-specific. Currently, most of the work has been done in Windows. It makes this document look Windows specific, but over time, the platform specific entries for other platforms will be added as they are defined.
Many of the ODMA functions accept or return a Document ID parameter. A document ID is a persistent, portable identifier for a document. It can be stored and used in a later session, and it can be passed across platforms via email or other processes.
A Document ID is a case insensitive, null-terminated string of printable characters. Although a document ID is case insensitive, an application should never change the case of a document ID. The format of a document ID is
::ODMA\DMS_ID\DM_SPECIFIC_INFOThe DMS_ID portion of a document ID will identify which DMS provided the
ID. This information is primarily for the use of ODMA itself; applications
using ODMA should not need to know which DMS provided a particular ID. The
ODMA group members will coordinate these IDs to ensure their uniqueness. The
maximum length of the DMS_ID portion of the document ID is specified by the
constant ODM_DMSID_MAX. The DM_SPECIFIC_INFO portion of the ID will
vary depending on which DMS built the ID. The total length of the document ID
including the terminating Null character cannot exceed ODM_DOCID_MAX
bytes.
ODMA-aware applications should be able to handle a document ID anywhere they handle an externally-generated document filename. For example, if the application allows a document filename to be passed as a command line argument then it should allow a document ID to be passed in the same way. If the application allows document filenames to be used in DDE commands then it should also support the use of document IDs in the same commands.
Although the technical definition of a document ID is a case insensitive,
null-terminated strings of printable characters, there are some general rules
that are more likely to make a DMS and ODMA application work better together.
ODMA was designed so that it would be easy to add to an application without
major modifications in code or structure. If a DMS passes a document ID that
breaks fundamental rules of normal file and path names it will probably run
into problems if it is passed in on a command line. Special characters like ^,
[, ], |, *, -,
>, < and ? are processed by the UNIX shell even before
they are seen by the application. It is possible to pass these characters by
using special escape sequences, but that places a burden on the DMS vendor to
process the document ID before giving it to the ODMA application. Some
operating systems require the application to handle the reverse process of
interpreting and removing the escape characters. The application may be able
to support the escape removal on the command line, but not if the document ID
with escape characters is returned in a procedure call. In most cases, it is
easier to generate a document ID that contains a fairly simple set of
characters. The following table suggests characters it may be wise to avoid
for different platforms.
| Platform | Characters to avoid |
| Windows 3.x | " ‘ < > * ? | and the space
character |
| Windows 95 | " ‘ < > * ? | |
| Other platforms to be defined |
The following table lists the constants that are defined in the odma.h
header.
| CONSTANTS | Win 3.x | Win32 | Mac | UNIX | Other |
ODM_DOCID_MAXMaximum length of a document ID including the null-terminator. |
80 | 255 | 255 | 255 | 255 |
ODM_FILENAME_MAXMaximum length of a path/filename returned by ODMA including the terminating Null character. |
128 | 255 | 255 | 1024 | 255 |
ODM_API_VERSIONThe version of the ODMA API to which this header file corresponds. See ODMRegisterApp. |
200 | 200 | 200 | 200 | 200 |
ODM_DMSID_MAXMaximum length of a DMS ID including the null-terminator. |
9 | 9 | 9 | 9 | 9 |
ODM_APPID_MAXMaximum length of an Application ID including the null-terminator. |
16 | 16 | 16 | 16 | 16 |
ODM_FORMAT_MAXMaximum length of a content format string including the null-terminator. |
81 | 81 | 81 | 81 | 81 |
ODM_QUERYID_MAXMaximum length of a query ID string including the null-terminator. |
255 | 255 | 255 | 255 | 255 |
Nearly all of the ODMA functions use the return value to indicate to the
calling application whether the function succeeded, failed because the user
canceled the operation, or failed for other reasons. The DMS is responsible
for displaying informational error messages to the user where appropriate
except when the ODM_SILENT flag is specified. The DMS must take care to
return the appropriate error indication because applications may act
differently depending on whether an ODMA call was canceled by the user or
failed for other reasons. The calling application generally should not display
error messages when an error value is returned from ODMA unless the ODM_SILENT flag was specified.
The ODMA connection manager is a small software module that sits between applications using ODMA and document management systems implementing ODMA. It manages the connections between these components and routes ODMA calls to the appropriate provider. A freely redistributable copy of the ODMA connection manager will be provided to any vendor wishing to implement or make use of the ODMA API. This is a place where it would be possible to provide mapping code that would allow ODMA to have truly platform independent document IDs, however, it currently only manages connections and does not touch document IDs.
When new documents are registered with a DMS via ODMA and when an existing
document's format is changed by an application, the application passes a
document format name to ODMA. Document format names are null-terminated
strings defining the format of a document's content. These strings have a
maximum length defined by the ODM_FORMAT_MAX constant.
There are several places in ODMA where a content format name for a document
can be specified or requested. The ODMNewDoc,
ODMSaveAs and ODMSaveAsEx functions each have a
lpszFormat parameter where a format
can be specified. The ODMSaveAs also has a callback, which uses a
format string. The ODM_CONTENTFORMAT attribute can be requested or set
using the ODMGetDocInfo and ODMSetDocInfo functions.
The ODMA 1.0 specification did not attempt to standardize the format names used by DMS and application vendors. This was a significant limitation in some cases. The DMS would not know in advance what type of file was being created by the application. Also an application that saved an existing file back to the DMS using a different format would have no standard format name to give to the DMS. This model relied on both the DMS and the application being able to auto-detect all file formats.
ODMA 2.0 defines guidelines to standardize format names. This has become
necessary due to vendors’ desire to have applications and DMSs more tightly
integrated and because ODMA 2.0 introduces some new functions which require
standardization in order to work. The new ODMGetAlternateContent and
ODMSetAlternateContent functions require the DMS and application to
have a standard way to identify file content. A new document attribute called ODM_ALTERNATE_RENDERINGS allows an application to find out if a DMS can
provide a document in other formats and make a choice of which to use.
ODMA has defined the following guidelines to standardize how a DMS or application might specify a document’s content format:
application/msword
.doc.doc/MS Word 95 Document.doc/MS Word 97 Document
image/tiff
.TIF.TIFF.TIF/Tagged Image File Format.TIF/Scanned TIFF
A DMS or application can use the Windows Registry or its own mapping capability to convert a file extension to a MIME code or vice versa. Note that some file extensions are used by more than one application, some file types have multiple valid file extensions, and that some MIME content types are used to define more than one file type within the same application. A DMS or application may have use whatever format name is most precise.
ODMA imposes no rules on applications requiring them to always show the DMS dialogs first in response to filing commands such as File Open and File Save As. ODMA applications are encouraged to provide a user preference setting so the user can designate if the application’s native file system dialog or the DMS’s dialog is displayed first. Ideally the application may provide a push-button or some other control in its native file system dialog box to allow the user to quickly select the DMS dialog box.
If the application cannot provide one or more of the options described
above then they have no choice but to always display the DMS dialog box in
response to the File Open and File Save As commands. Each ODMA compliant DMS
must provide a way for the user to select the native file system from dialogs
displayed while processing the ODMSelectDoc,
ODMSelectDocEx, ODMNewDoc,
ODMSaveAs and
ODMSaveAsEx functions. The DMS
returns the ODM_E_APPSELECT status if the user elects to use the native
file system. When this status is returned the application can display their
dialog box. If the user wishes to return to the DMS dialog box they will have
to cancel and re-do the file command.
All strings passed to or
returned from ODMA functions should be null-terminated series of octets, in
the standard character set of the system on where ODMA is being used. So for
example, 8859-1 would be used on English Windows, Shift-JIS would be used on
Japanese Windows, etc. The term "null-terminated" as used in this
specification means terminated by the character set's natural Null character.
For most character sets this means a single byte with the value 0x0.
If an application obtains an ODMA document ID on one platform and later uses it on another platform, the application is responsible for translating the ID to the character set being used on the second platform before using it there.
An
ODMA-aware application can choose to communicate with the ODMA Connection
Manager either through a traditional, function-oriented API or through
Component Object Model (COM) interfaces. Prototypes and constants used for the
function-oriented API are included in the odma.h header file. Prototypes,
constants, and interface definitions for the COM interface are included in the
odmacom.h header file.
After calling ODMRegisterApp, applications can obtain one or more
COM interfaces to ODMA through the ODMQueryInterface function. The
IODMDocMan interface provides an alternate entry point to most of the
ODMA functions documented below. Other functions are defined in the IODMDocMan2 and
IODMQuery interfaces. These interfaces and their
interface IDs are defined in the odmacom.h header file.
Note that IODMDocMan::QueryInterface will only query the default DMS
for the calling application. The application must call ODMQueryInterface in
order to query other DMSs.
The query syntax described
here is used in the ODMQueryExecute function.
| <query> | :: select <returned_list> <search_criteria> |
| <returned_list> | :: <returned_item> [, <returned_list>] |
| <returned_item> | :: ODM_DOCID:: ODM_NAME |
| <search_criteria> | :: <search_clause> :: <where_clause> :: <search_clause> <where_clause> :: <where_clause> <search_clause> |
| <search_clause> | :: search document contains <expression> |
| <expressioin> | :: (<expression>):: [ not]
(<expression>):: <term> [<operator> <expression>] |
| <term> | :: ‘<word>’ :: [ not] ‘<word>’ |
| <operator> | :: and:: or |
| <word> | is a user supplied word. If there is a single quote (’) inside this
word, it needs to be represented with two consecutive single quotes
(’’). |
| <where_clause> | :: where <condition_list> |
| <condition_list> | :: <condition> [<operator> <condition_list>] |
| <condition> | :: <attribute> <op> |
‘<attribute_value>’<attribute> |
:: ODM_FORMAT:: ODM_NAME:: ODM_AUTHOR:: ODM_TYPE::
ODM_DMS_DEFINED:<dms_attribute> :: * Any other document attribute listed in Appendix A |
| <op> | :: =:: !=:: <>:: >:: <:: <=::
>= |
| <dms_attribute> | is a DMS specific attribute name. |
| <attribute_value> | is a user supplied value for ODM_NAME, etc. If there is a single
quote (’) inside any of these names, it must be represented with two
consecutive single quotes (’’). |
| Example 1: | select ODM_DOCID, ODM_NAME |
| Example 2: | select ODM_DOCID, ODM_NAME |
| Example 3: | select ODM_DOCID, ODM_NAME |
| Example 4: | select ODM_DOCID, ODM_NAME |
The following section describes each function in the ODMA API that a typical application would use. The functions are listed in alphabetical order.
ODMSTATUS ODMActivate( ODMHANDLE handle, WORD action, LPSTR lpszDocId)
This function causes the DMS 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, except where noted. A DMS is not required to support all of these actions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ODMSTATUS ODMCloseDoc( ODMHANDLE handle, LPSTR lpszDocId, DWORD active Time, DWORD pagesPrinted, LPVOID sessionData, WORD dataLen)
An application that has opened a document by calling ODMOpenDoc must call
ODMCloseDoc when it is finished using the document. The application
should not call this function until after it has closed the document, because
the DMS may move the document or make it inaccessible as a result of this
call. Note that this function will not cause the document to be saved into the
DMS's persistent repository unless ODMSaveDoc has been called
previously.
It is possible for a user to explicitly check-out/reserve a document using
either ODMActivate or a command provided by the DMS. If a document was
already reserved by the user before ODMOpenDoc was called, then when
ODMCloseDoc is called it is recommended that the DMS keep the document
reserved. The DMS should only check-in/unreserve the document in ODMCloseDoc if it first displays a dialog box confirming this with the
user.
|
|
|
|
|
|
|
|
|
|
|
ODMSTATUS ODMCloseDocEx( ODMHANDLE handle, LPSTR lpszDocId, LPDWORD pdwFlags, DWORD activeTime, DWORD pagesPrinted, LPVOID sessionData, WORD dataLen)
ODMCloseDocEx is the same as ODMCloseDoc except it has a
pwdFlags parameter. There is an ODM_SILENT flag to facilitate
unattended document processing. Some DMSs display a user interface when
closing a document. This flag allows the calling application to suppress this
UI.
An application that has opened a document by calling ODMOpenDoc must
call ODMCloseDoc or ODMCloseDocEx when it is finished using the
document. The application should not call this function until after it has
closed the document, because the DMS may move the document or make it
inaccessible as a result of this call. Note that this function will not cause
the document to be saved into the DMS's persistent repository unless ODMSaveDoc or
ODMSaveDocEx has been called previously.
It is possible for a user to explicitly check-out/reserve a document using
either ODMActivate or a command provided by the DMS. If a document was
already reserved by the user before ODMOpenDoc was called, then when
ODMCloseDocEx is called it is recommended that the DMS keep the
document reserved. The DMS should only check-in/unreserve the document in ODMCloseDocEx if the
ODM_SILENT flag is not set and it first
displays a dialog box confirming this with the user.
|
|
|
|
|
|
|
|
|
|
|
|
|
ODMSTATUS ODMGetAlternateContent ( ODMHANDLE handle, LPSTR lpszDocId, LPDWORD pdwFlags, LPSTR lpszFormat, LPSTR lpszDocLocation)
This function causes the DMS to return an alternate content file for the
specified document. The format of the alternate content file should be one of
the formats returned by the ODM_ALTERNATE_RENDERINGS item in a previous
call to ODMGetDocInfo. The application is responsible for deleting the
alternate content file when it is finished using it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This function provides an application a programmatic way to get its default
DMS. The DMS ID of the current DMS for the application will be returned. This
can be either the default DMS from the registry or a DMS previously set by the
application using ODMSetDMS.
|
|
|
|
|
WORD ODMGetDMSCount( )
This is an informational function. It will count the number of DMSs
currently registered on the system. This information can be used to determine
the minimum size for the buffer in a call to ODMGetDMSList.
none.
The number of DMSs currently registered on the system.
ODMSTATUS ODMGetDMSInfo( ODMHANDLE handle, LPSTR lpszDmsId, LPWORD pwVerNo, LPDWORD pdwExtensions )
This function returns information to the application about the currently active DMS. The application if free to only request the information it needs.
|
|
|
|
|
|
WORD ODMGetDMSList( LPSTR buffer, WORD buffer_size )
This function gets a list of the DMSs currently registered on the system.
|
The number of DMSs returned in buffer.
ODMSTATUS ODMGetDocInfo( ODMHANDLE handle, LPSTR lpszDocId, WORD item, LPSTR lpszData, WORD dataLen )
An application can use this function to obtain information about a document from the DMS. It is recommended that the DMS not display any user interface while processing this function.
|
|
|
|
|
|
|
|
|
|
|
|
ODMSTATUS ODMGetDocRelation( ODMHANDLE handle, LPSTR lpszDocId, LPDWORD pdwFlags, LPSTR lpszLinkedId, LPSTR lpszFormat, LPSTR lpszPreviousId )
An application can use this function to retrieve pointers to document versions linked to a particular document ID. This function would be used typically as part of retrieving a compound document. It could also be used when saving an updated component document, for the user to verify which compound documents will be impacted by any changes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ODMSTATUS ODMGetLeadMoniker( ODMHANDLE handle, LPSTR lpszDocId, LPMONIKER FAR *ppMoniker )
Applications that are OLE 2 servers typically form composite monikers for their OLE links by combining a file moniker representing the document with one or more item monikers representing a particular section of the document. This approach often does not work in environments where Document Management Systems are in use because the filename that the application sees is usually just temporary. This function lets the application obtain a leading moniker from the DMS that can be used in place of the file moniker.
This function will only be available on platforms supporting OLE 2. This
function may not be supported by some DMSs; those DMSs will return ODM_E_FAIL. In this case the application should go ahead and use the
file moniker as though ODMA were not present. Note that this function is
prototyped in odmacom.h instead of odma.h, so that non-OLE-aware applications
do not have to #include the OLE header files.
|
|
|
|
|
|
|
ODMSTATUS ODMNewDoc( ODMHANDLE handle, LPSTR lpszDocId, DWORD dwFlags, LPSTR lpszFormat, LPSTR lpszDocLocation )
This function causes the DMS to create a new document profile and return the document ID for the new document to the calling application. The DMS may create a temporary or pending document profile; it may not have actually created a document in its data store. If the DMS displays a dialog box for this function it should be task/application modal.
The document ID returned by the DMS in ODMNewDoc provides a document
context for the application. This document ID must be used in subsequent ODMA
function calls which are needed to complete the process of saving a new
document into a DMS. If the user decides to cancel the operation or save the
document to the native file system, then the application should call ODMCloseDoc or
ODMCloseDocEx and throw the document ID away. The
document ID returned by ODMNewDoc may be temporary so the application must be
prepared for the possibility that the DMS will later override it in a call to ODMSaveAs,
ODMSaveAsEx or ODMSaveDoc or
ODMSaveDocEx.
The calling sequence for creating a new
document, which isn’t based on
another existing document, is as follows: ODMNewDoc,
ODMSaveAs, ODMOpenDoc then
ODMSaveDoc. Finally the document must be
closed with ODMCloseDoc. The above sequence will likely involve user
interaction with the DMS displaying one or more dialog boxes.
It is possible for an application to create a new document without any user
interaction if the DMS supports it. To accomplish this the calling application
should set the ODM_SILENT flag and use the following call sequence:
ODMNewDoc, {ODMSetDocInfo},
ODMSaveAsEx, ODMOpenDoc,
ODMSaveDocEx and ODMCloseDocEx.
Optionally, if the application wishes to pre-set some document attributes
in the Save As dialog box it can call ODMSetDocInfo using the
document
ID from ODMNewDoc. This should be done before calling
ODMSaveAs
or ODMSaveAsEx. Example attributes the DMS might accept and perhaps
show in its Save As dialog are ODM_NAME,
ODM_AUTHOR, ODM_KEYWORDS and others. After
ODMSaveAs is called, the
application might wish to call ODMGetDocInfo to see if the user changed
the value of any document attribute it is tracking.
|
|
|
|
|
|
|
|
|
|
|
|
ODMSTATUS ODMOpenDoc( ODMHANDLE handle, DWORD flags, LPSTR lpszDocId, LPSTR lpszDocLocation )
This function causes the DMS to make a document available to the application. It performs any necessary pre-processing (mapping network drives, checking security, etc.) and then returns to the application a temporary filename that can be used to access the document during the current session. Note that this function does not open the document file; it merely makes the file temporarily available to the calling application. The application can then open, read, write and close the file as needed.
If ODM_MODIFYMODE is requested, the DMS may refuse the request if
the user has view-only rights (ODM_E_ACCESS) or if the document is
currently checked-out (ODM_E_INUSE) to another user. It is
recommended that the application retry the request specifying ODM_VIEWMODE in
both cases so that the user can at least view the document and possibly save
changes to a new document.
Applications are encouraged to give the user the same level of feedback if a DMS based document is opened for read-only access as they would for a document based in the platform’s native file system.
When the application is finished using a file which was opened with either ODM_MODIFYMODE or
ODM_VIEWMODE it must call ODMCloseDoc
or ODMCloseDocEx. When an application is finished using a file that
was obtained with the ODM_REFCOPY option it does not have to call
ODMCloseDoc or
ODMCloseDocEx, however, it must delete the
temporary file.
If an application has opened a document in ODM_VIEWMODE and wishes
to switch to ODM_MODIFYMODE, it must first call ODMCloseDoc or
ODMCloseDocEx then call
ODMOpenDoc requesting ODM_MODIFYMODE. The same is true if the application wishes to switch
from ODM_MODIFYMODE to ODM_VIEWMODE. The
ODM_E_ALREADYOPENED error status is returned by the DMS if the
application attempts to re-open a document that it has already opened in
either of these two modes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If the application attempts to open a document for ODM_VIEWMODE that
it already has opened for ODM_VIEWMODE, then the DMS may either return
the ODM_E_ALREADYOPNED error status or
ODM_SUCCESS along with
the previously returned temporary file specification. The DMS should not
return ODM_S