Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Stardust/Knowledge Base/Reference Project

Purpose

The Charity Reference Project is intended to explain to the Stardust community and beyond for the Eclipse SOA Project how BPM technology can be used to created a complete application with minimal programming effort and maximum involvement of domain experts.

Note, that the entire functionality of the Charity Reference Project is implemented without Java expertise.

Scenario

The Federal Charity Institution of the fictitious country Neverland provides an Internet platform for charity organizations to distribute their benefits to those in need. Charity institutions can register and describe their rules for accepting beneficiaries. Beneficiaries can apply for benefits such as vacation funding.

Main Elements

Processes, Events and Activities

  • Charity Organization Registration and Approval
    • Data Entry
    • Address Verification
    • Review
    • Approval/Rejection
  • Vacation Request
    • Data Entry
    • Address Verification
    • Dispatching to Charity Organization
    • Review
    • Approval/Rejection

Participants

  • Platform Operators from the roof organization running/operating the system
  • Administrators of the charity organizations
  • Applicants would only be implicit participants kicking of workflows via a little portal and receiving notifications

Services

  • Address Validation Specifications managed in EasySOA, implementation prototyped in OW2 FraSCAti Studio
  • HTML/JS UI Component for Organization Review
  • Simplistic HTML5 web portal for Charity organization registration (kicking off first process) Application for vacation funding (kicking off second process)

Data Model

  • XSD
  • Charity Organization (Structure)
  • Vacation Funding Request (Structure)
  • Beneficiary (Structure)
  • Address (Structure)
  • Country (Structure)
  • Used across tools (BPM, WS)

Running the Project

  • Install Stardust for Helios or Kepler
  • Create a Dynamic Web Project charity with Stardust Profile enabled following the concepts of the Stardust Rapid Application Development (for more details see the Support Case example in the documentation).
  • Load the charity-portal Utility Project from Examples in Stardust Git into your workspace. Please read Source Code on how to checkout source code from stardust git repositories.
  • Download the file demo_table.css from [1] and copy it to org.eclipse.stardust.examples.git/charity-portal/resources/META-INF/webapp/public/css/
  • Download the file jquery.dataTables.css [2] and copy it to org.eclipse.stardust.examples.git/charity-portal/resources/META-INF/webapp/public/css/thirdparty/jquery/
  • Copy the Process Model under charity-portal/proces-models/Charity.xpdl to a folder proces-models (or the like) in your charity Dynamic Web Project. This is required because only this project has the proper classpath settings for embedded deployment of the Process Model via the Eclipse Export option.
  • Add the charity-portal Utility Project to your Deployment Assembly of the charity project (Properties > Deployment Assembly > Add Project).

After these steps your Outline should look like this

Outline.gif

After starting the server you should be able to open

  • http:/localhost:8080/charity to access the Stardust Process Portal and
  • http:/localhost:8080/charity/plugins/charity-portal/public/homePage.htm to access the Neverland Charity Portal.

Selected Implementation Aspects

Charity Portal

The Charity Portal is a simple HTML/JS-based implementation which leverages

Architecture is

  • a single HTML page (charity-portal/webapp/public/homePage.htm) containing all HTML markup,
  • JavaScript controller classes (OrganizationRegistrationPanelController.js, VacactionFundingRequestPanelController.js) in charity-portal/webapp/public/js binding and modifying the HTML content
  • a ServiceAdapter.js class in charity-portal/webapp/public/js to manage REST communication with the Stardust Server.

Processes are started via REST calls from the class ServiceAdapter

jQuery.ajax({type : "POST",
   beforeSend: function (request)
   {
      request.setRequestHeader("Authentication", self.getBasicAuthenticationHeader());
   },
   url : this.getProcessStartUrl("CharityOrganizationRegistration"),
   contentType : "application/xml",
   data : payload}).done(function() {
      deferred.resolve();
      }).fail(function() {
         deferred.reject();
      });

using a Deferred Pattern for synchronicity.

The XML payload to initialize the Process Data is assembled the JSON objects used in the UI via the x2js utility.

var converter = new X2JS();
var envelope = {Args: {CharityOrganization: {CharityOrganization : organization}}};					
var payload = converter.json2xml_str(envelope);
var self = this;

This might be replaced by an automated conversion, e.g. with json2xml. Volunteers to help are welcome to submit via Gerrit.

Process Descriptors

Process Descriptors allow to display specific process data to search for Process Instances or sort lists of those. They can be easily defined in the Process Properties Pages of the Stardust Browser Modeler:

Stardust-Reference-Project-Descriptors.gif

As a result of such a definition, e.g. Worklists will automatically provide corresponding information:

Stardust-Reference-Project-Worklist.gif

Department Concept

If Organizations are marked as supporting Departments and bound to Process Data like for Charity Organization below

Stardust-Reference-Project-Department-Definition.gif

Instances (Departments) of these Orgnizations and their respective Roles can be created at Runtime and users can be assigned to it.

Stardust-Reference-Project-Participant-Management.gif

Workitems are automatically dispatched as follows

Stardust-Reference-Project-Department-Worklist.gif

UI Mashup

The Activity Review Organization Registration in the Organization Registration Process uses a UI Mashup for its implementation.

It is defined as follows in the Stardust Browser Modeler

Stardust-Reference-Project-UI-Mashup-URL.gif

with the following Input and Output Parameters

Stardust-Reference-Project-UI-Mashup-Parameter.gif

and can even be tested in th Browser Modeler

Stardust-Reference-Project-UI-Mashup-Test.gif

The implementation also follows established HTML/JavaScript patterns with

  • an HTML file organizationRegistrationReviewPanelJQuery.htm and organizationRegistrationReviewPanelAngular.htm,
  • a JavaScript Controller js/OrganizationRegistrationReviewPanelControllerJQuery.js and js/OrganizationRegistrationReviewPanelControllerAngular.js
  • a Javascript Main function in js/OrganizationRegistrationReviewPanelMainJQuery.js and js/OrganizationRegistrationReviewPanelMainAngular.js which binds Controller and Markup.

all in charity-portal\resources\META-INF\webapp\public. Hereby the *JQuery* and *Angular* are alternative implementations. *Angular* asa declarative approach with minimal coding, *JQuery* with low level control. Combinations are obviously possible.

Both implementations should be fairly independend of Stardust the only connection is the use of the Interaction class in the *Main* class. On loading the content, the interaction object checks in its bind() method whether a callback to Stardust has been provided in the URL opening the page (as the Stardust Portal is providing a callback URI in the Query String when it opens the page in an IFRAME in the Stardust Portal) and retrieves input data from it. These input data are then available via interaction.input.<Input Data ID>.

jQuery(document).ready(function() {
   var interaction = UiMashupInteraction.create();

   interaction.bind().done(function() {
      var controller = OrganizationRegistrationReviewPanelController.create();

      controller.setCharityOrganization(interaction.input.CharityOrganization);
   }).fail(function() {
      console.log("Failed to bind Interaction object.");
   });
});

The interaction.bind() methode is using the Deferred pattern as it is performing an asynchronous callback to Stardust.

The result is an embedded UI component, which is initialized by Process Data:

Stardust-Reference-Project-UI-Mashup-Portal.gif

Note, that for the Angular-based implementation we use an Adapter class which allows us to write Angular Controllers in an "object-oriented" style. This way the Controller looks very simple and totally independent of the Stardust integration

function OrganizationRegistrationReviewPanelController() {
   this.approval = false;
   this.suspendListeners = [];
   this.completeListeners = [];

   OrganizationRegistrationReviewPanelController.prototype.setCharityOrganization = function(charityOrganization) {
      this.charityOrganization = charityOrganization;
   };

   OrganizationRegistrationReviewPanelController.prototype.complete = function() {
      for ( var n = 0; n < this.completeListeners.length; ++n) {
         this.completeListeners[n](this);
      }
   };

   OrganizationRegistrationReviewPanelController.prototype.suspend = function() {
      for ( var n = 0; n < this.suspendListeners.length; ++n) {
         this.suspendListeners[n](this);
      }
   };
}

and the Main function would just be used to wire-up Stardust Interaction and Controller in the

jQuery(document).ready(function() {
   var angularAdapter = new bpm.portal.AngularAdapter();

   angularAdapter.initialize(angular);

   var interaction = new bpm.portal.Interaction();

   interaction.bind().done(function() {
      var controller = angularAdapter.mergeControllerWithScope(OrganizationRegistrationReviewPanelController.create());

      // Wire-up Controller and Interaction
													
      controller.setCharityOrganization(interaction.input.CharityOrganization);
      controller.updateView(); // Just calling the Angular $apply function
      controller.completeListeners.push(function(){
         interaction.output.CharityOrganization = controller.charityOrganization;
         interaction.output.Approval = controller.approval;
         interaction.complete();
      });
      controller.suspendListeners.push(function(){
         interaction.output.loanPlan = controller.loanPlan;													
         interaction.suspend();
      });
   }).fail(function() {
      console.log("Failed to bind Interaction object.");
   });
});

Back to the top