`
dingchao.lonton
  • 浏览: 50382 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

osworkflow dynamic split 动态会签的实现

 
阅读更多

目前 osworkflow的版本是2.8,很久没有更新了,而且这个版本的动态会签无法实现,虽然她提供了 split和join这样的标签,但是split中result的个数是固定的,这往往在我们现实的系统中用的很少,比如 我要给你一个组提供会签功能,而这个组的人数事先是不知道的,所以必须提供动态会签,也就是动态的split。

附件里面是我通过改写osworkflow使其能够动态会签的例子

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.8//EN" "workflow_2_8.dtd" >
<workflow>
  <initial-actions>
    <action id="1" name="Start Workflow">
      <results>
        <unconditional-result old-status="Finished" status="Queued" step="1"/>
      </results>
    </action>
  </initial-actions>
  <steps>
    <step id="1" name="First Part">
      <actions>
        <action id="2" name="Finish First Part">
          <results>
            <unconditional-result old-status="Finished" status="Queued" split="1" owner="test1,test2,test3"/>
          </results>
        </action>
      </actions>
    </step>
    <step id="2" name="Second Part">
      <actions>
        <action id="3" name="Back to First Part">
          <results>
            <unconditional-result old-status="Rejected" status="Queued" join="2"/>
          </results>
        </action>
        <action id="4" name="Finish">
          <results>
            <unconditional-result old-status="Finished" status="Queued" join="1"/>
          </results>
        </action>
      </actions>
    </step>

    <step id="4" name="End" />
  </steps>

  <splits>
    <split id="1" dynamic="TRUE" obtain-groups-callback="com.siemens.dingchao.test.DynamicSplitGroup"

>
      <unconditional-result old-status="Finished" status="Queued" step="2"/>
    </split>
  </splits>

  <joins>
    <join id="1">
      <conditions type="AND">
        <condition type="beanshell">
          <arg name="script">"Finished".equals(jn.getStep(2,"test1").getStatus())</arg>
        </condition>
        <condition type="beanshell">
          <arg name="script">"Finished".equals(jn.getStep(2,"test2").getStatus())</arg>
        </condition>
         <condition type="beanshell">
          <arg name="script">"Finished".equals(jn.getStep(2,"test3").getStatus())</arg>
        </condition>
      </conditions>
      <unconditional-result old-status="Finished" status="Underway" step="4"/>
    </join>
    <join id="2">
      <conditions type="OR">
        <condition type="beanshell">
          <arg name="script">"Rejected".equals(jn.getStep(2,"test1").getStatus())</arg>
        </condition>
        <condition type="beanshell">
          <arg name="script">"Rejected".equals(jn.getStep(2,"test2").getStatus())</arg>
        </condition>
        <condition type="beanshell">
          <arg name="script">"Rejected".equals(jn.getStep(2,"test3").getStatus())</arg>
        </condition>
      </conditions>
      <unconditional-result old-status="Finished" status="Underway" step="1"/>
    </join>
  </joins>
</workflow>

 

上面的红颜色部分是我为split标签添加的 属性,dynamic 属性 : 可以为 TRUE,true,FALSE,false,指定是否是动态的,如果是动态的 则必须指定obtain-group-callback 属性,该callback必须实现com.opensymphony.workflow.util.DynamicSplitGroupCallback接口(该接口为新添加)

 

 

 

test case :

 

/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package com.siemens.dingchao.test;

import junit.framework.TestCase;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.opensymphony.workflow.Workflow;
import com.opensymphony.workflow.basic.BasicWorkflow;


/**
 * @author hani Date: Feb 17, 2005 Time: 4:24:20 PM
 */
public class JoinTestCase extends TestCase {
    //~ Instance fields ////////////////////////////////////////////////////////

    private Workflow workflow;

    //~ Methods ////////////////////////////////////////////////////////////////

    public void testWithReject() throws Exception {
    	//说明:
        checkRoute(new int[] {2, 3, 2, 4 ,4 ,4});

    	//checkRoute(new int[] {4,4});
    }

    protected void setUp() throws Exception {
       /* workflow = new BasicWorkflow("testuser");*/
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        workflow = (Workflow)context.getBean("workflow");
    
    }

    private void checkRoute(int[] actions) throws Exception {
        long workflowId = workflow.initialize("join", 1, null);

        for (int i = 0; i < actions.length; i++) {
            workflow.doAction(workflowId, actions[i], null);
        }
    }
}
 

 

test case 的红颜色部分标明了 步骤的 route 均是 xml里面的action id ,你可以把这个数字和xml对照起来看。

 

 

调试结果     以下图例都是 表 os_currentstep:

 

流程实例初始化


 

运行action  2 此时动态split为3个任务,因为 owner为 test1,test2,test3



 运行action : 3  reject(驳回) 回到step1

运行action 2 ,相当于再次提交任务,此时任务再次分裂成为3个任务,owner分别为test1 ,test2,test3


test1 执行action 4 : test1 用户提交任务


test2执行action 4 : test2 用户提交任务


test3 执行action 4 : test3 用户提交任务


此时3个用户都提交了任务,任务移动到下一步 , 即 结束节点,至此 这个工作流实例完成

 

在看看 os_historystep 表的数据 :

 


我们可以发现历史信息业完整的记录了这个操作轨迹。

 

希望能给你们带来帮助

  • 大小: 17.7 KB
  • 大小: 14.6 KB
  • 大小: 17.8 KB
  • 大小: 16.3 KB
  • 大小: 14.7 KB
  • 大小: 12.9 KB
  • 大小: 29.1 KB
  • 大小: 15.8 KB
分享到:
评论
7 楼 zhaoyangjay 2015-06-25  
你是不是改过JAR包中的源代码了,AbstractWorkflow是不是被你改过了?
6 楼 dingchao.lonton 2013-10-23  
TheMatrix 写道
有个问题,例子中都是用同一个用户去执行doAction三遍,现实中应该是不同的三个人去执行doAction,比如test1、test2、test3三人,怎么保证任何一个人先执行doAction,能处理owner=自己的那一条记录呢(OS_CURRENTSTEP)?
因为我发现,无论谁先执行doAction,都只是把这三条记录的第一条记录给执行掉了,那条记录的owner!=自己。

是有问题,需要修改一下源代码了。
5 楼 TheMatrix 2013-10-21  
有个问题,例子中都是用同一个用户去执行doAction三遍,现实中应该是不同的三个人去执行doAction,比如test1、test2、test3三人,怎么保证任何一个人先执行doAction,能处理owner=自己的那一条记录呢(OS_CURRENTSTEP)?
因为我发现,无论谁先执行doAction,都只是把这三条记录的第一条记录给执行掉了,那条记录的owner!=自己。
4 楼 opera4130 2012-10-18  
这个很赞,谢谢分享
3 楼 dingchao.lonton 2012-09-02  
public class ApproveJoinCondition implements Condition {

	public boolean passesCondition(Map transientVars, Map args, PropertySet ps)throws WorkflowException {
		// TODO Auto-generated method stub
		JoinNodes jn = (JoinNodes)transientVars.get("jn");
		
		Collection steps  = (Collection)jn.getSteps();
		Iterator it = steps.iterator();
		Step step = null;
		boolean result = true;
		while(it.hasNext()){
			step = (Step)it.next();
			result = result&&"Finished".equals(step.getStatus());
		}
		return result;
	}

}


处理 Approval的condition;

public class RejectJoinCondition implements Condition {

	public boolean passesCondition(Map transientVars, Map args, PropertySet ps)
			throws WorkflowException {
		// TODO Auto-generated method stub
		JoinNodes jn = (JoinNodes)transientVars.get("jn");
		
		Collection steps  = (Collection)jn.getSteps();
		Iterator it = steps.iterator();
		Step step = null;
		boolean result = false;
		while(it.hasNext()){
			step = (Step)it.next();
			result = result || "Rejected".equals(step.getStatus());
		}
		return result;
	}

}

处理 Reject的 condition

另外需要修改xml


<joins>
    <join id="1">
      <conditions type="AND">
        <condition type="class">
          <arg name="class.name">com.siemens.dingchao.test.ApproveJoinCondition</arg>
        </condition>
      </conditions>
      
      <unconditional-result old-status="Finished" status="Underway" step="4"/>
    </join>
    <join id="2">
      <conditions type="AND">
        <condition type="class">
          <arg name="class.name">com.siemens.dingchao.test.RejectJoinCondition</arg>
        </condition>
      </conditions>
      <unconditional-result old-status="Finished" status="Underway" step="1"/>
    </join>
  </joins>


另外 源代码还需要修改一个地方 就是JoinNodes 需要加一个 getSteps 方法 你可以反编译了再加,完后替换这个class即可

以上2个condition对全部通过,和一票否决的情况可以通用,但如果 比如说 2/3的人通过 ,否决这样的情况需要自己写自己的判断逻辑了
2 楼 dingchao.lonton 2012-09-01  
kjj 写道
 <join id="1">  
      <conditions type="AND">  
        <condition type="beanshell">  
          <arg name="script">"Finished".equals(jn.getStep(2,"test1").getStatus())</arg>  
        </condition>  
        <condition type="beanshell">  
          <arg name="script">"Finished".equals(jn.getStep(2,"test2").getStatus())</arg>  
        </condition>  
         <condition type="beanshell">  
          <arg name="script">"Finished".equals(jn.getStep(2,"test3").getStatus())</arg>  
        </condition>  
      </conditions>  
      <unconditional-result old-status="Finished" status="Underway" step="4"/>  
    </join>  


难道这个join只能join 固定的三个步骤吗!!!
如果会签数不确定能否可以,对付。。。。。。。

当然可以对付,我是用beanshell写的,你可以写自己的condition啊?

import java.util.Map;

import com.opensymphony.module.propertyset.PropertySet;
import com.opensymphony.workflow.Condition;
import com.opensymphony.workflow.JoinNodes;
import com.opensymphony.workflow.WorkflowException;

public enum JoinCondition implements Condition {
	;

	@Override
	public boolean passesCondition(Map transientVars, Map args, PropertySet ps)
			throws WorkflowException {
		// TODO Auto-generated method stub
		JoinNodes jn = (JoinNodes)transientVars.get("jn");
		
		//bla bla 你自己的判断逻辑
		return false;
	}

}

1 楼 kjj 2012-09-01  
 <join id="1">  
      <conditions type="AND">  
        <condition type="beanshell">  
          <arg name="script">"Finished".equals(jn.getStep(2,"test1").getStatus())</arg>  
        </condition>  
        <condition type="beanshell">  
          <arg name="script">"Finished".equals(jn.getStep(2,"test2").getStatus())</arg>  
        </condition>  
         <condition type="beanshell">  
          <arg name="script">"Finished".equals(jn.getStep(2,"test3").getStatus())</arg>  
        </condition>  
      </conditions>  
      <unconditional-result old-status="Finished" status="Underway" step="4"/>  
    </join>  


难道这个join只能join 固定的三个步骤吗!!!
如果会签数不确定能否可以,对付。。。。。。。

相关推荐

    SSO单点登录概要设计说明书.doc

    SSO单点登录概要设计说明书.doc

    奥塔北煤矿6.0 Mta新井设计说明书.docx

    奥塔北煤矿6.0 Mta新井设计说明书.docx

    基于S7-200 PLC和组态王的喷泉控制系统设计与实现

    内容概要:本文详细介绍了基于S7-200 PLC和组态王软件构建喷泉控制系统的全过程。首先明确了系统的IO分配,包括启动按钮、停止按钮以及喷泉水泵的连接方式。接着展示了梯形图程序的设计,涵盖了基本的启停控制逻辑、定时循环和模式切换机制。随后提供了详细的接线图原理图,解释了输入输出部分的具体接线方法。最后讲述了组态王的画面设计,包括创建工程、定义变量和绘制监控界面等步骤。此外还分享了一些调试过程中遇到的问题及解决方案。 适合人群:对自动化控制感兴趣的初学者和技术人员,尤其是那些希望深入了解PLC编程和人机界面设计的人群。 使用场景及目标:适用于小型喷泉项目的实际控制系统开发,旨在帮助读者掌握PLC编程技巧、熟悉组态软件的应用,并能够独立完成类似的自动化控制系统设计。 其他说明:文中不仅包含了理论知识讲解,还附带了许多实践经验分享,如硬件配置建议、常见错误规避措施等,有助于提高实际操作能力。

    计算机二级PPT精选二十套(标红).jpg

    计算机二级PPT精选二十套(标红)

    保险公司IT变更管理流程设计说明书.doc.doc

    保险公司IT变更管理流程设计说明书.doc.doc

    毕业设计说明书A江坝后式厂房双曲拱坝设计.pdf

    毕业设计说明书A江坝后式厂房双曲拱坝设计.pdf

    《计算机二级MS精选300道选择题.docx》

    内容概要:文档《计算机二级MS精选300道选择题.docx》涵盖了计算机二级考试中Microsoft Office软件(Word、Excel、PowerPoint)及计算机基础知识的选择题。题目涉及软件操作技巧、功能应用、常见问题解决等方面,旨在帮助考生熟悉并掌握相关知识点,提高应试能力。文档内容详尽,涵盖面广,从基础操作到高级应用均有涉及,适合考生全面复习备考。 适用人群:准备参加计算机二级考试的学生及相关从业人员,特别是需要强化Office软件操作技能和计算机基础知识的人员。 使用场景及目标:①考生可以在复习过程中使用这些选择题进行自我检测,巩固所学知识;②教师可以将其作为教学辅助材料,帮助学生更好地理解和掌握课程内容;③培训机构可以用这些题目作为测试题库,评估学员的学习效果。 其他说明:文档不仅提供了大量的选择题,还详细解析了每道题目的答案,有助于考生深入理解知识点。此外,题目内容紧跟最新考试大纲,确保考生能够获得最有效的备考资料。

    基于多目标黏菌优化算法(MOSMA)的SVM参数优化及其在回归预测中的应用

    内容概要:本文介绍了一种创新的方法,利用多目标黏菌优化算法(MOSMA)来优化支持向量机(SVM)的参数C和gamma,从而提高回归预测的效果。首先详细解释了MOSMA的工作原理,包括黏菌权重更新、快速非支配排序以及自适应参数调整等关键技术点。接着展示了具体的Python代码实现,涵盖数据预处理、适应度函数定义、参数更新规则等方面。实验结果显示,在风电功率预测等多个应用场景中,相较于传统的网格搜索方法,MOSMA能够更快更有效地找到最优参数组合,显著提升了预测性能。 适合人群:从事机器学习研究或应用开发的技术人员,尤其是关注SVM参数优化及回归预测领域的从业者。 使用场景及目标:适用于需要进行高效参数寻优的回归预测任务,如风电功率预测、设备负载预测等。主要目标是通过改进SVM参数配置,获得更高的预测精度和更好的泛化能力。 其他说明:文中提供了完整的代码示例和详细的实施步骤指导,帮助读者快速理解和应用这一先进的优化技术。此外,还讨论了一些常见的注意事项和技术细节,如数据标准化、参数范围设定、并行化改造等。

    毕业设计 某油库设计说明书.pdf

    毕业设计 某油库设计说明书.pdf

    Q235钢板焊接工艺设计说明书.docx

    Q235钢板焊接工艺设计说明书.docx

    75t循环流化床锅炉设计说明书.doc

    75t循环流化床锅炉设计说明书.doc

    (最新修订版)直列四缸柴油机配气机构设计毕业论文设计说明书.doc

    (最新修订版)直列四缸柴油机配气机构设计毕业论文设计说明书.doc

    DeepSeek大模型生态报告:中国AI技术突破及其全球影响分析

    内容概要:《deepseek大模型生态报告 2025年2月》详细介绍了DeepSeek大模型的背景、应用现状、技术特点及其产业生态。DeepSeek由杭州深度求索公司创立,通过一系列技术创新,如多层注意力架构(MLA)、FP8混合精度训练框架、DualPipe跨节点通信等,显著降低了训练成本和提高了模型性能。DeepSeek在国内和国际市场迅速崛起,登顶苹果应用商店免费APP下载排行榜,并被多家企业和机构接入,包括华为、三大运营商、微软、英伟达等。其开源策略和低成本优势对全球科技供应链和资本市场产生了深远影响,尤其是在AI领域。 适合人群:对人工智能、大模型技术感兴趣的科技爱好者、研究人员、企业家及政策制定者。 使用场景及目标:①了解DeepSeek大模型的技术创新和应用现状;②探讨DeepSeek对全球AI产业生态的影响;③分析DeepSeek在不同行业(如金融、医疗、教育、制造等)的具体应用案例。 其他说明:报告还涵盖了各国政府及相关机构对DeepSeek的态度和政策回应,以及DeepSeek对未来AI技术发展和国际竞争格局的启示。此外,报告深入剖析了DeepSeek在技术架构、数据策略和工程实践方面的突破,揭示了其成功背后的组织文化和创新机制。

    基于粒子群算法的电动汽车区域综合能源系统三方定价优化研究

    内容概要:本文详细介绍了利用粒子群算法解决电动汽车区域综合能源系统中光伏电站、充电桩运营商和电网公司在定价上的三方博弈问题。通过MATLAB代码实现了粒子群算法的具体应用,包括参数设置、适应度函数设计、粒子更新策略以及结果可视化。文中展示了如何将三方定价变量编码成多维粒子,并通过目标函数计算和约束处理确保粒子在合理的解空间内搜索最优解。最终得到的电价曲线反映了不同时间段内的供需变化,验证了算法的有效性和实用性。 适合人群:从事能源系统优化、智能算法应用的研究人员和技术开发者。 使用场景及目标:适用于需要进行能源系统优化调度的场景,特别是涉及多方利益协调的问题。目标是找到光伏电价、充电桩电价和电网电价的最佳组合,使得三方利益达到最优平衡。 其他说明:建议在调试过程中关注特定时段的电价突变,适当调整参数如社会认知系数和社会学习因子,以获得更好的收敛效果。此外,初始粒子的位置选择对收敛速度有很大影响,推荐采用高斯扰动等方法进行初始化。

    WY02锥齿轮的加工工艺规程及工时定额计算 课程设计说明书.docx

    WY02锥齿轮的加工工艺规程及工时定额计算 课程设计说明书.docx

    项目管理制度范文.docx

    项目管理制度范文.docx

    风电工程技术:DFIG双馈风力发电机仿真模型解析与应用

    内容概要:本文深入探讨了双馈风力发电机(DFIG)的仿真建模及其关键技术模块。首先介绍了最大功率跟踪(MPPT)模块的工作原理,利用爬山算法优化风能利用率。接着详细讲解了转子侧变流器的矢量控制,包括坐标变换、PI调节器参数设定以及抗饱和处理。文中还讨论了网侧变流器的直流电压控制方法,强调了双闭环结构的重要性,并分享了低电压穿越仿真的实践经验。此外,文章详细解释了功率解耦控制和变速恒频实现的技术细节,提供了丰富的故障案例和调试技巧。 适合人群:从事风电工程研究和技术开发的专业人士,尤其是对DFIG仿真建模感兴趣的工程师和研究人员。 使用场景及目标:适用于希望深入了解DFIG内部机制的研究人员,帮助他们掌握从基本原理到复杂控制策略的设计与实现。同时,也为实际工程项目提供宝贵的调试经验和故障排除指南。 其他说明:文章不仅涵盖了理论分析,还包括大量实用的代码片段和具体的参数配置建议,确保读者能够顺利构建并运行仿真模型。

    基于Matlab/Simulink的统一电能质量变换器(UPQC)仿真:IP-IQ检测与电压电流补偿

    内容概要:本文详细介绍了如何利用Matlab2016的Simulink进行统一电能质量变换器(UPQC)的仿真,重点探讨了IP-IQ检测方法及其在电压和电流补偿中的应用。文中首先描述了UPQC的整体结构,包括串联和并联逆变器的设计。接着深入讲解了IP-IQ检测的具体实现步骤,包括三相锁相环同步、坐标变换以及低通滤波器的应用。此外,文章还讨论了电压和电流补偿的控制策略,特别是双闭环控制和SVPWM模块的使用。作者分享了许多调试经验和常见问题的解决方案,如谐波滤波器的选择、PI控制器参数调整、仿真步长设置等。最终展示了仿真结果,证明了该方法的有效性。 适合人群:从事电能质量研究和技术开发的专业人士,尤其是有一定Matlab/Simulink基础的研究人员和工程师。 使用场景及目标:适用于希望深入了解UPQC工作原理和仿真实现的技术人员,帮助他们掌握IP-IQ检测方法和补偿控制策略,提高电能质量问题的解决能力。 其他说明:文中提供了详细的代码片段和调试技巧,有助于读者快速上手并优化自己的仿真模型。

    《金属打磨粉尘治理方案设计说明书》.doc

    《金属打磨粉尘治理方案设计说明书》.doc

Global site tag (gtag.js) - Google Analytics