Content Engine

When the persistence engines (structure and content) of [fleXive] were designed, we tried to solve this problem by using a generic approach (unlike hibernate, which accesses data instances with (auto)generated classes). Since we wanted to use hierarchical data structures which are quite like XML in nature, the weapon of choice was an XPath-like approach: Values are accessed using their XPath.

As a simple example lets consider the following XML file:

<?xml version=“1.0“ standalone=“yes“?>
<Person>
    <Name>Max Muster</Name>
    <Phone>+43 1 12345</Phone>
    <Phone>+43 1 800 FLEXIVE</Phone>
    <Address>
        <Street>Private road</Street>
    </Address>
    <Address>
        <Street>Office lane</Street>
    </Address>
</Person>

With [fleXive] we would create a type called Person. We can use the Java API or a custom Groovy builder, the GroovyTypeBuilder, which resembles the hierarchic structure of the type more closely.



Lets have a look at the following table, which is based on the XML data example, to visualize the mapping of XPath's to values:

Table 6.22. XPath to value mapping
XPath Value
PERSON/NAME[1] Max Muster
PERSON/PHONE[1] +43 1 12345
PERSON/PHONE[2] +43 1 800 FLEXIVE
PERSON/ADDRESS[1]/STREET[1] Private road
PERSON/ADDRESS[2]/STREET[1] Office lane

The XPath starts with the name of the type (which is optional if addressing in a FxContent instance, since there the type if obviously known but is needed for example in query results) and the path to address the property. Please note that XPaths are not case-sensitive and that an index of 1 is optional: PERSON/ADDRESS[2]/STREET[1] for example is identical to PERSON/ADDRESS[2]/STREET.

FxContent serves as a container for groups, properties and general information about a content instance. It is used to initialize (create an empty content instance), create, save and load content instances [2] .


The purpose of this example is to demonstrate how easy it is to create, update and remove content instances. Since a content instance is tied to a type (See the section called “Types” for more information) the first thing that needs to be done is to initialize a new (empty) content instance 1. Initializing a content instance creates as many property or group entries as defined in the respective assignments' default multiplicity. Setting a value to a property assignment 2 is done by creating a new FxValue instance corresponding to the property's data type for the XPath of the assignment. The same applies if a group is involved, as shown in 4 for the street property of the first address group. Adding a new index is done by simply setting the XPath to the desired value like in 3 or 5. Please note that using an index of 3 would be illegal if no index of 2 exists.

Removing an XPath is as simple as calling co.remove("/Address[2]") if the second address group should be removed.

A content is created 6 and updated by calling the ContentEngine's FxPK save(FxContent content) method which returns the primary key of a content instance. Loading is done by providing the primary key to the ContentEngine's load(FxPK pk)-method. 7.

Changing a value can be done by assigning a new FxValue instance (like in 5) or by reading the current value 8, and changing it 9 which is updated in the content instance as can be seen from the println command on the application servers console.

To remove a content instance (10) only the primary key - and all required permissions - is needed.

To be able to identify a content, a primary key (implemented in FxPK) is needed. This primary key consists of the unique identifier (usually equivalent to the id the content is stored in the database with) and the version. Depending on the configuration of the type the content belongs to it is possible to create different versions of a content.

A primary key can consist of a distinct version (a numerical value) or a predefined constant:

  • MAX: Constant to select the maximum (highest) available version

  • LIVE: Constant to select the version whose workflow step is flagged as live

To create a new version simply call the ContentEngine's createNewVersion(FxContent co) method.

Information about all versions of a content can be retrieved using the ContentEngine's FxContentVersionInfo getContentVersionInfo(FxPK id) method. FxContentVersionInfo contains information about the minimum-, maximum- and most recently modified version numbers as well as information which user was the last to update each version and if a live version exists.



[2] The term content instance is used to describe all data related to a concrete instance of a FxType where values are assigned to properties. A good analogy would be the instantiation ( FxContent ) of a class ( the section called “Structure Engine” FxType ).