This article covers a Bloomreach Experience Manager version 12. There's an updated version available that covers our most recent release.

Document Workflow

The DocumentWorkflow

The workflow for publishable documents is implemented by the org.onehippo.repository.documentworkflow.DocumentWorkflow interface. Publishable documents in Hippo are represented by nodes with primary type hippo:document and with the mixin hippostdpubwf:document. This is implemented by the org.onehippo.repository.documentworkflow.DocumentWorkflowImpl class.

The DocumentWorkflow is configured with a property hipposys:nodetype with the value hippo:handle. This means only nodes of type hippo:handle will trigger this workflow. The DocumentWorkflow expects and requires the node it operates on to be a hippo:handle, but see below for customizing the workflow for specific document types. The workflow is only enabled when the hippo:handle node has a child node by the same name and that node has the hippostdpubwf:document mixin. See also the Document Model documentation.

All workflow operations for hippo:handle nodes and their children are combined into and exposed via a single DocumentWorkflow. The benefit is that the whole (workflow) state of a document handle can be evaluated and managed as a single state machine.

Enabled Operations and Permissions

The DocumentWorkflow uses three different roles, hippo:author, hippo:editor and hippo:admin, to differentiate between specific operations. For example, only a user with role hippo:admin is allowed to execute the unlock operation, and a user with the role hippo:author can only use requestPublication or requestDepublication operations.

The DocumentWorkflow defines all available operations. Determining which ones are currently enabled and accessible depends on the current user privileges. This is decided by checking the information in the hints() returned map.

The hints() method provides information to determine if a workflow operation is enabled on a specific document handle and its children nodes. If a user is not authorized for an operation, then the hints method will not return any value. If the operation is meaningless for the current document the hints method will also not return a value (eg. it makes no sense to unpublish a document which isn't published). If no value is available for an operation it is disabled by default. The return value of the hints method is Map<String, Serializable>, where the specific type of Serializable is dependent on the type of operation. This will be explained in further detail below.

For document operations, the return value is of type Map<String, Boolean>. The key is the method name of the operation. The value is a Boolean value that tells if the operation should be enabled.

The values returned by the hints() method are only valid for the moment when it is invoked. The state of a document or authorization of a user may change between this moment and the moment an operation is invoked. This is also checked when an operation is invoked. Thus an operation that was reported as enabled may fail when it is actually invoked.

Hippo Request Workflow Operations

The review and scheduled workflow request operations are handled by the DocumentWorkflow. The DocumentWorkflow provides the state information and which operations are available for these requests. These are found in the above-mentioned hints map with the key "requests". The value attached to this key is also a map, of type Map<String, Map<String, Boolean>>. The key is the JCR node identifier (UUID) of the hippo:request node, which is a child node of the handle. The value is another map, of type Map<String, Boolean>. This map has as key the supported request workflow operations and as value a Boolean that tells if the operation should be enabled. This corresponds to the document operations map above, but is on a deeper level.

Invoking one of these DocumentWorkflow request workflow operations requires passing the JCR node identifier of the corresponding hippo:request node as a parameter.

SCXML DocumentWorkflow

The implementation of the DocumentWorkflow uses the Hippo SCXML Workflow Engine and a DocumentWorkflow-specific SCXML state machine definition.

Further technical details and plenty of examples (based upon the SCXML DocumentWorkflow) are provided in the related SCXML Workflow documentation.

You can find the registration of all SCXML state machine definitions at /hippo:configuration/hippo:modules/scxmlregistry/hippo:moduleconfig/hipposcxml:definitions. The document workflow uses the definition with the same name (documentworkflow). Read SCXML Workflow Execution as a starting point for learning about the semantics of these definitions.

Coupling the document workflow with an SCXML definition is done by name, in the configuration of the workflow itself. For the document workflow, this location is /hippo:configuration/hippo:workflows/default/handle/hipposys:config. If you need to create an additional SCXML definition in your project, this is the place to configure which workflow will to using it.

Customizing the DocumentWorkflow

You can customize the DocumentWorkflow by changing its SCXML state machine definition or by defining a new SCXML definition and switching the document workflow to using that.

Use cases for customization may be, for example, allowing users in the hippo:editor role to be able to unlock documents in use by other users. Or, plugging in your event listeners when a document state is changed. Note that any modifications in the SCXML definitions are automatically detected and loaded.

Another use case is when we need to use a different SCXML definition per document type. The workflow definition nodes are orderable and processed in order by the WorkflowManager. The first workflow definition that matches will be executed while the rest will be skipped. The document workflow is configured to operate on hippo:handle nodes that have a hippo:document child with the same name. This is configured on the node at /hippo:configuration/hippo:workflows/default/handle. The relevant properties are hipposys:nodetype and hipposys:subtype. Copy this handle node and make sure this new node is ordered above the handle node. Change the hipposys:subtype property to match your specific document type and change the SCXML definition name in the handle's child node hipposys:config to the name of your custom SCXML definition.

The DocumentWorkflow implementation class org.onehippo.repository.documentworkflow.DocumentWorkflowImpl can optionally leverage a custom factory class for instantiating its (SCXMLWorkflowData type) DocumentHandle model object, implementing the DocumentHandleFactory interface:

package org.onehippo.repository.documentworkflow;

import javax.jcr.Node;
import org.hippoecm.repository.api.WorkflowException;

/**
 * DocumentHandleFactory is an optional factory interface to be used to override the default
 * {@link DocumentHandle} instance creation for the DocumentWorkflowImpl
 *
 * @see DocumentWorkflowImpl#createDocumentHandle(javax.jcr.Node)
 */
public interface DocumentHandleFactory {
      /**
     * Factory method to create a DocumentHandle instance
     * @param node The JCR node representing the document handle
     * @return a DocumentHandle instance
     * @throws WorkflowException
     */
    DocumentHandle createDocumentHandle(Node node) throws WorkflowException;
}

which can be configured as config property on the workflow configuration itself, like this:

definitions:
  config:
    /hippo:configuration/hippo:workflows/default/handle/hipposys:config:
      documentHandleFactoryClass: my.custom.documentworkflow.DocumentHandleFactoryImpl
Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?