Variables

Variables are associated with processes, and their scope is within the same process, with the following exception: A variable is associated with a type, which defines the class name of the object that the variable can take as values. MDW provides a list of built-in variable types. To view them, follow this.

MDW variables are persisted in a database as Strings in order to preserve their values during long running business processes. Each variable type is associated with a variable translator, which translates between the persistent format (Strings) and the object format.

For simple data types (String, Integer, date, etc) and the variable values are stored along with the variable instance in the VARIABLE_INSTANCE table. For complex data types, all the document related information is stored in DOCUMENT, but the document itself is stored in DOCUMENT_CONTENT table.

Documents can also be used outside the context of variables, typically for storing messages received from or sent to external systems.

Variable Mode

A variable can have one of the following five modes, which define how the variables receive and output their values when the process is invoked. For the Sub Process Invocation, please refer to this link for details.

Accessing Variables in Activity Implementors

The base class for activity implementors, BaseActivity, defines quite a few methods for accessing variables.

To get or set values of variable instances, you can use the methods getParameterValue and setParameterValue, as in the examples:

    Integer value = (Integer)this.getParameterValue("my_variable_name");
    setParameterValue("my_variable_name", new Integer(123));
Note: You will need to ensure the object class matches the declared variable type of the given variable instance. For historical reasons, the method names refer to variables as "parameters", which are only appropriate when they are used for parameter passing (input/output modes).

The following table contains other methods related to variables, and refer to Javadocs (http://centurylinkcloud.github.io/mdw/docs/javadoc/) for more information on the methods.
Example methodPurpose
getVariableInstance(varname)get the variable instance object, which contains properties about the variable instance in addition to the value
getParameters()return an array of all variable instance objects for the process instance
VariableTranslator.realToString(getPackage(), docType, document) Convert the value object to the string format in the database
VariableTranslator.realToObject(getPackage(), type, docvo.getContent(getPackage()) Convert the string format into an object of the given variable type

Documents

The main difference between a document variable and a primitive (non-document) variable is that the former is bound to a reference (DocumentReference) to a document (the real value), whereas the latter is bound directly to the value.

The type of the variable (the translator associated with the variable type) determines whether the variable is a document variable -- the translator for a document variable type must extend the class DocumentReferenceTranslator which itself extends the class VariableTranslator, whereas the translator for a non-document variable type extends VariableTranslator directly. A DocumentReferenceTranslator contains final implementation of the two abstract methods, toString() and toObject(), of VariableTranslator, while demands two additional abstract methods, realToString and realToObject, to be implemented by concrete classes. The basic methods translate between String and DocumentReference, whereas the two new methods translate between String and the actual object class such as org.w3c.dom.Document.

A document is stored in the database table DOCUMENT_CONTENT. The content of the document is stored as a string in a CLOB (in a JSON Object format). The database table contains a couple of additional columns for querying and life cycle handling. Their values are not essential for work flow execution but are needed for querying, cleaning up and archiving purposes. These fields include

Accessing Documents in Activity Implementors

Variables bound to documents are actually taking objects of the class DocumentReference, which contains basically an ID for the document in the database table DOCUMENT. The methods mentioned above all perform on the objects of this class. The additional methods are used to access the actual objects (instead of the reference objects).

Here is an example for retrieving the document from variable:

    DocumentReference docref = (DocumentReference)this.getParameterValue("my_variable_name");
    Object doc = this.getDocument(docref);
The following example shows how to create a new document and bind it to a variable:
    Object doc;		// your object type, such as XmlObject
    String varType;		// the variable type
    DocumentReference docref = this.createDocument(varType, doc, OwnerType.VARIABLE_REFERENCE, new Long(0));
    Long varInstId = this.setParameterValue(name, docref);
    this.updateDocumentInfo(docref, null, null, null, varInstId, null, null);
The following is an example for updating the document referenced by the variable:
    Object doc;		// your object with updated value
    DocumentReference docref = (DocumentReference)this.getParameterValue("my_variable_name");
    this.updateDocument(docref, doc);
Indeed there is a simpler way to perform the above two functions:
    this.setParameterValueAsDocument(varName, varType, value);
This creates the document and binds the variable instance with the document reference if the variable is not yet bound, or updates the document the variable instances references when the variable is already bound to a document reference.

The following method determines if a variable type is a document variable:

   if (VariableTranslator.isDocumentReferenceVariable(package, varType)) {
       ... ...
   }

Remote Document

MDW allows documents stored in one MDW application to be accessed by another. The references to the documents are passed through remote process invocation or other means to other applications. The DocumentReference objects contain a server field referring to the owning application. The field is null for local document.

Remote documents are accessed in a similar way as local documents. We note there are following differences:

Because MDW automatically converts between local and remote document references during remote process invocation and return from it, you do not need to create remote document reference directly. In case you want to use remote document reference in other context, the second argument of the constructor for DocumentReference is used to specify the logical server name.

By using remote document references, we can avoid passing large documents between different workflow applications.

To check if a document reference object refers to a remote document, use

    if (documentReference.getServer()!=null) ... ...

Add Variable Types

In most cases, the built-in variable types should be sufficient for use, as they include XML DOM document, XML Beans and JSON Object. Since we are not encouraging adding custom variable types, the designer does not include an interface to create, modify or delete variable types.

If there is a good reason to add an additional type, you need to insert an entry in the database table VARIABLE_TYPE, as in

  insert into variable_type values (501, 'org.apache.xmlbeans.XmlObject', sysdate, 
     'cuid', '', '', '', 
     'com.centurylink.mdw.common.translator.impl.XmlBeanTranslator');
where 3 values are significant: You will need to implement a variable translator. A variable translator class must extend the abstract class com.centurylink.mdw.common.translator.VariableTranslator. Indeed, since the new type you are adding is likely non-primitive, we require custom variable types to be implemented as documents, which requires your translator to extend the abstract class com.centurylink.mdw.common.translator.DocumentReferenceTranslator, which you will need to implement two methods: realToString and realToObject.