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

xworker.flow.ThingFlow Maven / Gradle / Ivy

/*******************************************************************************
* Copyright 2007-2013 See AUTHORS file.
 * 
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
* 
* 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 xworker.flow;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmeta.ActionContext;
import org.xmeta.ActionException;
import org.xmeta.Thing;
import org.xmeta.World;

/**
 * 事物流程。
 * 
 * @author zyx
 *
 */
public class ThingFlow {
	static World world = World.getInstance();
	private static Logger log = LoggerFactory.getLogger(ThingFlow.class);
	private static long flowId = 0;
	private static ExecutorService executorService = Executors.newCachedThreadPool();
	private static Map flows = new HashMap();
	private static ThingFlowListenerDelegator listenerDelegator = new ThingFlowListenerDelegator();
	
	/** 流程默认继续执行的状态 */
	public static final int DEFAULT = 1;
	/** 流程强制结束 */
	public static final int TERMIATE = 2;
	/** 流程当前节点执行完后结束 */
	public static final int FINSIHE = 3;
	
	/** 流程事物 */
	Thing flowThing;
	
	/** 流程事件监听者列表 */
	List listeners = new ArrayList();
	
	/** 事物流程的当前请求列表 */
	List requests = new ArrayList();
	
	/** 事物流程的全局上动作下文 */
	ActionContext actionContext;
	
	/** 流程是否已终止 */
	int status = DEFAULT;
	
	/** 当前流程的标识 */
	long id;
	
	/** 保存flows时的字符串标识 */
	String flowInstanceId = null;
	
	/** 当前正在执行的事物流程的线程 */
	@SuppressWarnings("unchecked")
	Map threads = new HashMap();
	
	public ThingFlow(Thing flowThing, ActionContext actionContext){
		this.flowThing = flowThing;
		this.actionContext = actionContext;
		if(this.actionContext == null){
			this.actionContext = new ActionContext();
		}
		this.addThingFlowListener(listenerDelegator);
		flowId ++;
		id = flowId;
		actionContext.getScope(0).setCaller(this, null);
	}
	
	/** 开始执行事物流程 */
	public void start(){
		if(flowThing.getBoolean("oneInstance")){
			if(flows.get(flowThing.getMetadata().getPath()) != null){
				//只允许有一个实例,且实例已经存在
				log.info("事物流程实例已经存在,该事物流程实例唯一:" + flowThing.getMetadata().getPath());
				return;
			}else{
				flowInstanceId = flowThing.getMetadata().getPath();
				flows.put(flowInstanceId, this);
			}
		}else{
			flowInstanceId = flowThing.getMetadata().getPath() + ":" + flowId;
			flows.put(flowInstanceId, this);
		}

		invokeFlowStart();
		
		//启动起始节点
		ThingFlowNode node = new ThingFlowNode(this, flowThing);		
		startNode(node);
	}	
	
	/**
	 * 启动一个节点。
	 * 
	 * @param node
	 */
	@SuppressWarnings("unchecked")
	private void startNode(ThingFlowNode node){		
		synchronized(node){ //同步node,node的执行要在threads.put之后
			//log.info("" + this +" " + threads.size());
			Future future = executorService.submit(node);	
			threads.put(node, future);
			//log.info("" + this  +" " + threads.size());
		}
	}
	
	public void stop(){
		setStatus(ThingFlow.FINSIHE);
	}
	
	/**
	 * 检查是否已经接过。
	 */
	public boolean checkClose(){
		if(threads.size() == 0){
			close();
			
			return true;
		}else{
			return false;
		}
	}
	
	public void close(){
		flows.remove(flowInstanceId);
		//整个流程已经结束
		this.invokeClosed();
	}
	
	@SuppressWarnings("unchecked")
	public void terminate(){
		setStatus(ThingFlow.TERMIATE);
		
		for(ThingFlowNode node : threads.keySet()){
			try{
				Future future = threads.get(node);
				if(future.cancel(true)){
					threads.remove(node);
					checkClose();
				}
			}catch(Throwable t){
				log.error("terminate flow", t);
			}
		}
	
		//强制结束
		this.close();
	}
	
	/** 执行节点 */
	public void invokeNode(ThingFlowNode thingFlowNode, Thing flowThingNode){		
		if(this.getStatus() != DEFAULT){
			return;
		}
		
		//threads.put(Thread.currentThread(), flowThingNode);

		//触发流程节点开始的事件
		invokeNodeStart(thingFlowNode);		
		
		//首先取thingPath设置的事物
		Thing thing = null;
		
		String thingPath = flowThingNode.getString("thingPath");
		if(thingPath != null && !"".equals(thingPath)){
			thing = world.getThing(thingPath);
		}
		
		if(thing == null){
			//从子节点中取事物
			thing = flowThingNode.getThing("AThing@0");
			
			//创建新事物
			if(thing == null){
				String descriptorPath = flowThingNode.getString("descriptorPath");
				if(descriptorPath != null && !"".equals(descriptorPath)){
					thing = new Thing(descriptorPath);
					thing.initDefaultValue();
				}
			}
		}
		
		if(thing == null){
			thing = new Thing();
		}
				
		//------初始化事物的数据,确定是否需要编辑--------
		ActionContext nodeActionContext = new ActionContext(actionContext);
		
		boolean needEditValue = checkNeedEdit(thing);
		if(!needEditValue){
			String needSetvalue = flowThingNode.getString("edit");
			if("true".equals(needSetvalue)){
				needEditValue = true;
			}
		}
		
		//数据对象编辑请求
		ThingFlowUIRequest request = new ThingFlowUIRequest(this, flowThing, thing, flowThingNode.getString("prority"));
		request.setActionContext(actionContext);
		if(needEditValue && thing != null){
			try{				
				requests.add(request);
				if(!sendUIRequest(request)) return;			
				nodeActionContext.peek().put("uiData", request.getUiData());
			}catch(Exception e){				
			}
		}
			
		//--------执行事物的动作---------
		Object result = "success";		
		if(thing != null){
			String method = flowThingNode.getString("method");
			if(method == null || "".equals(method)){
				method = "run";
			}
			
			while(true){
				try{
					result = thing.doAction(method, nodeActionContext);
					break;
				}catch(Throwable e){
					if("true".equals(flowThingNode.getString("editOnExcetpion"))){
						try{		
							requests.add(request);
							request.setUiData(null);
							if(!sendUIRequest(request)) return;		
							
							nodeActionContext.peek().put("uiData", request.getUiData());
						}catch(Exception ie){							
						}
					}else{
						log.error("thing flow do method", e);
						result = "exception";
						if(e instanceof ActionException){
							throw (ActionException) e;
						}else{
							throw new ActionException("", e);
						}
					}
				}
			}			
		}
		this.invokeNodeClose(thingFlowNode);
		
		//--------执行的结果--------
		String sr = "success";
		if(result instanceof String){
			sr = (String) result;
		}else if(result != null){
			sr = "success";
		}
		//事物流程可以同时返回多个结果,结果之间使用,号隔开。
		String results[] = sr.split("[,]");
		
		//-----------执行下一级事物流程-------------		
		boolean haveNextFlow = false;			
		for(Thing resultObj : flowThingNode.getAllChilds("result")){
			boolean execue = false;
			String resultName = resultObj.getMetadata().getName();
			for(int i=0; i resultChilds = resultObj.getAllChilds("ThingFlow");
		if(resultChilds.size() == 0) return false;
		
		List results = new ArrayList();
		//执行子任务
		if("RANDOM_ONE".equals(resultObj.getString("type"))){
			Random r = new Random();
			int aChild = r.nextInt(resultChilds.size());
			
			Thing child = resultChilds.get(aChild);		
			results.add(child);
		}else{
			
			for(final Thing child : resultChilds){	
				results.add(child);
				
			}
		}
		
		boolean haveNext = false;		
		for(final Thing child : results){
			haveNext = true;
			ThingFlowNode node = new ThingFlowNode(this, child);
			startNode(node);
		}
		return haveNext;
	}
	
	/**
	 * 发送编辑请求。
	 * 
	 * @param request
	 * @param thingFlowManager
	 * @return
	 * @throws InterruptedException
	 */
	private boolean sendUIRequest(ThingFlowUIRequest request) throws InterruptedException{
		request.stop = false;
		for(ThingFlowListener listener : listeners){
			request.threadLockObject = new NotifyObject();
			listener.requestUI(request);
		}
		
		//等待UI处理完毕
		request.waitRequest();
		
		if(request.stop){
			return false;
		}else{
			return true;
		}
	}
	
	/**
	 * 校验事物是否需要编辑。
	 * 
	 * @param thing
	 * @return
	 */
	public static boolean checkNeedEdit(Thing thing){
		if(thing == null) return false;
		
		for(Thing field : thing.getAllAttributesDescriptors()){
			String fieldName = field.getMetadata().getName();
			
			if("false".equals(field.getString("optional")) && thing.getAttribute(fieldName) == null){
				return true;
			}
		}
		
		for(Thing child : thing.getChilds()){
			return checkNeedEdit(child);
		}
		
		return false;
	}
	
	/**
	 * 取是否正在运行的状态。
	 * 
	 * @return
	 */
	public boolean isRunning(){
		return threads.size() != 0;
	}
	
	public void removeFlowListener(ThingFlowListener listener){
		listeners.remove(listener);
	}
	
	public void addThingFlowListener(ThingFlowListener listener){
		listeners.add(listener);
	}

	public List getRequests(){
		return requests;
	}
	
	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}
	
	@SuppressWarnings("unchecked")
	public Map getThreads(){
		return this.threads;
	}
	
	public String getName(){
		return this.flowThing.getMetadata().getLabel();
	}
	
	public long getId(){
		return id;
	}
	
	public Thing getFlowThing() {
		return flowThing;
	}

	/**
	 * 启动一个事物流程,供流程事物定义的run方法使用。
	 * 
	 * @param context
	 */
	public static void run(ActionContext context){
		Thing self = (Thing) context.get("self");
		ThingFlow thingFlow = new ThingFlow(self, context);
		Object listener = context.get("thingFlowListener");
		if(listener != null 
				&& listener instanceof ThingFlowListener){
			thingFlow.addThingFlowListener((ThingFlowListener) listener);
		}
			
		thingFlow.start();
	}
	
	/**
	 * 返回当前运行的所有事物流程。
	 * 
	 * @return
	 */
	public static Map getThingFlows(){
		return flows;
	}
	
	/**
	 * 返回事物流程监听代理。 
	 * 
	 * @return
	 */
	public static ThingFlowListenerDelegator getThingFlowListenerDelegator(){
		return listenerDelegator;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy