/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.cms.workflow;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import com.jinhe.tss.cms.CMSConstants;
import com.jinhe.tss.cms.workflow.WorkFlowNode.WorkerFlowButton;
import com.jinhe.tss.core.cachepool.CacheManager;
import com.jinhe.tss.core.cachepool.Cacheable;
import com.jinhe.tss.core.cachepool.CacheableKey;
import com.jinhe.tss.core.cachepool.IPool;
import com.jinhe.tss.core.exception.BusinessException;
import com.jinhe.tss.core.util.EasyUtils;
import com.jinhe.tss.core.util.FileHelper;
import com.jinhe.tss.core.util.URLUtil;
import com.jinhe.tss.core.util.XMLDocUtil;
/**
* <p> WorkFlowOperator.java </p>
* 工作流操作对象
*/
public class WorkFlowManager {
static final String WORKFLOWS_CACHE_KEY = "workflows_info";
static IPool pool = CacheManager.getInstance().getCachePool(WORKFLOWS_CACHE_KEY);
static Document templateDoc ;
private WorkFlowManager(){
templateDoc = XMLDocUtil.createDoc(CMSConstants.WORKFLOW_TEMPLATE_PATH);
init();
}
private static WorkFlowManager manager;
public static WorkFlowManager getInstance(){
if(manager == null) {
manager = new WorkFlowManager();
}
return manager;
}
private void init() {
List<Element> workflowElementList = XMLDocUtil.selectNodes(templateDoc, "//workflow");
for ( Element workflowElement : workflowElementList ) {
String code = workflowElement.elementText("code");
String name = workflowElement.elementText("name");
WorkFlow workFlow = new WorkFlow(code, name);
List<Element> stepElementList = XMLDocUtil.selectNodes(workflowElement, "//flow");
for ( Element stepElement : stepElementList ) {
String status = stepElement.elementText("status");
String stepName = stepElement.elementText("name");
WorkFlowNode workFlowStep = new WorkFlowNode(status, stepName);
if (stepElement.element("next") != null) {
Element next = stepElement.element("next");
WorkerFlowButton wfButton = new WorkerFlowButton(next.elementText("status"), next.elementText("button"));
workFlowStep.setNextButton(wfButton);
}
if (stepElement.element("preview") != null) {
Element preview = stepElement.element("preview");
WorkerFlowButton wfButton = new WorkerFlowButton(preview.elementText("status"), preview.elementText("button"));
workFlowStep.setPreviewButton(wfButton);
}
workFlow.getFlowStepsMap().put(workFlowStep.getStatus(), workFlowStep);
}
pool.putObject(workFlow.getCode(), workFlow);
}
}
/**
* 获取文章工作量流列表
* @return
*/
public List<CacheableKey> getWorkFlowCodes() {
return pool.listKeys();
}
/**
* 将所有工作流拼成下拉列表
*/
public String[] getWorkFlowCodeAndNames() {
List<Cacheable> list = pool.listItems();
List<WorkFlow> workFlowList = new ArrayList<WorkFlow>();
for( Cacheable temp : list ){
workFlowList.add( (WorkFlow) temp.getValue() );
}
return EasyUtils.generateComboedit(workFlowList, "code", "name", "|");
}
/**
* 将指定工作流的步骤拼成下拉列表
*/
public String[] getFlowStepStatusAndNames(Integer workflowId){
Map<Integer, WorkFlowNode> map = getWorkFlow(workflowId).getFlowStepsMap();
List<WorkFlowNode> nodeList = new ArrayList<WorkFlowNode>(map.values());
return EasyUtils.generateComboedit(nodeList, "status", "name", "|");
}
/**
* 根据工作流ID获取工作流对象
* @param workflowId
* @return
*/
public WorkFlow getWorkFlow(Integer workflowId) {
Cacheable c = pool.getObject(workflowId);
if (c == null) {
throw new BusinessException("未找到id为:" + workflowId + "的文章工作流 ");
}
return (WorkFlow) c.getValue();
}
/**
* 获取文章流步骤
* @param workflowId 工作流
* @param status 工作流步骤状态
* @return
*/
public WorkFlowNode getWorkFlowNode(Integer workflowId, Integer status) {
WorkFlow wf = getWorkFlow(workflowId);
Object step = wf.getFlowStepsMap().get(status);
if (step == null) {
throw new BusinessException("未找到文章流步骤");
}
return (WorkFlowNode) step;
}
/**
* 获取文章流步骤的前进按钮
* @param workflowId
* @param status
* @return
*/
public WorkerFlowButton getNextButton(Integer workflowId, Integer status) {
return getWorkFlowNode(workflowId, status).getNextButton();
}
/**
* 获取文章流步骤的退回按钮
* @param workflowId
* @param status
* @return
*/
public WorkerFlowButton getPreviewButton(Integer workflowId, Integer status) {
return getWorkFlowNode(workflowId, status).getPreviewButton();
}
/**
* 获取文章流步骤的退回按钮列表
*
* @param workflowId
* @param status
* @return
*/
public Map<Integer, WorkerFlowButton> getPreviews(Integer workflowId, Integer status) {
WorkFlow wf = getWorkFlow(workflowId);
WorkFlowNode wfNode = wf.getFlowStepsMap().get(status);
Map<Integer, WorkerFlowButton> previewButtons = new LinkedHashMap<Integer, WorkerFlowButton>();
while(wfNode != null && wfNode.getPreviewButton() != null){
Integer preStatus = wfNode.getPreviewButton().getStatus();
previewButtons.put(preStatus, wfNode.getPreviewButton());
wfNode = (WorkFlowNode) wf.getFlowStepsMap().get((preStatus));
}
return previewButtons;
}
/**
* 导入工作流
* @param file
* @param name
* @return
*/
public void importWorkFlow(File file, String name) {
// 判断工作流名称是否重复
List<Element> workflowList = XMLDocUtil.selectNodes(templateDoc, "//workflow");
for ( Element workflow : workflowList ) {
String nodeName = workflow.elementText("name");
if(nodeName.equals(name)) {
throw new BusinessException("工作流名称已存在!请更换名称!");
}
}
Document importDoc = XMLDocUtil.createDocByAbsolutePath(file.getPath());
Element newWorkFlow = importDoc.getRootElement();
Element rootElement = templateDoc.getRootElement();
rootElement.add(newWorkFlow);
updateDocment(templateDoc);
}
private static void updateDocment(Document doc) {
String path = URLUtil.getResourceFileUrl(CMSConstants.WORKFLOW_TEMPLATE_PATH).getPath();
FileHelper.writeXMLDoc(doc, path);
manager = null; // 重新载入
}
/**
* 删除工作流
* @param code
* @return
*/
public boolean deleteWorkFlow(Integer code) {
Node node = templateDoc.selectSingleNode("/workflows/workflow[code/text()='" + code + "']");
if (node == null) {
throw new BusinessException("未找到要删除的工作流!");
}
node.detach();
updateDocment(templateDoc);
return true;
}
/**
* 获取工作流模板
*/
public static String getModel() {
return XMLDocUtil.createDoc("workflow/WorkFlowTemplate.xml").asXML();
}
}