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-Workflow will be included into the custom build of Imixs-Office-Workflow.

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.

 

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

 

 

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.

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

With the report capabilities of Imixs Workflow 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"
                    });
        }

Building a Web application with Imixs-Workflow – Part III.

NOTE: Please see the latest tutorial how to run Imixs-Workflow with Jakarta EE.

In the first part of my tutorial I explained how to define a business model using the Imixs Workflow Modeler. The second part describes how to setup the Java EE Application server. Now its time to complete the tutorial and deploy the workflow application!

As you have seen I spent much time in explaining the modeling process and the server configuration. The reason is that the deployment of the Imixs Workflow application is really easy and did not take much time. I will explain two szenarious. First I will show how to dpeloy the Imixs Workflow Sample application. Next I explain how to checkout the sources and use the Sample Application as a scaffolder to build your own application. Continue reading “Building a Web application with Imixs-Workflow – Part III.”

Building a Web application with Imixs-Workflow – Part II.

NOTE: Please see the latest tutorial how to run Imixs-Workflow with Jakarta EE.

In the first part of my tutorial I explained how you create a workflow model using the Imixs Workflow Modeler. This part now concerns about the setup of your application server on which you can run the workflow application later. I will describe the setup of the Application Server Glassfish which is common running a JEE application. But you can also use a different JEE application servers (e.g. JBoss, WildFly). Continue reading “Building a Web application with Imixs-Workflow – Part II.”

Building a Web application with Imixs-Workflow – Part I.

NOTE: Please see the latest tutorial how to run Imixs-Worklfow with Jakarta EE.

This Tutorial shows how to build a web based workflow application using the Open Source framework Imixs-Workflow. Imixs-Workflow gives you a powerful technology building a business process management system (BPMS). It is mostly easy to setup a new web application without spending to much time into development. So you can focus on the business process and your customers needs.

The Tutorial consist of three parts.

  • Part I. – shows the creation of a workflow model. The workflow model is the blueprint where you describe how your business process should work. You can use the Eclipse based graphical Imixs-Workflow Modeler to create a Workflow model.
  • Part II. – concerns about the setup of your application server which is responsible to authenticate users and store workitems (a running process instance) into a database.
  • Part III. – will show you how to build and deploy the web application. This is mostly easy as you can use Maven to setup a scaffold in a few seconds which will provide you with a typical web application project based on the latest JEE/JSF Technology. You can use the scaffold to start further development or just start you own implementation. Its up to you.

The hole tutorial will take less than one hour. You can find the Example Application also on GitHub. Continue reading “Building a Web application with Imixs-Workflow – Part I.”