浣滆咃細(xì) JeffreyHsu
灝界jbpm闈炲父寮哄ぇ錛屾槸鐩墠鏈閫傚悎鍟嗕笟鍖栫殑寮婧愬伐浣滄祦寮曟搸錛屽彲浠ュ紑鍙戝嚭澶嶆潅鐨勬祦紼嬶紝浣嗘槸鐗瑰埆閬楁喚鐨勬槸騫朵笉鏀寔騫跺彂瀛愭祦紼嬶紙multiple-subprocess錛?
鏈変竴嬈℃垜闇瑕佸仛涓涓鏉傜殑嫻佺▼錛屼富嫻佺▼閲岃姹傚悓鏃跺惎鍔ㄥ涓茍鍙戞墽琛岀殑瀛愭祦紼嬶紝騫朵笖瀛愭祦紼嬬殑鏁扮洰鍜屽惎鍔ㄧ殑鏃墮棿閮戒笉紜畾錛屽綋鎵鏈夊瓙嫻佺▼閮界粨鏉熶互鍚庯紝涓繪祦紼嬫墠緇х畫鎵ц銆傛垜浠煡閬搄bpm閲屾湁瀛愭祦紼嬬殑璁懼畾錛屾湁涓撻棬鐨勮妭鐐筆rocessState鏉ュ鐞嗭紝浣嗘槸鍚庢潵鍙戠幇鏃犺濡備綍涔熷疄鐜頒笉浜嗗瀛愭祦紼嬪茍鍙戞墽琛岋紝鍚庢潵鐪嬪叾婧愮爜鐭ラ亾鍥犱負(fù)subprocess鏄綔涓篜rocessState鐨勪竴涓睘鎬э紝涔熷氨鏄ProcessState鍙兘鍖呭惈涓涓猻ubprocess鐨勫畾涔夛紝騫朵笖鏈閲嶈鐨勬槸processInstance.getRootToken()鍜屽瓙嫻佺▼鐩稿叧鐨勫彧鏈塩reateSubProcessInstance, getSubProcessInstance, setSubProcessInstance涓変釜鏂規(guī)硶錛岃繖鎰忓懗鐫涓繪祦紼嬬殑rootToken鍙兘璁劇疆涓涓瓙嫻佺▼錛宩bpm騫朵笉鐩存帴鏀寔澶氬瓙嫻佺▼銆?
閭d箞鎴戜滑灝卞繀欏葷敤涓涓彉閫氱殑鏂規(guī)硶鏉ュ疄鐜幫紝“騫跺彂”寰堣嚜鐒剁殑璁╂垜浠兂鍒頒簡fork錛屼絾鏄繖閲岀殑fork涓嶈兘鎼厤join鏉ヤ嬌鐢紝鍏蜂綋鍘熷洜錛屽皢鍦ㄥ悗闈㈣璁恒?
涓嬮潰鍏堢粰鍑烘祦紼嬪浘錛?

state鑺傜偣鐢ㄦ潵鍚姩瀛愭祦紼嬶紙瀹為檯搴旂敤鍙互鎹㈡垚Task-Node錛夛紝state榪涘叆fork鍚庡悓鏃惰繘鍏ヤ袱涓垎鏀紝涓鏉″幓鍚姩瀛愭祦紼嬶紝鍙︿竴鏉″洖鍒拌嚜宸憋紝榪欐牱琛ㄩ潰鐪嬫潵state娌℃湁鍔紝鑰屽悓鏃朵綘鍙堝彲浠ュ惎鍔ㄧ2涓紝絎?涓?#8230;…瀛愭祦紼嬶紝闇瑕佹敞鎰忕殑鏄2鏉″瓙嫻佺▼鍜岀1涓瓙嫻佺▼騫朵笉澶勪簬鍚屼竴綰т笂錛岃屾瘮絎竴涓瓙嫻佺▼浣庝竴綰э紝鍏蜂綋璇風(fēng)湅鍚庨潰涓寮犲浘灝辨槑鐧戒簡錛屽垎瑙e悗鐨勶細(xì)

浠庡浘涓垜浠彲浠ョ湅鍒板悗涓涓瓙嫻佺▼鐨勬暣媯墊爲(wèi)鏄墠涓涓瓙嫻佺▼鐨勫厔寮燂紝浣嗘槸鍦ㄤ笟鍔$駭涓婃槸騫跺彂鐨勬晥鏋滐紝宸茬粡瀹炵幇鎴戜滑鍓嶉潰鐨勯渶姹傘?/font>
鐜板湪鏉ヨ璇翠負(fù)浠涔堜笉鑳界敤join鑰岀洿鎺ョ敤end錛屽洜涓轟細(xì)浜х敓涓涓棶棰橈紝state3鍜宻ub process 2閮藉埌杈句簡join浠ュ悗錛宻tate2涓嬮潰鐨刦ork灝辯粨鏉熶簡錛屽氨浼?xì)绔嬪埢瓒姌q噅oin鍒拌揪end錛岃宻ub process 1鍗充嬌鎵ц瀹屾瘯鍒拌揪浜唈oin鍗翠粛鐒跺湪鍌誨偦絳夊緟鐫浠栫殑鍏勫紵鍒嗘敮涔熷埌杈緅oin錛堣屽疄闄呬笂瀹冨凡緇忚嚜璺戝埌end鍘諱簡錛変竴鍚岀粨鏉燂紝榪欐牱sub process 1灝變細(xì)姘歌繙鍋滃湪join鍔ㄥ脊涓嶅緱錛屼笟鍔℃棤娉曡繘琛屻?/font>
榪欐槸鎴戠殑涓涓В鍐蟲柟妗堬紝浣嗚繕鏈変竴涓棶棰橈紝铏界劧鍏ㄩ儴鐨勫瓙嫻佺▼閮借兘緇撴潫錛屼富嫻佺▼涔熻兘緇撴潫錛屼絾鍥犱負(fù)娌℃湁join錛屼富嫻佺▼鐨剅ootToken浠嶇劧鍋滅暀鍦╢ork鑺傜偣涓娿傜洰鍓嶆垜灝氫笉鐭ュ浣曡В鍐籌紝甯屾湜鍚勪綅澶у鑳芥彁鍑哄叾浠栨洿濂界殑瑙e喅鍔炴硶銆?
鍒濆jbpm錛屾按騫蟲湁闄愶紝鏈変笉褰撲箣澶勮繕璇烽珮鎵嬫枾姝?/font>
鏈鍚庨檮涓奷emo浠g爜渚涘弬鑰冿細(xì)
浠g爜
-
- import static org.junit.Assert.*;
-
- import org.jbpm.graph.def.ProcessDefinition;
- import org.jbpm.graph.exe.ProcessInstance;
- import org.jbpm.graph.exe.Token;
- import org.jbpm.graph.node.ProcessState;
- import org.junit.Before;
- import org.junit.Test;
-
- public class MultiProcessTest {
- private ProcessDefinition superProcessDefinition;
-
- private ProcessDefinition subProcessDefinition;
-
- @Before
- public void setUp() throws Exception {
- superProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='super'>" +
- " <start-state name='start'>" +
- " <transition to='state' />" +
- " start-state>" +
- " <state name='state'>" +
- " <transition name='create sub' to='fork' />" +
- " <transition name='end' to='end' />" +
- " state>" +
- " <fork name='fork'>" +
- " <transition name='back' to='state' />" +
- " <transition name='go to sub' to='sub process' />" +
- " fork>" +
- " <process-state name='sub process'>" +
- " <sub-process name='sub' />" +
- " <transition to='end' />" +
- " process-state>" +
- " <end-state name='end' />" +
- "process-definition>");
-
- subProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='sub'>" +
- " <start-state name='start'>" +
- " <transition to='wait' />" +
- " start-state>" +
- " <state name='wait'>" +
- " <transition to='end' />" +
- " state>" +
- " <end-state name='end' />" +
- "process-definition>");
- ProcessState processState = (ProcessState) superProcessDefinition
- .getNode("sub process");
- processState.setSubProcessDefinition(subProcessDefinition);
- }
-
- @Test
- public void testMultiProcesses() {
- ProcessInstance pi = new ProcessInstance(superProcessDefinition);
-
- // 鍚姩涓涓富嫻佺▼
- pi.signal();
- assertEquals("state", pi.getRootToken().getNode().getName());
-
- // 榪涘叆鍒嗘敮錛屾澶勫皢榪涘叆瀛愭祦紼?
- pi.signal("create sub");
- // 涓繪祦紼媡oken灝嗗仠鐣欏湪fork鑺傜偣涓?
- assertEquals("fork", pi.getRootToken().getNode().getName());
-
- // fork鍒嗕負(fù)涓ゆ敮錛屽叾涓竴鏀殑鑺傜偣鍋滅暀鍦≒rocessState涓?
- Token subProcessToken1 = pi.getRootToken().getChild("go to sub");
- ProcessInstance subPi1 = subProcessToken1.getSubProcessInstance();
- assertEquals("wait", subPi1.getRootToken().getNode().getName());
-
- // 鍙︿竴鏀繑鍥炰簡state鑺傜偣錛屽疄闄呬笂騫舵病鏈夎繑鍥烇紝榪欎釜state鑺傜偣涓嶅悓浜庡厛鍓嶇殑state錛屽畠浠茍涓嶅湪鍚屼竴涓猵ath涓?
- Token stateToken1 = pi.getRootToken().getChild("back");
- assertEquals("state", stateToken1.getNode().getName());
-
- // 鍐嶆榪涘叆fork錛屽惎鍔ㄧ浜屼釜瀛愭祦紼?
- stateToken1.signal("create sub");
- ProcessInstance subPi2 = stateToken1.getChild("go to sub")
- .getSubProcessInstance();
- // 铏界劧閮芥槸瀛愭祦紼嬶紝浣嗗畠浠茍涓嶇浉鍚岋紝鍦ㄩ昏緫涓婃槸灞炰簬騫跺彂鐨勬棤鍏崇郴鐨勫瓙嫻佺▼
- assertFalse(subPi1.equals(subPi2));
- // 緇撴潫絎簩涓瓙嫻佺▼
- subPi2.signal();
- assertTrue(subPi2.hasEnded());
- assertFalse(pi.hasEnded());
-
- // 緇撴潫絎竴涓瓙嫻佺▼錛屼絾涓繪祦紼嬩粛鏈粨鏉?
- subPi1.signal();
- assertTrue(subPi1.hasEnded());
- assertFalse(pi.hasEnded());
-
- // 緇撴潫絎簩涓瓙嫻佺▼涓殑state錛岀涓瀛愭祦紼嬬殑back鍒嗘敮緇撴潫錛屼粠鑰屼富嫻佺▼涔熺粨鏉?
- Token stateToken2 = stateToken1.getChild("back");
- assertEquals("state", stateToken2.getNode().getName());
- assertFalse(stateToken1.hasEnded());
- assertFalse(pi.hasEnded());
- stateToken2.signal("end");
-
- assertTrue(stateToken1.hasEnded());
- assertTrue(subPi1.hasEnded());
- assertTrue(pi.getRootToken().getChild("back").hasEnded());
- assertTrue(pi.getRootToken().getChild("go to sub").hasEnded());
- // 涓繪祦紼嬬粨鏉熶簡
- assertTrue(pi.hasEnded());
- // 铏界劧涓繪祦紼嬪凡緇忕粨鏉熶簡錛屼絾鏄洜涓哄瓙嫻佺▼娌℃湁join錛屾墍浠ュ叾rootToken浠嶇劧鍋滅暀鍦╢ork涓?
- assertEquals("fork", pi.getRootToken().getNode().getName());
- // 絎簩涓瓙嫻佺▼鍒拌揪鐨別nd鍜屼富嫻佺▼涓殑end騫朵笉鏄悓涓涓妭鐐?/font>
- assertTrue(!pi.getRootToken().getNode().equals(stateToken2.getNode()));
- }
- }

]]>