/*
 * $Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Crimson" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
 * http://www.sun.com.  For more information on the Apache Software 
 * Foundation, please see <http://www.apache.org/>.
 */

package org.apache.xerces.tree;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Locale;

import org.w3c.dom.*;


/**
 * This is a convenience class for creating application-specific elements
 * associated with specified (or default) XML namespaces.  It maintains
 * tables mapping element tag names to classes, and uses them as needed
 * to instantiate classes.  The string <em>*Element</em>, which is not a
 * legal XML element name, may be used to map otherwise unrecognized tags
 * to a particular class.  If this factory is not configured, then all
 * mappings are to the <a href=ElementNode.html>ElementNode</a> class.
 * Erroneous mappings are fatal errors.
 *
 * <P> A suggested XML syntax for recording these bindings, which may
 * in the future be explicitly supported, is: <PRE>
 * <b>&lt;bindings xmlns="..."&gt;</b>
 *     &lt;!-- first, bindings for the "default" namespace --&gt;
 *     <b>&lt;binding tag="..." class="..."/&gt;</b>
 *     &lt;binding <b>tag="*Element"</b> class="..."/&gt;
 *     ...
 *
 *     &lt;!-- then bindings for other namespaces --&gt;
 *     <b>&lt;namespace uri="..."&gt;</b>
 *         &lt;binding tag="..." class="..."/&gt;
 *         ...
 *     <b>&lt;/namespace&gt;</b>
 *
 *     &lt;!-- can specify JAR files for namespaces --&gt;
 *     &lt;namespace uri="..." <b>jar="..."</b>&gt;
 *         &lt;binding tag="..." class="..."/&gt;
 *         ...
 *     &lt;/namespace&gt;
 *     ...
 * <b>&lt;/bindings&gt;</b>
 * </PRE>
 *
 * <P> Note that while most URIs used to identify namespaces will be URLs,
 * such as <em>http://www.example.com/xml/purchasing</em>, some may also
 * be URNs like <em>urn:uuid:221ffe10-ae3c-11d1-b66c-00805f8a2676</em>.
 * You can't assume that the URIs are associated with web-accessible data;
 * they must be treated as being no more than distinguishable strings.
 *
 * <P> Applications classes configuring an element factory will need to
 * provide their own class loader (<code>this.class.getClassLoader</code>)
 * to get the desired behavior in common cases.  Classes loaded via some
 * URL will similarly need to use a network class loader.
 *
 * @author David Brownell
 * @version $Revision$
 */
public class SimpleElementFactory implements ElementFactory
{
    // in the absense of a mapping tied to namespace URI, use these
    private Dictionary		defaultMapping;
    private ClassLoader		defaultLoader;

    private String		defaultNs;

    // these hold mappings tied to namespace URIs
    private Dictionary		nsMappings;
    private Dictionary		nsLoaders;
    private Locale 		locale = Locale.getDefault ();


    /**
     * Constructs an unconfigured element factory.
     */
    public SimpleElementFactory () { }

    /**
     * Records a default element name to namespace mapping, for use
     * by namespace-unaware DOM construction and when a specific
     * namespace mapping is not available.
     *
     * @param dict Keys are element names, and values are either class
     *	names (interpreted with respect to <em>loader</em>) or class
     *	objects.  This value may not be null, and the dictionary is
     *	retained and modified by the factory.
     * @param loader If non-null, this is used instead of the bootstrap
     *	class loader when mapping from class names to class objects.
     */
    public void addMapping (Dictionary dict, ClassLoader loader)
    {
	if (dict == null)
	    throw new IllegalArgumentException ();
	defaultMapping = dict;
	defaultLoader = loader;
    }

    /**
     * Records a namespace-specific mapping between element names and
     * classes.
     *
     * @param namespace A URI identifying the namespace for which the
     *	mapping is defined
     * @param dict Keys are element names, and values are either class
     *	names (interpreted with respect to <em>loader</em>) or class
     *	objects.  This value may not be null, and the dictionary is
     *	retained and modified by the factory.
     * @param loader If non-null, this is used instead of the bootstrap
     *	class loader when mapping from class names to class objects.
     */
    public void addMapping (
	String		namespace,
	Dictionary	dict,
	ClassLoader	loader
    ) {
	if (namespace == null || dict == null)
	    throw new IllegalArgumentException ();
	if (nsMappings == null) {
	    nsMappings = new Hashtable ();
	    nsLoaders = new Hashtable ();
	}
	nsMappings.put (namespace, dict);
	if (loader != null)
	    nsLoaders.put (namespace, loader);
    }

    /**
     * Defines a URI to be treated as the "default" namespace.  This
     * is used only when choosing element classes, and may not be
     * visible when instances are asked for their namespaces. 
     */
    public void setDefaultNamespace (String ns)
	{ defaultNs = ns; }

    private Class map2Class (
	String		key,
	Dictionary	node2class,
	ClassLoader	loader
    )
    {
	Object		mapResult = node2class.get (key);

	if (mapResult instanceof Class)
	    return (Class) mapResult;
	if (mapResult == null)
	    return null;
        
	if (mapResult instanceof String) {
	    String	className = (String) mapResult;
	    Class	retval;

	    try {
		if (loader == null)
		    retval = Class.forName (className);
		else
		    retval = loader.loadClass (className);

		//
		// We really have no option here.  DOM requires two
		// bidirectional relationships (parent/child, and
		// between siblings) and one unidirectional one (nodes
		// belong to one document) but doesn't provide APIs that
		// would suffice to maintain them.  So those APIs
		// must rely on knowledge of the implementation to
		// which things are connecting.
		//
		if (!ElementNode.class.isAssignableFrom (retval))
		    throw new IllegalArgumentException (getMessage ("SEF-000",
		    			new Object [] { key, className }));
		node2class.put (key, retval);
		return retval;
		
	    } catch (ClassNotFoundException e) {
		throw new IllegalArgumentException (getMessage ("SEF-001",
			new Object [] { key, className, e.getMessage ()}));
	    }
	}

	// another option:  clone elements, resetting parent
	// and document associations?

	throw new IllegalArgumentException (getMessage ("SEF-002", 
				new Object [] { key }));
    }

    private ElementNode doMap (
	String		tagName,
	Dictionary	node2class,
	ClassLoader	loader
    ) {
        Class		theClass;
	ElementNode	retval;

	theClass = map2Class (tagName, node2class, loader);
	if (theClass == null)
	    theClass = map2Class ("*Element", node2class, loader);
	if (theClass == null)
	    retval = new ElementNode ();
	else {
	    try {
		retval = (ElementNode) theClass.newInstance ();
	    } catch (Exception e) {
		    //InstantiationException
		    //IllegalAccessException
		throw new IllegalArgumentException (getMessage ("SEF-003",
			new Object [] {tagName, theClass.getName (),
					e.getMessage () }));
	    }
	}
	return retval;
    }

    /**
     * Creates an element by using the mapping associated with the
     * specified namespace, or the default namespace as appropriate.
     * If no mapping associated with that namespace is defined, then
     * the default mapping is used.
     *
     * @param namespace URI for namespace; null indicates use of
     *	the default namespace, if any.
     * @param tag element tag, without any embedded colon
     */
    public ElementEx createElementEx (String namespace, String tag)
    {
	Dictionary	mapping = null;

	if (namespace == null)
	    namespace = defaultNs;

	if (nsMappings != null)
	    mapping = (Dictionary) nsMappings.get (namespace);
	if (mapping == null)
	    return doMap (tag, defaultMapping, defaultLoader);
	else
	    return doMap (tag, mapping,
		(ClassLoader)nsLoaders.get (namespace));
    }

    /**
     * Creates an element by using the default mapping.
     *
     * @param tag element tag
     */
    public ElementEx createElementEx (String tag)
    {
	return doMap (tag, defaultMapping, defaultLoader);
    }

    /*
     * Gets the messages from the resource bundles for the given messageId.
     */
    String getMessage (String messageId) {
   	return getMessage (messageId, null);
    }

    /*
     * Gets the messages from the resource bundles for the given messageId
     * after formatting it with the parameters passed to it.
     */
    //XXX use the default locale only at this point.
    String getMessage (String messageId, Object[] parameters) {
	return XmlDocument.catalog.getMessage (locale, messageId, parameters);
    }
}
