熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

判斷流程開始節點是否能連通到結束節點

2013-11-23 18:50:36  來源: Java核心技術 

  在流程管理中有用戶自定義流程的需求就是用戶自己建立流程節點並指定流程節點的走向
   
    因為是用戶自己操作所以需要對用戶建立的流程的連通性進行判斷從開始節點經過若干審核節點的流轉後是否最終能到達結束節點
   
    一個流程必須有一個開始節點一個結束節點和若干審核節點
   
    例如用戶建立的節點如下

  

  然後用戶指定節點的流向

  )正確的節點流向

  

  以上這些都是正確的節點流向所謂正確就是開始節點經過若干審核節點的流轉可以最終連通到結束節點

  )不正確的節點流向 

  

  以上這些都是不正確定的節點流向

  所以必須檢查用戶指定的流向是否能從開始節點經過若干審核節點連通到結束節點


  )建立兩個表一個節點表和一個流向表

  

  )對應的實體
   
    節點Node:
   
    /** * 節點 * @author Luxh * */@Entity@Table(name=t_node)public class Node {
   
    @Id
   
    @GeneratedValue
   
    private Integer id;
   
    //節點名稱
   
    private String name;
   
    //節點標記START開始節點AUDIT審核節點END結束節點
   
    private String flag;
   
    //一個檢查標記位在遞歸是設置避免死循環
   
    Y已檢查
   
    private String checkStatus;}
   
    流向Flow:
   
    /** * 流向 * @author Luxh * */@Entity@Table(name=t_flow)public class Flow {
   
    @Id
   
    @GeneratedValue
   
    private Integer id;
   


    //開始編號
   
    private Integer beginNo;
   
    //指向編號
   
    private Integer endNo;
   
    )遞歸判斷方法
   
    /** * 節點檢查測試 * @author Luxh * */public class NodeTest {
   
    EntityManagerFactory emf = null;
   
    @Before
   
    public void before() {
   
    //根據在persistencexml中配置的persistenceunit name 創建EntityManagerFactory
   
    emf = PersistencecreateEntityManagerFactory(myJPA
   
    }
   
    @After
   
    public void after() {
   
    if(null != emf) {
   
    emfclose()
   
    }
   
    }
   
    /**
   
    * 添加節點數據
   
    */
   
    @Test
   
    public void testAddNode(){
   
    EntityManager em = emfcreateEntityManager()
   
    emgetTransaction()begin()
   
    Node n = new Node()
   
    nsetName(開始節點
   
    nsetFlag(START
   
    Node n = new Node()
   
    nsetName(節點
   
    nsetFlag(AUDIT
   
    Node n = new Node()
   
    nsetName(節點
   
    nsetFlag(AUDIT
   
    Node n = new Node()
   
    nsetName(節點
   
    nsetFlag(AUDIT
   
    Node n = new Node()
   
    nsetName(結束節點
   
    nsetFlag(END
   
    empersist(n
   
    empersist(n
   
    empersist(n
   
    empersist(n
   
    empersist(n
   
    emgetTransaction()commit()
   
    emclose()
   
    }
   
    /**
   
    * 添加節點流向數據
   
    */
   
    @Test
   
    public void testAddFlow(){
   
    EntityManager em = emfcreateEntityManager()
   
    emgetTransaction()begin()
   
    Flow f = new Flow()
   
    fsetBeginNo(
   
    fsetEndNo(
   
    Flow f = new Flow()
   
    fsetBeginNo(
   
    fsetEndNo(
   
    Flow f = new Flow()
   
    fsetBeginNo(
   
    fsetEndNo(
   
    Flow f = new Flow()
   
    fsetBeginNo(
   
    fsetEndNo(
   
    Flow f = new Flow()
   
    fsetBeginNo(
   
    fsetEndNo(
   
    empersist(f
   
    empersist(f
   
    empersist(f
   
    empersist(f
   
    empersist(f
   
    empersist(f
   
    emgetTransaction()commit()
   
    emclose()
   
    }
   
    /**
   


    * 測試
   
    */
   
    @Test
   
    public void testIsStartCanEnd() {
   
    //獲取JPA實體管理器
   
    EntityManager em = emfcreateEntityManager()
   
    //流程開始節點的編號
   
    Integer beginNo = ;
   
    List<String> flagList = new ArrayList<String>()
   
    //因為可能會多次檢查開始節點是否可以連通結束節點
   
    //所以在調用遞歸檢查方法前一定要清空當前流程所有節點的標記位
   
    //實際中節點表肯定會有一個字段表示所屬流程根據該字段清空當前流程的所有節點的標記位
   
    //調用清空標記位方法
   
    //…
   
    //首次調用時一定是傳入開始節點的編號
   
    isStartCanEnd(beginNoflagListem)
   
    if(ntains(END)) {
   
    Systemoutprintln(開始節點可以連通結束節點
   
    }else {
   
    Systemoutprintln(開始節點無法連通結束節點
   
    }
   
    emclose()
   
    }
   
    /**
   
    * 遞歸判斷 開始節點是否可以連通到結束節點
   
    * @param beginNo 開始編號
   
    * @param flagList 存放結束節點標記遞歸結束後如果flagList中有結束標記說明開始節點可以連通到結束節點
   
    * @param em
   
    JPA的實體管理器類似以hibernate的session
   
    */
   
    public void isStartCanEnd(Integer beginNoList<String> flagListEntityManager em) {
   
    //根據開始編號查詢出該開始編號的所有指向的節點的編號
   
    String jpql = select f from Flow f where fbeginNo = ?;
   
    List<Flow> flows = emcreateQuery(jpql)setParameter( beginNo)getResultList()
   
    if(flows != null && flowssize()>) {
   
    //遍歷開始編號所指向的所有流向
   
    for(Flow f : flows) {
   
    //根據編號找出節點
   
    Node n = emfind(Nodeclass fgetEndNo())
   
    //如果是結束節點就中斷循環
   
    if(ENDequals(ngetFlag())) {
   
    flagListadd(ngetFlag())//將結束節點的標記存放到flagList中
   
    break;
   
    }else if(STARTequals(ngetFlag())||Yequals(ngetCheckStatus())) {
   
    //如果是開始節點或者節點的標記位Y說明該節點已被查找過跳過避免遞歸時死循環
   
    continue;
   
    }else {
   
    emgetTransaction()begin()
   
    nsetCheckStatus(Y//設置節點的標記位
   
    rge(n)
   
    emgetTransaction()commit()
   
    //如果是審核節點則遞歸查找結束節點
   
    isStartCanEnd(ngetId()flagListem)
   
    }
   
    }
   
    }
   
    }
   
    }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25836.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.