An Annotation Server is a server-side HTTP application responsible for the storage and retrieval of a document's annotations. When a client-side Viewer loads a document associated with an Annotation Server, it will query the Server for the annotations to display. If the user subsequently edits and saves the annotations, the Viewer will send the edited annotations back to the Annotation Server. By implementing an Annotation Server, web sites can provide a shared annotation mechanism, whereby the annotations of one user can be immediately reviewed by other users. This document describes the API of the Annotation Server.
The specification described in this document is fully supported by Version 6.0 and higher of Cartesian's CPC Lite, CPC View pi, and CPC View ax client-side Viewers. Web sites that conform to this specification should interoperate with these client-side Viewers without problems.
In the documentation below, advanced topics are
described in this smaller font size.
The complexity of the Annotation Server is entirely up to the implementor.
At its simplest, the Annotation Server need do no more than store and retrieve
the annotations from some persistent storage medium, such as a database or flat files.
If the Annotation Server is expected to support
concurrent editing of annotations, it would also need to provide some form of
update concurrency control. A more robust Annotation Server might also provide
features such as access control and selective annotation display (e.g., show me
only Mary Smith's annotations or show me only annotations created in the last three days).
To associate an Annotation Server with a document, set the document's annServer URL parameter to the URL of the Annotation Server. The Server URL can be either absolute or relative. If a relative URL is specified, it is resolved against the base URL of the document.
For example, the URL:
http://foo.com/doc.cpc?annServer=as.cgi/docId=123/userId=renespecifies that the document at http://foo.com/doc.cpc should be displayed using the Annotation Server at http://foo.com/as.cgi/docId=123/userId=rene.
When an Annotation Server is specified, any local annotations that the user had associated with the document will not be displayed.
The specified Annotation Server URL is not augmented in any way by the Viewer. In particular, the Viewer does not add any information regarding the document associated with the annotations. It is expected that the Annotation Server URL already contains any such information that is required by the Server.
For the purposes of authentication, the Annotation Server URL might also encode
the user's session ID or similar information.
If the document has no associated annotations, the Server should still
respond with a valid (but empty) annotation XML description. If the Server
fails to respond with a valid annotation XML description, an error will be presented to the user.
If the Server's response contains an <error> tag, the save operation was unsuccessful and the Viewer should notify the user of the error. If the error tag contains data, the data is an error message that should be displayed to the user by the Viewer. For example, the response:
means that the save operation failed and the Viewer should display the error message "A disk error occurred".<error> A disk error occurred </error>
Any other data returned by the Server is ignored by the Viewer.
<?xml version="1.0" ?> <annotations> list of annotation pages </annotations>
The only exception to this comes in the original creation of the document. The API requires the Server to always return a valid Annotation Document in response to a GET request. Hence, if there are no annotations for a particular document, the Server should return an empty Annotation Document. The following document will suffice:
<?xml version="1.0" ?> <annotations/>
<page num="1"> list of annotations </page>
The individual pages within the annotations block do not need to occur in page order.
The num attribute of the page tag should be used by the Viewer to determine
the appropriate image page that the annotation page applies to.
Tag Annotation Class <Overlay> Box <CircleOverlay> Oval <LineOverlay> Line <FreehandLineOverlay> FreehandLine <TextOverlay> Text
For example, the text to display in a text annotation is controlled by the drawText parameter. This can be specified in either of two ways:
or<TextOverlay drawText="Hello, world" />
For the purposes of this example, annotation parameters other than drawText have been omitted.<TextOverlay> <drawText>Hello, world</drawText> </TextOverlay>
<CircleOverlay paperRect="149,2564,805,520" paperTransparent="1" createName="rene" createTime="1020567051" drawColor="ff6464" edgeColor="000000" />
The following XML fragment describes a text annotation:
<TextOverlay paperRect="134,494,200,1305" paperColor="ffff64" paperBorder="Button" createName="rene" createTime="1022295707" drawColor="ff0000" fontSize="36" fontFace="Arial" paperAutoSize="1" > <drawText>Hello, world</drawText> </TextOverlay>
<?xml version="1.0" ?> <annotations> <page num="1"> <LineOverlay paperRect="179,2039,2380,100" createName="pmark" createTime="1020566515" drawColor="c00000" drawSize="4" lineType="diagnw" /> <TextOverlay paperRect="134,494,200,1305" paperColor="ffff64" paperBorder="Button" createName="rene" createTime="1022295707" drawColor="ff0000" fontSize="36" fontFace="Arial" paperAutoSize="1" drawText="Hello, world" /> </page> <page num="2"> <CircleOverlay paperRect="149,2564,805,520" paperTransparent="1" createName="rene" createTime="1020567051" drawColor="ff6464" edgeColor="000000" /> </page> </annotations>
This section has been generated directly from the PERL source code found in the file annServer.cgi.
$AnnRoot = "/tmp/Annotations";
Function: adFileName($id) | ||||
Return the filename of the Annotation Document with the Document ID sub adFileName { my (
qq{ |
Function: adLoad($id) | ||||||
Return the annotation data for Document ID sub adLoad { my (
if(!open(FILE, adFileName(
binmode(FILE); flock(FILE, 1); my
close(FILE); |
Function: adStore($id, $xml) | ||||||
Save sub adStore { my (
if(!open(FILE, ">".adFileName(
binmode(FILE); flock(FILE, 2); print FILE
close(FILE); 1;} |
Function: cgiParse() | ||||||||||
Parse the CGI parameters and store the name-value pairs into the sub cgiParse {
foreach(split(/&/,
s/\+/ /g;
my (
|
Function: cgiRespond($code, $mime, $text) |
Generate the HTTP response to a request. The response specifies
a status code of sub cgiRespond { my ( |
The Document ID is specified as the |
cgiParse();
If they did not specify an ID, return an error |
if(!$CGI {ID}) { cgiRespond(400, "text/plain", "<error>There was no document specified</error>");}
If this is not a POST, load the XML data |
elsif($ENV {REQUEST_METHOD} ne "POST") { cgiRespond(200, "text/xml", adLoad($CGI {ID}));}
This is a POST operation. Store the XML data |
else {
Get the data to store |
my$xml ; read(STDIN,$xml ,$ENV {'CONTENT_LENGTH'});
Store the new annotation data |
my$worked = adStore($CGI {ID},$xml ); if(!$worked ) { cgiRespond(503, qq{<error>Unable to update file</error>}); } else { cgiRespond(200, "text/plain", "Update succeeded"); }}
� 1998-2002 Cartesian Products, Inc. | Contact Cartesian |