Java tutorial
/** * 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 org.soybeanMilk.core.config.parser; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.InputStream; import java.io.Serializable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.soybeanMilk.SbmUtils; import org.soybeanMilk.core.Constants; import org.soybeanMilk.core.Executable; import org.soybeanMilk.core.ExecuteException; import org.soybeanMilk.core.ObjectSource; import org.soybeanMilk.core.bean.Converter; import org.soybeanMilk.core.bean.DefaultGenericConverter; import org.soybeanMilk.core.bean.GenericConverter; import org.soybeanMilk.core.config.Configuration; import org.soybeanMilk.core.config.Interceptor; import org.soybeanMilk.core.exe.Action; import org.soybeanMilk.core.exe.Invoke; import org.soybeanMilk.core.exe.Invoke.Arg; import org.soybeanMilk.core.exe.support.DefaultResolverObjectFactory; import org.soybeanMilk.core.exe.support.DynamicResolver; import org.soybeanMilk.core.exe.support.FactoryResolver; import org.soybeanMilk.core.exe.support.KeyArg; import org.soybeanMilk.core.exe.support.ObjectResolver; import org.soybeanMilk.core.exe.support.ObjectSourceResolver; import org.soybeanMilk.core.exe.support.ResolverObjectFactory; import org.soybeanMilk.core.exe.support.ValueArg; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * ?? * @author earthangry@gmail.com * @date 2010-10-1 */ public class ConfigurationParser { private static Log log = LogFactory.getLog(ConfigurationParser.class); protected static final String TAG_ROOT = "soybean-milk"; protected static final String TAG_GLOBAL_CONFIG = "global-config"; protected static final String TAG_GENERIC_CONVERTER = "generic-converter"; protected static final String TAG_GENERIC_CONVERTER_ATTR_CLASS = "class"; protected static final String TAG_CONVERTER = "converter"; protected static final String TAG_CONVERTER_ATTR_SRC = "src"; protected static final String TAG_CONVERTER_ATTR_TARGET = "target"; protected static final String TAG_CONVERTER_ATTR_CLASS = TAG_GENERIC_CONVERTER_ATTR_CLASS; protected static final String TAG_INTERCEPROT = "interceptor"; protected static final String TAG_INTERCEPROT_ATTR_BEFORE = "before"; protected static final String TAG_INTERCEPROT_ATTR_AFTER = "after"; protected static final String TAG_INTERCEPROT_ATTR_EXCEPTION = "exception"; protected static final String TAG_INTERCEPROT_ATTR_EXECUTION_KEY = "execution-key"; protected static final String TAG_INCLUDES = "includes"; protected static final String TAG_LOCATION = "location"; protected static final String TAG_RESOLVERS = "resolvers"; protected static final String TAG_RESOLVER = "resolver"; protected static final String TAG_RESOLVER_ATTR_ID = "id"; protected static final String TAG_RESOLVER_ATTR_CLASS = "class"; protected static final String TAG_EXECUTABLES = "executables"; protected static final String TAG_EXECUTABLES_ATTR_PREFIX = "prefix"; protected static final String TAG_ACTION = "action"; protected static final String TAG_ACTION_ATTR_NAME = "name"; protected static final String TAG_INVOKE = "invoke"; protected static final String TAG_INVOKE_ATTR_NAME = TAG_ACTION_ATTR_NAME; protected static final String TAG_INVOKE_ATTR_METHOD = "method"; protected static final String TAG_INVOKE_ATTR_RESOLVER = "resolver"; protected static final String TAG_INVOKE_ATTR_RESULT_KEY = "result-key"; protected static final String TAG_INVOKE_ATTR_BREAKER = "breaker"; protected static final String TAG_ARG = "arg"; protected static final String TAG_ARG_ATTR_TYPE = "type"; protected static final String TAG_REF = "ref"; protected static final String TAG_REF_ATTR_NAME = "name"; /***/ private Document rootDocument; /**?*/ private Configuration configuration; /**??*/ private List<Document> modules; /**???*/ private String currentExecutablePrefix; /** * ??? */ public ConfigurationParser() { this(null); } /** * ????? * @param configuration ? */ public ConfigurationParser(Configuration configuration) { setConfiguration(configuration); } /** * ?? * @return */ public Configuration getConfiguration() { return configuration; } /** * ??????? * @param configuration */ public void setConfiguration(Configuration configuration) { this.configuration = configuration; } /** * ?? * @return */ public Document getDocument() { return this.rootDocument; } /** * ? * @param document */ public void setDocument(Document document) { this.rootDocument = document; } /** * ?? * @return */ public List<Document> getModules() { return modules; } /** * ? * @param modules */ public void setModules(List<Document> modules) { this.modules = modules; } /** * ?? * @return */ public Configuration parse() { return parse((String) null); } /** * ?? * @param configFile ???? * @return */ public Configuration parse(String configFile) { if (configFile == null || configFile.length() == 0) configFile = getDefaultConfigFile(); setDocument(parseDocument(configFile)); parseAll(); return getConfiguration(); } /** * ?? * @param in * @return */ public Configuration parse(InputStream in) { setDocument(parseDocument(in)); parseAll(); return getConfiguration(); } /** * ? * @param document * @return */ public Configuration parse(Document document) { setDocument(document); parseAll(); return getConfiguration(); } /** * ?? * @return ? */ protected void parseAll() { if (getConfiguration() == null) setConfiguration(createConfigurationInstance()); Element rootDocEle = getDocumentRootElement(rootDocument); parseGlobalConfigs(rootDocEle); parseIncludes(rootDocEle); parseResolvers(rootDocEle); parseExecutables(rootDocEle); if (modules != null) { for (Document doc : modules) { Element subDoc = getDocumentRootElement(doc); parseResolvers(subDoc); parseExecutables(subDoc); } } parseRefs(); } /** * ?? */ protected void parseGlobalConfigs(Element docRoot) { Element parent = getSingleElementByTagName(docRoot, TAG_GLOBAL_CONFIG); parseGenericConverter(parent); parseInterceptor(parent); } /** * ???? */ protected void parseIncludes(Element docRoot) { List<Element> files = getChildrenByTagName(getSingleElementByTagName(docRoot, TAG_INCLUDES), TAG_LOCATION); if (files == null || files.isEmpty()) return; this.modules = new ArrayList<Document>(); for (Element el : files) { String fileName = getTextContent(el); assertNotEmpty(fileName, "<" + TAG_LOCATION + "> content must not be null"); Document[] docs = parseDocuments(fileName); if (docs != null) { for (Document d : docs) this.modules.add(d); } } } /** * ? */ protected void parseResolvers(Element docRoot) { List<Element> children = getChildrenByTagName(getSingleElementByTagName(docRoot, TAG_RESOLVERS), TAG_RESOLVER); if (children != null && !children.isEmpty()) { ResolverObjectFactory rf = configuration.getResolverObjectFactory(); if (rf == null) { rf = createResolverObjectFactoryInstance(); configuration.setResolverObjectFactory(rf); } ResolverObjectFactory drf = (ResolverObjectFactory) rf; for (Element e : children) { String id = getAttributeValueIngoreEmpty(e, TAG_RESOLVER_ATTR_ID); assertNotEmpty(id, "<" + TAG_RESOLVER + "> attribute [" + TAG_RESOLVER_ATTR_ID + "] must not be null"); String clazz = getAttributeValueIngoreEmpty(e, TAG_RESOLVER_ATTR_CLASS); assertNotEmpty(clazz, "<" + TAG_RESOLVER + "> of id " + SbmUtils.toString(id) + " attribute [" + TAG_RESOLVER_ATTR_CLASS + "] must not be null"); Object resolver = createClassInstance(clazz); drf.addResolverObject(id, resolver); } } } /** * ?? */ protected void parseExecutables(Element docRoot) { List<Element> executables = getChildrenByTagName(docRoot, TAG_EXECUTABLES); if (executables != null) { for (Element ele : executables) { setCurrentExecutablePrefix(getAttributeValue(ele, TAG_EXECUTABLES_ATTR_PREFIX)); List<Element> children = getChildrenByTagName(ele, null); if (children != null) { for (Element e : children) { Executable executable = createExecutableInstance(e.getTagName()); if (executable instanceof Action) setActionProperties((Action) executable, e); else setInvokeProperties((Invoke) executable, e, true); configuration.addExecutable(executable); } } } } } /** * ? */ protected void parseRefs() { processExecutableRefs(); processInterceptorInfoRefs(); } /** * ?? * @param parent */ protected void parseGenericConverter(Element parent) { Element cvtEl = getSingleElementByTagName(parent, TAG_GENERIC_CONVERTER); String clazz = cvtEl == null ? null : getAttributeValueIngoreEmpty(cvtEl, TAG_GENERIC_CONVERTER_ATTR_CLASS); GenericConverter genericConverter = configuration.getGenericConverter(); if (genericConverter == null) { if (clazz == null || clazz.length() == 0) genericConverter = createGenericConverterInstance(); else genericConverter = (GenericConverter) createClassInstance(clazz); configuration.setGenericConverter(genericConverter); } parseSupportConverters(genericConverter, cvtEl); } /** * ???? * @param genericConverter * @param parent */ protected void parseSupportConverters(GenericConverter genericConverter, Element parent) { List<Element> children = getChildrenByTagName(parent, TAG_CONVERTER); if (children == null || children.isEmpty()) return; for (Element e : children) { String src = getAttributeValueIngoreEmpty(e, TAG_CONVERTER_ATTR_SRC); String target = getAttributeValueIngoreEmpty(e, TAG_CONVERTER_ATTR_TARGET); String clazz = getAttributeValueIngoreEmpty(e, TAG_CONVERTER_ATTR_CLASS); assertNotEmpty(src, "<" + TAG_CONVERTER + "> attribute [" + TAG_CONVERTER_ATTR_SRC + "] must not be empty"); assertNotEmpty(target, "<" + TAG_CONVERTER + "> attribute [" + TAG_CONVERTER_ATTR_TARGET + "] must not be empty"); assertNotEmpty(clazz, "<" + TAG_CONVERTER + "> attribute [" + TAG_CONVERTER_ATTR_CLASS + "] must not be empty"); genericConverter.addConverter(nameToType(src), nameToType(target), (Converter) createClassInstance(clazz)); } } /** * ?? * @param element */ protected void parseInterceptor(Element parent) { Element el = getSingleElementByTagName(parent, TAG_INTERCEPROT); if (el == null) return; String before = getAttributeValueIngoreEmpty(el, TAG_INTERCEPROT_ATTR_BEFORE); String after = getAttributeValueIngoreEmpty(el, TAG_INTERCEPROT_ATTR_AFTER); String exception = getAttributeValueIngoreEmpty(el, TAG_INTERCEPROT_ATTR_EXCEPTION); String executionKey = getAttributeValueIngoreEmpty(el, TAG_INTERCEPROT_ATTR_EXECUTION_KEY); assertNotEmpty(executionKey, "<" + TAG_INTERCEPROT + "> attribute [" + TAG_INTERCEPROT_ATTR_EXECUTION_KEY + "] must not be empty"); Interceptor ii = createInterceptorInfoInstance(); ii.setExecutionKey(executionKey); if (before != null) ii.setBefore(new ExecutableRefProxy(before, getCurrentExecutablePrefix())); if (after != null) ii.setAfter(new ExecutableRefProxy(after, getCurrentExecutablePrefix())); if (exception != null) ii.setException(new ExecutableRefProxy(exception, getCurrentExecutablePrefix())); getConfiguration().setInterceptor(ii); } /** * ? * @param action * @param element */ protected void setActionProperties(Action action, Element element) { //???""servlet??serlvet String name = getAttributeValue(element, TAG_ACTION_ATTR_NAME); assertNotNull(name, "<" + TAG_ACTION + "> attribute [" + TAG_ACTION_ATTR_NAME + "] must not be null"); action.setName(formatGlobalExecutableName(name)); List<Element> children = getChildrenByTagName(element, null); for (Element e : children) { String tagName = e.getTagName(); if (TAG_REF.equals(tagName)) { String refExecutableName = getAttributeValue(e, TAG_REF_ATTR_NAME); assertNotNull(refExecutableName, "<" + TAG_REF + "> attribute [" + TAG_REF_ATTR_NAME + "] in <" + TAG_ACTION + "> named " + SbmUtils.toString(action.getName()) + " must not be null"); action.addExecutable(new ExecutableRefProxy(refExecutableName, getCurrentExecutablePrefix())); } else if (TAG_INVOKE.equals(tagName)) { Invoke invoke = createInvokeIntance(); setInvokeProperties(invoke, e, false); action.addExecutable(invoke); } } } /** * ? * @param invoke * @param element * @param global ? */ protected void setInvokeProperties(Invoke invoke, Element element, boolean global) { String methodName = getAttributeValueIngoreEmpty(element, TAG_INVOKE_ATTR_METHOD); String breaker = getAttributeValueIngoreEmpty(element, TAG_INVOKE_ATTR_BREAKER); if (breaker != null) { Serializable brk = null; if (Boolean.TRUE.toString().equals(breaker)) brk = Boolean.TRUE; else if (Boolean.FALSE.toString().equals(breaker)) brk = Boolean.FALSE; else brk = breaker; invoke.setBreaker(brk); } if (methodName == null) setInvokePropertiesStatement(invoke, element, global); else setInvokePropertiesXml(invoke, element, global); } /** * ?? * @param invoke * @param element * @param global ? */ protected void setInvokePropertiesStatement(Invoke invoke, Element element, boolean global) { String statement = getTextContent(element); assertNotEmpty(statement, "<" + TAG_INVOKE + "> content must not be empty"); String name = getAttributeValue(element, TAG_INVOKE_ATTR_NAME); if (global) name = formatGlobalExecutableName(name); InvokeStatementParser isp = new InvokeStatementParser(statement); isp.parse(); invoke.setName(name); invoke.setResultKey(isp.getResultKey()); invoke.setMethodName(isp.getMethodName()); processInvokeResolverInit(invoke, isp.getResolver()); processInvokeArgsInit(invoke, isp.getArgs(), isp.getArgTypes()); } /** * XML? * @param invoke * @param element * @param global ? */ protected void setInvokePropertiesXml(Invoke invoke, Element element, boolean global) { String name = getAttributeValue(element, TAG_INVOKE_ATTR_NAME); if (global) name = formatGlobalExecutableName(name); String methodName = getAttributeValueIngoreEmpty(element, TAG_INVOKE_ATTR_METHOD); String resolver = getAttributeValueIngoreEmpty(element, TAG_INVOKE_ATTR_RESOLVER); String resultKey = getAttributeValueIngoreEmpty(element, TAG_INVOKE_ATTR_RESULT_KEY); if (methodName == null) throw new ParseException( "<" + TAG_INVOKE + "> attribute [" + TAG_INVOKE_ATTR_METHOD + "] must not be null"); if (resolver == null) throw new ParseException( "<" + TAG_INVOKE + "> attribute [" + TAG_INVOKE_ATTR_RESOLVER + "] must not be null"); invoke.setName(name); invoke.setResultKey(resultKey); invoke.setMethodName(methodName); processInvokeResolverInit(invoke, resolver); parseArgs(invoke, element); } /** * ?parent?? * @param invoke * @param parent */ protected void parseArgs(Invoke invoke, Element parent) { List<Element> elements = getChildrenByTagName(parent, TAG_ARG); if (elements == null) return; String[] strArgs = new String[elements.size()]; String[] strArgTypes = new String[elements.size()]; for (int i = 0, len = strArgs.length; i < len; i++) { Element e = elements.get(i); String type = getAttributeValue(e, TAG_ARG_ATTR_TYPE); String content = getTextContent(e); if (content == null) throw new ParseException("<" + TAG_ARG + "> must have text content"); strArgs[i] = content; strArgTypes[i] = type; } processInvokeArgsInit(invoke, strArgs, strArgTypes); } /** * ?Invoke? * @param invoke * @param resultKey * @param resolver * @param methodName * @param args * @param strArgTypes * @date 2012-5-8 */ /* protected void processInvokePropertiesInit(Invoke invoke, String resultKey, String resolver, String methodName, String[] strArgs, String[] strArgTypes) { invoke.setResultKey(resultKey); boolean classResolver=false; //resolver?? if(resolver.indexOf('.') > -1) { try { Class<?> rc=Class.forName(resolver); invoke.setResolverProvider(new ObjectResolverProvider(null, rc)); classResolver=true; } catch(Exception e) { classResolver=false; } } if(!classResolver) { FactoryResolverProvider frp=new FactoryResolverProvider(configuration.getResolverObjectFactory(), resolver); ObjectSourceResolverProvider orp=new ObjectSourceResolverProvider(resolver); invoke.setResolverProvider(new DynamicResolverProvider(frp, orp)); } invoke.setMethodName(methodName); if(strArgs != null) { Arg[] args=new Arg[strArgs.length]; for(int i=0; i<strArgs.length; i++) args[i]=stringToArg(strArgs[i], (strArgTypes==null ? null : strArgTypes[i])); invoke.setArgs(args); } } */ /** * ?? * @param invoke * @param resolver * @date 2012-5-11 */ protected void processInvokeResolverInit(Invoke invoke, String resolver) { boolean classResolver = false; //resolver?? if (resolver.indexOf('.') > -1) { try { Class<?> rc = SbmUtils.narrowToClass(nameToType(resolver)); invoke.setResolver(new ObjectResolver(null, rc)); classResolver = true; } catch (Exception e) { classResolver = false; } } if (!classResolver) { FactoryResolver frp = new FactoryResolver(configuration.getResolverObjectFactory(), resolver); ObjectSourceResolver orp = new ObjectSourceResolver(resolver); invoke.setResolver(new DynamicResolver(frp, orp)); } } /** * ??? * @param invoke * @param resolver * @date 2012-5-11 */ protected void processInvokeArgsInit(Invoke invoke, String[] strArgs, String[] strArgTypes) { if (strArgs != null) { Arg[] args = new Arg[strArgs.length]; for (int i = 0; i < strArgs.length; i++) args[i] = stringToArg(strArgs[i], (strArgTypes == null ? null : strArgTypes[i])); invoke.setArgs(args); } } /** * ????? * ?? */ protected void processExecutableRefs() { Collection<Executable> executables = configuration.getExecutables(); if (executables == null) return; for (Executable exe : executables) { if (exe instanceof Action) { Action action = (Action) exe; List<Executable> actionExes = action.getExecutables(); if (actionExes == null) continue; for (int i = 0, len = actionExes.size(); i < len; i++) { Executable e = actionExes.get(i); if (e instanceof ExecutableRefProxy) { ExecutableRefProxy proxy = ((ExecutableRefProxy) e); Executable targetExe = getTargetRefExecutable((ExecutableRefProxy) e); if (targetExe == null) throw new ParseException( "can not find Executable named " + SbmUtils.toString(proxy.getRefName()) + " referenced in Action " + SbmUtils.toString(action.getName())); actionExes.set(i, targetExe); } } } } } /** * ??? */ protected void processInterceptorInfoRefs() { Interceptor ii = getConfiguration().getInterceptor(); if (ii == null) return; { Executable before = ii.getBefore(); if (before instanceof ExecutableRefProxy) { Executable targetExe = getTargetRefExecutable((ExecutableRefProxy) before); if (targetExe == null) throw new ParseException("can not find 'before' interceptor named " + SbmUtils.toString(((ExecutableRefProxy) before).getRefName())); ii.setBefore(targetExe); } } { Executable after = ii.getAfter(); if (after instanceof ExecutableRefProxy) { Executable targetExe = getTargetRefExecutable((ExecutableRefProxy) after); if (targetExe == null) throw new ParseException("can not find 'after' interceptor named " + SbmUtils.toString(((ExecutableRefProxy) after).getRefName())); ii.setAfter(targetExe); } } { Executable exception = ii.getException(); if (exception instanceof ExecutableRefProxy) { Executable targetExe = getTargetRefExecutable((ExecutableRefProxy) exception); if (targetExe == null) throw new ParseException("can not find 'exception' interceptor named " + SbmUtils.toString(((ExecutableRefProxy) exception).getRefName())); ii.setException(targetExe); } } } /** * ?? * @param proxy * @return * @date 2011-3-15 */ protected Executable getTargetRefExecutable(ExecutableRefProxy proxy) { Executable target = null; //? if (target == null) { if (proxy.getCurrentExecutablePrefix() != null) target = configuration.getExecutable(proxy.getCurrentExecutablePrefix() + proxy.getRefName()); } if (target == null) target = configuration.getExecutable(proxy.getRefName()); return target; } /** * ?????? * @param rawName * @return * @date 2011-3-15 */ protected String formatGlobalExecutableName(String rawName) { String cep = getCurrentExecutablePrefix(); return cep == null ? rawName : cep + rawName; } /** * ??xml?? * @param in * @return * @throws ParseException */ protected Document parseDocument(InputStream in) { Document doc = null; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(false); //?? dbf.setValidating(false); dbf.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); doc = dbf.newDocumentBuilder().parse(in); in.close(); return doc; } catch (Exception e) { throw new ParseException("", e); } } /** * ???? * @param fileName * @return */ protected Document[] parseDocuments(String fileName) { Document[] docs = null; if (fileName.endsWith("/*")) { fileName = formatIncludeFileName(fileName); fileName = fileName.substring(0, fileName.length() - 2); File folder = new File(fileName); if (!folder.exists() || !folder.isDirectory()) throw new ParseException("can not find directory " + SbmUtils.toString(fileName)); File[] files = folder.listFiles(new FileFilter() { //@Override public boolean accept(File pathname) { String name = pathname.getName().toLowerCase(); if (name.endsWith(".xml")) return true; else return false; } }); if (files != null && files.length > 0) { docs = new Document[files.length]; for (int i = 0; i < files.length; i++) { InputStream in = null; try { in = new FileInputStream(files[i]); } catch (Exception e) { throw new ParseException("", e); } docs[i] = parseDocument(in); if (log.isDebugEnabled()) log.debug("parsed Document object from " + SbmUtils.toString(files[i].getAbsolutePath())); } } else { if (log.isDebugEnabled()) log.debug("no xml file found in directory " + SbmUtils.toString(fileName)); } } else { docs = new Document[1]; docs[0] = parseDocument(fileName); } return docs; } /** * ???? * @param fileName * @return */ protected Document parseDocument(String fileName) { fileName = formatIncludeFileName(fileName); InputStream in = null; try { in = getClass().getClassLoader().getResourceAsStream(fileName); } catch (Exception e) { } if (in == null) { try { in = new FileInputStream(fileName); } catch (Exception e1) { } } if (in == null) throw new ParseException("can not find config file named " + SbmUtils.toString(fileName)); Document doc = parseDocument(in); if (log.isDebugEnabled()) log.debug("parsing Document object from " + SbmUtils.toString(fileName)); return doc; } /** * ??? * @param rawFileName * @return */ protected String formatIncludeFileName(String rawFileName) { return rawFileName; } /** * ? * @return */ protected Element getDocumentRootElement(Document doc) { return doc.getDocumentElement(); } protected void setCurrentExecutablePrefix(String currentExecutablePrefix) { this.currentExecutablePrefix = currentExecutablePrefix; } /** * ???? * @return * @date 2011-3-15 */ protected String getCurrentExecutablePrefix() { return this.currentExecutablePrefix; } /** * ?? * @return */ protected String getDefaultConfigFile() { return Constants.DEFAULT_CONFIG_FILE; } /** * ??null * ??????????null * @param parent * @param name * @return * @throws Exception */ protected List<Element> getChildrenByTagName(Element parent, String name) { if (parent == null) return null; boolean filter = name != null; NodeList nl = parent.getChildNodes(); List<Element> elements = new ArrayList<Element>(); for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); if (!(n instanceof Element)) continue; Element e = (Element) nl.item(i); if (!filter) elements.add(e); else { if (name.equals(e.getTagName())) elements.add(e); } } return elements; } /** * ??? * @param parent * @param name * @return */ protected Element getSingleElementByTagName(Element parent, String name) { if (parent == null) return null; NodeList nodes = parent.getElementsByTagName(name); if (nodes == null || nodes.getLength() == 0) return null; return (Element) nodes.item(0); } /** * ??null??? * @param o * @param msg ? */ protected void assertNotEmpty(Object o, String msg) { boolean toThrow = false; if (o == null) toThrow = true; else if (o instanceof String) { String s = (String) o; if (s.length() == 0) toThrow = true; } if (toThrow) throw new ParseException(msg); } /** * ???null * @param o * @param msg */ protected void assertNotNull(Object o, String msg) { if (o == null) throw new ParseException(msg); } /** * ?null * @param element * @param attrName * @return */ protected String getAttributeValueIngoreEmpty(Element element, String attrName) { String v = element.getAttribute(attrName); return v == null || v.length() == 0 ? null : v; } /** * ? * @param element * @param attrName * @return */ protected String getAttributeValue(Element element, String attrName) { Attr attr = element.getAttributeNode(attrName); return attr == null ? null : attr.getValue(); } /** * ? * @param element * @return */ protected String getTextContent(Element element) { String re = element.getTextContent(); return re == null || re.length() == 0 ? null : re; } /** * ?Arg * @param strArg * @param strType * @return * @date 2012-5-8 */ protected Arg stringToArg(String strArg, String strType) { Arg re = null; Type argType = null; if (strType != null && strType.length() > 0) argType = nameToType(strType); if (strArg == null || strArg.length() == 0) re = new ValueArg(strArg, argType); else { int len = strArg.length(); char first = strArg.charAt(0); char end = strArg.charAt(len - 1); // if (Character.isDigit(first)) { Type wrappedType = (argType == null ? null : SbmUtils.wrapType(argType)); if (Byte.class.equals(wrappedType)) { re = new ValueArg(new Byte(strArg), argType); } else if (Short.class.equals(wrappedType)) { re = new ValueArg(new Short(strArg), argType); } else if (Integer.class.equals(wrappedType)) { re = new ValueArg(new Integer(strArg), argType); } else if (Long.class.equals(wrappedType)) { re = new ValueArg(new Long(strArg), argType); } else if (Float.class.equals(wrappedType)) { re = new ValueArg(new Float(strArg), argType); } else if (Double.class.equals(wrappedType)) { re = new ValueArg(new Double(strArg), argType); } else if ('L' == end) { re = new ValueArg(new Long(strArg.substring(0, len - 1)), Long.class); } else if ('l' == end) { re = new ValueArg(new Long(strArg.substring(0, len - 1)), long.class); } else if ('F' == end) { re = new ValueArg(new Float(strArg.substring(0, len - 1)), Float.class); } else if ('f' == end) { re = new ValueArg(new Float(strArg.substring(0, len - 1)), float.class); } else if ('D' == end) { re = new ValueArg(new Double(strArg.substring(0, len - 1)), Double.class); } else if ('d' == end) { re = new ValueArg(new Double(strArg.substring(0, len - 1)), double.class); } else { boolean point = strArg.indexOf('.') >= 0; if (point) re = new ValueArg(new Double(strArg), argType); else re = new ValueArg(new Integer(strArg), argType); } } else if (first == '"') { String ue = SbmUtils.unEscape(strArg); len = ue.length(); if (len < 2 || ue.charAt(len - 1) != '"') throw new ParseException("illegal String definition: " + strArg); if (len == 2) re = new ValueArg("", argType); else re = new ValueArg(ue.subSequence(1, len - 1), argType); } else if (first == '\'') { String ue = SbmUtils.unEscape(strArg); len = ue.length(); if (len != 3 || end != '\'') throw new ParseException("illegal char definition: " + strArg); re = new ValueArg(ue.charAt(1), argType); } else if ("true".equals(strArg)) { re = new ValueArg(Boolean.TRUE, argType); } else if ("false".equals(strArg)) { re = new ValueArg(Boolean.FALSE, argType); } else if ("null".equals(strArg)) { re = new ValueArg(null, argType); } else re = new KeyArg(strArg, argType); } return re; } /** * ??? * @return */ protected Configuration createConfigurationInstance() { return new Configuration(); } protected ResolverObjectFactory createResolverObjectFactoryInstance() { return new DefaultResolverObjectFactory(); } /** * ? * @return */ protected GenericConverter createGenericConverterInstance() { return new DefaultGenericConverter(); } /** * ? * @return */ protected Interceptor createInterceptorInfoInstance() { return new Interceptor(); } /** * ??? * @return */ protected Executable createExecutableInstance(String type) { if (TAG_ACTION.equals(type)) return createActionIntance(); else if (TAG_INVOKE.equals(type)) return createInvokeIntance(); else throw new ParseException("illegal Executable type <" + type + ">"); } /** * ?? * @return */ protected Action createActionIntance() { return new Action(); } /** * ?? * @return */ protected Invoke createInvokeIntance() { return new Invoke(); } /** * * @param clazz * @return */ protected Object createClassInstance(String clazz) { try { return SbmUtils.narrowToClass(SbmUtils.nameToType(clazz)).newInstance(); } catch (Exception e) { throw new ParseException(e); } } /** * ??? * @param type * @return * @date 2012-5-27 */ protected Type nameToType(String type) { try { return SbmUtils.nameToType(type); } catch (Exception e) { throw new ParseException(e); } } /** * ???? * @author earthangry@gmail.com * @date 2010-10-28 * */ protected static class ExecutableRefProxy implements Executable { private String refName; private String currentExecutablePrefix; public ExecutableRefProxy(String refName, String currentExecutablePrefix) { super(); this.refName = refName; this.currentExecutablePrefix = currentExecutablePrefix; } public String getRefName() { return refName; } public void setRefName(String refName) { this.refName = refName; } public String getCurrentExecutablePrefix() { return currentExecutablePrefix; } public void setCurrentExecutablePrefix(String currentExecutablePrefix) { this.currentExecutablePrefix = currentExecutablePrefix; } //@Override public void execute(ObjectSource objectSource) throws ExecuteException { throw new UnsupportedOperationException(); } //@Override public String getName() { throw new UnsupportedOperationException(); } //@Override public String toString() { return Executable.class.getSimpleName() + " [name=" + refName + "]"; } } }