/** * Copyright 1996-2014 FoxBPM ORG. * * 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. * * @author yangguangftlp */ package org.foxbpm.engine.impl.util; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.foxbpm.engine.config.FoxBPMConfig; import org.foxbpm.engine.config.ProcessEngineConfigurator; import org.foxbpm.engine.impl.datavariable.DataObjectDefinitionImpl; import org.foxbpm.engine.impl.event.EventListenerImpl; import org.foxbpm.engine.impl.task.CommandParam; import org.foxbpm.engine.impl.task.TaskCommandDefinitionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * foxbpmcfg配置文件解析处理类 * * @author yangguangftlp * @date 2014年10月28日 */ @SuppressWarnings("unchecked") public class FoxBPMCfgParseUtil { protected static final Logger LOGGER = LoggerFactory.getLogger(XMLToObject.class); private static FoxBPMCfgParseUtil instance; public static final String GENERAL_M_PREFIX = "set"; public static final String BOOL_PREFIX = "is"; public static final String ELEMENT_FOXBPMCONFIG = "FoxBPMConfig"; public static final String ELEMENT_TASKCOMMANDS = "taskCommands"; public static final String ELEMENT_TASKCOMMANDDEFINITION = "taskCommandDefinition"; public static final String ELEMENT_COMMANDPARAM = "commandParam"; public static final String ELEMENT_EVENTLISTENERS = "eventListeners"; public static final String ELEMENT_EVENTLISTENER = "eventListener"; public static final String ELEMENT_BIZDATAOBJECTS = "bizDataObjects"; public static final String ELEMENT_DATAOBJECTBEHAVIOR = "dataObjectBehavior"; public static final String ELEMENT_PLUGIN = "plugin"; public static final String ELEMENT_PLUGINS = "plugins"; private FoxBPMCfgParseUtil() { } /** * 获取实例 * * @return */ public static FoxBPMCfgParseUtil getInstance() { if (null == instance) { synchronized (XMLToObject.class) { if (null == instance) { instance = new FoxBPMCfgParseUtil(); } } } return instance; } /** * 解析foxbpm.cfg配置文件 * * @param in * 文件流 * @return 返回解析后生成的FoxBPMConfig实例对象 */ public FoxBPMConfig parsecfg(InputStream in) { if(in == null){ return null; } try { SAXReader reader = new SAXReader(); Document document; document = reader.read(in); Element rootElem = document.getRootElement(); if (ELEMENT_FOXBPMCONFIG.equals(rootElem.getName())) { return parseElement(rootElem); } } catch (DocumentException e) { throw ExceptionUtil.getException("00006001",e); } return null; } private FoxBPMConfig parseElement(Element element){ Element childElem = null; String nodeName = null; FoxBPMConfig foxBPMConfig = new FoxBPMConfig(); for (Iterator<Element> iterator = element.elementIterator(); iterator.hasNext();) { childElem = iterator.next(); nodeName = childElem.getName(); if (ELEMENT_TASKCOMMANDS.equals(nodeName)) { foxBPMConfig.setTaskCommandDefinitions(parseTaskCommands(childElem)); } else if (ELEMENT_EVENTLISTENERS.equals(nodeName)) { foxBPMConfig.setEventListeners(parseEventListeners(childElem)); } else if (ELEMENT_BIZDATAOBJECTS.equals(nodeName)) { foxBPMConfig.setDataObjectDefinitions(parseBizDataObject(childElem)); }else if(ELEMENT_PLUGINS.equals(nodeName)){ foxBPMConfig.setConfigurators(parsePlugins(childElem)); } } return foxBPMConfig; } private List<ProcessEngineConfigurator> parsePlugins(Element element){ List<ProcessEngineConfigurator> configurators = null; Element childElem = null; String nodeName = null; String className = null; ProcessEngineConfigurator configurator = null; for (Iterator<Element> iterator = element.elementIterator(); iterator.hasNext();) { childElem = iterator.next(); nodeName = childElem.getName(); if (ELEMENT_PLUGIN.equals(nodeName)) { String id = childElem.attributeValue("id"); className = childElem.attributeValue("configurator"); if(StringUtil.isEmpty(className)){ LOGGER.error("plugin{}未配置configurator属性,忽略此配置",id); continue; } try{ configurator = (ProcessEngineConfigurator)ReflectUtil.instantiate(className); }catch(Exception ex){ LOGGER.error("plugin:"+id+"加载失败,已忽略。原因:类:"+className+"反射失败!",ex); continue; } if(configurator != null){ if(configurators == null){ configurators = new ArrayList<ProcessEngineConfigurator>(); } configurators.add(configurator); } } } return configurators; } /** * 解析任务命令 * * @param element * 节点 * @return 返回任务命令定义 * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException */ private List<TaskCommandDefinitionImpl> parseTaskCommands(Element element) { Element childElem = null; String nodeName = null; List<TaskCommandDefinitionImpl> taskCommandDefs = null; TaskCommandDefinitionImpl taskCommandDef = null; List<CommandParam> commandParams = null; for (Iterator<Element> iterator = element.elementIterator(); iterator.hasNext();) { childElem = iterator.next(); nodeName = childElem.getName(); if (ELEMENT_TASKCOMMANDDEFINITION.equals(nodeName)) { taskCommandDef = new TaskCommandDefinitionImpl(); // 处理基本属性 doAttributes(childElem, taskCommandDef); // 处理命令 commandParams = parseCommandParams(childElem); if (null != commandParams) { taskCommandDef.setCommandParam(commandParams); } if (null == taskCommandDefs) { taskCommandDefs = new ArrayList<TaskCommandDefinitionImpl>(); } taskCommandDefs.add(taskCommandDef); } } return taskCommandDefs; } private List<CommandParam> parseCommandParams(Element element) { Element childElem = null; String nodeName = null; List<CommandParam> commandParams = null; CommandParam commandParam = null; for (Iterator<Element> iterator = element.elementIterator(); iterator.hasNext();) { // 处理基本属性 childElem = iterator.next(); nodeName = childElem.getName(); if (ELEMENT_COMMANDPARAM.equals(nodeName)) { commandParam = new CommandParam(); doAttributes(childElem, commandParam); if (null == commandParams) { commandParams = new ArrayList<CommandParam>(); } commandParams.add(commandParam); } } return commandParams; } private List<EventListenerImpl> parseEventListeners(Element element){ Element childElem = null; String nodeName = null; List<EventListenerImpl> eventListeners = null; EventListenerImpl eventListener = null; for (Iterator<Element> iterator = element.elementIterator(); iterator.hasNext();) { childElem = iterator.next(); nodeName = childElem.getName(); if (ELEMENT_EVENTLISTENER.equals(nodeName)) { eventListener = new EventListenerImpl(); // 处理基本属性 doAttributes(childElem, eventListener); if (null == eventListeners) { eventListeners = new ArrayList<EventListenerImpl>(); } eventListeners.add(eventListener); } } return eventListeners; } private List<DataObjectDefinitionImpl> parseBizDataObject(Element element){ Element childElem = null; String nodeName = null; List<DataObjectDefinitionImpl> dataObjectDefinitions = null; DataObjectDefinitionImpl dataObjectDefinition = null; for (Iterator<Element> iterator = element.elementIterator(); iterator.hasNext();) { childElem = iterator.next(); nodeName = childElem.getName(); if (ELEMENT_DATAOBJECTBEHAVIOR.equals(nodeName)) { dataObjectDefinition = new DataObjectDefinitionImpl(); // 处理基本属性 doAttributes(childElem, dataObjectDefinition); if (null == dataObjectDefinitions) { dataObjectDefinitions = new ArrayList<DataObjectDefinitionImpl>(); } dataObjectDefinitions.add(dataObjectDefinition); } } return dataObjectDefinitions; } private void doAttributes(Element element, Object paramObj){ // 处理element属性 Method method = null; Attribute attribute = null; Map<String, Method> methodMap = getSetMethods(GENERAL_M_PREFIX, paramObj); for (int i = 0, length = element.attributeCount(); i < length; i++) { attribute = element.attribute(i); method = methodMap.get(generateMethodName(GENERAL_M_PREFIX, attribute.getName())); if (null != method) { doAttributeValue(paramObj, method, attribute.getValue(), method.getParameterTypes()[0]); } } } private Map<String, Method> getSetMethods(String prefix, Object obj) { Map<String, Method> methodMap = new HashMap<String, Method>(); Method[] methods = obj.getClass().getMethods(); if (null != methods) { int length = methods.length; Method method = null; for (int i = 0; i < length; i++) { method = methods[i]; if (method.getParameterTypes().length == 1 && method.getName().startsWith(prefix)) { methodMap.put(method.getName(), method); } } } return methodMap; } /** * 通过节点名称构造方法名 * * @param prefix * get * @param name * 节点名称 * @return 返回方法名 */ private String generateMethodName(String prefix, String name) { StringBuffer sbuffer = new StringBuffer(); sbuffer.append(name.substring(name.indexOf(':') + 1)); // 处理boolean变量 if (sbuffer.toString().startsWith(BOOL_PREFIX)) { sbuffer.delete(0, 2); } // 处理有些节点属性a:b 去掉a: return new StringBuffer(prefix).append(Character.toUpperCase(sbuffer.charAt(0))).append(sbuffer.substring(1)).toString(); } private void doAttributeValue(Object pObj, Method method, String value, Class<?> pType){ try { if (String.class == pType) { method.invoke(pObj, value); } else if (boolean.class == pType) { method.invoke(pObj, Boolean.valueOf(value)); } else if (int.class == pType) { method.invoke(pObj, Integer.valueOf(value)); } else { // 暂不支持的类型 LOGGER.warn("不支持的类型是:" + pType); } } catch (IllegalArgumentException e) { throw ExceptionUtil.getException("00006002",e,method.toString(),pObj.toString(),value,pType.getName()); } catch (IllegalAccessException e) { throw ExceptionUtil.getException("00006003",e,method.toString(),pObj.toString(),value,pType.getName()); } catch (InvocationTargetException e) { throw ExceptionUtil.getException("00006004",e,method.toString(),pObj.toString(),value,pType.getName()); } } }