/* * Copyright 2010-2011 the original author or authors. * * 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 com.googlecode.starflow.engine.xml; import java.io.StringReader; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.googlecode.starflow.engine.core.Constants; import com.googlecode.starflow.engine.model.elements.ActivityElement; import com.googlecode.starflow.engine.model.elements.ProcessElement; import com.googlecode.starflow.engine.model.elements.TransitionElement; /** * 把流程定义信息解析为java对象 * * @author libinsong1204@gmail.com * @version 1.0 */ public class ProcessDefineParser { public static Document createDocument(String xml) { SAXReader reader = new SAXReader(); Document document = null; try { document = reader.read(new StringReader(xml)); } catch (Exception e) { throw new StarFlowParserException("流程定义信息不正确", e); } return document; } public static ProcessElement createProcessXml(String xml) { ProcessElement processXml = new ProcessElement(); Document document = createDocument(xml); queryProcessXmlInfo(processXml, document); processXml.setTransitions(queryTransitionXmlInfo(document)); processXml.setActivitys(queryActivityXmlInfo(processXml, document)); return processXml; } private static void queryProcessXmlInfo(ProcessElement processXml, Document document) { Element rootElement = document.getRootElement(); String name = rootElement.attributeValue(StarFlowNames.FLOW_ATTR_NAME); String chname = rootElement.attributeValue(StarFlowNames.FLOW_ATTR_CHNAME); String version = rootElement.attributeValue(StarFlowNames.FLOW_ATTR_VERSION); String xpath = "/ProcessDefine/ProcessProperty/".concat(StarFlowNames.FLOW_CHILD_DESC); String description = rootElement.selectSingleNode(xpath).getText(); xpath = "/ProcessDefine/ProcessProperty/".concat(StarFlowNames.FLOW_CHILD_LIMITTIME); String limitTime = rootElement.selectSingleNode(xpath).getText(); processXml.setName(name); if(chname != null) processXml.setChname(chname); else processXml.setChname(name); processXml.setVersion(version); processXml.setDescription(description); processXml.setLimitTime(Long.parseLong(limitTime)); Element node = (Element)rootElement.selectSingleNode("/ProcessDefine/ProcessProperty"); processXml.setEvents(NodeUtil.getTriggerEvents(node)); processXml.setProperties(NodeUtil.getExtProperties(node)); } @SuppressWarnings("unchecked") private static Map<String, ActivityElement> queryActivityXmlInfo(ProcessElement processXml, Document document) { Map<String, ActivityElement> aMap = new ConcurrentHashMap<String, ActivityElement>(); List<Element> actEls = null; String _xpath = "/ProcessDefine/Activitys/Activity"; actEls = document.selectNodes(_xpath); for(Element actEl : actEls) { ActivityElement activityXml = new ActivityElement(); String id = NodeUtil.getNodeAttrValue(actEl, StarFlowNames.ACT_ATTR_ID); activityXml.setId(id); String type = NodeUtil.getNodeAttrValue(actEl, StarFlowNames.ACT_ATTR_TYPE); activityXml.setType(type); activityXml.setName(NodeUtil.getNodeAttrValue(actEl, StarFlowNames.ACT_ATTR_NAME)); activityXml.setDescription(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_DESC)); if(Constants.ACT_TYPE_START.equalsIgnoreCase(type)) {//开始 activityXml.setSplitMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_SPLIT)); } else if(Constants.ACT_TYPE_END.equalsIgnoreCase(type)) {//结束 activityXml.setJoinMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_JOIN)); activityXml.setActivateRuleType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_ACTIVATE_RULE_TYPE)); activityXml.setStartStrategybyAppAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_STARTSTRATEGYBYAPPACTION)); } else if(Constants.ACT_TYPE_TOOLAPP.equalsIgnoreCase(type)) {//自动 activityXml.setFinishType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_AUTO_FINSISH_TYPE)); activityXml.setInvokePattern(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_AUTO_INVOKE_PATTERN)); activityXml.setTransactionType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_AUTO_TRANSACTION_TYPE)); activityXml.setExceptionStrategy(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_EXCEPTION_STRATEGY)); activityXml.setExceptionAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_EXCEPTION_ACTION)); activityXml.setExecuteAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_AUTO_EXEC_ACTION)); activityXml.setJoinMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_JOIN)); activityXml.setSplitMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_SPLIT)); activityXml.setActivateRuleType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_ACTIVATE_RULE_TYPE)); activityXml.setStartStrategybyAppAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_STARTSTRATEGYBYAPPACTION)); activityXml.setEvents(NodeUtil.getTriggerEvents(actEl)); activityXml.setProperties(NodeUtil.getExtProperties(actEl)); } else if(Constants.ACT_TYPE_SUBPROCESS.equalsIgnoreCase(type)) {//子流程 activityXml.setSubProcess(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_SUBPROCESS)); activityXml.setSpInvokePattern(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_SP_INVOKE_PATTERN)); activityXml.setJoinMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_JOIN)); activityXml.setSplitMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_SPLIT)); activityXml.setActivateRuleType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_ACTIVATE_RULE_TYPE)); activityXml.setStartStrategybyAppAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_STARTSTRATEGYBYAPPACTION)); activityXml.setEvents(NodeUtil.getTriggerEvents(actEl)); } else if(Constants.ACT_TYPE_MANUL.equalsIgnoreCase(type)) {//人工环节 activityXml.setParticipantType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_PARTICI_MODE)); activityXml.setIsAllowAppointParticipants(NodeUtil.getNodeBooleanValue(actEl, StarFlowNames.ACT_CHILD_PARTICI_IS_ALLOW_APPOINT)); activityXml.setParticiLogic(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_PARTICI_LOGIC)); activityXml.setParticiSpecActID(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_PARTICI_ACTID)); activityXml.setIsFreeActivity(NodeUtil.getNodeBooleanValue(actEl, StarFlowNames.ACT_FREE_ISFREEACT)); activityXml.setFreeRangeStrategy(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_FREE_RANGESTRATEGY)); activityXml.setIsOnlyLimitedManualActivity(NodeUtil.getNodeBooleanValue(actEl, StarFlowNames.ACT_FREE_ISONLYLIMITEDMANUALACT)); activityXml.setWiMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_WI_MODE)); activityXml.setIsSequentialExecute(NodeUtil.getNodeBooleanValue(actEl, StarFlowNames.ACT_CHILD_WI_IS_SEQ_EXEC)); activityXml.setWorkitemNumStrategy(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_WI_WORKITEMNUMSTRATEGY)); activityXml.setFinishRule(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_WI_FINISHRULE)); activityXml.setFinishRequiredPercent(NodeUtil.getNodeDoubleValue(actEl, StarFlowNames.ACT_CHILD_WI_FINISHREQUIREDPERCENT)); activityXml.setFinishRquiredNum(NodeUtil.getNodeIntValue(actEl, StarFlowNames.ACT_CHILD_WI_FINISHRQUIREDNUM)); activityXml.setIsAutoCancel(NodeUtil.getNodeBooleanValue(actEl, StarFlowNames.ACT_CHILD_WI_IS_AUTO_CANCEL)); activityXml.setJoinMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_JOIN)); activityXml.setSplitMode(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_SPLIT)); activityXml.setLimitTime(NodeUtil.getNodeLongValue(actEl, StarFlowNames.ACT_CHILD_LIMITTIME)); activityXml.setActivateRuleType(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_ACTIVATE_RULE_TYPE)); activityXml.setStartStrategybyAppAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_STARTSTRATEGYBYAPPACTION)); activityXml.setResetParticipant(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_RESET_PARTICIPANT)); activityXml.setAction(NodeUtil.getNodeStringValue(actEl, StarFlowNames.ACT_CHILD_ACTION)); activityXml.setOperations(NodeUtil.getOperations(actEl)); activityXml.setEvents(NodeUtil.getTriggerEvents(actEl)); activityXml.setProperties(NodeUtil.getExtProperties(actEl)); activityXml.setParticipants(NodeUtil.getActParticipants(actEl)); activityXml.setFreeActs(NodeUtil.getActFreeActs(actEl)); } for(TransitionElement transitionXml : processXml.getTransitions()) { if(transitionXml.getTo().equalsIgnoreCase(id)) activityXml.getBeforeTrans().add(transitionXml); if(transitionXml.getFrom().equalsIgnoreCase(id)) activityXml.getAfterTrans().add(transitionXml); } activityXml.setLeft(NodeUtil.getElementLeft(actEl)); activityXml.setTop(NodeUtil.getElementTop(actEl)); aMap.put(id, activityXml); } return aMap; } @SuppressWarnings("unchecked") private static List<TransitionElement> queryTransitionXmlInfo(Document document) { List<TransitionElement> transitions = new CopyOnWriteArrayList<TransitionElement>(); List<Element> tranEls = null; String _xpath = "/ProcessDefine/Transitions/Transition"; tranEls = document.selectNodes(_xpath); for(Element tranEl : tranEls) { TransitionElement transitionXml = new TransitionElement(); transitionXml.setId(NodeUtil.getNodeAttrValue(tranEl, StarFlowNames.TRAN_ATTR_ID)); transitionXml.setName(NodeUtil.getNodeAttrValue(tranEl, StarFlowNames.TRAN_ATTR_NAME)); transitionXml.setFrom(NodeUtil.getNodeAttrValue(tranEl, StarFlowNames.TRAN_ATTR_FROM)); transitionXml.setTo(NodeUtil.getNodeAttrValue(tranEl, StarFlowNames.TRAN_ATTR_TO)); transitionXml.setIsDefault(NodeUtil.getNodeBooleanValue(tranEl, StarFlowNames.TRAN_CHILD_ISDEFAULT)); transitionXml.setComplexExpressionValue(NodeUtil.getNodeStringValue(tranEl, StarFlowNames.TRAN_CHILD_COMPLEXEXPRESSIONVALUE)); transitionXml.setIsSimpleExpression(NodeUtil.getNodeBooleanValue(tranEl, StarFlowNames.TRAN_CHILD_ISSIMPLEEXPRESSION)); transitionXml.setLeftValue(NodeUtil.getNodeStringValue(tranEl, StarFlowNames.TRAN_CHILD_LEFTVALUE)); transitionXml.setCompType(NodeUtil.getNodeStringValue(tranEl, StarFlowNames.TRAN_CHILD_COMPTYPE)); transitionXml.setRightValue(NodeUtil.getNodeStringValue(tranEl, StarFlowNames.TRAN_CHILD_RIGHTVALUE)); transitionXml.setPriority(NodeUtil.getNodeIntValue(tranEl, StarFlowNames.TRAN_CHILD_PRIORITY)); transitionXml.setPoint(NodeUtil.getElementPoint(tranEl)); transitions.add(transitionXml); } return transitions; } }