Introduction

Document and Publication Job Plugins allow to implement custom functionality in the Publication Planner workflow engine and make them available in the download dialog for a publication or document selection.

Basically, two types of jobs are available: DocumentJobs and PublicationJobs. The following overview lists the main specifics of these job types:

DocumentJob PublicationJob
Can be integrated in Document workflows Can be integrated in Publication workflows and Download dialog
Operate on single documents Operate on a publication, on several publications or mixed selections (publications and documents).
Preparation of documents (close, create, recreate, open and closing after job execution) managed by the Rendering Server. Affected documents are locked by the Rendering Server during job execution, all other preparation must be implemented in the job or in the target script executed by the renderer. After job execution, documents are unlocked and closed.
It is not allowed to open / close documents in the job implementation or target renderer scripts It is explicitly allowed to open and close certain documents in the job implementation or target scripts
Implementation requires
  • a Job Plugin with a PubServerMethod with MethodType=WORKFLOW_JOB
  • a DocumentJob implementation and
  • (optionally) a cscript, which is executed by the renderer.
Implementation requires
  • a Job Plugin with a PubServerMethod with MethodType=PUBLICATION_WORKFLOW_JOB and / or MethodType=PUB_PLANNER_DOWNLOAD
  • a PublicationJob implementation and
  • (optionally) a cscript, which is executed by the renderer.

This Howto covers a simple implementation example for either type of job. Detailed information about relevant Java interfaces and cscript resources can be found in the PubServerSDK documentation resp. InDesign Plugin documentation.

Note:
When implementing workflow jobs for publications or documents or additional download functionality without rendering interaction, you only need to implement the "Plugin" part (no DocumentJob resp. PublicationJob implementation). Though, this documentation may help to clarify some questions.

Requirements

Implementing document and publication jobs as described in this documentation requires

Beside the PublishingServer SDK (PubServerSDK.jar), also some classes of the CometServer4 SDK (CometServer4SDK.jar) are referenced in the example solutions, therefore this library - though mainly for internal use - also has to be included in the build path of DocumentJob or PublicationJob Plugins.

Document Jobs Example

DocumentJobs are executed during workflow processing for a single document.

Implementation of a DocumentJob requires

The example shown below is also part of the DemoDocumentJob project available on the documentation site.

Plugin Implementation

We start with the PubServer Plugin for our new DocumentJob.

Basically, this is just a PubServer Plugin (i.e. PluginControl implementation), though some additional methods and the tagging interface RenderingPlugin must be implemented. For ease of implementation, we inherit from the AbstractDocumentJobPlugin class defined in CometServer4SDK.

In the workflow job context, the Plugin implementation serves as connector for the UI and job scheduling enginge.

package com.priint.pubserver.pubplanner.demo.document;
import java.util.Map;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import com.priint.pubserver.comet.renderer.DocumentJob;
import com.priint.pubserver.comet.renderer.legacy.AbstractDocumentJobPlugin;
import com.priint.pubserver.exception.PubServerException;
import com.priint.pubserver.plugin.PluginMethod;
import com.priint.pubserver.plugin.annotation.PubServerMethod;
import com.priint.pubserver.plugin.annotation.PubServerMethodParameter;
import com.priint.pubserver.plugin.annotation.PubServerPlugin;
import com.werkii.server.PubPlannerPlugins;

@Stateless(mappedName=SyncPlaceholderJobPlugin.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class SyncPlaceholderJobPlugin extends AbstractDocumentJobPlugin {
  
  public static final String MAPPED_NAME = 
    "com.priint.pubserver.pubplanner.demo.document.SyncPlaceholderJobPlugin";

  @Override
  public DocumentJob getDocumentJob(Map<String, Object> parameters) {
    return new SyncPlaceholderJob();
  }

  @PubServerMethod(
    label="name",
    type=PluginMethod.MethodType.GENERIC,  
    description="plugin method called to obtain a translation of plugin label")
  public String getMethodName(
      @PubServerMethodParameter(
        name="lang", 
        defaultValue=PubPlannerPlugins.EN, 
        listOfValues={}) final String lang) {
    return "Synchronize placeholders";
  }
    
  @PubServerMethod(
    label="Synchronize placeholders",
    type=PluginMethod.MethodType.WORKFLOW_JOB)
  public void exec(
        @PubServerMethodParameter(
          name="parameters") final Map<String,Object> parameters) throws PubServerException {
    // just call the super class exec method:
    super.exec(parameters);
  }
}

Remarks

Job Implementation

Job implementations represent the business logic for an actual server job. They must implement the com.priint.pubserver.comet.renderer.DocumentJob interface, or - as shown below - use default implementations and inherit from com.priint.pubserver.comet.renderer.DocumentJobImpl.

package com.priint.pubserver.pubplanner.demo.document;

import java.io.File;

import javax.activation.DataHandler;

import com.priint.pubserver.comet.bridge.entitydata.RecordId;
import com.priint.pubserver.comet.renderer.Comet;
import com.priint.pubserver.comet.renderer.DocumentJobImpl;
import com.priint.pubserver.comet.renderer.Options;
import com.priint.pubserver.comet.renderer.Renderer.DocumentTarget;
import com.priint.pubserver.comet.renderer.Renderer.Target;
import com.priint.pubserver.exception.PubServerException;

public class SyncPlaceholderJob extends DocumentJobImpl {

  @Override
  public DataHandler executeJob(String documentId, String documentPath,
      Comet renderer) throws PubServerException {
    DocumentTarget target = Target.document(documentId, new File(documentPath));
    
    int pages = renderer.documentGetPageCount(target, Options.NO_OPTIONS);
    int[] placeholderIds = new int[0]; 
        
    for (int index = 0; index < pages; ++index) {
      renderer.syncPlaceholders(
        target.page(index), 
        placeholderIds, 
        RecordId.getEmpty(), 
        Options.NO_OPTIONS);
    }
    return "";
  }
}

What will happen?
This job iterates all pages and synchronizes all placeholders (empty placeholder list means: all).
All the document handling is done by the RenderingServer, we don't have to (and actually must not) open, close, delete or create the document in our job implementation.

Remarks

Publication Jobs Example

Publication jobs can be executed during publication workflow processing or be used to extend the functionality of the Publication Planner Download dialog.

Implementation of a PublicationJob requires

The example shown below is also part of the DemoDocumentJob project available on the documentation site.

Plugin Implementation

Again, we start with the PubServer Plugin for our new PublicationJob.

As for DocumentJobs, the Plugin serves as a connector for UI integration and the job scheduling engine. Dependeing on the purpose, we just have to implement the PluginControl interface and in addition, if supposed to be available in the Download Dialog, the com.werkii.server.ejb.download.PubPlannerDownloadLocal interface.

For ease of implementation, we can also use the default implementation AbstractPublicationJobPlugin defined in CometServer4SDK.

Core Plugin

package com.priint.pubserver.pubplanner.demo.publication;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.xml.bind.JAXBException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.priint.pubserver.comet.config.CometConfigurationLocal;
import com.priint.pubserver.comet.entity.planner.CometBookScript;
import com.priint.pubserver.comet.renderer.Parameters;
import com.priint.pubserver.comet.renderer.PublicationJob;
import com.priint.pubserver.comet.renderer.legacy.AbstractPublicationJobPlugin;
import com.priint.pubserver.config.PluginConfigDataHandler;
import com.priint.pubserver.exception.PubServerException;
import com.priint.pubserver.plugin.PluginControlDefault;
import com.priint.pubserver.plugin.PluginMethod;
import com.priint.pubserver.plugin.PluginUtils;
import com.priint.pubserver.plugin.annotation.PubServerMethod;
import com.priint.pubserver.plugin.annotation.PubServerMethodParameter;
import com.priint.pubserver.plugin.annotation.PubServerPlugin;
import com.werkii.server.PubPlannerPlugins;
import com.werkii.server.ejb.download.PubPlannerDownloadLocal;
import com.werkii.server.entities.results.GuiParameter;
import com.werkii.server.entities.results.GuiParameterComboBoxItem;

@Stateless(mappedName=BookScriptPlugin.MAPPED_NAME)
@LocalBean
@PubServerPlugin
public class BookScriptPlugin extends AbstractPublicationJobPlugin implements PubPlannerDownloadLocal  {
  public static final String MAPPED_NAME = 
      "com.priint.pubserver.pubplanner.demo.publication.BookScriptPlugin";
  
  @Override
  public PublicationJob getPublicationJob(Map<String, Object> parameters) {
    Integer scriptId = Integer.parseInt((String)parameters.get(Parameters.SCRIPTID));
    String  tmpPath  = (String)parameters.get(Parameters.DESTINATION_TMP_PATH);
    return new BookScriptJob(scriptId, tmpPath);
  }

  @PubServerMethod(
    label = "name", 
    type = PluginMethod.MethodType.GENERIC, 
    description = "plugin method called to obtain a translation of plugin label")
  public String getMethodName(
      @PubServerMethodParameter(
        name = "lang", 
        defaultValue = PubPlannerPlugins.EN, 
        listOfValues = {}) final String lang) {
    return "Book script";
  }
  
  @Override
  @PubServerMethod(
    label="Run a book script",
    type=PluginMethod.MethodType.PUBLICATION_WORKFLOW_JOB)
  public void exec(
    @PubServerMethodParameter(name="parameters") final Map<String,Object> parameters)
        throws PubServerException {
    super.exec(parameters);
  }
}

Remarks

Download Integration

By adding the following method, this Job is available in the Download Dialog also.
Note: to use a Job in the Download Dialog, you have to implement the PubPlannerDownloadLocal interface. In the example, this is implicitly implemented by inheritance.

@PubServerMethod(
    label="Run a book script",
    type=PluginMethod.MethodType.PUB_PLANNER_DOWNLOAD,
    description="plugin method called to start download job")  
public byte[] exec(
  @PubServerMethodParameter(name="parameters") final Map<String,Object> parameters, 
  @PubServerMethodParameter(name="documents") final List<String> documents) 
    throws PubServerException {
  return super.exec(parameters, documents);
}

Remarks