There are basically two three ways to access priint:comet functionality in a Server environment:

  1. Connect to InDesign® Server via the SOAP Interface provided by the CometServer application.
  2. Directly connect to InDesign® Server using the Scripting DOM extensions
    This interface is mainly intended for internal use!
  3. Use the Java library introduced with version 4.2. This approach is particularly recommended in Java environments, such as server solutions or other Java applications. More information can be found here

Connecting via the CometServer SOAP interface (1) is the recommended way and will also cover basic aspects of authentication, session handling, document management and load balancing.
Usage examples are included in this document, see below.
For a full API reference see CometWhiteboard class reference. A Java SOAP client based on the JAX-WS reference implementation is included in this documentation.

The Scripting interface (2) is especially useful for test scripts, to access the full priint:comet Plug-In functionality with the least effort for application environment. This interface is not recommended for application integration.
The InDesign® Server Scripting DOM is exposed in JavaScript, VBScript, AppleScript and (via a generated CORBA client) Java. The priint:comet extensions can also be addressed via a SOAP WebService interface.
For a full reference see InDesign® Server scripting.

The examples below refer to the CometServer SOAP interface and Java. Most of them can easily be adapted for the Scripting DOM interface and other programming platforms.

To use the CometServe SOAP interface (1), you need a CometServer 3.4 installation with InDesign® Server and priint:comet InDesign® Server Plug-Ins or or PubServer installation with CometServerLight Plugin and priint:comet InDesign® Server Plug-Ins.
Depending on the client platform you may also need a compiler or interpreter and additional libraries to support SOAP.

To use the Scripting DOM extension (2), you need print:comet InDesign® Server Plug-Ins and a client application (such as ExtendScript Toolkit to run JavaScript or the AppleScript Editor for AppleScript) to execute your scripts.

In both cases, you need a fully setup Comet Project, i.e. Templates, Placeholders, application data etc.

More examples can be found in priintwsclient.jar (compiled Java classes and source code) included in this documentation.
If you need development support, please contact support@priint.com.

To connect to CometServer via the CometWhiteboard SOAP interface, you need a SOAP client. The SOAP service is exposed via HTTP and described in a standard WSDL (Web Service description language) document and there are tools to generate SOAP clients (so called client stubs) available for almost any platform.*
Solutions have already been developed in Java, C#, .Net, C++ and PHP. A Java client is included in this documentation. If required, Werk II can provide support to integrate the Comet WebServices in other platforms, please contact support@priint.com.
As Java is the most common client platform, the examples below refer to Java.
 * If you'd prefer a REST service rather than SOAP: please consider SOAP over HTTP as a REST service using only a subset of REST capabilities, but providing a huge gain in comfort regarding object serialization and deserialization, error handling etc. etc. - at the cost of only a small overhead for XML / application protocol.

In three steps:

  1. create a new empty Java project (e.g. in Eclipse create a plain Java Project)
  2. add the priintwsclient.jar library to your build path
  3. do some magic to bypass server WSDL validation (because time consuming and not necessary in this context) and to set the endpoint property, see code below
package com.priint.example;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import javax.xml.namespace.QName;

import com.priint.comet.wsclient.whiteboard.CometWhiteboard;
import com.priint.comet.wsclient.whiteboard.CometWhiteboard_Service;

public class SoapExample {

  public static void main(String args[]) {
    // magic ...
    URL wsdlUrl = com.priint.comet.wsclient.whiteboard.CometWhiteboard_Service.class.getResource("/META-INF/CometWhiteboard.wsdl");
    // ... end of magic
    final CometWhiteboard_Service service = new CometWhiteboard_Service(wsdlUrl, new QName("http://whiteboard.service.comet.priint.com/", "CometWhiteboard"));
    CometWhiteboard port = service.getCometWhiteboardPort ();
    // set service endpoint property, sort of magic too:
    final Map<String, Object> context = ((javax.xml.ws.BindingProvider)port).getRequestContext();
    context.put (javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://my.server.tld:port/CometServerSOAP/CometWhiteboard");
  }
}     
That's it. You are connected to CometServer.

Of course, you have to replace the schema, host and port part in the endpoint URL by the actual address of your server (but keep the path part of the URL), but that's all that has to be changed to establish a real connection to your server.
The CometWhiteboard port object provides all methods described in the CometWhiteboard interface and will do all necessary work to send and receive data to and from your server.

Most methods of the CometWhiteboard interface (except for login) require a sessionID as first parameter.*
To get a sessionID (i.e. initialize a session) you must login first:

package com.priint.example;

// ... (see above)
import com.priint.comet.wsclient.whiteboard.SessionInfo;

public class SoapExample {

  public static void main(String args[]) {
    // ... (see above)
    try {
      SessionInfo session = port.connectionLogin("username", "password", "project-name");
      String sessionID = session.getSessionID();
      System.out.println(sessionID);
    } catch (CometException_Exception e) {
      e.printStackTrace();
    }
  }
}
      
 * Why do we use this old-style parameter based session handling? In the behalf of interoperability. It's simply the solution which will cause least problems with any framework, internet proxy, firewall or whatsoever. It's not the most elegant or sophisticated, but the most robust and compatible solution.

When you're done, you should logout. This will allow the server to perform cleanup tasks, e.g. delete intermediate session files etc.

package com.priint.example;

// ... (see above)

public class SoapExample {

  public static void main(String args[]) {
    // ... (see above)
    try {
      // ... (see above)
      port.connectionLogout(sessionID);
    } catch (CometException_Exception e) {
      e.printStackTrace();
    }
  }
}
You can reuse a session for further jobs. In this case, please remind, that the session will expire after 12 hours. So you should add something like this to your code:
package com.priint.example;

// ... (see above)
import javax.activation.DataHandler;
import com.priint.comet.wsclient.whiteboard.CometException;

public class SoapExample {

  public static void main(String args[]) {
    // ... (see above)
    try {
      // ... (see above)
      // just what your program was supposed to do:
      DataHandler pdf = port.createProductPDF(sessionID, masterdocName, recordID, templateID, pdfProfile, options);
    } catch (CometException_Exception e) {
      CometException cause = e.getFaultInfo();
      if (cause.getErrorCode() == com.priint.comet.wsclient.util.ErrorCodes.INVALID_SESSION) {
        // session invalid or expired. 
        // Login again to initialize a new session and repeat request
        // ... 
      }
      e.printStackTrace();
    }
  }
}

If all this works, you're ready for the next step and you can start working with real InDesign® documents.
Full working code for connecting, login and logout, including error handling for expired connections:

package com.priint.example;

import java.net.URL;
import java.util.Map;

import javax.xml.namespace.QName;

import com.priint.comet.wsclient.whiteboard.CometException;
import com.priint.comet.wsclient.whiteboard.CometException_Exception;
import com.priint.comet.wsclient.whiteboard.CometWhiteboard;
import com.priint.comet.wsclient.whiteboard.CometWhiteboard_Service;
import com.priint.comet.wsclient.whiteboard.SessionInfo;

public class SoapExample {

  public static void main(String args[]) {
    URL wsdlUrl = com.priint.comet.wsclient.whiteboard.CometWhiteboard_Service.class.getResource("/META-INF/CometWhiteboard.wsdl");
    final CometWhiteboard_Service service = new CometWhiteboard_Service(wsdlUrl, new QName("http://whiteboard.service.comet.priint.com/", "CometWhiteboard"));
    CometWhiteboard port = service.getCometWhiteboardPort ();
    final Map<String, Object> context = ((javax.xml.ws.BindingProvider)port).getRequestContext();
    context.put (javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://my.server.tld:port/CometServerSOAP/CometWhiteboard");
    try {
      // start session
      SessionInfo session = port.connectionLogin("username", "password", "project-name");
      String sessionID = session.getSessionID();
      
      // real work is done HERE
      // ...
      
      // finally end session
      port.connectionLogout(sessionID);
    } catch (CometException_Exception e) {
      CometException cause = e.getFaultInfo();
      if (cause.getErrorCode() == com.priint.comet.wsclient.util.ErrorCodes.INVALID_SESSION) {
        // session invalid or expired. 
        // Login again to initialize a new session and repeat request
        // ... 
      }
      e.printStackTrace();
    }
  }
}

Documents on the server can be referred in several ways. Generally you refer to a document by name or a unique document ID. This name or document ID is bound to a physical InDesign® document on the server file system.
In this documentation, we only cover three four very common use cases:

  1. a InDesign® master document uploaded with the publication planner
  2. an arbitrary file on the server file system
  3. a document created "from scratch"
  4. a document managed by the publication planner

When uploading a master document, you must provide a unique name. In certain methods, you can refer to this master document using this name. In the latest publication planner shipped with PubServer 4.0.5, you can also provide a masterdocument label when uploading a masterdocument and refer to the label in API methods.

Example:

// the name of my master document
String masterDocumentName = "myMasterDocument.indd";

// the ID for the temporary copy, null means: let server determine unique ID (generally recommended)
String tmpID = null;

// this creates a temporary copy, which will be deleted when session expires:
tmpID = port.copyMasterdocument(sessionID, masterDocumentName, tmpID);

// ... do some processing, see examples below ...

// finally download document
DataHandler document = port.documentDownload(sessionID, tmpID);
        

You do not want clients to access arbitrary files on the server file system, therefore files must be registered before and after that can be refered using a unique document ID.
Registering files can be restricted to certain paths and / or certain user accounts, for details see the Installation Guide or contact support@priint.com.

// the ID for this document, null means: let server determine unique ID (generally recommended)
String newDocumentID = null;

// depending on your configuration,  "/path/on/server/" probably must be registered as
// a repository root, otherwise this method call will fail:
newDocumentID = port.documentRegister(sessionID, newDocumentID, "/path/on/server/document.indd");

// ... do some processing, see examples below ...

You can also just use InDesign® Server to create a new document. Various setup options can be passed in the "option" parameter, for details see the Options reference:

// this will create a new document, ID is provided by server
String newDocumentID = port.documentCreate(sessionID, null, "height:500pt;width20pt;");
      
A more sophisticated example: we first register a not yet existing file using a certain document ID. When calling documentCreate, this location will be used to save the file:
// register a not-yet-existing file with a certain document ID
String documentID = port.documentRegister(sessionID, "myDocumentID", "/Volumes/InDesignDocuments/work/myDocument.indd");

// create a document using this document ID
port.documentCreate(sessionID, documentID, "");

// save ...
port.documentSave(sessionID, documentID);

// and close. 
// It's good practice to close documents when done with processing, though 
// documents will be closed automatically, when the session is finished or expires
port.documentClose(sessionID, documentID);
      

Documents in the publication planner are refered by their document ID.
This ID is available in many programming environments: in priint:comet publication scripts (implemented in cscript) as the global variable gDocument, in the InDesign® document as an attribute of the XML root element of the document namend documentId and, consequently, can also be used to refer documents managed in the publication planner in Java client application.

Once you know the ID of the document you want to process, it is very easy to access this document in a client application:

String documentID = "67110123";
port.documentOpen(sessionID, documentID);
// etc.

You probably got the idea.
Of course, more combinations of the methods shown above are possible and you will find more document related methods in the CometWhiteboard class reference. If in doubt, which methods best suit your business requirements, please contact support@priint.com.

You can place a single product and create a PDF in one go using the createProductPDF method:

// can be null also. In this case, a new document will be created
String masterDocumentName = "myMasterDocument.indd";

// RecordID consists of 4 parts: three numerical IDs and one "StringID"
// Values and meaning of these IDs depend on your environment
RecordID recordID = com.priint.comet.wsclient.util.Utils.createRecordID(new String[] {"1", "0", "0", "RecordStringID"});

// ID of the template (aka "pageitem")
int templateID = 12345;

// name of pdf profile. Leave empty for default profile 
String pdfProfile = "";

// various options, see options reference for details 
String options     = "";

// build and create PDF in one go
DataHandler pdf = port.createProductPDF(sessionID, masterDocumentName, recordID, templateID, pdfProfile, options);

// save result to local file
com.priint.comet.wsclient.util.Utils.saveBytes("/destination/path/out.pdf", com.priint.comet.wsclient.util.Utils.readAllBytes(pdf.getInputStream()));
      

To generate a PDF for a list of products, use the createPDF method.
Products are defined in a very simple XML format: the name of the root node must be <items>, each product is defined in a <item> element and must consist at least of the following information: You don't have to (and actually should not) define namespaces, xml version, encoding etc.
String xml = "<items>\n";

// each product is an "item" in the xml.
// 1st product:
xml += "<item>\n" +
      "<ID>1</ID>\n" +
      "<ID2>0</ID2>\n" +
      "<ID3>0</ID3>\n" + 
      "<stringID>RecordStringID</stringID>\n" +
      "<pageitemID>12345</pageitemID>\n" +
    "</item>";

// 2nd product:
xml += "<item>\n" +
      "<ID>2</ID>\n" +
      "<ID2>0</ID2>\n" +
      "<ID3>0</ID3>\n" + 
      "<stringID>RecordStringID2</stringID>\n" +
      "<pageitemID>12345</pageitemID>\n" +
    "</item>\n";

// etc.
xml += "</items>";

javax.xml.transform.Source itemsXML = com.priint.comet.wsclient.util.XML.createXMLSource(xml, "items.xml");

DataHandler pdf = port.createPDF(sessionID, masterDocumentName, itemsXML,
                                 com.priint.comet.wsclient.whiteboard.Renderer.INDESIGNSERVER, pdfProfile, options);
    
Using this method and the items XML, you can also define a page template or force page breaks by inserting page template definitions in the list:
String xml = "<items>\n";

// start with this page template: 
xml += "<item>\n" +
      "<type>pagetemplate</type>\n" + 
      "<ID>1685</ID>\n" +               // ID of the page template
      "<ID2>0</ID2>\n" +
      "<ID3>0</ID3>\n" + 
      "<stringID></stringID>\n" +       // empty
      "<pageitemID></pageitemID>\n" +   // empty
    "</item>";

// 1st product:
xml += "<item>\n" +
      "<ID>1</ID>\n" +
      "<ID2>0</ID2>\n" +
      "<ID3>0</ID3>\n" + 
      "<stringID>RecordStringID</stringID>\n" +
      "<pageitemID>12345</pageitemID>\n" +
    "</item>";

// force page break after first product: 
xml += "<item>\n" +
      "<type>pagetemplate</type>\n" + 
      "<ID>1685</ID>\n" +               // ID of the page template
      "<ID2>0</ID2>\n" +
      "<ID3>0</ID3>\n" + 
      "<stringID></stringID>\n" +       // empty
      "<pageitemID></pageitemID>\n" +   // empty
    "</item>";

// 2nd product:
xml += "<item>\n" +
      "<ID>2</ID>\n" +
      "<ID2>0</ID2>\n" +
      "<ID3>0</ID3>\n" + 
      "<stringID>RecordStringID2</stringID>\n" +
      "<pageitemID>12345</pageitemID>\n" +
    "</item>\n";

// etc.

xml += "</items>";
      

Just like creating PDFs, you can also create previews in various formats:

// resolution in dpi
double resolution = 300.0;

// creates a JPEG with default quality settings
DataHandler preview = port.createProductPreview(sessionID, masterDocumentName, recordID, templateID, resolution, options);
      
Image format can be set in the "options" string:
// settings suitable for web...
String options = "format:png;transparency:high;add-alpha:true;";

// resolution in dpi
double resolution = 72.0;

// creates a JPEG with default quality settings
DataHandler preview = port.createProductPreview(sessionID, masterDocumentName, recordID, templateID, resolution, options);

In case you want to keep the processed InDesign® file, you can generate pages using one of the build methods.
Example:

// use this document
String documentID   = "myTargetDocument";

// start building at spread 0
int spreadIndex   = 0;

// the method returns the number of pages generated
int numberOfSpreadsGenerated = port.spreadBuild(sessionID, documentID, spreadIndex, itemsXML, options);
Another example: create a temporary copy of a masterdocument, place some products, create preview and pdf and download the generated document:
// create a temporary copy of a master document
String tmpDocumentID   = port.copyMasterdocument(sessionID, masterDocumentName, null); 

// start building at spread 0
int spreadIndex   = 0;

// we prefer to use the EXISTING pages
options += "prefer-existing-pages:true;";
      
// place products
int numberOfSpreadsGenerated = port.spreadBuild(sessionID, tmpDocumentID, spreadIndex, itemsXML, options);

// generate a preview for each spread
int spreadCount = port.documentGetSpreadCount(sessionID, tmpDocumentID);
for (int i = 0; i < spreadCount; ++i) {
  DataHandler preview = port.spreadGetPreview(sessionID, tmpDocumentID, i, resolution, options);
  // you might want to save the preview, see examples above ...
}

// generate a PDF
DataHandler pdf = port.documentGeneratePDF(sessionID, tmpDocumentID, pdfProfile, options);

// save and download InDesign® document
port.documentSave(sessionID, tmpDocumentID);
DataHandler indd = port.documentDownload(sessionID, tmpDocumentID);
 

You may have noticed the options parameter, which allows to pass various options to almost all methods. These options are not absolutely required to execute a method, but can be extremely powerful.
Please refer to the Options Reference to find out, which options are available and useful for your requirements.

You can run arbitrary cscripts with InDesign® Server, typically this is a build scripts (such as Document Planning or Publication Tree scripts).
To run scripts use the method

        	documentExecCScript (String sessionID, String documentID, int scriptID, String arguments);
        
The method returns a string, which can be defined in the target cscript. This way it's possible to pass values from the cscript / Renderer environment to Java / SOAP.

Scripts executed via the Server interface provide some additional environment variables:

The following example shows how to get spread previews and PDFs from a document generated with a custom build script. Compared to the Generate InDesign® Document example from above, only very slight changes are required:
// create a temporary copy of a master document
String tmpDocumentID   = port.copyMasterdocument(sessionID, masterDocumentName, null); 

String arguments = "";

// the cscript ID
int scriptId = 67101234;

// execute cscript
String scriptResult = port.documentExecCScript(sessionID, tmpDocumentID, scriptId, arguments);

// generate a preview for each spread
int spreadCount = port.documentGetSpreadCount(sessionID, tmpDocumentID);
for (int i = 0; i < spreadCount; ++i) {
  DataHandler preview = port.spreadGetPreview(sessionID, tmpDocumentID, i, resolution, options);
  // you might want to save the preview, see examples above ...
}

// generate a PDF
DataHandler pdf = port.documentGeneratePDF(sessionID, tmpDocumentID, pdfProfile, options);

// save and download InDesign® document
port.documentSave(sessionID, tmpDocumentID);
DataHandler indd = port.documentDownload(sessionID, tmpDocumentID);
        
Of course - in this case - we expect, that script 67101234 defines suitable code to generate pages.

 

This documentation only covers very basic - though, I hope, the most important - aspects of using the CometWhiteboard interface. Please refer to the CometWhiteboard API Reference to find out, which methods best suit your business requirements.
If in doubt, please contact support@priint.com.