/*
 * $Id: DomFactory.java,v 1.1.1.1 2002/09/30 15:08:51 smartine Exp $
 * Copyright (C) 1999-2000 David Brownell
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package xml;

import java.lang.reflect.InvocationTargetException;
import org.w3c.dom.DOMImplementation;


// $Id: DomFactory.java,v 1.1.1.1 2002/09/30 15:08:51 smartine Exp $

/**
 * <p>Instantiates a DOMImplementation object, according to system defaults or
 * a user-specified implementation choice.  When used with the current
 * <a href="http://www.w3.org/TR/DOM-Level-2/"> DOM Level 2</a>
 * specification, this means that Java applications have a
 * completely portable mechanism way to create empty DOM documents. This is
 * one of the two basic ways that DOM documents are normally used.  Any
 * vendor-specific issues may be encapsulated through changes to the
 * implementation of one static method.  </p>
 *
 * <p> A separate mechanism is still required to connect a DOM implementation
 * to an XML or HTML processor ("parser"), producing a document which is not
 * empty but rather is populated with results of parsing a document.  In this
 * package the <a href="DomBuilder.html">DomBuilder</a> class solves that
 * problem for SAX parsers.  (In the future these two mechanisms might be
 * integrated in one class, once it is possible to use a single configuration
 * mechanism to address both issues.) </p>
 *
 * <p> Also, because DOM includes APIs that provide read-only access to some
 * facilities without including the capability to write them, some parts of
 * DOM still remain accessible only through use of proprietary APIs.  Much
 * DTD-related functionality is so constrained. </p>
 *
 * @see xml.DomBuilder
 *
 * @author David Brownell
 * @version $Date: 2002/09/30 15:08:51 $
 */
public class DomFactory
{
    // BEGIN IMPLEMENTATION-SPECIFIC

    /**
     * This value is used to configure a default DOM that'll be used
     * when the system property isn't defined.  It's far preferable to
     * change this default value than to modify the code implementing
     * the no-arguments "createDom" method.
     */
    private static final String DEFAULT_DOM =
	"xml.dom.DomImpl";

    // END IMPLEMENTATION-SPECIFIC


    // no instances may be constructed
    private DomFactory () { }

    /**
     * <p>Access the system default DOM implementation.  The actual
     * implementation of this method may vary between implementations
     * of the DOM, but the interface is not subject to change.</p>
     *
     * <p> The reference implementation of this class works with all
     * DOM implementations which can be accessed using only a default
     * constructor.  The class name may be specified by the
     * <b>xml.dom</b> system property, or by a built-in
     * default if that property is not available.  The named class must
     * exist and must implement the <b>org.w3c.dom.DomImplementation</b>
     * interface.  </p>
     *
     * <p> Other implementations of this method are free to use other
     * mechanisms.  For example, a browser might both hard-wire some
     * specific implementation, and also arrange that it be initialized
     * to bind the DOM objects to some particular window and an associated
     * rendering engine. </p>
     *
     * @exception java.lang.reflect.InvocationTargetException
     *	No default DOM implementation is available.  This may be due
     *	to a a variety of underlying errors, reported through the
     *	"target exception" property of this exception.  These usually
     *	involve configuration errors such as incorrect values for a
     *	system property, bad class path, or a malfunctioning DOM.
     *	
     * @see #createDom(java.lang.String)
     */
    public static DOMImplementation createDom ()
    throws InvocationTargetException
    {
	// BEGIN IMPLEMENTATION-SPECIFIC

	String className = DEFAULT_DOM;

	try {
	    className = System.getProperty ("xml.dom",
		DEFAULT_DOM);
	} catch (SecurityException x) {
	    // e.g. in browser
	}

	return createDom (className);

	// END IMPLEMENTATION-SPECIFIC
    }


    /**
     * Create a new DOM implementation object using the class name provided.
     * If that class can't be instantiated, or does not implement the
     * <b>org.w3c.dom.DomImplementation</b> interface, an exception is
     * thrown.
     *
     * <p>No implementation-specific behavior is allowed for this method,
     * unlike its no-arguments cousin which explicitly allows it.  This
     * method is only useful for DOM implementations which provide a null
     * constructor which is publicly accessible, which at this writing
     * describes almost all DOM implementations in Java.  </p>
     *
     * @param className A string containing the name of the class
     *	implementing the DomImplementation interface.
     *
     * @exception java.lang.reflect.InvocationTargetException
     *	No default DOM implementation is available.  This may be due
     *	to a a variety of underlying errors, reported through the
     *	"target exception" property of this exception.  These usually
     *	involve configuration errors such as incorrect values for a
     *	system property, bad class path, or a malfunctioning DOM.
     *	
     * @see #createDom()
     */
    public static DOMImplementation createDom (String className)
    throws InvocationTargetException
    {
	try {
	    return (DOMImplementation)
		Class.forName (className).newInstance ();
	} catch (Exception e) {
	    throw new InvocationTargetException (e, "can't create DOM");
	}
    }

}
