/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.springext.util; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static com.alibaba.citrus.util.ObjectUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import static org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.*; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import com.alibaba.citrus.util.Assert; import org.dom4j.io.DOMReader; import org.dom4j.io.SAXWriter; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.ContentHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; /** * 方便操作dom的工具。 * * @author Michael Zhou */ public class DomUtil { /** 将W3C element转换成DOM4j element。 */ public static org.dom4j.Element convertElement(Element element) { Document doc; try { doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw new IllegalArgumentException("Failed to create dom4j document", e); } Element clonedElement = (Element) doc.importNode(element, true); doc.appendChild(clonedElement); DOMReader reader = new DOMReader(); org.dom4j.Document dom4jDoc = reader.read(doc); return dom4jDoc.getRootElement(); } /** 将W3C element转换成SAX事件。 */ public static void convertElement(Element element, ContentHandler contentHandler) throws SAXException { SAXWriter writer = new SAXWriter(contentHandler); if (contentHandler instanceof ErrorHandler) { writer.setErrorHandler((ErrorHandler) contentHandler); } if (contentHandler instanceof LexicalHandler) { writer.setLexicalHandler((LexicalHandler) contentHandler); } writer.write(convertElement(element)); } /** 取得所有子elements。 */ public static List<Element> subElements(Element element) { return subElements(element, null); } /** 取得所有子elements,如果未指定selector,则返回所有elements。 */ public static List<Element> subElements(Element element, ElementSelector selector) { NodeList nodes = element.getChildNodes(); List<Element> subElements = createArrayList(nodes.getLength()); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node instanceof Element) { Element subElement = (Element) node; if (selector == null || selector.accept(subElement)) { subElements.add(subElement); } } } return subElements; } public static Element theOnlySubElement(Element element, ElementSelector selector) { List<Element> subElements = subElements(element, selector); switch (subElements.size()) { case 1: return subElements.get(0); case 0: return null; default: fail("too more sub-elements of %s", element.getNodeName()); return null; } } /** Element选择器。 */ public static interface ElementSelector { boolean accept(Element element); } /** 过滤出指定namespace下的elements,或不存在namespace的elements(unqualified)。 */ public static ElementSelector sameNs(Element element) { String namespaceURI = assertNotNull(element, "element").getNamespaceURI(); return or(ns(namespaceURI), ns(null)); } /** 过滤出默认namespace,即beans名字空间下的elements。 */ public static ElementSelector beansNs() { return ns(BEANS_NAMESPACE_URI); } /** 匹配任意element。 */ public static ElementSelector any() { return new ElementSelector() { public boolean accept(Element element) { return true; } @Override public String toString() { return "any"; } }; } /** 不匹配任意element。 */ public static ElementSelector none() { return new ElementSelector() { public boolean accept(Element element) { return false; } @Override public String toString() { return "none"; } }; } /** 过滤出指定namespace下的elements。 */ public static ElementSelector ns(String nsUri) { final String trimmedNsUri = trimToNull(nsUri); return new ElementSelector() { public boolean accept(Element element) { return isEquals(element.getNamespaceURI(), trimmedNsUri); } @Override public String toString() { return "ns[" + (trimmedNsUri == null ? "no namespace" : trimmedNsUri) + "]"; } }; } /** 过滤指定名称的elements。 */ public static ElementSelector name(String name) { final String trimmedName = assertNotNull(trimToNull(name), "elementName"); return new ElementSelector() { public boolean accept(Element element) { String name = element.getNamespaceURI() == null ? element.getNodeName() : element.getLocalName(); return isEquals(name, trimmedName); } @Override public String toString() { return "name[" + trimmedName + "]"; } }; } /** 符合任意一个selector条件,即接受之。 */ public static ElementSelector or(final ElementSelector... selectors) { return new ElementSelector() { public boolean accept(Element element) { if (selectors != null) { for (ElementSelector selector : selectors) { if (selector.accept(element)) { return true; } } return false; } else { return true; } } @Override public String toString() { return "or" + asList(selectors); } }; } /** 符合所有selector条件,才接受之。 */ public static ElementSelector and(final ElementSelector... selectors) { return new ElementSelector() { public boolean accept(Element element) { if (selectors != null) { for (ElementSelector selector : selectors) { if (!selector.accept(element)) { return false; } } } return true; } @Override public String toString() { return "and" + asList(selectors); } }; } /** 不符合selector条件,才接受之。 */ public static ElementSelector not(final ElementSelector selector) { assertNotNull(selector, "selector"); return new ElementSelector() { public boolean accept(Element element) { return !selector.accept(element); } @Override public String toString() { return "not[" + selector + "]"; } }; } /** 抛出异常,通常和or子句配合。 */ public static ElementSelector error() { return error(null, null); } /** 抛出异常,通常和or子句配合。 */ public static ElementSelector error(final Assert.ExceptionType type, final String message) { return new ElementSelector() { public boolean accept(Element element) { assertTrue(false, type, defaultIfEmpty(message, "Unexpected element: " + element.getNodeName())); return false; } @Override public String toString() { return "error"; } }; } }