cancel
Showing results for 
Search instead for 
Did you mean: 

activiti-exploer process instance highlight diagram is incorrent

long_187
Champ in-the-making
Champ in-the-making


activiti-exploer process instance highlight diagram is incorrent

see attachment "Activiti incorrent diagram highlight.png"
My historicActivityInstances are A -> exclusiveGateway -> B -> C -> D, but flow between exclusiveGateway and D is also highted.

And if have SignalBoundaryEvent on UserTask, the outgoing flow of SignalBoundaryEvent never be highlighted.

[img]https://jira.codehaus.org/secure/attachment/63590/Activiti%20incorrent%20diagram%20highlight.png[/img]
5 REPLIES 5

long_187
Champ in-the-making
Champ in-the-making
If the process instance was started by a callActivity, it will be not have the startEvent activity in ACT_HI_ACTINST table, then ,the outgoing flow of startevent will not highlighted.

jbarrez
Star Contributor
Star Contributor
Could you create a patch for this (or pull request on github) so we can review it there and easily merge it?

long_187
Champ in-the-making
Champ in-the-making
I have pulled a request on github #129

long_187
Champ in-the-making
Champ in-the-making
I was resoved this issue. pls review my code.

Method: org.activiti.diagram.rest.services.ProcessInstanceHighlightsResource.getHighLightedFlows

        /**
  * 新版本的getHighLightedFlows方法
  *
  * @param processDefinition
  * @param processInstanceId
  * @return
  */
private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
    
     List<String> highLightedFlows = new ArrayList<String>();
    
     List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
             .processInstanceId(processInstanceId)
             //用开始时间升序不准确,直接默认按id升序排是准确的
             //.orderByHistoricActivityInstanceStartTime().asc()/*.orderByActivityId().asc()*/
             .list();
       
     LinkedList<HistoricActivityInstance> hisActInstList = new LinkedList<HistoricActivityInstance>();
        hisActInstList.addAll(historicActivityInstances);
       
        getHighlightedFlows(processDefinition.getActivities(), hisActInstList, highLightedFlows);
    
     return highLightedFlows;
}

/**
  * getHighlightedFlows
  *
  *
  * @param activityList
  * @param hisActInstList
  * @param highLightedFlows
  */
private void getHighlightedFlows(List<ActivityImpl> activityList, LinkedList<HistoricActivityInstance> hisActInstList, List<String> highLightedFlows){
    
     //Activity定义中的startEvent活动
     List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
        Map<String, ActivityImpl> activityMap = new HashMap<String, ActivityImpl>(activityList.size());
        for(ActivityImpl activity : activityList){
           
            activityMap.put(activity.getId(), activity);
           
            String actType = (String)activity.getProperty("type");
            if(actType!=null && actType.toLowerCase().indexOf("startevent")>=0){
                startEventActList.add(activity);
            }
        }
    
        //检查第一个节点是否是startEvent(如果流程是由别的callActivity节启动的则没有startEvent),
        //如果不是startEvent节点则要找出startEvent的高亮flow
        HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
        String firstActType = (String)firstHistActInst.getActivityType();
        if(firstActType!=null && firstActType.toLowerCase().indexOf("startevent")<0){
            PvmTransition startTrans = getStartTransaction(startEventActList, firstHistActInst);
            if(startTrans!=null){
                highLightedFlows.add(startTrans.getId());
            }
        }
       
     while(hisActInstList.size()>0){
         HistoricActivityInstance histActInst = hisActInstList.removeFirst();
         ActivityImpl activity = activityMap.get(histActInst.getActivityId());
        
         boolean isParallel = false;
         String type = histActInst.getActivityType();
         if("parallelGateway".equals(type) || "inclusiveGateway".equals(type)){
             isParallel = true;
            }
         else if("subProcess".equals(histActInst.getActivityType())){
             getHighlightedFlows(activity.getActivities(), hisActInstList, highLightedFlows);
         }
        
         List<PvmTransition> outgoingTrans = new ArrayList<PvmTransition>();
                outgoingTrans.addAll(activity.getOutgoingTransitions());
         outgoingTrans.addAll(getBoundaryEventOutgoingTransitions(activity));
        
         List<String> activityHighLightedFlowIds = getHighlightedFlows(outgoingTrans, hisActInstList, isParallel);
                 
         highLightedFlows.addAll(activityHighLightedFlowIds);
     }
    
}

/**
  * 查找startEventActList列表中,谁的outgoing flow连接的是firstActInst
  * @param startEventActList
  * @param firstActInst
  * @return
  */
private PvmTransition getStartTransaction(List<ActivityImpl> startEventActList, HistoricActivityInstance firstActInst){
     for(ActivityImpl startEventAct: startEventActList){
         for(PvmTransition trans : startEventAct.getOutgoingTransitions()){
             if(trans.getDestination().getId().equals(firstActInst.getActivityId())){
                 return trans;
             }
         }
     }
     return null;
}

/**
  *
  * @param activity
  * @return
  */
private List<PvmTransition> getBoundaryEventOutgoingTransitions(ActivityImpl activity){
     List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
     for(ActivityImpl subActivity : activity.getActivities()){
         String type = (String)subActivity.getProperty("type");
         if(type!=null && type.toLowerCase().indexOf("boundary")>=0){
             boundaryTrans.addAll(subActivity.getOutgoingTransitions());
         }
     }
     return boundaryTrans;
}

/**
  * 获取单个activity的高亮flow
  *
  * @param activity
  * @param hisActInstList
  * @param isExclusive 是否只有单一的outgoing(比如说exclusiveGateway, Task上的BoundaryEvent)
  * @return
  */
private List<String> getHighlightedFlows(List<PvmTransition> pvmTransitionList, LinkedList<HistoricActivityInstance> hisActInstList, boolean isParallel){
    
     List<String> highLightedFlowIds = new ArrayList<String>();
    
        PvmTransition earliestTrans = null;
        HistoricActivityInstance earliestHisActInst = null;
       
        for (PvmTransition pvmTransition : pvmTransitionList) {
                           
            String destActId = pvmTransition.getDestination().getId();
            HistoricActivityInstance destHisActInst = findHisActInst(hisActInstList, destActId);
            if(destHisActInst!=null){
               
                if(isParallel){
                    highLightedFlowIds.add(pvmTransition.getId());
                }
                else{
                    if(earliestHisActInst==null || (earliestHisActInst.getId().compareTo(destHisActInst.getId())>0)){//用开始时间比较不准确,直接默认按id比较是准确的
                        earliestTrans = pvmTransition;
                        earliestHisActInst = destHisActInst;
                    }
                }
            }
        }
       
        if((!isParallel) && earliestTrans!=null){
            highLightedFlowIds.add(earliestTrans.getId());
        }
       
        return highLightedFlowIds;
}

private HistoricActivityInstance findHisActInst(LinkedList<HistoricActivityInstance> hisActInstList, String actId){
     for(HistoricActivityInstance hisActInst : hisActInstList){
         if(hisActInst.getActivityId().equals(actId)){
             return hisActInst;
         }
     }
     return null;
}

long_187
Champ in-the-making
Champ in-the-making
OK, I'll do