Category Archives: Development

Development

BPMN Modeller not Loading Correctly

After an update of the Eclipse-BPMN Plugin or the Imixs-BPMN Plugin in some cases it can happen, that an existing process model is no longer loaded correctly into the BPMN editor. In this case it is recommanded to remove the file

org.eclipse.bpmn2.modeler.core.prefs

which is located in the Eclipse workspace under the folder .settings/

After restarting Eclipse the BPMN Plugin is working again correctly.

Development

E-Mail validation with Imixs-Workflow

With the help of the Imixs RulePlugin the validation of a E-Mail address entered by the user is very simple.

Just add the following JavaScript in the corresponding Workflow Activity:

 var isValid=true;
 var errorCode="VALIDATION_ERROR",errorMessage;

 // E-Mail validierung
 if (!validateEmail("_contact")) {
   isValid=false; 
   var errorMessage='Bitte geben Sie eine gültige E-Mail Adresse ein';
 }

function validateEmail(fieldName) {
 var email = workitem.get(fieldName);
 if (email == null ) 
    return false;  
 var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
 return re.test(email[0]);
}

 

Architecture Development

BPMN Versioning

Running BPMN models in a BPM system often requires to take care about the internal version of a BPMN model. This occurs, for example, in scenarios where you run multiple instances of an active process in a live system with different versions of the same BPMN model.

The Imixs-Workflow Engine provides a nice mechanism to manage different versions of a BPMN 2.0 model. This allows to setup complex production environments with different models and different model versions at the same time. A model version, which is placed as an extension element of a BPMN 2.0 model can be evaluated by the Imixs-Workflow engine:
imixs-bpmn-versioning
read more »

Development

How to use latest Imixs-Workflow-Engine in Imixs-Office-Workflow

This short tutorial explains how the latest version of Imixs-Workflow can be used in a custom build of Imixs-Office-Workflow.

In some cases it is necessary to use a newer version of the Imixs-Workflow engine event if the custom build of Imixs-Office-Workflow forces to use an older version because of the maven dependencies. To solve this problem you can do this:

1.) Update the imixs-workflow version in the parent pom.xml

First change the version number of the imixs-workflow engine in the parent pom.xml by changing the property ‘org.imixs.workflow.version’

For example:

 <org.imixs.workflow.version>3.4.0-SNAPSHOT</org.imixs.workflow.version>

2.) Remove the ‘imixs-office-workflow-ejb’ dependency

The dependency of the artefact ‘imixs-office-workflow-ejb’ is not necessaray in a custom build. You can remove this dependency form the parent pom.xml and the ear module of the custom build. In the ear pom.xml also remove the imixs-office-workflow-ejb module from the application module configuration.

3.) Change the overlay of the web module

Finally you need to change the overly setting in the web moudle of the custom build. Per default all elements form the overlay war-module (in this case imixs-office-workflow-web’ will be copied into the target web module. This includes also artifacts form the Imixs-Workflow faces and jax-rs dependencies. To avoid this overlay of libs you can add the following plugin configuration into the web module of the custom build:

 <build>
 <plugins>
 <plugin>
 <artifactId>maven-war-plugin</artifactId>
 <version>2.6</version>

 <configuration>
 <workDirectory>target/overlay-war-folder</workDirectory>

 <!-- We exclude libs form the parent WAR artifact -->
 <overlays>
 <overlay>
 <groupId>com.imixs.workflow</groupId>
 <artifactId>imixs-office-workflow-web</artifactId>
 <excludes>
 <exclude>WEB-INF/lib/*.jar</exclude>
 </excludes>
 </overlay>
 </overlays>

 </configuration>

 </plugin>
 </plugins>
 </build>

That’s it! Now only the latest version of Imixs-Worklfow will be included into the custom build of Imixs-Office-Workflow.

Development

Why you should prefer XML to JSON

If you are developing Single Page Applications with JavaScript, REST Services play a central role. REST Services allow you to deal with data in a simple way. In most JavaScript applications REST Services based on JSON become very important in particular. But the JSON format can cause problems if you need to process type save objects. In this case, XML is much more reliable. read more »

Architecture Development

Microservice Architecture for Workflow Applications

With our new project Imixs-Microservice we now provide a solution to build workflow management applications based on a modern microservice architecture.

Imixs-Microservice encapsulates the Imixs-Workflow Engine into a microservice architecture. The service can be bound to any business application, independent from the technology behind. This allows business applications to change the business logic without changing a single line of code. Thus the state of a business object can be controlled through the workflow model.

Based on the comprehensive functionality of the Imixs-Workflow Engine the Imixs-Microservice is empowered to control business data in various ways. Imixs-Microservice can send E-Mail notifications, log business transactions and secures any kind of business data.

The Imixs-Workflow Modeller can set an ACL for each single state in a business process model. This allows the definition of highly complex business applications and waves a security layer around each process instance.

 

The Rest Service API

Imixs-Microservice provides a flexible REST Service API which can be accessed from any platform and any kind of application. The Web Service is based on JSON and XML objects and allows an easy integration in existing projects (Java, .Net, PHP, …). Once deployed a new Workflow Model can be defined using the Eclipse based Imixs-Workflow Modeller. Any business object can be bound to a new business process by posting a JSON or XML based process instance. The state is then controlled by the Imixs-Workflow engine and can be requested and updated in various ways.

Runns with Docker

DockerImixs-Microservice provides a docker image. This makes is easy to run Imixs-Microservice in a Docker container and provides a powerful way to integrate a full featured workflow engine into a microservice architecture. The Docker image can be used as a template for custom projects and provides a scaffold to start with a microservice achitecture.

 

Imixs-Workflow and Imixs-Microservice are Open Source projects and can simplify the development of business applications in various ways. The Imixs Software Solutions provides professional services and support for building enterprise workflow management solutions.

 

Development

Drag & Drop Fileuploads with Imixs-Workflow

With the latest Update of the Imixs-Workflow the project now supports Drag&Drop functionallity for FileUplods. The Imixs-Web-Tool libray provide several JSF Components for building workflow forms fast and easy. The library extends the functionality of the FileUpload Component.

Files which where uploaded can now be viewed in the browser before they are persisted by the Imixs-Workflow Engine. The new FileUpload widget includes the jquery fileupload plugin and supports most browser platforms.

In different to most other frameworks Imixs-Workflow persists files with an access-control-list (ACL). This ACL can be configured by the Workflow Model and restricts access to files for different actors. Each process instance controlled by Imixs-Workflow can have an individual access list. With this functionality also confidential documents can be controlled by the Workflow Engine.

The integration of the new FileUpload control is quite simple as Imixs-Workflow provides a custom tag library:

<i:imixsFileUpload workitem="#{workflowController.workitem}"
   context_url="#{facesContext.externalContext.requestContextPath}/rest/workflow/workitem/#{workflowController.workitem.item['$uniqueid']}" />

The component can be tested within the Imixs Sample Web Application.

imixs_fileupload_032

 

 

Architecture Development

Building transaction save business logic

As I posted in my last blog about JSF and Transactioncontext, it is importend to keep the transaction context in mind when developing a business application within JSF. When you use the Imixs-Workflow Engine you normaly don’t need to think about transactions because Imixs-Workflow takes care about processing a workitem in a full controlled transaction context. But developing with JSF can lead into situations where the business logic is not allways encapsulated correctly in a single transaction. Look at the following example of an Imixs-Workflow web application based on JSF:

//jsf bean...
@EJB WorkflowService workflowService;
...
public String process(ItemCollection workitem) {
 workitem=workflowService.process(workitem);
 // evaluate result and trigger another process step...
 if (workitem.getItemValueString('department').equals('finance')) {
    workitem.replaceItemValue('$activity',APPROVE_BY_MANAGEMENT);
    workitem=workflowService.process(workitem);
 }
 ....
}

In this example, the process method of the front-end controller evaluates the result of a process step and calls a second process for the same business object. Now you have the problem that the workflowService will run in two separate transactions. As I mentioned in my blog this can result into unexpected database results.

When you are working with Imixs-Workflow, the solution is quite simple: Just put your business logic into Imixs-Workflow Plugi-In. Plug-Ins are always controlled by the WorkflowManager and called inside a single transaction. So there is no risk that your business process runs in an undefined context.

Development

What are the benefits of a workflow engine?

Today I was asked by a friend what the benefits of a workflow engine are. And this make me think about the ‘why’ we have started the open source project ‘Imixs-Workflow‘. read more »

Development

How to generate PDF output containing embedded html tags using xsl-fo

With the report capabilities of Imixs-Worklfow it is possible to generate PDF files from a process instance using the XML and Rest API. A description and examples of how to generate a PDF Template can be found here.

With the latest Version of the Imixs Rest API it is now also possible to embed HTML output into a PDF file generated using xsl-fo. The Report-Plugin from Imixs-Workflow now preserve embedded HTML and XML structures in a workitem property if the name of the property starts with ‘html’ or ‘xml’.

To transform the HTML block (which have to be well formed XHTML) inside xsl-fo for each html tag a fo template can be applied in the xsl template.

This is a short example how to use this template technique:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:output encoding="UTF-8" method="xml" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:param name="font-size" select="''" />
    <xsl:param name="font.symbol" select="'Arial Unicode MS'" />
    <xsl:template match="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4"
                    page-width="210mm" page-height="297mm">
                    <fo:region-body region-name="xsl-region-body"
                        margin="20mm" />
                </fo:simple-page-master>
                <fo:simple-page-master master-name="A4-landscape"
                    page-width="297mm" page-height="210mm">
                    <fo:region-body region-name="xsl-region-body"
                        margin="20mm" />
                </fo:simple-page-master>
            </fo:layout-master-set>

            <fo:page-sequence master-reference="A4">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block space-after="20mm">
                        <fo:block text-align="end" font-size="16pt" font-weight="bold">
                            <fo:inline>
                                HTML - PDF - Example
                            </fo:inline>
                        </fo:block>
                    </fo:block>
                    <fo:block>
                        <fo:block font-weight="bold">Text Output:</fo:block>
                        <fo:block>
                            <xsl:value-of
                                select="/collection/entity[normalize-space(item[name = 'txtworkflowgroup']/value) = 'Frage']/item[name='txtname']/value" />
                        </fo:block>

                        <!-- format html output -->
                        <fo:block font-weight="bold">HTML Output:</fo:block>
                        <fo:block>
                            <xsl:apply-templates
                                select="/collection/entity[normalize-space(item[name = 'txtworkflowgroup']/value) = 'Frage']/item[name='htmlanswer']/value" />
                        </fo:block>
                    </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>

    <xsl:template
        match="/collection/entity[normalize-space(item[name = 'txtworkflowgroup']/value) = 'Frage']/item[name='htmlanswer']/value">
        <xsl:apply-templates />
    </xsl:template>
   
    <!-- html format -->
    <xsl:template match="p">
        <fo:block>
            <fo:inline>
                <xsl:text disable-output-escaping="yes">
                <xsl:apply-templates />
                </xsl:text>
            </fo:inline>
        </fo:block>
    </xsl:template>
    <xsl:template match="b|strong">
        <fo:inline font-weight="bold">
            <xsl:apply-templates />
        </fo:inline>
    </xsl:template>

    <xsl:template match="table">
        <fo:table table-layout="auto" width="100%">
            <fo:table-body>
                <xsl:apply-templates />
            </fo:table-body>
        </fo:table>
    </xsl:template>
    <xsl:template match="tr">
        <fo:table-row>
            <xsl:apply-templates />
        </fo:table-row>
    </xsl:template>

    <xsl:template match="td">
        <fo:table-cell>
            <fo:block>
                <xsl:apply-templates />
            </fo:block>
        </fo:table-cell>
    </xsl:template>

    <xsl:template match="address">
        <fo:block font-style="italic">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="blockquote">
        <fo:block space-before="1em" space-after="1em" start-indent="3em"
            end-indent="3em">

            <xsl:apply-templates />
        </fo:block>
    </xsl:template>

    <xsl:template match="caption">
        <fo:block keep-with-next="always" text-align="center">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="center">
        <fo:block text-align="center">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="div|multicol|noembed|noframes   |nolayer|noscript">
        <fo:block>
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>

    <xsl:template match="h1">
        <fo:block font-size="180%" font-weight="bold">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="h2">
        <fo:block font-size="160%" font-weight="bold">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="h3">
        <fo:block font-size="140%" font-weight="bold">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="h4">
        <fo:block font-size="120%" font-weight="bold">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>
    <xsl:template match="h5">
        <fo:block font-size="110%" font-weight="bold">
            <xsl:apply-templates />
        </fo:block>
    </xsl:template>

    <xsl:template match="br">
        <fo:block white-space="pre">
            <xsl:text disable-output-escaping="yes">&#10;</xsl:text>
        </fo:block>
    </xsl:template>

    <xsl:template match="ol">
        <fo:list-block provisional-label-separation=".2em"
            provisional-distance-between-starts="{string-length(count(li))*.9+.6}em">
            <xsl:apply-templates />
        </fo:list-block>
    </xsl:template>

    <xsl:template match="ol/li">
        <fo:list-item>
            <fo:list-item-label end-indent="label-end()">
                <fo:block text-align="end">
                    <xsl:variable name="value">
                        <xsl:choose>
                            <xsl:when test="@value">
                                <xsl:value-of select="@value" />
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:number />
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    <xsl:choose>
                        <xsl:when test="@type='I'">
                            <xsl:number format="I" value="$value" />
                        </xsl:when>
                        <xsl:when test="@type='A'">
                            <xsl:number format="A" value="$value" />
                        </xsl:when>
                        <xsl:when test="@type='i'">
                            <xsl:number format="i" value="$value" />
                        </xsl:when>
                        <xsl:when test="@type='a'">
                            <xsl:number format="a" value="$value" />
                        </xsl:when>
                        <xsl:when test="parent::ol/@type='I'">
                            <xsl:number format="I" value="$value" />
                        </xsl:when>
                        <xsl:when test="parent::ol/@type='I'">
                            <xsl:number format="A" value="$value" />
                        </xsl:when>
                        <xsl:when test="parent::ol/@type='I'">
                            <xsl:number format="i" value="$value" />
                        </xsl:when>
                        <xsl:when test="parent::ol/@type='I'">
                            <xsl:number format="a" value="$value" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:number format="1" value="$value" />
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:text>.</xsl:text>
                </fo:block>
            </fo:list-item-label>
            <fo:list-item-body start-indent="body-start()">
                <fo:block>
                    <xsl:apply-templates />
                </fo:block>
            </fo:list-item-body>
        </fo:list-item>
    </xsl:template>

    <xsl:template match="ul|menu">
        <fo:list-block provisional-label-separation=".2em"
            provisional-distance-between-starts="1.6em">
            <xsl:apply-templates />
        </fo:list-block>
    </xsl:template>
    <xsl:template match="ul/li|menu/li">
        <fo:list-item>
            <fo:list-item-label end-indent="label-end()">
                <fo:block text-align="end">
                    <fo:inline font-family="{$font.symbol}">
                        <xsl:choose>
                            <xsl:when test="@type='square'">
                                <xsl:text disable-output-escaping="yes">&#x25AA;</xsl:text>
                            </xsl:when>
                            <xsl:when test="@type='circle'">
                                <xsl:text disable-output-escaping="yes">&#x25CB;</xsl:text>
                            </xsl:when>
                            <xsl:when test="parent::ul/@type='square'">
                                <xsl:text disable-output-escaping="yes">&#x25AA;</xsl:text>
                            </xsl:when>
                            <xsl:when test="parent::ul/@type='circle'">
                                <xsl:text disable-output-escaping="yes">&#x25CB;</xsl:text>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:text disable-output-escaping="yes">&#x2022;</xsl:text>
                            </xsl:otherwise>
                        </xsl:choose>
                    </fo:inline>
                </fo:block>
            </fo:list-item-label>
            <fo:list-item-body start-indent="body-start()">
                <fo:block>
                    <xsl:apply-templates />
                </fo:block>
            </fo:list-item-body>
        </fo:list-item>
    </xsl:template>

    <xsl:template match="font">
        <fo:inline>
            <xsl:choose>
                <xsl:when test="@size=1">
                    <xsl:attribute name="font-size">xx-small</xsl:attribute>
                </xsl:when>
                <xsl:when test="@size=2">
                    <xsl:attribute name="font-size">x-small</xsl:attribute>
                </xsl:when>
                <xsl:when test="@size=3">
                    <xsl:attribute name="font-size">small</xsl:attribute>
                </xsl:when>
                <xsl:when test="@size=4">
                    <xsl:attribute name="font-size">medium</xsl:attribute>
                </xsl:when>
                <xsl:when test="@size=5">
                    <xsl:attribute name="font-size">large</xsl:attribute>
                </xsl:when>
                <xsl:when test="@size=6">
                    <xsl:attribute name="font-size">x-large</xsl:attribute>
                </xsl:when>
                <xsl:when test="@size=7">
                    <xsl:attribute name="font-size">xx-large</xsl:attribute>
                </xsl:when>
            </xsl:choose>
            <xsl:if test="@face">
                <xsl:attribute name="font-family"><xsl:value-of select="@face" /></xsl:attribute>
            </xsl:if>
            <xsl:apply-templates />
        </fo:inline>
    </xsl:template>

    <xsl:template match="small">
        <fo:inline font-size="smaller">
            <xsl:apply-templates />
        </fo:inline>
    </xsl:template>

    <xsl:template match="span">
        <xsl:choose>
            <xsl:when test="self::node()[contains(@style,'underline')]">
                <fo:inline text-decoration="underline">
                    <xsl:apply-templates />
                </fo:inline>
            </xsl:when>
            <xsl:otherwise>
                <fo:inline>
                    <xsl:apply-templates />
                </fo:inline>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="sub">
        <fo:inline baseline-shift="sub">
            <xsl:apply-templates />
        </fo:inline>
    </xsl:template>
    <xsl:template match="sup">
        <fo:inline baseline-shift="super">
            <xsl:apply-templates />
        </fo:inline>
    </xsl:template>


    <xsl:template match="ins|u">
        <fo:inline text-decoration="underline">
            <xsl:apply-templates />
        </fo:inline>
    </xsl:template>
</xsl:stylesheet>

A complete example of a xsl-fo template for html tags can be found here.

Entity Encoding!

If you need to parse XML content make sure that this content did not contain HTML encoded characters like &auml; – this entities contained in the xml source can not be processed by the XSL processor. You need to work with raw utf-8 or unicode encoded characters. For example:

"ä" or "&#228;" works, but "&auml;" wont work!

As we are using TinyMCE Edtior in most of our web applications we need to set the “raw” format to initialize TinyMCE. Otherwise characters will be HTML encoded!

$('textarea.imixs-editor')            
            .tinymce(
                    { ....
                    .... // set entity encoding
                        entity_encoding: "raw"
                    });
        }