胡长城(银狐999)BLOG

工作流,BPM,SOA,Java,J2EE、Flex;个人主页http://www.javafox.org;普元BPS业务流程平台

原创 Bossa研究总结(之一)收藏

 

Bossa研究总结

 

胡长城(银狐999)

2004-10-10

 

Bossa主站点:http://www.bigbross.com/bossa/

      

       Bossa与其说是一个workflow engine,不如说是一个Petri Net Engine。其完全采用Petri NetNotation,定义语言也是采用WFNet PNMLWFNet是其的Net Type)。

       其可以采用PNK进行模型定义,但是需要使用WFNetPNK支持配置文件,这个Bossa提供了,但是很遗憾的是,总是造成PNK的错误,可能与文件格式和编码有关系,这个后来因为时间问题,没有继续查找具体原因

 

       Bossa的帮助文档非常匮乏,即使其网站上提供的how toapi文档,也仅仅只是泛泛介绍。甚至没有一个如何正确运行其所提供了example的说明。

 

       Bossa支持的是Color Petri Net。这一点是由Case对象的attribute属性体现

 

Bossa的基本对象元素:

       这些主要对象元素,放在 com.bigbross.bossa.wfnet 包中。

       包括:CaseTypeCasePlaceTransitionEdgeActivityWorkitem

 

 

 

CaseType

流程定义对象

Case

流程的实例

Place

对应于Petri Net中的元素 place

Transition

对应于Petri Net中的元素 transition

Edge

对应于Petri NetArc(有向弧)

Workitem

代表了一个Transtionfiring

This class represents a transition of a specific case instancea work item is a likely fireable transition

Activity

当打开一个workitem的时候就获取一个Activiy对象

This class represents an open (firing) work item

 

 

Bossatoken解决

       Petri Net允许从一个placetransition有几个arc,来表示允许几个token

       Bossa为了解决这个问题,引入了weight这个方式。而且允许这个weight是一个javascripte计算表达式(运行期间,解析表达式,返回的值就是token的个数)。

       但注意,weight本身并不是以属性存在于这些对象中,而是以方法。

 

        List edges = activity.getTransition().getOutputEdges();

        for (Iterator i = edges.iterator(); i.hasNext(); ) {

            Edge e = (Edge) i.next();

            /* An EvaluationException can be inconsistently thrown here. */

            int tokenNumber = e.output(this);

            this.marking[e.getPlace().getIndex()] += tokenNumber;

            eventQueue.newPlaceEvent(getBossa(), WFNetEvents.ID_ADD_TOKENS,

                                     this, e.getPlace(), tokenNumber);

        }

 

 

BossaResouce

       Bossa中,ResouceTaskTransition)的执行者,但是其不是简单的实user的集合,在定义的时候,其表示的是一个“表达式”,而运行中,才会转换为相应得user list

       比如“sales - $a”,代表的就是,这个Task的执行者是“sales用户组中的用户 减去 a任务(Task,Transition)的执行者”。

       注意,这个“表达式”,不是script的了,而是bossa自己的规则表达式。

 

       但是,具体这个Resouce如何解析、运行。并没有深入

 

Bossa的引擎

       Bossa的引擎类com.bigbross.bossa.Bossa.

       其是通过BossaFactory创建的

 

BossaWorkitem

       注意,我们通常所理解的workitem概念,在Bossa中是不一样的。

       在一个CaseType,如果存在多少个Transition,则在一个Case实例中,则存在多少个Workitem。其workitem表示的代表一个transitionfirable状态。

 

Collection ts = caseType.getTransitions();

workItems = new HashMap(ts.size());

for (i = ts.iterator(); i.hasNext(); ) {

Transition t = (Transition) i.next();

workItems.put(t.getId(), new WorkItem(this, t, isFireable(t)));

}

 

       这个是在Case实例初始化的时候构造workitems列表,只是其中一些workitemfireable的,一些不是。

       每一次close activity之后,会更改workitemfirable状态(主要是调用其update方法)。    

 

BossaEventQueqe

       com.bigbross.bossa.notify 包提供了一种事件监听、通知的机制。

      

       Listener

       Event

       NotificationBus 就是一个support类。

       NotificationQueue 表示的是一个“处理队列”类,提供记录了一些需要处理的Event可能。

 

WFNetEvents extends NotificationQueue)则记录了所有有关 WFNetevent事件ID,以及调用这些事件的方法。每调用一个时间处理方法,如下所示

 

    void newCaseEvent(Bossa bossa, String notificationId, Case caze) {

        if (bossa != null) {

            Map attrib = new HashMap();

            attrib.put(ATTRIB_CASE_ID, Integer.toString(caze.getId()));

            attrib.put(ATTRIB_CASE_TYPE_ID, caze.getCaseType().getId());

            addEvent(new Event(notificationId, Event.WFNET_EVENT, attrib,

                               bossa.getTimeSource().getTime()));

        }

    }

 

可以看出来,其是将一个event注入到NotificationQueue 所提供的queue列表中。

 

那么是如何执行的呢?

        WFNetEvents queue = new WFNetEvents();

        queue.newCaseEvent(getBossa(), WFNetEvents.ID_OPEN_CASE, caze);

        queue.notifyAll(getBossa());

 

其最后调用notifyAll方法,来进行处理。

    public void notifyAll(Bossa bossa) {

        if (bossa != null) {

            NotificationBus bus = bossa.getNotificationBus();

            for (Iterator i = queue.iterator(); i.hasNext(); ){

                Event e = (Event) i.next();

                bus.notifyEvent(e);

                i.remove();         }        }    }

 

到这一步,就可以很清晰的明白了吧:

       整个内部还是一个“事件监听”,但是在这个事件监听外围,封装了一层“事件处理队列”。

 

发表于 @ 2004年10月10日 14:09:00|评论(loading...)

新一篇: YAWL的gui控制端 | 旧一篇: Bossa支持PNML

Csdn Blog version 3.1a
Copyright © 银狐999