/*
 * 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.openjpa.lib.xml;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;

/**
 * The XMLFactory produces validating and non-validating DOM level 2
 * and SAX level 2 parsers and XSL transformers through JAXP. It uses
 * caching to avoid repeatedly paying the relatively expensive runtime costs
 * associated with resolving the correct XML implementation through the
 * JAXP configuration mechanisms.
 *
 * @author Abe White
 */
public class XMLFactory {

    // cache parsers and transformers in all possible configurations
    private static SAXParserFactory[] _saxFactories = null;
    private static DocumentBuilderFactory[] _domFactories = null;
    private static ErrorHandler _validating;

    static {
        _saxFactories = new SAXParserFactory[4];
        _domFactories = new DocumentBuilderFactory[4];

        SAXParserFactory saxFactory;
        DocumentBuilderFactory domFactory;
        int arrIdx;
        for (int validating = 0; validating < 2; validating++) {
            for (int namespace = 0; namespace < 2; namespace++) {
                arrIdx = factoryIndex(validating == 1, namespace == 1);

                saxFactory = SAXParserFactory.newInstance();
                saxFactory.setValidating(validating == 1);
                saxFactory.setNamespaceAware(namespace == 1);
                _saxFactories[arrIdx] = saxFactory;

                domFactory = DocumentBuilderFactory.newInstance();
                domFactory.setValidating(validating == 1);
                domFactory.setNamespaceAware(namespace == 1);
                _domFactories[arrIdx] = domFactory;
            }
        }
        _validating = new ValidatingErrorHandler();
    }

    /**
     * Return a SAXParser with the specified configuration.
     */
    public static SAXParser getSAXParser(boolean validating,
        boolean namespaceAware) {
        SAXParser sp;
        try {
            sp = _saxFactories[factoryIndex(validating, namespaceAware)].
                newSAXParser();
        } catch (ParserConfigurationException pce) {
            throw new RuntimeException(pce);
        } catch (SAXException se) {
            throw new RuntimeException(se);
        }

        if (validating) {
            try {
                sp.getXMLReader().setErrorHandler(_validating);
            } catch (SAXException se) {
                throw new RuntimeException(se);
            }
        }

        return sp;
    }

    /**
     * Return a DocumentBuilder with the specified configuration.
     */
    public static DocumentBuilder getDOMParser(boolean validating,
        boolean namespaceAware) {
        DocumentBuilder db;
        try {
            db = _domFactories[factoryIndex(validating, namespaceAware)].
                newDocumentBuilder();
        } catch (ParserConfigurationException pce) {
            throw new RuntimeException(pce);
        }

        if (validating)
            db.setErrorHandler(_validating);
        return db;
    }

    /**
     * Return a new DOM Document.
     */
    public static Document getDocument() {
        return getDOMParser(false, false).newDocument();
    }

    /**
     * Return the array index of the factory with the given properties.
     */
    private static int factoryIndex(boolean validating,
        boolean namespaceAware) {
        int arrayIndex = 0;
        if (validating)
            arrayIndex += 2;
        if (namespaceAware)
            arrayIndex += 1;
        return arrayIndex;
    }
}
