cancel
Showing results for 
Search instead for 
Did you mean: 

From jpdl to bpmn 2.0, oh so verbose.

unsavory
Champ on-the-rise
Champ on-the-rise
I'm hoping someone has some pointers for me and can help me figure out how to model this process is a more efficient manner.  I am porting our existing business processes from JBPM 4 to Activiti.  Our old processes were written in jpdl, and now that I'm moving things over to bpmn, I am finding bpmn to be both extremely verbose and complicated to do very simple things.

Here is a task we had modeled in jpdl:
<decision name="check_if_language_exam_required">
      <!– Language exam required for Simplified Chinese. –>
      <transition name="to complete language exam" to="complete_language_exam">
         <condition expr="#{ (!isLanguageExamComplete) and jobLanguage == 'zh' }" />
      </transition>
      <transition name="to check applicant auto rejection" to="check_applicant_auto_rejection" />
   </decision>
<task name="complete_language_exam" assignee="#{ stringId }">
            <transition name="completed" to="check_applicant_auto_rejection" />
            <transition name="abandoned" to="abandoned" />
            <transition name="to abandoned" to="abandoned" ends-task="true">
               <timer duedate="45 days" />
            </transition>
         </task>

It is essentially a language screening exam for Chinese applicants that they have 45 days to complete.  If it is not completed within 45 days, the process is ended in an abandoned state.  We also have the ability to manually mark a screening exam as abandoned.  Pretty simple stuff.

Now for bpmn 2.0:
      <exclusiveGateway id="isLanguageExamRequiredGw" name="Check if language exam required" default="langExamNotRequiredFlow" />
      
      <sequenceFlow id="langExamRequiredFlow" sourceRef="isLanguageExamRequiredGw" targetRef="completeLangExamTaskSetup">
         <!– Language exam required for Simplified Chinese. –>
         <conditionExpression xsi:type="tFormalExpression">${ (!isLanguageExamComplete) and jobLanguage == 'zh' }</conditionExpression>
      </sequenceFlow>
      
      <sequenceFlow id="langExamNotRequiredFlow" sourceRef="isLanguageExamRequiredGw" targetRef="sendRegisteredEmailTask" />
      
      <scriptTask id="completeLangExamTaskSetup" name="Complete language exam setup (hidden)" scriptFormat="groovy">
         <script>execution.setVariable('AvailableOutcomes', 'completed,abandoned')</script>
      </scriptTask>
      
      <sequenceFlow id="completeLangExamSetupFlow" sourceRef="completeLangExamTaskSetup" targetRef="completeLangExamTask" />
               
      <userTask id="completeLangExamTask" name="Complete language exam">
         <documentation>
            Complete the required language screening exam.
         </documentation>
         <extensionElements>
            <activiti:formProperty id="TaskOutcome" variable="TaskOutcome" required="true" />
         </extensionElements>
         <humanPerformer>
            <resourceAssignmentExpression>
               <formalExpression>${ stringId }</formalExpression>
            </resourceAssignmentExpression>
         </humanPerformer>
      </userTask>
      
      <boundaryEvent id="completeLangExamTaskAbandonedTimer" cancelActivity="true" attachedToRef="completeLangExamTask">
         <timerEventDefinition>
            <timeDuration>P45D</timeDuration>
         </timerEventDefinition>
      </boundaryEvent>
      
      <sequenceFlow id="completeLangExamTaskAbandonedTimerFlow" sourceRef="completeLangExamTaskAbandonedTimer" targetRef="abandonedOutcome" />
      
      <sequenceFlow id="langExamCompletedFlow" sourceRef="completeLangExamTask" targetRef="completeLangExamTaskOutcomeGw" />
      
      <exclusiveGateway id="completeLangExamTaskOutcomeGw" name="Check language exam outcome (hidden)" default="completeLangExamCompletedFlow" />
      
      <sequenceFlow id="completeLangExamCompletedFlow" sourceRef="completeLangExamTaskOutcomeGw" targetRef="sendRegisteredEmailTask" />
      
      <sequenceFlow id="completeLangExamAbandonedFlow" sourceRef="completeLangExamTaskOutcomeGw" targetRef="abandonedOutcome">
         <conditionExpression xsi:type="tFormalExpression">${ (LastTaskOutcome == 'abandoned') }</conditionExpression>
      </sequenceFlow>

Wow :shock: .  Please tell me there is a more efficient way to do this.  Am I missing something?  Thanks for any help or pointers you can provide.
3 REPLIES 3

trademak
Star Contributor
Star Contributor
Yes BPMN 2.0 is more verbose than jPDL. But this shouldn't be too much of a problem since there are tools like the Activti Modeler and Designer to simplify the generation of XML.
In addition there are ways to make it less verbose.
The user task you included can for example be rewritten to:

<userTask id="completeLangExamTask" activiti:assignee="${stringId}">
   <extensionElements>
      <activiti:formProperty id="TaskOutcome" variable="TaskOutcome" required="true" />
   </extensionElements>
</userTask>

And in jBPM you didn't set a form property, so no increase of verbosity there.
But again in the end, yes BPMN 2.0 is more verbose than jPDL.

Best regards,

unsavory
Champ on-the-rise
Champ on-the-rise
Yes, you are correct that in JBPM I didn't set a form property.  The reason being is that in JBPM I had outgoing task transitions, I could take; something which has to be hacked into bpmn.  And yes, I do consider it a hack.

Thanks for the pointer on the task assignment.  I did see that in the documentation, but I prefer to stick with the bpmn conventions where possible.

I guess the way I am handling task transitions is the proper way of doing it and I will have to live with the verbose and complicated XML then.

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Thanks for the pointer on the task assignment. I did see that in the documentation, but I prefer to stick with the bpmn conventions where possible.

You compare a totally proprietary format (jPDL) with a standard (BPMN) and then 'complain' the standard is to verbose. But at the same time do not 'accept' shortcuts which can if wanted be implemented more verbosely with exactely the same functionality… I don't get that. Sounds no valid reason to complain then 😉

I guess the way I am handling task transitions is the proper way of doing it and I will have to live with the verbose and complicated XML then.
The way you handle the transitions with the exclusive gateway is 'normal' but you still do not need to use a form property. I do not use the Activiti forms at all (use JSF) and just set a variable based on a button on a form that is clicked. So that part can be left out and the difference is even smaller then.
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.