All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinygroup.flow.config.Flow Maven / Gradle / Ivy

There is a newer version: 2.2.3
Show newest version
/**
 *  Copyright (c) 1997-2013, www.tinygroup.org ([email protected]).
 *
 *  Licensed under the GPL, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.gnu.org/licenses/gpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.tinygroup.flow.config;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.tinygroup.event.Parameter;
import org.tinygroup.flow.FlowExecutor;
import org.tinygroup.flow.exception.FlowRuntimeException;
import org.tinygroup.flow.exception.errorcode.FlowExceptionErrorCode;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;

/**
 * 流程,如果节点的名称叫eAxception,则表示是整个流程的异常处理节点,里面只能添加异常类的nextNode
 * 在执行时,如果节点没有处理,则异常会由本部分进行处理,本部分没有处理,则由异常管理器进行处理。
 *
 * @author luoguo
 */

@XStreamAlias("flow")
public class Flow implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = -7228372373320970405L;
    @XStreamAsAttribute
    @XStreamAlias("extend-flow-id")
    private String extendFlowId;// 继承的flowID
    @XStreamAsAttribute
    private String id;// flow的唯一ID
    @XStreamAsAttribute
    private String name;// flow的名字
    @XStreamAsAttribute
    private String title;// 流程名称
    private String description;// 流程说明
    private List nodes;// 流程节点
    private transient Map nodeMap;
    private transient FlowExecutor flowExecutor;
    private transient boolean assembled = false;// 是否已经组装完毕
    @XStreamAsAttribute
    @XStreamAlias("private-context")
    private boolean privateContext = false;
    @XStreamAsAttribute
    private boolean enable;// 是否可用
    @XStreamAsAttribute
    private String category;
    @XStreamAlias("parameters")
    private List parameters;// 流程的参数

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public List getInputParameters() {
        if (parameters == null) {
            return null;
        }
        List result = new ArrayList();
        for (Parameter parameter : parameters) {
            if (parameter.getScope() == null
                    || parameter.getScope().equalsIgnoreCase(Parameter.BOTH)
                    || parameter.getScope().equalsIgnoreCase(Parameter.INPUT)) {
                result.add(parameter);
            }
        }
        return result;
    }

    public List getOutputParameters() {
        if (parameters == null) {
            return parameters;
        }
        List result = new ArrayList();
        for (Parameter parameter : parameters) {
            if (parameter.getScope() == null
                    || parameter.getScope().equalsIgnoreCase(Parameter.BOTH)
                    || parameter.getScope().equalsIgnoreCase(Parameter.OUTPUT)) {
                result.add(parameter);
            }
        }
        return result;
    }

    public void setParameters(List parameters) {
        this.parameters = parameters;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }


    public boolean isPrivateContext() {
        return privateContext;
    }

    public void setPrivateContext(boolean privateContext) {
        this.privateContext = privateContext;
    }

	public void validate(){
		for(Node node : nodes){
			//节点名称非空校验
			validateNode(node);
			//流程节点有挂组件,则校验组件必传的参数是否有赋值
			if(node.getComponent()!=null){
				validateParameter(node);
			}
		}
    }
    
    private void validateNode(Node node) {
		if(StringUtils.isBlank(node.getName())){
			throw new FlowRuntimeException(FlowExceptionErrorCode.FLOW_NODE_NAME_VALIDATE_EXCEPTION,id,node.getId());
		}
	}

	private void validateParameter(Node node) {
		List componentParameters = flowExecutor.getComponentDefine(node.getComponent().getName()).getParameters();
		for(Parameter p : componentParameters){
			if(p.isRequired()){
				List flowProperties = node.getComponent().getProperties();
				if(flowProperties.isEmpty()){
					throw new FlowRuntimeException(FlowExceptionErrorCode.FLOW_PROPERTY_VALIDATE_EXCEPTION,id,node.getId(),name);
				}else{
					compareParameter(flowProperties,p.getName(),node.getId());
				}
			}
		}
	}

	private void compareParameter(List flowProperties, String name,String nodeId) {
		for(FlowProperty fp : flowProperties){
			if(name.equals(fp.getName()) && fp.getValue().isEmpty()){
				throw new FlowRuntimeException(FlowExceptionErrorCode.FLOW_PROPERTY_VALIDATE_EXCEPTION,id,nodeId,name);
			}
		}
	}

	public void assemble() {
        if (assembled) {
            return;
        }
        if (extendFlowId != null) {
            Flow parentFlow = flowExecutor.getFlowIdMap().get(extendFlowId);
            if (parentFlow == null) {
                throw new FlowRuntimeException("flow.flowNotExist", extendFlowId);
            } else {
                parentFlow.assemble();
                copyFlow(parentFlow);
            }
        }
        assembled = true;
    }

    private void copyFlow(Flow parentFlow) {
        List tmpNodes = nodes;
        nodes = new ArrayList();
        nodes.addAll(parentFlow.getNodes());// 首先把父亲所有节点复制过来
        for (Node node : tmpNodes) {
            Node parentNode = parentFlow.getNodeMap().get(node.getId());
            if (parentNode == null) {
                // 如果父节点在子节点中不存在,则直接拿过来
                getNodeMap().put(node.getId(), node);
                nodes.add(node);
            } else {
                // 否则进行合并
                int index = nodes.indexOf(parentNode);
                nodes.remove(index);
                node.combine(parentNode);
                nodes.add(index, node);
            }
        }
    }

    public FlowExecutor getFlowExecutor() {
        return flowExecutor;
    }

    public void setFlowExecutor(FlowExecutor flowExecutor) {
        this.flowExecutor = flowExecutor;
    }

    public String getExtendFlowId() {
        return extendFlowId;
    }

    public void setExtendFlowId(String extendFlowId) {
        this.extendFlowId = extendFlowId;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Map getNodeMap() {
        if (nodeMap == null) {
            nodeMap = new HashMap();
            if (nodes != null) {
                for (Node node : nodes) {
                    nodeMap.put(node.getId(), node);
                }
            }
        }
        return nodeMap;
    }

    public List getNodes() {
        return nodes;
    }

    public void setNodes(List nodes) {
        this.nodes = nodes;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


    public String getServiceName() {
        return id;
    }


    public List getParameters() {
        List p = getInputParameters();
        if (p != null) {
            return p;
        }
        return new ArrayList();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy