org.tinygroup.flow.impl.FlowExecutorImpl Maven / Gradle / Ivy
/**
* 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.impl;
import org.apache.commons.beanutils.PropertyUtils;
import org.tinygroup.commons.match.SimpleTypeMatcher;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.commons.tools.ValueUtil;
import org.tinygroup.context.Context;
import org.tinygroup.context.impl.ContextImpl;
import org.tinygroup.context2object.util.Context2ObjectUtil;
import org.tinygroup.event.Parameter;
import org.tinygroup.flow.ComponentInterface;
import org.tinygroup.flow.FlowExecutor;
import org.tinygroup.flow.config.*;
import org.tinygroup.flow.containers.ComponentContainers;
import org.tinygroup.flow.exception.FlowRuntimeException;
import org.tinygroup.flow.exception.errorcode.FlowExceptionErrorCode;
import org.tinygroup.flow.util.FlowElUtil;
import org.tinygroup.format.Formater;
import org.tinygroup.format.impl.ContextFormater;
import org.tinygroup.format.impl.FormaterImpl;
import org.tinygroup.i18n.I18nMessageFactory;
import org.tinygroup.i18n.I18nMessages;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 默认流程执行器
*
* @author luoguo
*/
public class FlowExecutorImpl implements FlowExecutor {
private static final Logger LOGGER = LoggerFactory
.getLogger(FlowExecutorImpl.class);
private static Map> exceptionMap = new HashMap>();
private static transient Formater formater = new FormaterImpl();
private Map flowIdMap = new HashMap();// 包含了name和id两个,所以通过名字和id都可以访问
private I18nMessages i18nMessages = I18nMessageFactory.getI18nMessages();
private boolean change;
// 组件容器
private ComponentContainers containers = new ComponentContainers();
static {
formater.addFormatProvider("", new ContextFormater());
formater.addFormatProvider(Parameter.INPUT, new ContextFormater());
formater.addFormatProvider(Parameter.OUTPUT, new ContextFormater());
formater.addFormatProvider(Parameter.BOTH, new ContextFormater());
}
public Map getFlowIdMap() {
return flowIdMap;
}
public void execute(String flowId, Context context) {
execute(flowId, null, context);
}
public void execute(String flowId, String nodeId, Context context) {
LOGGER.logMessage(LogLevel.INFO, "开始执行流程[flowId:{0},nodeId:{1}]执行",
flowId, nodeId);
if (!getFlowIdMap().containsKey(flowId)) {
LOGGER.log(LogLevel.ERROR, "flow.flowNotExist", flowId);
throw new FlowRuntimeException("flow.flowNotExist", flowId);
}
Flow flow = getFlowIdMap().get(flowId);
Node node = getNode(flow, nodeId);
if (node != null) {
logContext(context);
checkInputParameter(flow, context);
execute(flow, node, context);
checkOutputParameter(flow, context);
logContext(context);
}
LOGGER.logMessage(LogLevel.INFO, "流程[flowId:{0},nodeId:{1}]执行完毕",
flowId, nodeId);
}
/**
* 如果nodeId为空,则为其赋值Begin 如果begin不存在,分两种情况 1、节点数大于0,则执行第一个节点 2、节点数等于0,无需执行
* 如果nodeId为end,则无需执行 无需执行的两种情况下,返回的结果集为null 除以上情况外,若节点不存在,则抛出节点不存在的异常
*
* @param flow
* @param nodeId
* @return
*/
private Node getNode(Flow flow, String nodeId) {
if (DEFAULT_END_NODE.equals(nodeId)) { // 如果执行的是end,则无需执行
LOGGER.logMessage(LogLevel.INFO,
"流程[flowId:{0},nodeId:{1}]为结束节点,无需执行", flow.getId(),
DEFAULT_END_NODE);
return null;
}
if (nodeId == null) { // 如果节点为空,则赋值为begin
nodeId = DEFAULT_BEGIN_NODE;
}
if (DEFAULT_BEGIN_NODE.equals(nodeId) && flow.getNodes().size() == 0) {
LOGGER.logMessage(LogLevel.INFO,
"流程无节点,流程[flowId:{0},nodeId:{1}]执行完毕。", flow.getId(),
DEFAULT_BEGIN_NODE);
return null;
}
Node node = flow.getNodeMap().get(nodeId);
// 如果begin节点不存在,且节点数大于0,则从第一个节点开始执行
if (node == null && DEFAULT_BEGIN_NODE.equals(nodeId)) {
node = flow.getNodes().get(0);
} else if (node == null) {// 节点不存在,且节点名不为begin
LOGGER.log(LogLevel.ERROR, "flow.flowNodeNotExist", flow.getId(),
nodeId);
throw new FlowRuntimeException(i18nMessages.getMessage(
"flow.flowNodeNotExist", flow.getId(), nodeId));
}
return node;
}
private void logContext(Context context) {
if (LOGGER.isEnabled(LogLevel.DEBUG)) {
LOGGER.logMessage(LogLevel.DEBUG, "环境内容开始:");
logItemMap(context.getItemMap());
logSubContext(context.getSubContextMap());
LOGGER.logMessage(LogLevel.DEBUG, "环境内容结束");
}
}
private void logSubContext(Map subContextMap) {
LOGGER.logMessage(LogLevel.DEBUG, "子环境的内容开始:");
if (subContextMap != null) {
for (String key : subContextMap.keySet()) {
logContext(subContextMap.get(key));
}
}
LOGGER.logMessage(LogLevel.DEBUG, "子环境的内容结束:");
}
private void logItemMap(Map itemMap) {
for (String key : itemMap.keySet()) {
LOGGER.logMessage(LogLevel.DEBUG, "key: {0}, value: {1}", key,
itemMap.get(key));
}
}
private static Class> getExceptionType(String name) {
Class> exceptionType = exceptionMap.get(name);
if (exceptionType == null) {
try {
exceptionType = Class.forName(name);// TODO:通过Loader进行获取
exceptionMap.put(name, exceptionType);
} catch (ClassNotFoundException e) {
throw new FlowRuntimeException(e);
}
}
return exceptionType;
}
/**
* 获取一个新环境
*
* @param flow
* @param context
* @return
*/
private Context getNewContext(Flow flow, Context context) {
Context flowContext = null;
if (context == null) {
return null;
}
flowContext = context.getSubContextMap().get(flow.getId());
if (flowContext == null) {
return getNewContext(flow, context.getParent());
}
return flowContext;
}
/**
* 执行具体节点,并继续往下执行
*
* @param flow
* 当前执行的流程
* @param node
* 非end节点的任意合法节点
* @param context
*/
private void execute(Flow flow, Node node, Context context) {
String nodeId = node.getId(); // 当前节点id
Context flowContext = context;
try {
LOGGER.logMessage(LogLevel.INFO, "开始执行节点:{}", nodeId);
if (flow.isPrivateContext()) { // 是否context私有
flowContext = getNewContext(flow, context);
if (flowContext == null) {
flowContext = new ContextImpl();
context.putSubContext(flow.getId(), flowContext);
}
}
Component component = node.getComponent();
if (component != null) {
ComponentInterface componentInstance = getComponentInstance(component
.getName());
setProperties(node, componentInstance, flowContext);
if (!nodeId.equals(DEFAULT_END_NODE)) { // 如果当前节点不是最终节点
componentInstance.execute(flowContext);
}
LOGGER.logMessage(LogLevel.INFO, "节点:{}执行完毕", nodeId);
} else {
LOGGER.logMessage(LogLevel.INFO, "节点:{}未配置组件,无需执行", nodeId);
}
} catch (RuntimeException exception) {
/**
* 遍历所有异常节点
*/
LOGGER.errorMessage("流程执行[flow:{},node:{}]发生异常", exception,
flow.getId(), node.getId());
if (exceptionNodeProcess(flow, node, context, flowContext,
exception)) {
return;
}
// 如果节点中没有处理掉,则由流程的异常处理节点进行处理
Node exceptionNode = flow.getNodeMap().get(EXCEPTION_DEAL_NODE);
if (exceptionNode != null
&& exceptionNodeProcess(flow, exceptionNode, context,
flowContext, exception)) {
return;
// executeNextNode(flow, newContext, exceptionNode.getId());
}
// 如果还是没有被处理掉,则交由异常处理流程进行管理
Flow exceptionProcessFlow = this.getFlow(EXCEPTION_DEAL_FLOW);
if (exceptionProcessFlow != null) {
exceptionNode = exceptionProcessFlow.getNodeMap().get(
EXCEPTION_DEAL_NODE);
if (exceptionNode != null
&& exceptionNodeProcess(exceptionProcessFlow,
exceptionNode, context, flowContext, exception)) {
return;
}
}
throw exception;
}
if (nodeId != null && !nodeId.equals(DEFAULT_END_NODE)) {
// 先直接取,如果取到就执行,如果取不到,则用正则去匹配,效率方面的考虑
String nextNodeId = node.getNextNodeId(context);
if (nextNodeId == null) {
throw new FlowRuntimeException(FlowExceptionErrorCode.FLOW_NEXT_NODE_NOT_FOUND_EXCEPTION,flow.getId(),nodeId);
// int index = flow.getNodes().indexOf(node);
// if (index != flow.getNodes().size() - 1) {
// nextNodeId = flow.getNodes().get(index + 1).getId();
// } else {
// nextNodeId = DEFAULT_END_NODE;
// }
}
LOGGER.logMessage(LogLevel.INFO, "下一节点:{}", nextNodeId);
executeNextNode(flow, flowContext, nextNodeId);
}
}
private void checkInputParameter(Flow flow, Context context) {
StringBuffer buf = new StringBuffer();
if (flow.getInputParameters() != null) {
for (Parameter parameter : flow.getInputParameters()) {
if (parameter.isRequired()) {// 如果是必须
// =============20130619修改begin================
// Object value = context.get(parameter.getName());
// if (value == null) {//
// 如果从上下文直接拿没有拿到,则通过ClassNameObjectGenerator去解析
// value = getObjectByGenerator(parameter, context);
// if (value != null) {// 如果解析出来不为空,则放入上下文
// context.put(parameter.getName(), value);
// continue;
// }
// }
Object value = Context2ObjectUtil.getObject(parameter,
context, this.getClass().getClassLoader());
if (value != null) {// 如果解析出来不为空,则放入上下文
context.put(parameter.getName(), value);
continue;
}
// =============20130619修改end================
if (value == null) {
buf.append("参数<");
buf.append(parameter.getName());
buf.append(">在环境中不存在;");
}
}
}
if (buf.length() > 0) {
// buf.insert(0, "流程<" + flow.getId() + ">需要的参数不足:");
// throw new FlowRuntimeException(buf.toString());
throw new FlowRuntimeException("flow.inParamNotExist",
flow.getId(), buf.toString());
}
}
}
// private Object getObjectByGenerator(Parameter parameter, Context context)
// {
// String collectionType = parameter.getCollectionType();
// if (generator == null) {
// generator = SpringUtil.getBean(
// GeneratorFileProcessor.CLASSNAME_OBJECT_GENERATOR_BEAN);
// }
// if (collectionType != null && !"".equals(collectionType)) {
// return generator.getObjectCollection(parameter.getName(),
// collectionType, parameter.getType(), context);
// } else if (parameter.isArray()) {
// return generator.getObjectArray(parameter.getName(),
// parameter.getType(), context);
// }
//
// return generator.getObject(parameter.getName(),parameter.getName(),
// parameter.getType(),
// context);
// }
private void checkOutputParameter(Flow flow, Context context) {
StringBuffer buf = new StringBuffer();
if (flow.getOutputParameters() != null) {
for (Parameter parameter : flow.getOutputParameters()) {
if (parameter.isRequired()) {// 如果是必须
Object value = context.get(parameter.getName());
if (value == null) {
buf.append("参数<");
buf.append(parameter.getName());
buf.append(">在环境中不存在;");
}
}
}
if (buf.length() > 0) {
// buf.insert(0, "流程<" + flow.getId() + ">需要输出的参数不足:");
// throw new FlowRuntimeException(buf.toString());
throw new FlowRuntimeException("flow.outParamNotExist",
flow.getId(), buf.toString());
}
}
}
private boolean exceptionNodeProcess(Flow flow, Node node, Context context,
Context newContext, Exception exception) {
List nextExceptionList = node.getNextExceptionList();
// 20130524调整为顺序取异常进行匹配
for (int i = 0; i < nextExceptionList.size(); i++) {
String exceptionName = nextExceptionList.get(i);
if (dealException(exception, context, newContext, node, flow,
exceptionName)) {
return true;
}
Throwable t = exception.getCause();
while (t != null) {
if (dealException(t, context, newContext, node, flow,
exceptionName)) {
return true;
}
t = t.getCause();
}
}
return false;
}
private boolean dealException(Throwable exception, Context context,
Context newContext, Node node, Flow flow, String exceptionName) {
if (getExceptionType(exceptionName).isInstance(exception)) {// 如果异常匹配
String nextNode = node.getNextExceptionNodeMap().get(exceptionName);
context.put(EXCEPTION_DEAL_FLOW, flow);
context.put(EXCEPTION_DEAL_NODE_KEY, node);
context.put(EXCEPTION_KEY, exception);
executeNextNode(flow, newContext, nextNode);
LOGGER.errorMessage("处理流程异常:flow:{},node:{}", exception,
flow.getId(), nextNode);
return true;
}
return false;
}
private void executeNextNode(Flow flow, Context context, String nextNodeId) {
String nextExecuteNodeId = nextNodeId;
int index = nextNodeId.indexOf(':');
if (index > 0) { // newflowId:newnodeId
String[] str = nextNodeId.split(":");
if (str.length > 1) {
nextExecuteNodeId = str[1];
} else {
nextExecuteNodeId = DEFAULT_BEGIN_NODE;
}
// 从另一个流程的节点开始执行
execute(str[0], nextExecuteNodeId, context);
} else if (!DEFAULT_END_NODE.equals(nextNodeId)) {
Node nextNode = flow.getNodeMap().get(nextNodeId);
execute(flow, nextNode, context);
}
}
/**
* 把配置的参数注入进去
*
* @param node
* @param componentInstance
*/
private void setProperties(Node node, ComponentInterface componentInstance,
Context context) {
Map properties = node.getComponent()
.getPropertyMap();
if (properties != null) {
for (String name : properties.keySet()) {
FlowProperty property = properties.get(name);
String value = property.getValue();
Object object = null;
// 如果是el表达式,则通过el表达式处理
if (FlowProperty.EL_TYPE.equals(property.getType())) {
object = FlowElUtil.execute(value, context, this.getClass()
.getClassLoader());
} else {// 否则采用原有处理方式
object = getObject(property.getType(), value, context);
}
try {
PropertyUtils.setProperty(componentInstance, name, object);
} catch (Exception e) {
throw new FlowRuntimeException(e);
}
}
}
}
private Object getObject(String type, String value, Context context) {
String str = value;
if (str instanceof String) {
str = formater.format(context, str);
}
// 所有的都不是,说明是对象或表达式,此时返回null
Object o = null;
if (str != null) {
str = str.trim();
// type为空,按原先逻辑处理
if (StringUtil.isEmpty(type)) {
o = SimpleTypeMatcher.matchType(str);
} else {
// type不为空,则根据设置的type进行处理。可以避免数值型结果和参数类型不一致的问题。
o = ValueUtil.getValue(str, type);
}
}
return o;
}
// protected Object getObjectByName(String name, Context context) {
// Object object = getObject(name, context);
// if (object == null) {
// int index = name.indexOf('.');
// if (index == -1) {
// object = context.get(name);
// } else {
// String k = name.substring(0, index);
// String p = name.substring(index + 1);
// object = context.get(k);
// if (object != null) {
// try {
// object = PropertyUtils.getProperty(object, p);
// } catch (Exception e) {
// throw new FlowRuntimeException(e);
// }
// }
// }
// }
// return object;
// }
public void assemble() {
for (Flow flow : flowIdMap.values()) {
flow.validate();
flow.assemble();
}
}
public void addFlow(Flow flow) {
if (flow.getId() != null && flowIdMap.get(flow.getId()) != null) {
LOGGER.logMessage(LogLevel.ERROR, "flow:[id:{0}]已经存在!",
flow.getId());
}
if (flow.getName() != null && flowIdMap.get(flow.getName()) != null) {
LOGGER.logMessage(LogLevel.ERROR, "flow:[name:{0}]已经存在!",
flow.getName());
}
if (flow.getId() != null) {
LOGGER.logMessage(LogLevel.INFO, "添加flow:[id:{0}]", flow.getId());
flowIdMap.put(flow.getId(), flow);
}
if (flow.getName() != null) {
LOGGER.logMessage(LogLevel.INFO, "添加flow:[Name:{0}]",
flow.getName());
flowIdMap.put(flow.getName(), flow);
}
flow.setFlowExecutor(this);
setChange(true);
}
public void removeFlow(Flow flow) {
LOGGER.logMessage(LogLevel.INFO, "移除flow:[id:{0}]", flow.getId());
flowIdMap.remove(flow.getId());
LOGGER.logMessage(LogLevel.INFO, "移除flow:[name:{0}]", flow.getName());
flowIdMap.remove(flow.getName());
setChange(true);
}
public void removeFlow(String flowId) {
Flow flow = getFlow(flowId);
removeFlow(flow);
}
public Flow getFlow(String flowId) {
return flowIdMap.get(flowId);
}
public void addComponents(ComponentDefines components) {
containers.addComponents(components);
}
public void removeComponents(ComponentDefines components) {
containers.removeComponents(components);
}
/**
* 根据流程组件信息实例化组件
*
* @param componentName
* 流程组件名
* @return
*/
public ComponentInterface getComponentInstance(String componentName) {
ComponentInterface componentInstance = null;
if (!StringUtil.isBlank(componentName)) {
componentInstance = containers.getComponentInstance(componentName);
return componentInstance;
}
throw new FlowRuntimeException("flow.componentNotExist", componentName);
// throw new FlowRuntimeException("组件名称:" + componentName + "找不到");
}
public Context getInputContext(Flow flow, Context context) {
return getContext(flow.getInputParameters(), context);
}
private Context getContext(List parameters, Context context) {
Context result = new ContextImpl();
if (parameters != null) {
for (Parameter parameter : parameters) {
result.put(parameter.getName(),
context.get(parameter.getName()));
}
}
return result;
}
public Context getOutputContext(Flow flow, Context context) {
return getContext(flow.getOutputParameters(), context);
}
public void addComponent(ComponentDefine component) {
containers.addComponent(component);
}
public void removeComponent(ComponentDefine component) {
containers.removeComponent(component);
}
public ComponentDefine getComponentDefine(String componentName) {
return containers.getComponentDefine(componentName);
}
public boolean isChange() {
return change;
}
public void setChange(boolean change) {
this.change = change;
}
public List getComponentDefines() {
return containers.getComponentDefines();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy