org.jboss.security.util.xml.DOMUtils Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 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. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.security.util.xml;
// $Id$
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
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 org.jboss.security.PicketBoxLogger;
import org.jboss.security.PicketBoxMessages;
import org.jboss.security.util.StringPropertyReplacer;
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.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* DOM2 utilites
*
* @author [email protected]
* @version $Revision$
*/
@SuppressWarnings("unchecked")
public final class DOMUtils
{
// All elements created by the same thread are created by the same builder and belong to the same doc
private static ThreadLocal documentThreadLocal = new ThreadLocal();
private static ThreadLocal builderThreadLocal = new ThreadLocal() {
protected Object initialValue() {
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new JBossEntityResolver());
return builder;
}
catch (ParserConfigurationException e)
{
throw PicketBoxMessages.MESSAGES.failedToCreateDocumentBuilder(e);
}
}
};
// Hide the constructor
private DOMUtils()
{
}
public static DocumentBuilder getDocumentBuilder()
{
DocumentBuilder builder = (DocumentBuilder)builderThreadLocal.get();
return builder;
}
/** Parse the given XML string and return the root Element
* @param xmlString
* @return the element
* @throws IOException
*/
public static Element parse(String xmlString) throws IOException
{
return parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
}
/** Parse the given XML stream and return the root Element
* @param xmlStream
* @return the element
* @throws IOException
*/
public static Element parse(InputStream xmlStream) throws IOException
{
try
{
Document doc = getDocumentBuilder().parse(xmlStream);
Element root = doc.getDocumentElement();
return root;
}
catch (SAXException e)
{
throw new IOException(e);
}
}
/** Parse the given input source and return the root Element
* @param source
* @return the element
* @throws IOException
*/
public static Element parse(InputSource source) throws IOException
{
try
{
Document doc = getDocumentBuilder().parse(source);
Element root = doc.getDocumentElement();
return root;
}
catch (SAXException e)
{
throw new IOException(e);
}
}
/** Create an Element for a given name
* @param localPart
* @return the element
*/
public static Element createElement(String localPart)
{
Document doc = getOwnerDocument();
return doc.createElement(localPart);
}
/** Create an Element for a given name and prefix
* @param localPart
* @param prefix
* @return the element
*/
public static Element createElement(String localPart, String prefix)
{
Document doc = getOwnerDocument();
return doc.createElement(prefix + ":" + localPart);
}
/** Create an Element for a given name, prefix and uri
* @param localPart
* @param prefix
* @param uri
* @return the element
*/
public static Element createElement(String localPart, String prefix, String uri)
{
Document doc = getOwnerDocument();
if (prefix == null || prefix.length() == 0)
{
return doc.createElementNS(uri, localPart);
}
else
{
return doc.createElementNS(uri, prefix + ":" + localPart);
}
}
/** Create an Element for a given QName
* @param qname
* @return the element
*/
public static Element createElement(QName qname)
{
return createElement(qname.getLocalPart(), qname.getPrefix(), qname.getNamespaceURI());
}
/** Create a org.w3c.dom.Text node
* @param value
* @return the text node
*/
public static Text createTextNode(String value)
{
Document doc = getOwnerDocument();
return doc.createTextNode(value);
}
/** @return the qname of the given node.
* @param el
*/
public static QName getElementQName(Element el)
{
String qualifiedName = el.getNodeName();
return resolveQName(el, qualifiedName);
}
/** Transform the giveen qualified name into a QName
* @param el
* @param qualifiedName
* @return the resolved name
*/
public static QName resolveQName(Element el, String qualifiedName)
{
QName qname;
String prefix = "";
String namespaceURI = "";
String localPart = qualifiedName;
int colIndex = qualifiedName.indexOf(":");
if (colIndex > 0)
{
prefix = qualifiedName.substring(0, colIndex);
localPart = qualifiedName.substring(colIndex + 1);
if ("xmlns".equals(prefix))
{
namespaceURI = "URI:XML_PREDEFINED_NAMESPACE";
}
else
{
Element nsElement = el;
while (namespaceURI.equals("") && nsElement != null)
{
namespaceURI = nsElement.getAttribute("xmlns:" + prefix);
if (namespaceURI.equals(""))
nsElement = getParentElement(nsElement);
}
}
if (namespaceURI.equals(""))
throw PicketBoxMessages.MESSAGES.failedToFindNamespaceURI(qualifiedName);
}
qname = new QName(namespaceURI, localPart, prefix);
return qname;
}
/** Get the value from the given attribute
* @param el
* @param attrName
*
* @return null if the attribute value is empty or the attribute is not present
*/
public static String getAttributeValue(Element el, String attrName)
{
return getAttributeValue(el, new QName(attrName));
}
/** Get the value from the given attribute
* @param el
* @param attrName
*
* @return null if the attribute value is empty or the attribute is not present
*/
public static String getAttributeValue(Element el, QName attrName)
{
String attr = null;
if ("".equals(attrName.getNamespaceURI()))
attr = el.getAttribute(attrName.getLocalPart());
else attr = el.getAttributeNS(attrName.getNamespaceURI(), attrName.getLocalPart());
if ("".equals(attr))
attr = null;
return attr;
}
/** @return the qname value from the given attribute
* @param el
* @param attrName
*/
public static QName getAttributeValueAsQName(Element el, String attrName)
{
return getAttributeValueAsQName(el, new QName(attrName));
}
/** @return the qname value from the given attribute
* @param el
* @param attrName
*/
public static QName getAttributeValueAsQName(Element el, QName attrName)
{
QName qname = null;
String qualifiedName = getAttributeValue(el, attrName);
if (qualifiedName != null)
{
qname = resolveQName(el, qualifiedName);
}
return qname;
}
/** @return the boolean value from the given attribute
* @param el
* @param attrName
*/
public static boolean getAttributeValueAsBoolean(Element el, String attrName)
{
return getAttributeValueAsBoolean(el, new QName(attrName));
}
/** @return the boolean value from the given attribute
* @param el
* @param attrName
*/
public static boolean getAttributeValueAsBoolean(Element el, QName attrName)
{
String attrVal = getAttributeValue(el, attrName);
boolean ret = "true".equalsIgnoreCase(attrVal) || "1".equalsIgnoreCase(attrVal);
return ret;
}
/** @return the integer value from the given attribute
* @param el
* @param attrName
*/
public static Integer getAttributeValueAsInteger(Element el, String attrName)
{
return getAttributeValueAsInteger(el, new QName(attrName));
}
/** @param el
* @param attrName
* @return the integer value from the given attribute
*/
public static Integer getAttributeValueAsInteger(Element el, QName attrName)
{
String attrVal = getAttributeValue(el, attrName);
return (attrVal != null ? new Integer(attrVal) : null);
}
/** @param el
* @return the attributes as Map
*/
public static Map getAttributes(Element el)
{
Map attmap = new HashMap();
NamedNodeMap attribs = el.getAttributes();
for (int i = 0; i < attribs.getLength(); i++)
{
Attr attr = (Attr)attribs.item(i);
String name = attr.getName();
QName qname = resolveQName(el, name);
String value = attr.getNodeValue();
attmap.put(qname, value);
}
return attmap;
}
/** Copy attributes between elements
* @param destElement
* @param srcElement
*/
public static void copyAttributes(Element destElement, Element srcElement)
{
NamedNodeMap attribs = srcElement.getAttributes();
for (int i = 0; i < attribs.getLength(); i++)
{
Attr attr = (Attr)attribs.item(i);
String uri = attr.getNamespaceURI();
String qname = attr.getName();
String value = attr.getNodeValue();
// Prevent DOMException: NAMESPACE_ERR: An attempt is made to create or
// change an object in a way which is incorrect with regard to namespaces.
if (uri == null && qname.startsWith("xmlns"))
{
PicketBoxLogger.LOGGER.traceIgnoreXMLAttribute(uri, qname, value);
}
else
{
destElement.setAttributeNS(uri, qname, value);
}
}
}
/** True if the node has child elements
* @param node
* @return true when has child elements
*/
public static boolean hasChildElements(Node node)
{
NodeList nlist = node.getChildNodes();
for (int i = 0; i < nlist.getLength(); i++)
{
Node child = nlist.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE)
return true;
}
return false;
}
/** Gets child elements
* @param node
* @return the iterator
*/
public static Iterator getChildElements(Node node)
{
ArrayList list = new ArrayList();
NodeList nlist = node.getChildNodes();
for (int i = 0; i < nlist.getLength(); i++)
{
Node child = nlist.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE)
list.add(child);
}
return list.iterator();
}
/** Get the concatenated text content, or null.
* @param node
* @return getTextContent(node, false).
*/
public static String getTextContent(Node node)
{
return getTextContent(node, false);
}
/** Get the concatenated text content, or null.
* @param node node to search for TEXT_NODE conent
* @param replaceProps flag indicating if ${x} property refs should be replace
* @return the text content
*/
public static String getTextContent(Node node, boolean replaceProps)
{
boolean hasTextContent = false;
StringBuffer buffer = new StringBuffer();
NodeList nlist = node.getChildNodes();
for (int i = 0; i < nlist.getLength(); i++)
{
Node child = nlist.item(i);
if (child.getNodeType() == Node.TEXT_NODE)
{
buffer.append(child.getNodeValue());
hasTextContent = true;
}
}
String text = (hasTextContent ? buffer.toString() : null);
if ( text != null && replaceProps)
text = StringPropertyReplacer.replaceProperties(text);
return text;
}
/** @return the first child element
* @param node
*/
public static Element getFirstChildElement(Node node)
{
return getFirstChildElementIntern(node, null);
}
/** @param node
* @param nodeName
* @return the first child element for a given local name without namespace
*/
public static Element getFirstChildElement(Node node, String nodeName)
{
return getFirstChildElementIntern(node, new QName(nodeName));
}
/** @param node
* @param nodeName
* @return the first child element for a given qname
*/
public static Element getFirstChildElement(Node node, QName nodeName)
{
return getFirstChildElementIntern(node, nodeName);
}
private static Element getFirstChildElementIntern(Node node, QName nodeName)
{
Element childElement = null;
Iterator it = getChildElementsIntern(node, nodeName);
if (it.hasNext())
{
childElement = (Element)it.next();
}
return childElement;
}
/** Gets the child elements for a given local name without namespace
* @param node
* @param nodeName
* @return the iterator
*/
public static Iterator getChildElements(Node node, String nodeName)
{
return getChildElementsIntern(node, new QName(nodeName));
}
/** Gets the child element for a given qname
* @param node
* @param nodeName
* @return the iterator
*/
public static Iterator getChildElements(Node node, QName nodeName)
{
return getChildElementsIntern(node, nodeName);
}
private static Iterator getChildElementsIntern(Node node, QName nodeName)
{
ArrayList list = new ArrayList();
NodeList nlist = node.getChildNodes();
for (int i = 0; i < nlist.getLength(); i++)
{
Node child = nlist.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE)
{
if (nodeName == null)
{
list.add(child);
}
else
{
QName qname;
if (nodeName.getNamespaceURI().length() > 0)
{
qname = new QName(child.getNamespaceURI(), child.getLocalName());
}
else
{
qname = new QName(child.getLocalName());
}
if (qname.equals(nodeName))
{
list.add(child);
}
}
}
}
return list.iterator();
}
/** Gets parent element or null if there is none
* @param node
* @return the element
*/
public static Element getParentElement(Node node)
{
Node parent = node.getParentNode();
return (parent instanceof Element ? (Element)parent : null);
}
/** @return the owner document that is associated with the current thread */
public static Document getOwnerDocument()
{
Document doc = (Document)documentThreadLocal.get();
if (doc == null)
{
doc = getDocumentBuilder().newDocument();
documentThreadLocal.set(doc);
}
return doc;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy