IBM FileNet P8, Version 5.2.1            

Working with DITA Publishing

The following tasks and code examples demonstrate DITA publishing-related operations.

Setting Up a DITA Project

Use the following steps to set up DITA Publishing and verify that it is working correctly. You need a DITA project (DITA topics and maps) to complete this task. For testing purposes, you can find a simple DITA project in the DITA Open Toolkit's samples directory.

  1. Retrieve the DITA Open Toolkit from http://sourceforge.net/projects/dita-ot/ and expand the package (.zip or .tar.gz) to an installation directory on either the Content Engine server or a server that is mapped/mounted on the Content Engine server. For example, you might expand the package to c:\DITA-OT1.4.2.1 (Windows) or /DITA-OT1.4.2.1 (non-Windows).
  2. Install the DITA Publishing Extensions with Administration Console for Content Platform Engine. For more information, see Installing an add-on feature to an object store.
    • Add or remove properties from a DITA document class.
    • Add a new component relationship subclass.
    • Add support for a DITA specialization.
    • Modify component relationship object properties (for example, enable cascade delete).
    • Modify the default string property length. (The default length is 64.)

    The DITA Classifier Java™ source code (DITAClassifier.java) is provided through the IBM® support portal. The source code distribution includes instructions for modifying and installing a customized DITA Classifier. You can download the source code from the IBM FileNet® P8 Platform publication library.

  3. Optional: Modify the DITA Open Toolkit to support a DITA specialization or a custom rendering plug-in. See the DITA Open Toolkit documentation for instructions.
  4. Optional: Create a p8dita.env file to specify the DITA Open Toolkit environment. For more information, see Creating a p8dita.env File.
  5. Create a DITARenditionEngineConnection object. To complete this task, you can use either the Administration Console for Content Platform Engine or the Content Engine API (see Creating a DITARenditionEngineConnection Object).
  6. Create a publish style template. To complete this task, you can use either the Publishing Style Template Manager (see Add or modify DITA Rendition Engine style templates) or the Content Engine API (see Creating a Publish Style Template for DITA).
  7. Create a publish template. To complete this task, you can use either IBM FileNet P8 Workplace or the Content Engine API (see Creating a Publish Template for DITA).
  8. Check in your DITA project. You can check in the files manually (by using Administration Console for Content Platform Engine), or you can write a program to import an entire DITA project. A sample DITA importer is provided through the IBM support portal. You can download the sample from the IBM FileNet P8 Platform publication library.
  9. Publish the DITA project by using the copy-only option. To complete this task, you can useeither IBM FileNet P8 Workplace (see Publish your first document) or the Content Engine API (see Publishing a DITA Project). After the publish operation is complete, verify that all of the imported DITA project files were copied to the working directory. Also, check for missing references by searching the project files in the working directory for zero-length files.
  10. Publish the project again, but this time set the "copy-only" option to false and choose PDF as the transformation type. Verify that the PDF is generated and checked in as expected. If the publish operation fails, check the log file that is in the publish folder of your DITA working directory (for example, c:\ditatemp\ditapr-23445\my_project_pdf.log or /tmp/ditatemp/ditapr-23445/my_project_pdf.log).

Creating a p8dita.env File

To statically define the DITA Open Toolkit invocation environment:

  1. Create a file that is named p8dita.env.
  2. Edit the file to include the CLASSPATH, ANT_HOME, and PATH environment variables.
  3. Save the file to the top-level DITA Open Toolkit installation directory (for example, c:\DITA-OT1.4.2.1 or /tmp/DITA-OT1.4.2.1).

A Microsoft Windows example of the p8dita.env file is shown in the following example. Note that the lines CLASSPATH, ANT_HOME, and PATH must each be on a single, separate line. They are shown on multiple lines here for clarity.

p8dita.env Example

CLASSPATH=e:\DITA-OT1.4\lib\avalon-framework-cvs-20020806.jar;
    e:\DITA-OT1.4\lib\batik.jar;e:\DITA-OT1.4\lib\dost.jar;
    e:\DITA-OT1.4\lib\fop.jar;e:\DITA-OT1.4\lib\icu4j.jar;
    e:\DITA-OT1.4\lib\resolver.jar;e:\DITA-OT1.4\lib\xalan.jar;
    e:\DITA-OT1.4\lib\xercesImpl.jar;e:\DITA-OT1.4\lib\xml-apis.jar;
    e:\DITA-OT1.4C:\WINDOWS\system32;
ANT_HOME=e:\DITA-OT1.4\tools\ant
PATH=e:\DITA-OT1.4\tools\ant\bin;
E:\Program Files\IBM\WebSphere\AppServer\java\bin;%PATH%

A non-Windows example of the p8dita.env file is shown in the following example.

p8dita.env Example

CLASSPATH=/DITA-OT1.4/lib/avalon-framework-cvs-20020806.jar;
    /DITA-OT1.4/lib/batik.jar;/DITA-OT1.4/lib/dost.jar;
    /DITA-OT1.4/lib/fop.jar;/DITA-OT1.4/lib/icu4j.jar;
    /DITA-OT1.4/lib/resolver.jar;/DITA-OT1.4/lib/xalan.jar;
    /DITA-OT1.4/lib/xercesImpl.jar;/DITA-OT1.4/lib/xml-apis.jar;
    /DITA-OT1.4;
ANT_HOME=/DITA-OT1.4/tools/ant
PATH=/DITA-OT1.4/tools/ant/bin;
/opt/IBM/WebSphere/AppServer/java/bin;%PATH%

Navigating DITA Relationships

The following code example traverses and displays the compound document structure of a DITA document. The output format is as follows:

    /[Component relationship class] => [Document class]: [Document title] [Document id]

For example:

   /DitaTopicref => DitaConcept: Lawnmower {78C7186D-5DB6-462A-8F91-B461A7C01870}

Where the child document's title is "Lawnmower", the class that represents the component relationship between the child and parent documents is DitaTopicref, and the child document's class is DitaConcept.

The code also detects circular relationships. If one of the parent components that are shown for a document is itself, "[circular reference]" is displayed next to the child document.

For information on compound documents, see Compound Documents. For information on DITA-specific relationships, see DITA Relationships.

Java Example

private static void navigateDitaStructure(
        Document rootParent)
{
    String[] titlePropName = { "DitaTitle", "DocumentTitle" };
    traverseCompoundDocument(rootParent, null, 0, null, titlePropName);
}

// Traverse compound document structure.
private static void traverseCompoundDocument(
        Document parent, 
        ComponentRelationship crParent, // Component relationship to parent (null on first call)
        int level,                      // Indentation level (zero on first call)
        HashMap circRefMap,             // Circular reference checking (null on first call)
        String[] titlePropName)        // Document title property name(s)
{
    
    // Initialize message.
    String message = "";
    
    // Indent based on document level.
    for (int count = 0; count < level; count++)
    {
        message += "    ";
    }
    message += "/";
    
    // Show type of component relationship.
    if (crParent != null)
    {
        message += crParent.getClassName() + " => ";
    }
    
    // Show document title.
    String title = getDocTitle(parent, titlePropName);
    if (title == null)
    {
        title = "???";
    }
    message += parent.getClassName() + ": " + title + " " + parent.get_Id();

    // Create map for circular reference checking. 
    if (circRefMap == null)
    {
        circRefMap = new HashMap();
    }

    // Check for circular reference.
    boolean circRef = false;
    String parentKey = parent.get_Id().toString();
    if (circRefMap.containsKey(parentKey) == true)
    {
        circRef = true;
        message += " [circular reference]";
    }
    circRefMap.put(parentKey, parent);
    
    // Output message.
    System.out.println(message);
    if (circRef == true)
    {
        return;
    }
        
    // Iterate through child documents.
    ComponentRelationshipSet crSet = parent.get_ChildRelationships();
    Iterator iter = crSet.iterator();
    while(iter.hasNext())
    {
        // Make recursive call.
        ComponentRelationship crChild = (ComponentRelationship) iter.next();
        Document child = crChild.get_ChildComponent();
        if (child != null)
        {
            traverseCompoundDocument(child, crChild, level + 1, circRefMap, titlePropName);
        }
    }   
            
    // Remove document from circular reference map.
    circRefMap.remove(parentKey);
    
}

// Get document title.
private static String getDocTitle(
        Document doc,
        String[] propName)
{

    String title = null;
    doc.refresh();
    for (int ele = 0; ele < propName.length; ele++)
    {
        if (doc.getProperties().isPropertyPresent(propName[ele]) == true)
        {
            title = doc.getProperties().get(propName[ele]).getStringValue();
            if (title != null)
            {
                break;
            }
        }
    }
    return title;    
}

C# Example

private static void NavigateDitaStructure(
        IDocument rootParent)
{
    TraverseCompoundDocument(rootParent, null, 0, null,
                        "DitaTitle", "DocumentTitle");
}

// Traverse compound document structure.
private static void TraverseCompoundDocument(
        IDocument parent, 
        IComponentRelationship crParent,    // Component relationship to parent (null on first call)
        int level,                          // Indentation level (zero on first call)
        Hashtable circRefMap,               // Circular reference checking (null on first call)
        params String[] titlePropName)      // Document title property name(s)
{

    // Initialize message.
    String message = "";

    // Indent based on document level.
    for (int count = 0; count < level; count++)
    {
        message += "    ";
    }
    message += "/";

    // Show type of component relationship
    if (crParent != null)
    {
        message += crParent.GetClassName() + " => ";
    }

    // Show document title.
    String title = GetDocTitle(parent, titlePropName);
    if (title == null)
    {
        title = "???";
    }
    message += parent.GetClassName() + ": " + title + " " + parent.Id;

    // Create map for circular reference checking. 
    if (circRefMap == null)
    {
        circRefMap = new Hashtable();
    }

    // Check for circular reference.
    Boolean circRef = false;
    String parentKey = parent.Id.ToString();
    if (circRefMap.ContainsKey(parentKey) == true)
    {
        circRef = true;
        message += " [circular reference]";
    }
    if (circRefMap.ContainsKey(parentKey) == false)
    {
        circRefMap.Add(parentKey, parent);
    }

    // Output message.
    Debug.WriteLine(message);
    if (circRef == true)
    {
        return;
    }
    
    // Iterate through child documents.
    IComponentRelationshipSet crSet = parent.ChildRelationships;
    foreach (IComponentRelationship crChild in crSet)
    {
        // Make recursive call.
        IDocument child = crChild.ChildComponent;
        if (child != null)
        {
            TraverseCompoundDocument(child, crChild, level + 1, circRefMap, titlePropName);
        }
    }   
        
    // Remove document from circular reference map.
    circRefMap.Remove(parentKey);

}

// Get document title.
private static String GetDocTitle(
        IDocument doc,
        params String[] propName)
{
    String title = null;
    doc.Refresh();
    foreach (String titlePropName in propName)
    {
        if (doc.Properties.IsPropertyPresent(titlePropName) == true)
        {
            title = (String) doc.Properties[titlePropName];
            if (title != null)
            {
                break;
            }
        }
    }
    return title;    
}
        

Searching for DITA Metadata

The following code example illustrates how to perform a simple query for DITA documents based on property values. The class that is queried against, DitaBase, is the parent class for all of the DITA document subclasses that represent the standard DITA information types (concept, glossentry, reference, task, and topic).

For background information on performing queries, see Queriess. For more information about querying DITA documents, see DITA Query.

Java Example

public static void queryDitaAuthor(
        ObjectStore objStore,
        String userName)
{
    // Construct SQL object.
    SearchSQL sqlObject = new SearchSQL();
    sqlObject.setSelectList("db.DitaTitle, db.Id");
    sqlObject.setFromClauseInitialValue("DitaBase", "db", true);
    sqlObject.setWhereClause("IsCurrentVersion = true "
                             + "AND '" + userName + "' IN db.DitaAuthors");        
    System.out.println("SQL: " + sqlObject.toString()); 

    // Execute the query.
    SearchScope search = new SearchScope(objStore);
    RepositoryRowSet queryRows = search.fetchRows(
            sqlObject, new Integer(10), null, new Boolean(true));

    // Iterate through the returned rows.
    int rowCount = 0;
    Iterator iter = queryRows.iterator();
    while (iter.hasNext()) 
    {
        RepositoryRow row = (RepositoryRow) iter.next();
            
        String ditaTitle 
                = row.getProperties().get("DitaTitle").getStringValue();
        Id docId = row.getProperties().get("Id").getIdValue();
            
        rowCount++;
        System.out.print(" row " + rowCount + ":");
        System.out.print(" Id=" + docId.toString());
        if (ditaTitle != null) 
        {
            System.out.print(" DitaTitle=" + ditaTitle);
        }
        System.out.println();
    }            
    if (rowCount == 0)
    {
        System.out.println("No rows returned for query");
    }
    
}

C# Example

public static void queryDitaAuthor(
        IObjectStore objStore,
        String userName)
{
    // Construct SQL object.
    SearchSQL sqlObject = new SearchSQL();
    sqlObject.SetSelectList("db.DitaTitle, db.Id");
    sqlObject.SetFromClauseInitialValue("DitaBase", "db", true);
    sqlObject.SetWhereClause("IsCurrentVersion = true "
                         + "AND '" + userName + "' IN db.DitaAuthors");        
    Debug.WriteLine("SQL: " + sqlObject.ToString()); 

    // Execute the query.
    SearchScope search = new SearchScope(objStore);
    IRepositoryRowSet queryRows = search.FetchRows(
            sqlObject, 10, null, true);

    // Iterate through the returned rows.
    int rowCount = 0;
    foreach (IRepositoryRow row in queryRows)
    {
        String ditaTitle 
                = row.Properties
                  .GetProperty("DitaTitle").GetStringValue();
        Id docId = row.Properties.GetProperty("Id").GetIdValue();
            
        rowCount++;
        Debug.Write(" row " + rowCount + ":");
        Debug.Write(" Id=" + docId.ToString());
        if (ditaTitle != null) 
        {
            Debug.Write(" DitaTitle=" + ditaTitle);
        }
        Debug.WriteLine("");
    }            
    if (rowCount == 0)
    {
        Debug.WriteLine("No rows returned for query");
    }

}

The following code example illustrates how to find all of the parent documents for a particular child document. This query is useful, for instance, when you are attempting to determine all of the topics that reference a particular DITA topic.

Java Example

public static void queryDitaComponent(
        ObjectStore objStore,
        String childVerSeriesId,    // Child document version series id.
        String tableName,           // Example: "DitaTopicref" or "DitaConref".
        String propName,            // Example: "DitaId" or "DitaElementId".
        String propValue)           // Property value.
{
    // Show parameters.
    System.out.println("Parameter childVerSeriesId: " + childVerSeriesId);
    System.out.println("Parameter tableName: " + tableName);
    System.out.println("Parameter propName: " + propName);
    System.out.println("Parameter propValue: " + propValue);
    System.out.println("");
    
    // Construct SQL object
    // Note: "ChildComponent" could be used in the SQL below instead of
    // "ChildVersionSeries" to query for a specific child document. The
    // query below catches all component relationships that bind to any 
    // document within the child version series.
    SearchSQL sqlObject = new SearchSQL();
    sqlObject.setSelectList("d.id, d.DitaTitle"); 
    sqlObject.setFromClauseInitialValue("Document", "d", true);
    sqlObject.setFromClauseAdditionalJoin(JoinOperator.INNER, tableName, "cr", "d.This", JoinComparison.EQUAL, "cr.ParentComponent", false);
    sqlObject.setWhereClause("cr.ChildVersionSeries = OBJECT(" + childVerSeriesId + ") "
                             + "AND cr." + propName + " = '" + propValue + "'");
    System.out.println("SQL: " + sqlObject.toString()); 
    
    // Execute the query.
    SearchScope search = new SearchScope(objStore);
    RepositoryRowSet queryRows = search.fetchRows(
            sqlObject, new Integer(10), null, new Boolean(true));

    // Iterate through the returned rows.
    int rowCount = 0;
    Iterator iter = queryRows.iterator();
    while (iter.hasNext()) 
    {
        RepositoryRow row = (RepositoryRow) iter.next();
            
        String ditaTitle 
                = row.getProperties().get("DitaTitle").getStringValue();
        Id docId = row.getProperties().get("Id").getIdValue();
            
        rowCount++;
        System.out.print(" row " + rowCount + ":");
        System.out.print(" Id=" + docId.toString());
        if (ditaTitle != null) 
        {
            System.out.print(" DitaTitle=" + ditaTitle);
        }
        System.out.println();
    }            
    if (rowCount == 0)
    {
        System.out.println("No rows returned for query");
    }
    
}

C# Example

public static void QueryDitaComponent(
        IObjectStore objStore,
        String childVerSeriesId,    // Child document version series id.
        String tableName,           // Example: "DitaTopicref" or "DitaConref".
        String propName,            // Example: "DitaId" or "DitaElementId".
        String propValue)           // Property value.
{   
    // Show parameters.
    Debug.WriteLine("Parameter childVerSeriesId: " + childVerSeriesId);
    Debug.WriteLine("Parameter tableName: " + tableName);
    Debug.WriteLine("Parameter propName: " + propName);
    Debug.WriteLine("Parameter propValue: " + propValue);
    Debug.WriteLine("");

    // Construct SQL object.
    // Note: "ChildComponent" could be used in the SQL below instead of
    // "ChildVersionSeries" to query for a specific child document. The
    // query below catches all component relationships that bind to any 
    // document within the child version series.
    SearchSQL sqlObject = new SearchSQL();
    sqlObject.SetSelectList("d.id, d.DitaTitle"); 
    sqlObject.SetFromClauseInitialValue("Document", "d", true);
    sqlObject.SetFromClauseAdditionalJoin(JoinOperator.INNER, tableName, "cr", "d.This", JoinComparison.EQUAL, "cr.ParentComponent", false);
    sqlObject.SetWhereClause("cr.ChildVersionSeries = OBJECT(" + childVerSeriesId + ") "
                         + "AND cr." + propName + " = '" + propValue + "'");
    Debug.WriteLine("SQL: " + sqlObject.ToString()); 

    // Execute the query.
    SearchScope search = new SearchScope(objStore);
    IRepositoryRowSet queryRows = search.FetchRows(
            sqlObject, 10, null, true);

    // Iterate through the returned rows.
    int rowCount = 0;
    foreach (IRepositoryRow row in queryRows)
    {
        String ditaTitle
                = row.Properties["DitaTitle"].ToString();
        String docId = row.Properties["Id"].ToString();
        
        rowCount++;
        Debug.Write(" row " + rowCount + ":");
        Debug.Write(" Id=" + docId);
        if (ditaTitle != null) 
        {
            Debug.Write(" DitaTitle=" + ditaTitle);
        }
        Debug.WriteLine("");
    }            
    if (rowCount == 0)
    {
        Debug.WriteLine("No rows returned for query");
    }

}

Creating a DITARenditionEngineConnection Object

One of the objects that are needed to publish a DITA document is a connection to a DITA Rendition Engine. To establish such a connection, follow this sequence of steps (as illustrated in the following code example):

  1. Retrieve or add a publishing configuration.
  2. Create an engine connection object, and set the connection properties.
  3. Save the configuration with the newly created engine connection.

For more information about the DITARenditionEngineConnection object, see DITA Publishing.

Java Example

public static PublishingConfiguration createDitaConnection(
        Domain domain,
        String ditaHome,        // Example: C:/DITA-OT1.4.2.1 or /tmp/DITA-OT1.4.2.1
        String ditaWorkingDir)  // Example: C:/Temp or /tmp
{
    // Get default site.
    Site site = domain.get_DefaultSite();

    // Get publishing configuration for site.
    SubsystemConfigurationList scl 
            = site.get_SubsystemConfigurations();
    PublishingConfiguration pubConfig = getPublishingConfiguration(scl);
    if (pubConfig == null)
    {
        // Add new configuration since one does not already exist. 
        pubConfig = addPublishingConfiguration(scl);
    }
            
    // Create new engine connection instance.
    DITARenditionEngineConnection newEngineConn 
        = Factory.DITARenditionEngineConnection.createInstance(
          domain, null);
    
    // Set engine connection display name
    SimpleDateFormat timeStamp = new SimpleDateFormat("yyyyMMdd-HHmmss-SSS");
    String displayName = "DREC-" + timeStamp.format(new Date());
    newEngineConn.set_DisplayName(displayName);
    
    // Set engine connection properties.
    newEngineConn.set_DITADatabaseTimeout(new Integer(3600));
    newEngineConn.set_DITAHome(ditaHome);
    newEngineConn.set_DITAWorkingDirectory(ditaWorkingDir);
    newEngineConn.set_Site(site);
    
    // Save and associate engine connection with publishing configuration.
    newEngineConn.save(RefreshMode.REFRESH);
    pubConfig.set_DITARenditionEngineConnection(newEngineConn);
    System.out.println("DITA engine connection created: " 
                       + newEngineConn.get_Id());   
            
    // Save publishing configuration changes.
    site.save(RefreshMode.REFRESH);
    System.out.println("DITA engine connection associated with site: " 
                       + site.get_Id());

    // Re-retrieve publishing configuration to get identifier.
    scl = site.get_SubsystemConfigurations();
    pubConfig = getPublishingConfiguration(scl);
    System.out.println(
            "DITA engine connection associated with publishing configuration: "
            + pubConfig.get_Id());      

    // Return publishing configuration.
    return pubConfig;

}

// Add new publishing configuration.
private static PublishingConfiguration addPublishingConfiguration(
        SubsystemConfigurationList scl)
{
    // Create new publishing configuration.
    PublishingConfiguration pubConfig 
            = Factory.PublishingConfiguration.createInstance();
    pubConfig.set_DispatcherEnabled(Boolean.TRUE);
    pubConfig.set_DispatcherWaitInterval(new Integer(300));
    pubConfig.set_QueueItemDatabaseTimeout(new Integer(600));
    pubConfig.set_QueueItemMaxDispatchers(new Integer(2));
    pubConfig.set_QueueItemRetryCount(new Integer(3));
    
    // Add publishing configuration.
    scl.add(pubConfig);
    return pubConfig;
}

// Get existing publishing configuration (if any).
private static PublishingConfiguration getPublishingConfiguration(
        SubsystemConfigurationList scl)
{
    // Cycle through subsystem configurations.
    Iterator iter = scl.iterator();
    while (iter.hasNext() == true)
    {
        // Get next configuration.
        SubsystemConfiguration subConfig 
                = (SubsystemConfiguration) iter.next();
        
        // Check if publishing configuration.
        if (subConfig instanceof PublishingConfiguration)
        {
            return (PublishingConfiguration) subConfig;
        }
    }
    return null;
    
}

C# Example

public static IPublishingConfiguration CreateDitaConnection(
        IDomain domain,
        String ditaHome,        // Example: C:/DITA-OT1.4.2.1 or /tmp/DITA-OT1.4.2.1
        String ditaWorkingDir)  // Example: C:/Temp or /tmp
{
    // Get default site.
    ISite site = domain.DefaultSite;

    // Get publishing configuration for site
    ISubsystemConfigurationList scl 
            = site.SubsystemConfigurations;
    IPublishingConfiguration pubConfig = GetPublishingConfiguration(scl);
    if (pubConfig == null)
    {
        // Add new configuration since one does not already exist. 
        pubConfig = AddPublishingConfiguration(scl);
    }

    // Create new engine connection instance.
    IDITARenditionEngineConnection newEngineConn 
            = Factory.DITARenditionEngineConnection.CreateInstance(
                domain, null);

    // Set engine connection display name
    String displayName = "DREC-" + DateTime.Now.ToString("yyyyMMdd-HHmmss-fff");
    newEngineConn.DisplayName = displayName;

    // Set engine connection properties.
    newEngineConn.DITADatabaseTimeout = 3600;
    newEngineConn.DITAHome = ditaHome;
    newEngineConn.DITAWorkingDirectory = ditaWorkingDir;
    newEngineConn.Site = site;

    // Save and associate engine connection with publishing configuration.
    newEngineConn.Save(RefreshMode.REFRESH);
    pubConfig.DITARenditionEngineConnection = newEngineConn;
    Debug.WriteLine("DITA engine connection created: " 
                   + newEngineConn.Id); 
        
    // Save publishing configuration changes.
    site.Save(RefreshMode.REFRESH);
    Debug.WriteLine("DITA engine connection associated with site: " 
                   + site.Id);

    // Re-retrieve publishing configuration to get identifier.
    scl = site.SubsystemConfigurations;
    pubConfig = GetPublishingConfiguration(scl);
    Debug.WriteLine(
            "DITA engine connection associated with publishing configuration: "
            + pubConfig.Id);        
        
    // Return publishing configuration.
    return pubConfig;

}

// Add new publishing configuration.
private static IPublishingConfiguration AddPublishingConfiguration(
        ISubsystemConfigurationList scl)
{
    // Create new publishing configuration.
    IPublishingConfiguration pubConfig
            = Factory.PublishingConfiguration.CreateInstance();
    pubConfig.DispatcherEnabled = true;
    pubConfig.DispatcherWaitInterval = 300;
    pubConfig.QueueItemDatabaseTimeout = 600;
    pubConfig.QueueItemMaxDispatchers = 2;
    pubConfig.QueueItemRetryCount = 3;

    // Add publishing configuration.
    scl.Add(pubConfig);
    return pubConfig;
}

// Get existing publishing configuration (if any).
private static IPublishingConfiguration GetPublishingConfiguration(
        ISubsystemConfigurationList scl)
{
    // Cycle through subsystem configurations.
    foreach (ISubsystemConfiguration subConfig in scl)
    {           
        // Check if publishing configuration.
        if (subConfig is IPublishingConfiguration)
        {
            return (IPublishingConfiguration) subConfig;
        }
    }
    return null;

}

Creating a Publish Style Template for DITA

DITA publishing uses a publish style template (as provided by the IBM FileNet P8 publishing framework) to specify how the Rendition Engine translates a source document into a different format. A publish style template for DITA publishing uses the following unique transformation options:

Also, the PublishID property on the style template must be set to a publish event handler that is associated with DITA (for example, PublishRequestDITAPDFHandler).

For more information about the standard publish style template that is provided by the IBM FileNet P8 publishing framework, see Publishing and Working with Publish Objects.

Java Example

public static PublishStyleTemplate createDitaStyleTemplate(
        ObjectStore objStore)
{
    // Create instance.
    PublishStyleTemplate pubStyleTemplate 
        = Factory.PublishStyleTemplate.createInstance(objStore);
    
    // Set template title.
    SimpleDateFormat timeStamp = new SimpleDateFormat("yyyyMMdd-HHmmss-SSS");
    String title = "DITAPublishStyle-" + timeStamp.format(new Date());
    pubStyleTemplate.set_Title(title);

    // Set template formats.
    StringList formats = Factory.StringList.createList();
    formats.add("text/xml");
    pubStyleTemplate.set_InputFormats(formats);
    
    // Set template transformation options.
    final String TRANS_OPTIONS =
        "<dita-options>"+
            "<ditaval-version-series-id>{DE42374D-B04B-4F47-A62E-CAC9AC9A5719}</ditaval-version-series-id>" +
            "<ditaval-title>Dev. Guide Processing Profile<ditaval-title>"+
            "<trans-type>PDF</trans-type>"+
            "<copy-only>false</copy-only>"+
        "</dita-options>";
    pubStyleTemplate.set_TransformationOptions(TRANS_OPTIONS.getBytes("UTF-16LE"));

    // Set template output format as PDF.
    pubStyleTemplate.set_OutputFormat("application/pdf");
    
    // Set the event handler.
    pubStyleTemplate.set_ProviderID("PublishRequestDITAPDFHandler");
    
    // Save template.
    pubStyleTemplate.save(RefreshMode.REFRESH);
    System.out.println("Publish style template created: " 
                       + pubStyleTemplate.get_Id());
    return pubStyleTemplate;
    
}

C# Example

public static IPublishStyleTemplate CreateDitaStyleTemplate(
        IObjectStore objStore)
{
    // Create instance.
    IPublishStyleTemplate pubStyleTemplate 
            = Factory.PublishStyleTemplate.CreateInstance(objStore);

    // Set template title.
    String title = "DITAPublishStyle-" 
                 + DateTime.Now.ToString("yyyyMMdd-HHmmss-fff");
    pubStyleTemplate.Title = title;

    // Set template formats.
    IStringList formats = Factory.StringList.CreateList();
    formats.Add("text/xml");
    pubStyleTemplate.InputFormats = formats;

    // Set template transformation options.
    String TRANS_OPTIONS =
        "<dita-options>"+
            "<ditaval-version-series-id></ditaval-version-series-id>" +
            "<trans-type>pdf</trans-type>"+
            "<copy-only>false</copy-only>"+
        "</dita-options>";
    System.Text.ASCIIEncoding encoding 
            = new System.Text.ASCIIEncoding();
    pubStyleTemplate.TransformationOptions 
            = encoding.GetBytes(TRANS_OPTIONS);

    // Set template output format as PDF.
    pubStyleTemplate.OutputFormat = "application/pdf";

    // Set the event handler.
    pubStyleTemplate.ProviderID = "PublishRequestDITAPDFHandler";

    // Save template.
    pubStyleTemplate.Save(RefreshMode.REFRESH);
    Debug.WriteLine("Publish style template created: " 
                    + pubStyleTemplate.Id);
    return pubStyleTemplate;

}

Creating a Publish Template for DITA

DITA publishing uses a publish template (as provided by the IBM FileNet P8 publishing framework) to specify options for a publishing request. A publish template for DITA publishing must specify a publish style template. If the publish template has no associated style template, document publication causes a copy of the source document (DITA map), without its referenced components, to be created in the object store output folder.

For more information about the standard publish template that is provided by the IBM FileNet P8 publishing framework, see Publishing and Working with Publish Objects.

Java Example

public static PublishTemplate createDitaTemplate(
        ObjectStore objStore,
        String ditaOutputFolder,    // Example: /Publication
        boolean copyOnly)           // Set to false for DITA Publishing.
{
    // Create instance
    PublishTemplate pubTemplate. 
            = Factory.PublishTemplate.createInstance(objStore);

    // Set template title.
    SimpleDateFormat timeStamp = new SimpleDateFormat("yyyyMMdd-HHmmss-SSS");       
    String title = "DITAPublish-" + timeStamp.format(new Date());
    pubTemplate.getProperties().putValue("DocumentTitle", title);
    
    // Create content transfer element for template content.
    final String PUBLISH_TEMPLATE_CONTENT 
            = buildTemplateContent(ditaOutputFolder);
    ByteArrayInputStream inputStream 
            = new ByteArrayInputStream(PUBLISH_TEMPLATE_CONTENT.getBytes());
    ContentTransfer contentElement 
            = Factory.ContentTransfer.createInstance();
    contentElement.setCaptureSource(inputStream);
    contentElement.set_RetrievalName("DitaPublishTemplate.xml");
    contentElement.set_ContentType("application/x-filenet-publishtemplate");
    
    // Add content transfer element.
    ContentElementList cel = Factory.ContentElement.createList();
    cel.add(contentElement);
    pubTemplate.set_ContentElements(cel);
    
    // Set style template (calls create-style-template snippet).
    if (copyOnly == false)
    {
        PublishStyleTemplate pubStyleTemplate 
            = SnippetsAdvancedDocManagement.createStyleTemplate(objStore);
        pubTemplate.set_StyleTemplate(pubStyleTemplate);
    }

    // Check in and save.
    // Need to checkin because publishing only takes 
    // the current major version on the publish template.
    pubTemplate.checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, 
                        CheckinType.MAJOR_VERSION);
    pubTemplate.save(RefreshMode.REFRESH);
    System.out.println("Publish template created: " 
                       + pubTemplate.get_Id());
    return pubTemplate;     
   
}

// Build template content. 
private static String buildTemplateContent(
        String ditaOutputFolder)    // Example: /Publication            
{
    final String VALUE_ISSOURCEDEPENDENT = "true";

    // Publish template content.
    final String PUBLISH_TEMPLATE_CONTENT =
        "<?xml version=\"1.0\" ?>" +
        "<publishtemplatecontent>" +
        "<version>2.0.1</version>" +
        "<newinstructions>" +
            "<issourcedependent>" + VALUE_ISSOURCEDEPENDENT + "</issourcedependent>" +
            "<outputfoldername>" + ditaOutputFolder + "</outputfoldername>" +
            "<applyproperties>" +
                "<classdescriptionname>Document</classdescriptionname>" +
                "<properties>" +
                "<property>" +
                    "<name>DocumentTitle</name>" +
                    "<value>MyNewDITAPubTitle</value>" +
                "</property>" +
                "</properties>" +
            "</applyproperties>" +
            "<applysecurity>" +
                "<from>default</from>" + // apply security from class definition
            "</applysecurity>" +
        "</newinstructions>" +
        "<republishinstructions>" +
            "<versionablerepublishtype>versionandkeep</versionablerepublishtype>" +
            "<nonversionablerepublishtype>addandkeep</nonversionablerepublishtype>" +
            "<applypropertiesfrom>destination</applypropertiesfrom>" +
            "<applysecurityfrom>destination</applysecurityfrom>" +
        "</republishinstructions>" +
        "</publishtemplatecontent>";
    
    // Return string.
    return PUBLISH_TEMPLATE_CONTENT;
}

C# Example

public static IPublishTemplate CreateDitaTemplate(
        IObjectStore objStore,
        String ditaHome,            // Example: C:/DITA-OT1.4.2.1 or /tmp/DITA-OT1.4.2.1
        String ditaOutputFolder,    // Example: /Publication 
        Boolean copyOnly)           // Set to false for DITA Publishing
{
    // Create instance.
    IPublishTemplate pubTemplate 
            = Factory.PublishTemplate.CreateInstance(objStore);

    // Set template title.
    String title = "DITAPublish-" 
                 + DateTime.Now.ToString("yyyyMMdd-HHmmss-fff");
    pubTemplate.Properties["DocumentTitle"] = title;

    // Create content transfer element for template content.
    String PUBLISH_TEMPLATE_CONTENT 
            = buildTemplateContent(ditaOutputFolder);
    System.Text.ASCIIEncoding encoding 
            = new System.Text.ASCIIEncoding();
    System.IO.Stream inputStream 
            = new MemoryStream(encoding.GetBytes(PUBLISH_TEMPLATE_CONTENT));
    IContentTransfer contentElement 
            = Factory.ContentTransfer.CreateInstance();
    contentElement.SetCaptureSource(inputStream);
    contentElement.RetrievalName = "DitaPublishTemplate.xml";
    contentElement.ContentType = "application/x-filenet-publishtemplate";

    // Add content transfer element.
    IContentElementList cel = Factory.ContentElement.CreateList();
    cel.Add(contentElement);
    pubTemplate.ContentElements = cel;

    // Set style template (calls create-style-template snippet).
    if (copyOnly == false)
    {
        IPublishStyleTemplate pubStyleTemplate
            = SnippetsAdvancedDocManagement.CreateStyleTemplate(
                    objStore);
        pubTemplate.StyleTemplate = pubStyleTemplate;
    }

    // Check in and save.
    // Need to checkin because publishing only takes 
    // the current major version on the publish template
    pubTemplate.Checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, 
                        CheckinType.MAJOR_VERSION);
    pubTemplate.Save(RefreshMode.REFRESH);
    Debug.WriteLine("Publish template created: " 
                    + pubTemplate.Id);
    return pubTemplate;     
}

// Build template content. 
private static String buildTemplateContent(
        String ditaOutputFolder)    // Example: /Publication            
{
    String VALUE_ISSOURCEDEPENDENT = "true";

    // publish template content
    String PUBLISH_TEMPLATE_CONTENT =
        "<?xml version=\"1.0\" ?>" +
        "<publishtemplatecontent>" +
            "<version>2.0.1</version>" +
            "<newinstructions>" +
                "<issourcedependent>" + VALUE_ISSOURCEDEPENDENT + "</issourcedependent>" +
                "<outputfoldername>" + ditaOutputFolder + "</outputfoldername>" +
                "<applyproperties>" +
                    "<classdescriptionname>Document</classdescriptionname>" +
                    "<properties>" +
                        "<property>" +
                            "<name>DocumentTitle</name>" +
                            "<value>MyNewDITAPubTitle</value>" +
                        "</property>" +
                    "</properties>" +
                "</applyproperties>" +
                "<applysecurity>" +
                    "<from>default</from>" + // apply security from class definition
                "</applysecurity>" +
            "</newinstructions>" +
            "<republishinstructions>" +
                "<versionablerepublishtype>versionandkeep</versionablerepublishtype>" +
                "<nonversionablerepublishtype>addandkeep</nonversionablerepublishtype>" +
                "<applypropertiesfrom>destination</applypropertiesfrom>" +
                "<applysecurityfrom>destination</applysecurityfrom>" +
            "</republishinstructions>" +
        "</publishtemplatecontent>";

    // Return string.
    return PUBLISH_TEMPLATE_CONTENT;
}

Publishing a DITA Project

The following code example publishes a DITA document by calling the methods that are shown in the previous examples to create a DITA Rendition Engine connection and a DITA publish template. (The publish template method also creates a publish style template when the value of the copy-only parameter is false.) The example sets the title of the published document by using the publish <publicationname> option. Other publish options allow you to override options set in the publish template. For more information, see Publish XML Options.

Note:

Java Example

public static void publishDitaDocument(
        ObjectStore objStore,
        Document sourceDitaDoc, 
        String ditaHome,            // Example: C:/DITA-OT1.4.2.1 or /tmp/DITA-OT1.4.2.1
        String ditaWorkingDir,      // Example: C:/Temp or /tmp
        String ditaOutputFolder,    // Example: /Publication 
        boolean copyOnly)           // Set to true if publishing = copying.
        throws Exception
{
    // Show parameters.
    System.out.println("Parameter copyOnly: " + copyOnly);
    System.out.println("");
    
    // Make sure the publishing configuration has a DITA engine connection
    // (calls create-DITA-Connection snippet).
    SnippetsAdvancedDocManagement.createDitaConnection(
            objStore.get_Domain(), ditaHome, ditaWorkingDir);
    
    // Get publish template (calls create-template snippet).
    PublishTemplate pubTemplate 
        = SnippetsAdvancedDocManagement.createTemplate(
                objStore, ditaHome, ditaOutputFolder, copyOnly);
    
    // Build publish options.
    SimpleDateFormat timeStamp = new SimpleDateFormat("yyyyMMdd-HHmmss-SSS");
    String title = "DITAdocument-" + timeStamp.format(new Date());
    String pubOptions = new String(
            "<publishoptions><publicationname>"
            + title 
            + "</publicationname></publishoptions>");

    // Publish document.
    PublishRequest pubRequest 
            = sourceDitaDoc.publish(pubTemplate, pubOptions);
    pubRequest.save(RefreshMode.REFRESH);
    System.out.println("Submitted request to publish document with title '" 
                        + title + "'");
    
}

C# Example

public static void PublishDitaDocument(
        IObjectStore objStore,
        IDocument sourceDitaDoc,    
        String ditaHome,            // Example: C:/DITA-OT1.4.2.1 or /tmp/DITA-OT1.4.2.1
        String ditaWorkingDir,      // Example: C:/Temp or /tmp
        String ditaOutputFolder,    // Example: /Publication 
        Boolean copyOnly)           // Set to true if publishing = copying
{
    // Show parameters.
    Debug.WriteLine("Parameter copyOnly: " + copyOnly);
    Debug.WriteLine("");
    
    // Make sure the publishing configuration has a DITA engine connection
    // (calls create-DITA-Connection snippet).
    SnippetsAdvancedDocManagement.CreateDitaConnection(
            objStore.Domain, ditaHome, ditaWorkingDir);

    // Get publish template (calls create-template snippet).
    IPublishTemplate pubTemplate 
            = SnippetsAdvancedDocManagement.CreateTemplate(
                    objStore, ditaHome, ditaOutputFolder, copyOnly);

    // Build publish options.
    String title = "DITADocument="
                 + DateTime.Now.ToString("yyyyMMdd-HHmmss-fff");
    String pubOptions = 
            "<publishoptions><publicationname>"
            + title
            + "</publicationname></publishoptions>";

    // Publish document.
    IPublishRequest pubRequest 
            = sourceDitaDoc.Publish(pubTemplate, pubOptions);
    pubRequest.Save(RefreshMode.REFRESH);
    Debug.WriteLine("Submitted request to publish " +
                    "document with title '" + title + "'");

}


Last updated: October 2015
dita_procedures.htm

© Copyright IBM Corporation 2015.