Client interface

How to use Shark library

Client application uses Shark library through a set of interfaces in org.enhydra.shark.api.client package. The first thing the application should do is to configure library either by calling configure() method by specifying filename (as String or File object) or by preparing and calling the method with a Properties object. After configuration org.enhydra.shark.Shark.getInstance() returns an instance of SharkInterface. From this point on, it's application developer preference (or task) how it would use library, either getting a connection and executing assignments or getting some of the administrative interfaces (PackageAdministration, ExecutionAdministration, AdminMisc, ...) and managing packages, process instances, ...

Example 1. Not very useful work-list handler

First line of this example configures engine using conf/Shark.conf file. Then after getting a connection and successfully connecting it asks Resource object how many assignments there are for this user (in line 4).

      UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");  
      ut.begin();    
      Shark.configure("c:/Shark/conf/Shark.conf");
      ut.commit();

      ut.begin();    
      WMConnectInfo wmci=new WMConnectInfo("test", "", "", "");      
      SharkConnection sConn = Shark.getInstance().getSharkConnection();
      sConn.connect(wmci);
      if (0 < sConn.getResourceObject().how_many_work_item()) {
          System.err.println("Oh, let these tasks wait until tomorrow!");
      }
      ut.commit();

      System.out.println("Job done!");

NOTE: Shark 2.0 is JTA oriented, and thus when shark works outside container which provides JTA TransactionManager, we have to start one by our own. Also, in shark 2.0 for defining database we work with, we use DataSource which should be registered in JNDI, and thus when working outside container we also need to take care about registering data source in JNDI. For the purpose of stand-alone shark usage we made LocalContextFactory which is implementation of InitialContextFactory interface, and which purpose is to: 1. start TransactionManager 2. provide a JNDI context - register TransactionManager in JNDI context (so we can afterwards obtain TransactionManager and UserTransaction from JNDI) - register DataSource in JNDI context So, when using shark outside container before executing code above, you need to call setup method on LocalContextFactory class (read shark.pdf document to see how to start shark).

Example 2. Loading package into Shark library

First you need the location of the package's XPDL file, then you need a PackageAdministation instance.

      UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");  
      ut.begin();    
      Shark.configure("c:/Shark/conf/Shark.conf");
      ut.commit();

      ut.begin();
      WMConnectInfo wmci=new WMConnectInfo("test", "", "", "");
      SharkConnection sc = Shark.getInstance().getSharkConnection();
      sc.connect(wmci);
      WMSessionHandle sh=sc.getSessionHandle();
      ut.commit();

      String xpdlName = "c:/test.xpdl";

      ut.begin();
      PackageAdministration pa = Shark.getInstance().getPackageAdministration();
      if (!pa.isPackageOpened(sh,pkgId)) {
         pa.openPackage(sh,xpdlName);
      }
      ut.commit();
      System.out.println("Package " + xpdlName + " is loaded");

Example 3. Creating and starting process

After loading XPDL into shark, lets create, fill with initial variable values, and start some processes based on their XPDL definitions.

      String pkgId = "test";
      String pDefId1 = "basic";
      String pDefId2 = "complex";

      UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");  
      ut.begin();    
      Shark.configure("c:/Shark/conf/Shark.conf");
      ut.commit();

      ut.begin();
      WMConnectInfo wmci=new WMConnectInfo("test", "", "", "");
      SharkConnection sc = Shark.getInstance().getSharkConnection();
      sc.connect(wmci);
      ut.commit();

      ut.begin();
      XPDLBrowser xpdlb = Shark.getInstance().getXPDLBrowser();
      String procDefName = xpdlb.getUniqueProcessDefinitionName(sc.getSessionHandle(),
                                                              pkgId,
                                                              "",
                                                              pDefId);
      WfProcessMgr mgr = sc.getProcessMgr(procDefName);
      ut.commit();

      ut.begin();
      WfProcess proc1 = mgr.create_process(null);
      Map m1 = new HashMap();
      m1.put("test_var",
            "This is String variable defined in XPDL for the process basic");
      proc1.set_process_context(m1);
      proc1.start();
      ut.commit();
      
      ut.begin();
      WfProcess proc2 = mgr.create_process(null);
      Map m2 = new HashMap();
      m2.put("counter", new Long(55));
      proc2.set_process_context(m2);
      proc2.start();
      ut.commit();

Example 4. Setting a variable

After successfully connecting to Shark, and acquiring list of assignments, lets do something useful, like setting a variable and completing the activity.

      /*
      SharkConnection sConn;
      String activityId;
      String vName;
      String vValue;
       */
      WfAssignment a = null;
      ut.begin();
      String uname=sc.getResourceObject().resource_key();
      WfAssignment[] ar = sc.getResourceObject().get_sequence_work_item(0);
      for (int i = 0; i < ar.length; ++i) {
         if (activityId.equals(ar[i].activity().key())) {
            a = ar[i];
            break;
         }
      }
      ut.commit();
      
      if (null == a)
         throw new Exception("Activity:"
                                 + activityId
                                 +" not found in "
                                 + uname
                                 +"'s worklist");
      
      ut.begin();
      boolean as=a.get_accepted_status();      
      if (!as) {
         a.set_accepted_status(true);
      }
      ut.commit();

      
      ut.begin();
      Map _m = new HashMap();
      WfActivity activity = a.activity();
      Object c = activity.process_context().get(vName);
      if (c instanceof Long) {
         c = new Long(vValue);
      } else {
         c = vValue;
      }
      _m.put(vName, c);
      activity.set_result(_m);
      activity.complete();      
      ut.commit();

Example 5. Getting process managers based on some criteria

This example shows how to get process managers based on some criteria. It'll try to get all process managers which package Id is "test", and which state is enabled.

      UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");  
      ut.begin();    
      Shark.configure("c:/Shark/conf/Shark.conf");
      ut.commit();

      ut.begin();
      WMConnectInfo wmci=new WMConnectInfo("user", "secret", "", "");
      SharkConnection sc = Shark.getInstance().getSharkConnection();
      sc.connect(wmci);
      ut.commit();

      ut.begin();
      WfProcessMgrIterator pmi = eAdmin.get_iterator_processmgr();
      String query = "packageId.equals(\"test\") && enabled.booleanValue()";
      pmi.set_query_expression(query);
      WfProcessMgr[] procs = pmi.get_next_n_sequence(0);
      ut.commit();

Another approach is to use so called Filter builders to create expression that will be (in this case) executed directly on DB:

      UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");  
      ut.begin();    
      Shark.configure("c:/Shark/conf/Shark.conf");
      ut.commit();

      ut.begin();
      WMConnectInfo wmci=new WMConnectInfo("user", "secret", "", "");
      SharkConnection sc = Shark.getInstance().getSharkConnection();
      sc.connect(wmci);
      WMSessionHandle shandle=sc.getSessionHandle();
      ut.commit();
      
      ut.begin();
      WfProcessMgrIterator pmi = sc.get_iterator_processmgr();
      ProcessMgrFilterBuilder fb=Shark.getInstance().getProcessMgrFilterBuilder();
      WMFilter f=fb.addPackageIdEquals(shandle, "test");
      WMFilter f2=fb.addIsEnabled(shandle);
      f=fb.and(shandle, f, f2);
      
      String query = fb.toIteratorExpression(shandle, f);
      pmi.set_query_expression(query);
      WfProcessMgr[] procs = pmi.get_next_n_sequence(0);
      ut.commit();

Example 6. Getting processes based on some criteria

This example shows how to get processes created by some process manager based on some criteria. It'll try to get all processes which state is "open.running", which are started in last 10 minutes, which have more than 3 active activities, and which String variable called "myvariable" has value "test".

      /*
      WfProcessMgr mgr;
      WMSessionHandle shandle;
       */
      ut.begin();
      WfProcessIterator wpi = mgr.get_iterator_process();
      String query = "state.equals(\"open.running\") && "
                     + "startTime.longValue()>(java.lang.System.currentTimeMillis()-10*60*1000) && "
                     + "activeActivitiesNo.longValue()>3 && "
                     + "context_myvariable.equals(\"test\")";
      wpi.set_query_expression(query);
      WfProcess[] procs = wpi.get_next_n_sequence(0);
      ut.commit();

Another approach is to use so called Filter builders to create expression:

      /*
      SharkConnection sc;
      WMSessionHandle shandle;
       */
      ut.begin();
      WfProcessIterator wpi = sc.get_iterator_process();
      
      ProcessFilterBuilder fb=Shark.getInstance().getProcessFilterBuilder();
      WMFilter f=fb.addStateEquals(shandle, "open.running");
      WMFilter f2=fb.addStartTimeAfter(shandle,(java.lang.System.currentTimeMillis()-10*60*1000));
      WMFilter f3=fb.addActiveActivitiesCountGreaterThan(shandle, 3);
      WMFilter f4=fb.addVariableEquals(shandle, "myvariable", "test");
      f=fb.and(shandle, new WMFilter[] {f, f2, f3, f4});
      
      String query = fb.toIteratorExpression(shandle, f);
      wpi.set_query_expression(query);
      WfProcess[] procs = wpi.get_next_n_sequence(0);
      ut.commit();