⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlutil.java

📁 jbpm-bpel-1.1.Beta3 JBoss jBPM Starters Kit  是一个综合包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
 * published by JBoss Inc.; either version 1.0 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
package org.jbpm.bpel.xml.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.Text;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jaxen.JaxenException;
import org.jaxen.Navigator;
import org.jaxen.SimpleNamespaceContext;
import org.jaxen.UnsupportedAxisException;
import org.jaxen.XPath;
import org.jaxen.dom.DOMXPath;
import org.jaxen.dom.DocumentNavigator;
import org.jaxen.function.StringFunction;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.ibm.wsdl.util.xml.DOMUtils;

import org.jbpm.bpel.endpointref.EndpointReference;
import org.jbpm.bpel.xml.BpelConstants;

/**
 * Utility methods for dealing with JAXP objects.
 * @author Alejandro Gu韟ar
 * @version $Revision: 1.5 $ $Date: 2007/01/22 17:27:03 $
 */
public class XmlUtil {

  private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
  static final String DEFAULT_NAMESPACE_PREFIX = "defaultNS";

  private static final Log log = LogFactory.getLog(XmlUtil.class);
  private static final boolean traceEnabled = log.isTraceEnabled();

  private static ThreadLocal documentBuilderLocal = new ThreadLocal() {

    protected Object initialValue() {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setNamespaceAware(true);
      factory.setValidating(true);
      factory.setCoalescing(true);
      factory.setIgnoringElementContentWhitespace(true);
      factory.setIgnoringComments(true);
      try {
        // Pick XML Schema as the schema language
        factory.setAttribute(JAXP_SCHEMA_LANGUAGE, BpelConstants.NS_XML_SCHEMA);
      }
      catch (IllegalArgumentException e) {
        log.fatal(
            "JAXP implementation does not support XML Schema validation, "
                + "BPEL reader will not work properly", e);
        throw new AssertionError(e);
      }
      try {
        // Do full type checking
        factory.setAttribute(
            "http://apache.org/xml/features/validation/schema-full-checking",
            Boolean.TRUE);
        // Only do schema validation if a schema is specified as a namespace
        factory.setAttribute(
            "http://apache.org/xml/features/validation/dynamic", Boolean.TRUE);
      }
      catch (IllegalArgumentException e) {
        log.warn("JAXP implementation is not Xerces, cannot enable dynamic schema validation, "
            + "XML documents without schema location will not parse.");
      }
      try {
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        documentBuilder.setEntityResolver(new LocalEntityResolver());
        return documentBuilder;
      }
      catch (ParserConfigurationException e) {
        throw new RuntimeException("could not create document builder", e);
      }
    }
  };

  private static ThreadLocal transformerFactoryLocal = new ThreadLocal() {

    protected Object initialValue() {
      return TransformerFactory.newInstance();
    }
  };

  private XmlUtil() {
    // Suppress default constructor, ensuring non-instantiability
  }

  /**
   * Gets the first child element of the given node with the specified local
   * name and a <code>null</code> or empty namespace URI.
   * @param parent the parent node to examine
   * @param localName the local name of the desired child element
   * @return the corresponding child element, or <code>null</code> if there is
   *         no match
   */
  public static Element getElement(Node parent, String localName) {
    return getElement(parent, null, localName);
  }

  /**
   * Gets the first child element of the given SOAP element with the specified
   * local name and a <code>null</code> or empty namespace URI. This overload
   * is necessary as method {@link Node#getNextSibling()} does not behave as
   * expected under some SAAJ implementations.
   * @param parent the parent SOAP element to examine
   * @param localName the local name of the desired child element
   * @return the corresponding child element, or <code>null</code> if there is
   *         no match
   */
  public static SOAPElement getElement(SOAPElement parent, String localName) {
    return getElement(parent, null, localName);
  }

  /**
   * Gets the first child element of the given node with the specified namespace
   * URI and local name.
   * @param parent the parent node to examine
   * @param namespaceURI the namespace URI of the desired child element; if
   *        <code>null</code>, only elements with a <code>null</code> or
   *        empty namespace URI will be considered
   * @param localName the local name of the desired child element
   * @return the corresponding child element, or <code>null</code> if there is
   *         no match
   */
  public static Element getElement(Node parent, String namespaceURI,
      String localName) {
    for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (QNameElementPredicate.evaluate(child, namespaceURI, localName))
        return (Element) child;
    }
    return null;
  }

  /**
   * Gets the first child element of the given SOAP element with the specified
   * namespace URI and local name. This overload is necessary as method
   * {@link Node#getNextSibling()} does not behave as expected under some SAAJ
   * implementations.
   * @param parent the parent node to examine
   * @param namespaceURI the namespace URI of the desired child element; if
   *        <code>null</code>, only elements with a <code>null</code> or
   *        empty namespace URI will be considered
   * @param localName the local name of the desired child element
   * @return the corresponding child element, or <code>null</code> if there is
   *         no match
   */
  public static SOAPElement getElement(SOAPElement parent, String namespaceURI,
      String localName) {
    Iterator childIt = parent.getChildElements();
    while (childIt.hasNext()) {
      javax.xml.soap.Node child = (javax.xml.soap.Node) childIt.next();
      if (QNameElementPredicate.evaluate(child, namespaceURI, localName))
        return (SOAPElement) child;
    }
    return null;
  }

  /**
   * Gets the first child element of the given node.
   * @param parent the parent node to examine
   * @return the corresponding child element, or <code>null</code> if there is
   *         no match
   */
  public static Element getElement(Node parent) {
    for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (child.getNodeType() == Node.ELEMENT_NODE)
        return (Element) child;
    }
    return null;
  }

  /**
   * Gets the first child element of the given SOAP element.
   * @param parent the parent SOAP element to examine
   * @return the corresponding child element, or <code>null</code> if there is
   *         no match
   */
  public static SOAPElement getElement(SOAPElement parent) {
    Iterator childIt = parent.getChildElements();
    while (childIt.hasNext()) {
      Object child = childIt.next();
      if (child instanceof SOAPElement)
        return (SOAPElement) child;
    }
    return null;
  }

  /**
   * Gets an iterator over the child elements of the given node with the
   * specified namespace URI and any local name.
   * @param parent the parent node to iterate
   * @param namespaceURI the namespace URI of the desired child elements; if
   *        <code>null</code>, only elements with a <code>null</code> or
   *        empty namespace URI will be iterated
   * @return an {@link Element} iterator, empty if there is no match
   */
  public static Iterator getElements(Node parent, String namespaceURI) {
    return IteratorUtils.filteredIterator(new NodeIterator(parent),
        new NamespaceElementPredicate(namespaceURI));
  }

  /**
   * Gets an iterator over the child elements of the given node with the
   * specified namespace URI and local name.
   * @param parent the parent node to iterate
   * @param namespaceURI the namespace URI of the desired child elements; if
   *        <code>null</code>, only elements with a <code>null</code> or
   *        empty namespace URI will be iterated
   * @param localName the local name of the desired child elements
   * @return an {@link Element} iterator, empty if there is no match
   */
  public static Iterator getElements(Node parent, String namespaceURI,
      String localName) {
    return IteratorUtils.filteredIterator(new NodeIterator(parent),
        new QNameElementPredicate(namespaceURI, localName));
  }

  /**
   * Gets an attribute value of the given element.
   * @param ownerElem the element that owns the attribute
   * @param attrName the name of the attribute to retrieve
   * @return the attribute value as a string, or <code>null</code> if that
   *         attribute does not have a specified value
   */
  public static String getAttribute(Element ownerElem, String attrName) {
    Attr attribute = ownerElem.getAttributeNode(attrName);
    return attribute != null ? attribute.getValue() : null;
  }

  /**
   * Resolves a qualified name from a prefixed name appearing in the context of
   * the given node.
   * @param prefixedName a name that may contain a colon character
   * @param contextNode the node to search for namespace declarations
   * @return a qualified name whose fields are set as follows:
   *         <ul>
   *         <li><i>localPart</i> substring of the name after the first colon</li>
   *         <li><i>prefix</i> substring of the name before the first colon</li>
   *         <li><i>namespaceURI</i> namespace associated with the prefix
   *         above</li>
   *         </ul>
   */
  public static QName getQName(String prefixedName, Node contextNode) {
    String prefix;
    String namespaceURI;
    String localPart;

    int index = prefixedName.indexOf(':');
    if (index == -1) {
      localPart = prefixedName;
      prefix = "";
      namespaceURI = "";
    }
    else {
      localPart = prefixedName.substring(index + 1);
      prefix = prefixedName.substring(0, index);
      namespaceURI = getNamespaceURI(prefix, contextNode);
    }
    return new QName(namespaceURI, localPart, prefix);
  }

  public static String getStringValue(Object value) {
    return DatatypeUtil.toString(value);
  }

  public static void setObjectValue(Node node, Object value) {
    switch (node.getNodeType()) {
    case Node.ELEMENT_NODE:
      setObjectValue((Element) node, value);
      break;
    case Node.DOCUMENT_NODE:
      setObjectValue(((Document) node).getDocumentElement(), value);
      break;
    default:
      // replace content
      node.setNodeValue(getStringValue(value));
    }
  }

  public static void setObjectValue(Element elem, Object value) {
    if (value instanceof Node) {
      if (value instanceof SOAPElement) {
        // replace element
        copy(elem, (SOAPElement) value);
      }
      else if (value instanceof Element) {
        // replace element
        copy(elem, (Element) value);
      }
      else if (value instanceof Document) {
        // replace element
        copy(elem, ((Document) value).getDocumentElement());
      }
      else {
        // replace content
        setStringValue(elem, ((Node) value).getNodeValue());
      }
    }
    else if (value instanceof EndpointReference) {
      // replace element
      ((EndpointReference) value).writeServiceRef(elem);
    }
    else {
      // replace content
      setStringValue(elem, StringFunction.evaluate(value,
          DocumentNavigator.getInstance()));
    }
  }

  public static void setStringValue(Element elem, String value) {
    // remove xsi:nil
    elem.removeAttributeNS(BpelConstants.NS_XML_SCHEMA_INSTANCE,
        BpelConstants.ATTR_NIL);
    // save first child
    Node firstChild = elem.getFirstChild();
    // if first child is text, reuse it
    if (firstChild instanceof org.w3c.dom.Text) {
      firstChild.setNodeValue(value);
    }
    // otherwise, just create new text
    else {
      firstChild = elem.getOwnerDocument().createTextNode(value);
    }
    // remove all children
    removeChildNodes(elem);
    // append text
    elem.appendChild(firstChild);
  }

  static final String QUALIFIED_VALUE_PREFIX = "valueNS";

  public static void setQNameValue(Element elem, QName value) {
    String namespace = value.getNamespaceURI();
    String prefixedValue;
    if (namespace.length() > 0) {
      String prefix = XmlUtil.getPrefix(namespace, elem);
      if (prefix == null) {
        prefix = generatePrefix(elem, QUALIFIED_VALUE_PREFIX);
        addNamespaceDeclaration(elem, namespace, prefix);
      }
      prefixedValue = prefix + ':' + value.getLocalPart();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -