Objects and Model Elements

Model Elements

Model Elements in the Infinity Process Platform runtime are defined as model parts of deployed workflow models, e.g. a process definition, activity or a role. The base interface for all model elements is org.eclipse.stardust.engine.api.model.ModelElement.

Model elements usually are referred to by ID or by element object ID (element OID).

The ID of a model element is a string assigned to this element at modeling time. The ID uniquely identifies a model element within an element specific scope, which may be the whole model or just a part of the model (e.g. an activity ID is only unique within the scope of its process definition). As IDs are user defined they allow for application-specific names easily to be used in the embedding application. As a downside, the modeler is responsible for ensuring consistency of IDs between model versions.

The element OID in contrast is an automatically assigned 32-bit numeric identifier for model elements. Element OIDs are unique within model scope and guaranteed to be consistent between model versions. As a downside, the numeric nature of element OIDs makes them less intuitive to use in client applications than element IDs.

Both the element ID as well as the element OID per se allow for model version-neutral element identification, e.g.:

WorkflowService workflowService = ...
final Map NO_INPUT = Collections.EMPTY_MAP;
workflowService.startProcess("INTERNET_ORDER", NO_INPUT, true);

starts the process with ID INTERNET_ORDER of the current model version but there may exist pending process instances with the same ID from other model versions.

To uniquely identify model elements across model versions you have to additionally use the 32-bit numeric model OID attached to every model element during deployment. The pair of model OID/element OID is guaranteed to be unique within runtime environment scope.

Model elements additionally may have a user-defined name possibly to be used as label in client applications.

In the fragmented modeling environment, each referenced models have unique namespace assigned. So when referencing and deploying, each model is identified uniquely.

Runtime Objects

Runtime objects are defined as persistent objects created during runtime. They have a persistent representation as a row in the audit trail database. The base interface for runtime objects is org.eclipse.stardust.engine.api.runtime.RuntimeObject.

Runtime objects (e.g. process instances, activity instances or users) are identified by their object ID (OID). The OIDs of runtime objects are 64-bit numeric identifiers guaranteed to be unique within the scope of a concrete runtime objects type, e.g.:

ActivityInstance activityInstance = ...
WorkflowService workflowService = ...
workflowservice.activate(activityInstance.getOID());

Runtime objects describing instances of model elements additionally have attached the element's ID, element OID and model OID.

Detail Objects

Many methods of the Infinity Process Platform APIs return detail objects. Detail objects are a realization of the Data Transfer Object design pattern, efficiently passing to the clients serializable objects by value.

Instances of these classes are often snapshot views of runtime objects or model elements, such as process instances, activity instances or activity definitions and contain data describing these runtime objects or model elements in a structured way (e.g. their OID, element ID or start timestamp). Due to their snapshot nature such objects are read-only. A common usage pattern is to retrieve an updated detail object as return value of modifying operations, thus efficiently being able to keep a synchronized view on interesting parts of a runtime environment in client applications.

The following detail object interfaces referring to runtime objects are currently provided:

Runtime detail object are in general located in the org.eclipse.stardust.engine.api.runtime package and specializations of the previously mentioned org.eclipse.stardust.engine.api.runtime.RuntimeObject interface where appropriate.

The following detail object interfaces referring to model elements are provided:

Model element detail objects are in general located in the
org.eclipse.stardust.engine.api.model package and specialization of the previously mentioned
org.eclipse.stardust.engine.api.model.ModelElement interface where appropriate.

Detail objects are sometimes root detail objects, containing a possibly complex data structure of other child detail objects, e.g. an instance of User may contain references to instances of Grant, representing the role or organization assignments of the user.

Specifically, most runtime detail objects contain the appropriate model element detail object for convenience. An exception of this rule is the ProcessInstance runtime detail object as the appropriate ProcessDefinition detail object will be usually costly to transfer due to its deeply nested structure and is omitted for performance reasons. Client applications needing ProcessDefinition model element detail objects are required to use the QueryService for retrieval and highly advised to use some caching mechanism.

Keys

Due to the lack of native support for enumerations in current JDKs Infinity Process Platform employs a variation of the enum emulation pattern to define named constants. Such constants come in two flavors as numeric constants or character string constants.

Numerical key classes are specializations of org.eclipse.stardust.common.IntKey. Such keys generally contain integer constants defining the numeric key values using an all-caps notation and additionally constants for key instances using a camel-case notation. Key instances additionally provide a human-readable name for keys.

A sample implementation is:

public class ProcessInstanceState extends org.eclipse.stardust.common.IntKey
{
public static final int CREATED = -1;
public static final int ACTIVE = 0;
public static final int ABORTED = 1;
public static final int COMPLETED = 2;
public static final int INTERRUPTED = 3;
...
public static final ProcessInstanceState Created = new ProcessInstanceState(CREATED, "Created");
public static final ProcessInstanceState Active = new ProcessInstanceState(ACTIVE, "Active");
public static final ProcessInstanceState Aborted = new ProcessInstanceState(ABORTED, "Aborted");
public static final ProcessInstanceState Completed = new ProcessInstanceState(COMPLETED, "Completed");
public static final ProcessInstanceState Interrupted = new ProcessInstanceState(INTERRUPTED, "Interrupted");
};

Numeric keys can be used in switch-statements as follows:

switch (state.getValue())
{
case ProcessInstanceState.ACTIVE: ...
case ProcessInstanceState.ABORTED: ...
case ProcessInstanceState.COMPLETED: ...
}

or in comparison:

if (ProcessInstanceState.Aborted.equals(state))
{
...
}

Left-hand-side key instances support equals()-comparison to both key instances and numeric key values as right-hand-side operand.

The following numeric key classes are currently provided:

Character string-based key classes are specializations of org.eclipse.stardust.common.StringKey. Such keys generally contain constants for key instances using a camel-case notation. Key instances support both an internal ID as well as a human-readable name for keys.

Left-hand-side key instances support equals()-comparison to both key instances and character string representations of the key's internal ID value as right-hand-side operand.

The following character string based key classes are currently provided:

Query Objects

The Infinity Process Engine offers a rich query API for querying runtime elements working with two concepts:

Query classes to express your query intentions. For every query type there is a subtype supporting the special semantics required to query the corresponding runtime elements:

public abstract class Query implements Serializable
{
public final FilterAndTerm getFilter();
public final FilterAndTerm where(FilterCriterion filter);
public final OrderCriteria orderBy(OrderCriterion criterion);
public final OrderCriteria orderBy(FilterableAttribute attribute);
public final OrderCriteria orderBy(FilterableAttribute attribute, boolean ascending);
public final EvaluationPolicy getPolicy(Class policyClass);
public final void setPolicy(EvaluationPolicy policy);
...
}

A query contains one filter which can be arbitrarily complex (WHERE clause), a list of order criteria (ORDER BY clause) and possibly zero ore more policies which fine tune the behavior for more complex queries. Creating your own queries is discussed in detail in the chapter Querying Workflow.

You will never instantiate a Query class directly but one of the provided subclasses corresponding to the similarly named runtime elements. There are the following concrete Query subclasses all located in the org.eclipse.stardust.engine.api.query package:

Each of these classes provides a couple of static factory methods to provide instances of itself for the most common use cases, e.g.:

ActivityInstanceQuery findAlive();

on the ActivityInstanceQuery class.

QueryResult classes return the result of a query as a wrapped collection of the corresponding detail objects.

public interface QueryResult extends List, Serializable
{
// inherits iterator() and size() from List
public long getTotalCount();
public SubsetPolicy getSubsetPolicy();
public boolean hasMore();
}

There exists a QueryResult subtype for every query type, located in the org.eclipse.stardust.engine.api.query package:

The actual queries are performed using the QueryService with methods like:

ActivityInstance findFirstActivityInstance(ActivityInstanceQuery query);
ActivityInstances findActivityInstances(ActivityInstanceQuery query);

As a result of a query you will get either a single detail object of the appropriate type or a subtype of a QueryResult object which encapsulates the returned items.