/*
 * Copyright (c) 2017-2025 XMLmind Software. All rights reserved.
 *
 * Author: Hussein Shafie
 *
 * This file is part of several XMLmind projects.
 * For conditions of distribution and use, see the accompanying legal.txt file.
 */
package com.xmlmind.util;

import org.xml.sax.SAXException;
import java.util.HashSet;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * A collection of utility functions (static methods) related to XML.
 */
public final class XMLUtil {
    private XMLUtil() {}

    // -----------------------------------------------------------------------

    /**
     * The set of local names of HTML (any version) elements for which 
     * the end tag <em>must</em> be omitted.
     * <p>For any other HTML element, including custom elements, 
     * the end tag must <em>not</em> be omitted.
     */
    public static final HashSet<String> HTML_NO_END_TAG = new HashSet<String>();
    static {
        // These element names come from XHTML 1.0 Transitional, Frameset and
        // XHTML 5.x.
        String[] list = {
            "base",
            "link",
            "meta",
            "hr",
            "br",
            "wbr",
            "source",
            "img",
            "embed",
            "param",
            "track",
            "area",
            "col",
            "input",
            // Obsolete elements ---
            "basefont",
            "isindex",
            "frame",
            "keygen" // Removed as of HTML 5.2.
        };
        for (String tag : list) {
            HTML_NO_END_TAG.add(tag);
        }
    }

    // -----------------------------------------------------------------------

    /**
     * Equivalent to {@link #newSAXParser(boolean, boolean, boolean) 
     * newSAXParser(true, false, false)}.
     */
    public static SAXParser newSAXParser()
        throws ParserConfigurationException, SAXException {
        return newSAXParser(true, false, false);
    }

    /**
     * Convenience method: creates and returns a SAXParser.
     * 
     * @param namespaceAware specifies whether the parser produced 
     * by this code will provide support for XML namespaces
     * @param validating specifies whether the parser produced by 
     * this code will validate documents against their DTD
     * @param xIncludeAware specifies whether the parser produced by 
     * this code will process XIncludes
     * @return newly created SAXParser
     * @exception ParserConfigurationException if a parser cannot be created 
     * which satisfies the requested configuration
     * @exception SAXException for SAX errors
     */
    public static SAXParser newSAXParser(boolean namespaceAware, 
                                         boolean validating, 
                                         boolean xIncludeAware)
        throws ParserConfigurationException, SAXException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(namespaceAware);
        factory.setValidating(validating);
        factory.setXIncludeAware(xIncludeAware);

        // For Xerces which otherwise, does not support "x-MacRoman".
        try {
            factory.setFeature(
                "http://apache.org/xml/features/allow-java-encodings", true);
        } catch (Exception ignored) {}

        return factory.newSAXParser();
    }
}
