/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.cxf.helpers;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.cxf.common.util.StringUtils;

/**
 * Few simple utils to read DOM. This is originally from the Jakarta Commons Modeler.
 */
public final class DOMUtils {
    private static boolean isJre9SAAJ;
    private static final Map<ClassLoader, DocumentBuilder> DOCUMENT_BUILDERS
        = Collections.synchronizedMap(new WeakHashMap<ClassLoader, DocumentBuilder>());
    private static final String XMLNAMESPACE = "xmlns";
    private static volatile Document emptyDocument;

    private static final ClassValue<Method> GET_DOM_ELEMENTS_METHODS = new ClassValue<Method>() {
        @Override
        protected Method computeValue(Class<?> type) {
            try {
                return ReflectionUtil.getMethod(type, "getDomElement");
            } catch (NoSuchMethodException e) {
                //best effort to try, do nothing if NoSuchMethodException
                return null;
            }
        }
    };
    private static final ClassValue<Field> GET_DOCUMENT_FRAGMENT_FIELDS = new ClassValue<Field>() {
        @Override
        protected Field computeValue(Class<?> type) {
            return ReflectionUtil.getDeclaredField(type, "documentFragment");
        }

    };

    static {
        try {
            Method[] methods = DOMUtils.class.getClassLoader().
                loadClass("com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl").getMethods();
            for (Method method : methods) {
                if ("register".equals(method.getName())) {
                    //this is the 1.4+ SAAJ impl
                    setJava9SAAJ(true);
                    break;
                }
            }
        } catch (ClassNotFoundException cnfe) {
            LogUtils.getL7dLogger(DOMUtils.class).finest(
                "can't load class com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl");

            try {
                Method[] methods = DOMUtils.class.getClassLoader().
                    loadClass("com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl").getMethods();
                for (Method method : methods) {
                    if ("register".equals(method.getName())) {
                        //this is the SAAJ impl in JDK9
                        setJava9SAAJ(true);
                        break;
                    }
                }
            } catch (ClassNotFoundException cnfe1) {
                LogUtils.getL7dLogger(DOMUtils.class).finest(
                    "can't load class com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl");
            }
        } catch (Throwable throwable) {
            LogUtils.getL7dLogger(DOMUtils.class).finest(
                "Other JDK vendor");
        }
    }

    private DOMUtils() {
    }

    private static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
        ClassLoader loader = getContextClassLoader();
        if (loader == null) {
            loader = getClassLoader(DOMUtils.class);
        }
        if (loader == null) {
            return createDocumentBuilder();
        }
        DocumentBuilder factory = DOCUMENT_BUILDERS.get(loader);
        if (factory == null) {
            factory = createDocumentBuilder();
            DOCUMENT_BUILDERS.put(loader, factory);
        }
        return factory;
    }

    private static DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
        f.setNamespaceAware(true);
        f.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
        f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        return f.newDocumentBuilder();
    }

    private static ClassLoader getContextClassLoader() {
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
                public ClassLoader run() {
                    return Thread.currentThread().getContextClassLoader();
                }
            });
        }
        return Thread.currentThread().getContextClassLoader();
    }

    private static ClassLoader getClassLoader(final Class<?> clazz) {
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
                public ClassLoader run() {
                    return clazz.getClassLoader();
                }
            });
        }
        return clazz.getClassLoader();
    }

    /**
     * Creates a new Document object
     * @throws ParserConfigurationException
     */
    public static Document newDocument() {
        return createDocument();
    }
    public static Document createDocument() {
        try {
            return getDocumentBuilder().newDocument();
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        }
    }

    private static synchronized Document createEmptyDocument() {
        if (emptyDocument == null) {
            emptyDocument = createDocument();

            // uncomment this to see if anything is actually setting anything into the empty doc
            /*
            final Document doc  = createDocument();
            emptyDocument = (Document)org.apache.cxf.common.util.ProxyHelper.getProxy(
                DOMUtils.class.getClassLoader(),
                new Class<?>[] {Document.class},
                new java.lang.reflect.InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getName().contains("create")) {
                            return method.invoke(doc, args);
                        }
                        throw new IllegalStateException("Cannot modify factory document");
                    }
                });
            */
        }
        return emptyDocument;
    }
    /**
     * Returns a static Document that should always be "empty".  It's useful as a factory for
     * for creating Elements and other nodes that will be traversed later and don't need to
     * be attached into a document
     * @return an empty document
     */
    public static Document getEmptyDocument() {
        Document doc = emptyDocument;
        if (doc == null) {
            doc = createEmptyDocument();
        }
        return doc;
    }


    /**
     * This function is much like getAttribute, but returns null, not "", for a nonexistent attribute.
     *
     * @param e
     * @param attributeName
     */
    public static String getAttributeValueEmptyNull(Element e, String attributeName) {
        Attr node = e.getAttributeNode(attributeName);
        if (node == null) {
            return null;
        }
        return node.getValue();
    }

    /**
     * Get the text content of a node and all it's children or null if there is no text
     */
    public static String getAllContent(Node n) {
        StringBuilder b = new StringBuilder();
        getAllContent(n, b);
        return b.toString();
    }
    private static void getAllContent(Node n, StringBuilder b) {
        Node nd = n.getFirstChild();
        while (nd != null) {
            if (nd instanceof Text && !(nd instanceof Comment)) {
                b.append(((Text)nd).getData());
            } else {
                getAllContent(nd, b);
            }
            nd = nd.getNextSibling();
        }
    }
    /**
     * Get the trimmed text content of a node or null if there is no text
     */
    public static String getContent(Node n) {
        String s = getRawContent(n);
        if (s != null) {
            s = s.trim();
        }
        return s;
    }

    /**
     * Get the raw text content of a node or null if there is no text
     */
    public static String getRawContent(Node n) {
        if (n == null) {
            return null;
        }
        StringBuilder b = null;
        String s = null;
        Node n1 = n.getFirstChild();
        while (n1 != null) {
            if (n1.getNodeType() == Node.TEXT_NODE || n1.getNodeType() == Node.CDATA_SECTION_NODE) {
                if (b != null) {
                    b.append(((Text)n1).getNodeValue());
                } else if (s == null) {
                    s = ((Text)n1).getNodeValue();
                } else {
                    b = new StringBuilder(s).append(((Text)n1).getNodeValue());
                    s = null;
                }
            }
            n1 = n1.getNextSibling();
        }
        if (b != null) {
            return b.toString();
        }
        return s;
    }

    /**
     * Get the first element child.
     *
     * @param parent lookup direct childs
     * @param name name of the element. If null return the first element.
     */
    public static Node getChild(Node parent, String name) {
        if (parent == null) {
            return null;
        }

        Node first = parent.getFirstChild();
        if (first == null) {
            return null;
        }

        for (Node node = first; node != null; node = node.getNextSibling()) {
            
            if (node.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }
            if (name != null && name.equals(node.getNodeName())) {
                return node;
            }
            if (name == null) {
                return node;
            }
        }
        return null;
    }


    public static boolean hasAttribute(Element element, String value) {
        NamedNodeMap attributes = element.getAttributes();
        for (int i = 0; i < attributes.getLength(); i++) {
            Node node = attributes.item(i);
            if (value.equals(node.getNodeValue())) {
                return true;
            }
        }
        return false;
    }
    public static String getAttribute(Node element, String attName) {
        NamedNodeMap attrs = element.getAttributes();
        if (attrs == null) {
            return null;
        }
        Node attN = attrs.getNamedItem(attName);
        if (attN == null) {
            return null;
        }
        return attN.getNodeValue();
    }

    public static String getAttribute(Element element, QName attName) {
        Attr attr;
        if (StringUtils.isEmpty(attName.getNamespaceURI())) {
            attr = element.getAttributeNode(attName.getLocalPart());
        } else {
            attr = element.getAttributeNodeNS(attName.getNamespaceURI(), attName.getLocalPart());
        }
        return attr == null ? null : attr.getValue();
    }

    public static void setAttribute(Node node, String attName, String val) {
        NamedNodeMap attributes = node.getAttributes();
        Node attNode = node.getOwnerDocument().createAttributeNS(null, attName);
        attNode.setNodeValue(val);
        attributes.setNamedItem(attNode);
    }

    public static void removeAttribute(Node node, String attName) {
        NamedNodeMap attributes = node.getAttributes();
        attributes.removeNamedItem(attName);
    }

    /**
     * Set or replace the text value
     */
    public static void setText(Node node, String val) {
        Node chld = DOMUtils.getChild(node, Node.TEXT_NODE);
        if (chld == null) {
            Node textN = node.getOwnerDocument().createTextNode(val);
            node.appendChild(textN);
            return;
        }
        // change the value
        chld.setNodeValue(val);
    }

    /**
     * Find the first direct child with a given attribute.
     *
     * @param parent
     * @param elemName name of the element, or null for any
     * @param attName attribute we're looking for
     * @param attVal attribute value or null if we just want any
     */
    public static Element findChildWithAtt(Node parent, String elemName, String attName, String attVal) {

        Element child = (Element)getChild(parent, Node.ELEMENT_NODE);
        if (attVal == null) {
            while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
                   && DOMUtils.getAttribute(child, attName) != null) {
                child = (Element)getNext(child, elemName, Node.ELEMENT_NODE);
            }
        } else {
            while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
                   && !attVal.equals(DOMUtils.getAttribute(child, attName))) {
                child = (Element)getNext(child, elemName, Node.ELEMENT_NODE);
            }
        }
        return child;
    }

    /**
     * Get the first child's content ( ie it's included TEXT node ).
     */
    public static String getChildContent(Node parent, String name) {
        Node first = parent.getFirstChild();
        if (first == null) {
            return null;
        }
        for (Node node = first; node != null; node = node.getNextSibling()) {
          
            if (name.equals(node.getNodeName())) {
                return getRawContent(node);
            }
        }
        return null;
    }

    public static QName getElementQName(Element el) {
        return new QName(el.getNamespaceURI(), el.getLocalName());
    }

    /**
     * Creates a QName object based on the qualified name
     * and using the Node as a base to lookup the namespace
     * for the prefix
     * @param qualifiedName
     * @param node
     */
    public static QName createQName(String qualifiedName, Node node) {
        if (qualifiedName == null) {
            return null;
        }

        int index = qualifiedName.indexOf(':');

        if (index == -1) {
            return new QName(qualifiedName);
        }

        String prefix = qualifiedName.substring(0, index);
        String localName = qualifiedName.substring(index + 1);
        String ns = node.lookupNamespaceURI(prefix);

        if (ns == null) {
            throw new RuntimeException("Invalid QName in mapping: " + qualifiedName);
        }

        return new QName(ns, localName, prefix);
    }

    public static QName convertStringToQName(String expandedQName) {
        return convertStringToQName(expandedQName, "");
    }

    public static QName convertStringToQName(String expandedQName, String prefix) {
        int ind1 = expandedQName.indexOf('{');
        if (ind1 != 0) {
            return new QName(expandedQName);
        }

        int ind2 = expandedQName.indexOf('}');
        if (ind2 <= ind1 + 1 || ind2 >= expandedQName.length() - 1) {
            return null;
        }
        String ns = expandedQName.substring(ind1 + 1, ind2);
        String localName = expandedQName.substring(ind2 + 1);
        return new QName(ns, localName, prefix);
    }
    public static Set<QName> convertStringsToQNames(List<String> expandedQNames) {
        Set<QName> dropElements = Collections.emptySet();
        if (expandedQNames != null) {
            dropElements = new LinkedHashSet<>(expandedQNames.size());
            for (String val : expandedQNames) {
                dropElements.add(convertStringToQName(val));
            }
        }
        return dropElements;
    }


    /**
     * Get the first direct child with a given type
     */
    public static Element getFirstElement(Node parent) {
        Node n = parent.getFirstChild();
        while (n != null && Node.ELEMENT_NODE != n.getNodeType()) {
            n = n.getNextSibling();
        }
        if (n == null) {
            return null;
        }
        return (Element)n;
    }

    public static Element getNextElement(Element el) {
        Node nd = el.getNextSibling();
        while (nd != null) {
            if (nd.getNodeType() == Node.ELEMENT_NODE) {
                return (Element)nd;
            }
            nd = nd.getNextSibling();
        }
        return null;
    }

    /**
     * Return the first element child with the specified qualified name.
     *
     * @param parent
     * @param q
     */
    public static Element getFirstChildWithName(Element parent, QName q) {
        String ns = q.getNamespaceURI();
        String lp = q.getLocalPart();
        return getFirstChildWithName(parent, ns, lp);
    }

    /**
     * Return the first element child with the specified qualified name.
     *
     * @param parent
     * @param ns
     * @param lp
     */
    public static Element getFirstChildWithName(Element parent, String ns, String lp) {
        for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
            if (n instanceof Element) {
                Element e = (Element)n;
                String ens = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI();
                if (ns.equals(ens) && lp.equals(e.getLocalName())) {
                    return e;
                }
            }
        }
        return null;
    }

    /**
     * Return child elements with specified name.
     *
     * @param parent
     * @param ns
     * @param localName
     */
    public static List<Element> getChildrenWithName(Element parent, String ns, String localName) {
        List<Element> r = new ArrayList<>();
        for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
            if (n instanceof Element) {
                Element e = (Element)n;
                String eNs = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI();
                if (ns.equals(eNs) && localName.equals(e.getLocalName())) {
                    r.add(e);
                }
            }
        }
        return r;
    }

    /**
     * Returns all child elements with specified namespace.
     *
     * @param parent the element to search under
     * @param ns the namespace to find elements in
     * @return all child elements with specified namespace
     */
    public static List<Element> getChildrenWithNamespace(Element parent, String ns) {
        List<Element> r = new ArrayList<>();
        for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
            if (n instanceof Element) {
                Element e = (Element)n;
                String eNs = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI();
                if (ns.equals(eNs)) {
                    r.add(e);
                }
            }
        }
        return r;
    }

    /**
     * Get the first child of the specified type.
     *
     * @param parent
     * @param type
     */
    public static Node getChild(Node parent, int type) {
        Node n = parent.getFirstChild();
        while (n != null && type != n.getNodeType()) {
            n = n.getNextSibling();
        }
        if (n == null) {
            return null;
        }
        return n;
    }

    /**
     * Get the next sibling with the same name and type
     */
    public static Node getNext(Node current) {
        String name = current.getNodeName();
        int type = current.getNodeType();
        return getNext(current, name, type);
    }

    /**
     * Return the next sibling with a given name and type
     */
    public static Node getNext(Node current, String name, int type) {
        Node first = current.getNextSibling();
        if (first == null) {
            return null;
        }

        for (Node node = first; node != null; node = node.getNextSibling()) {

            if (type >= 0 && node.getNodeType() != type) {
                continue;
            }

            if (name == null) {
                return node;
            }
            if (name.equals(node.getNodeName())) {
                return node;
            }
        }
        return null;
    }

    public static class NullResolver implements EntityResolver {
        public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
            return new InputSource(new StringReader(""));
        }
    }

    public static String getPrefixRecursive(Element el, String ns) {
        String prefix = getPrefix(el, ns);
        if (prefix == null && el.getParentNode() instanceof Element) {
            prefix = getPrefixRecursive((Element)el.getParentNode(), ns);
        }
        return prefix;
    }

    public static String getPrefix(Element el, String ns) {
        NamedNodeMap atts = el.getAttributes();
        for (int i = 0; i < atts.getLength(); i++) {
            Node node = atts.item(i);
            String name = node.getNodeName();
            if (ns.equals(node.getNodeValue())
                && (name != null && (XMLNAMESPACE.equals(name) || name.startsWith(XMLNAMESPACE + ":")))) {
                return node.getLocalName();
            }
        }
        return null;
    }

    /**
     * Get all prefixes defined, up to the root, for a namespace URI.
     *
     * @param element
     * @param namespaceUri
     * @param prefixes
     */
    public static void getPrefixesRecursive(Element element, String namespaceUri, List<String> prefixes) {
        getPrefixes(element, namespaceUri, prefixes);
        Node parent = element.getParentNode();
        if (parent instanceof Element) {
            getPrefixesRecursive((Element)parent, namespaceUri, prefixes);
        }
    }

    /**
     * Get all prefixes defined on this element for the specified namespace.
     *
     * @param element
     * @param namespaceUri
     * @param prefixes
     */
    public static void getPrefixes(Element element, String namespaceUri, List<String> prefixes) {
        NamedNodeMap atts = element.getAttributes();
        for (int i = 0; i < atts.getLength(); i++) {
            Node node = atts.item(i);
            String name = node.getNodeName();
            if (namespaceUri.equals(node.getNodeValue())
                && (name != null && (XMLNAMESPACE.equals(name) || name.startsWith(XMLNAMESPACE + ":")))) {
                prefixes.add(node.getPrefix());
            }
        }
    }

    public static String createNamespace(Element el, String ns) {
        String p = "ns1";
        int i = 1;
        while (getPrefix(el, ns) != null) {
            p = "ns" + i;
            i++;
        }
        addNamespacePrefix(el, ns, p);
        return p;
    }

    /**
     * Starting from a node, find the namespace declaration for a prefix. for a matching namespace
     * declaration.
     *
     * @param node search up from here to search for namespace definitions
     * @param searchPrefix the prefix we are searching for
     * @return the namespace if found.
     */
    public static String getNamespace(Node node, String searchPrefix) {

        Element el;
        while (!(node instanceof Element)) {
            node = node.getParentNode();
        }
        el = (Element)node;

        NamedNodeMap atts = el.getAttributes();
        for (int i = 0; i < atts.getLength(); i++) {
            Node currentAttribute = atts.item(i);
            String currentLocalName = currentAttribute.getLocalName();
            String currentPrefix = currentAttribute.getPrefix();
            if (searchPrefix.equals(currentLocalName) && XMLNAMESPACE.equals(currentPrefix)) {
                return currentAttribute.getNodeValue();
            } else if (StringUtils.isEmpty(searchPrefix) && XMLNAMESPACE.equals(currentLocalName)
                       && StringUtils.isEmpty(currentPrefix)) {
                return currentAttribute.getNodeValue();
            }
        }

        Node parent = el.getParentNode();
        if (parent instanceof Element) {
            return getNamespace(parent, searchPrefix);
        }

        return null;
    }

    public static List<Element> findAllElementsByTagNameNS(Element elem, String nameSpaceURI,
                                                           String localName) {
        List<Element> ret = new LinkedList<>();
        findAllElementsByTagNameNS(elem, nameSpaceURI, localName, ret);
        return ret;
    }

    /**
     * Try to get the DOM Node from the SAAJ Node with JAVA9 afterwards
     * @param node The original node we need check
     * @return The DOM node
     */
    public static Node getDomElement(Node node) {
        if (node != null && isJava9SAAJ()) {
            //java9plus hack
            Method method = GET_DOM_ELEMENTS_METHODS.get(node.getClass());
            if (method != null) {
                try {
                    return (Node)ReflectionUtil.setAccessible(method).invoke(node);
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return node;
    }

    /**
     * Try to get the DOM DocumentFragment from the SAAJ DocumentFragment with JAVA9 afterwards
     * @param fragment The original documentFragment we need to check
     * @return The DOM DocumentFragment
     */
    public static DocumentFragment getDomDocumentFragment(DocumentFragment fragment) {
        if (fragment != null && isJava9SAAJ()) {
            //java9 plus hack
            Field f = GET_DOCUMENT_FRAGMENT_FIELDS.get(fragment.getClass());
            if (f != null) {
                return ReflectionUtil.accessDeclaredField(f, fragment, DocumentFragment.class);
            }
        }
        return fragment;
    }

    private static void findAllElementsByTagNameNS(Element el, String nameSpaceURI, String localName,
                                                   List<Element> elementList) {

        if (el.getNamespaceURI() != null && localName.equals(el.getLocalName())
            && nameSpaceURI.contains(el.getNamespaceURI())) {
            elementList.add(el);
        }
        Element elem = getFirstElement(el);
        while (elem != null) {
            findAllElementsByTagNameNS(elem, nameSpaceURI, localName, elementList);
            elem = getNextElement(elem);
        }
    }

    public static List<Element> findAllElementsByTagName(Element elem, String tagName) {
        List<Element> ret = new LinkedList<>();
        findAllElementsByTagName(elem, tagName, ret);
        return ret;
    }

    private static void findAllElementsByTagName(Element el, String tagName, List<Element> elementList) {

        if (tagName.equals(el.getTagName())) {
            elementList.add(el);
        }
        Element elem = getFirstElement(el);
        while (elem != null) {
            findAllElementsByTagName(elem, tagName, elementList);
            elem = getNextElement(elem);
        }
    }
    public static boolean hasElementWithName(Element el, String nameSpaceURI, String localName) {
        if (el.getNamespaceURI() != null && localName.equals(el.getLocalName())
            && nameSpaceURI.contains(el.getNamespaceURI())) {
            return true;
        }
        Element elem = getFirstElement(el);
        while (elem != null) {
            if (hasElementWithName(elem, nameSpaceURI, localName)) {
                return true;
            }
            elem = getNextElement(elem);
        }
        return false;
    }
    public static boolean hasElementInNS(Element el, String namespace) {

        if (namespace.equals(el.getNamespaceURI())) {
            return true;
        }
        Element elem = getFirstElement(el);
        while (elem != null) {
            if (hasElementInNS(elem, namespace)) {
                return true;
            }
            elem = getNextElement(elem);
        }
        return false;
    }
    /**
     * Set a namespace/prefix on an element if it is not set already. First off, it searches for the element
     * for the prefix associated with the specified namespace. If the prefix isn't null, then this is
     * returned. Otherwise, it creates a new attribute using the namespace/prefix passed as parameters.
     *
     * @param element
     * @param namespace
     * @param prefix
     * @return the prefix associated with the set namespace
     */
    public static String setNamespace(Element element, String namespace, String prefix) {
        String pre = getPrefixRecursive(element, namespace);
        if (pre != null) {
            return pre;
        }
        element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, namespace);
        return prefix;
    }

    /**
     * Add a namespace prefix definition to an element.
     *
     * @param element
     * @param namespaceUri
     * @param prefix
     */
    public static void addNamespacePrefix(Element element, String namespaceUri, String prefix) {
        element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, namespaceUri);
    }

    public static boolean isJava9SAAJ() {
        return isJre9SAAJ;
    }

    private static void setJava9SAAJ(boolean isJava9SAAJ) {
        DOMUtils.isJre9SAAJ = isJava9SAAJ;
    }
}
