/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 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 "Xalan" 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) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author Morten Jorgensen
 *
 */

package org.apache.xalan.xsltc.runtime;

import java.util.Vector;
import java.util.Enumeration;
import java.util.ResourceBundle;

public class ErrorMessages extends ResourceBundle {

/*
 * XSLTC run-time error messages.
 *
 * General notes to translators and definitions:
 *
 *   1) XSLTC is the name of the product.  It is an acronym for XML Stylesheet:
 *      Transformations Compiler
 *
 *   2) A stylesheet is a description of how to transform an input XML document
 *      into a resultant output XML document (or HTML document or text)
 *
 *   3) An axis is a particular "dimension" in a tree representation of an XML
 *      document; the nodes in the tree are divided along different axes.
 *      Traversing the "child" axis, for instance, means that the program
 *      would visit each child of a particular node; traversing the "descendant"
 *      axis means that the program would visit the child nodes of a particular
 *      node, their children, and so on until the leaf nodes of the tree are
 *      reached.
 *
 *   4) An iterator is an object that traverses nodes in a tree along a
 *      particular axis, one at a time.
 *
 *   5) An element is a mark-up tag in an XML document; an attribute is a
 *      modifier on the tag.  For example, in <elem attr='val' attr2='val2'>
 *      "elem" is an element name, "attr" and "attr2" are attribute names with
 *      the values "val" and "val2", respectively.
 *
 *   6) A namespace declaration is a special attribute that is used to associate
 *      a prefix with a URI (the namespace).  The meanings of element names and
 *      attribute names that use that prefix are defined with respect to that
 *      namespace.
 *
 *   7) DOM is an acronym for Document Object Model.  It is a tree
 *      representation of an XML document.
 *
 *      SAX is an acronym for the Simple API for XML processing.  It is an API
 *      used inform an XML processor (in this case XSLTC) of the structure and
 *      content of an XML document.
 *
 *      Input to the stylesheet processor can come from an XML parser in the
 *      form of a DOM tree or through the SAX API.
 *
 *   8) DTD is a document type declaration.  It is a way of specifying the
 *      grammar for an XML file, the names and types of elements, attributes,
 *      etc.
 *
 */

    // These message should be read from a locale-specific resource bundle
    private static final String errorMessages[] = {

	/*
	 * Note to translators:  the substitution text in the following message
	 * is a class name.  Used for internal errors in the processor.
	 */
	// RUN_TIME_INTERNAL_ERR
	"Run-time internal error in ''{0}''",

	/*
	 * Note to translators:  <xsl:copy> is a keyword that should not be
	 * translated.
	 */
	// RUN_TIME_COPY_ERR
	"Run-time error when executing <xsl:copy>.",

	/*
	 * Note to translators:  The substitution text refers to data types.
	 * The message is displayed if a value in a particular context needs to
	 * be converted to type {1}, but that's not possible for a value of type
	 * {0}.
	 */
	// DATA_CONVERSION_ERR
	"Invalid conversion from ''{0}'' to ''{1}''.",

	/*
	 * Note to translators:  This message is displayed if the function named
	 * by the substitution text is not a function that is supported.  XSLTC
	 * is the acronym naming the product.
	 */
	// EXTERNAL_FUNC_ERR
	"External function ''{0}'' not supported by XSLTC.",

	/*
	 * Note to translators:  This message is displayed if two values are
	 * compared for equality, but the data type of one of the values is
	 * unknown.
	 */
	// EQUALITY_EXPR_ERR
	"Unknown argument type in equality expression.",

	/*
	 * Note to translators:  The substitution text for {0} will be a data
	 * type; the substitution text for {1} will be the name of a function.
	 * This is displayed if an argument of the particular data type is not
	 * permitted for a call to this function.
	 */
	// INVALID_ARGUMENT_ERR
	"Invalid argument type ''{0}'' in call to ''{1}''",

	/*
	 * Note to translators:  There is way of specifying a format for a
	 * number using a pattern; the processor was unable to format the
	 * particular value using the specified pattern.
	 */
	// FORMAT_NUMBER_ERR
	"Attempting to format number ''{0}'' using pattern ''{1}''.",

	/*
	 * Note to translators:  The following represents an internal error
	 * situation in XSLTC.  The processor was unable to create a copy of an
	 * iterator.  (See definition of iterator above.)
	 */
	// ITERATOR_CLONE_ERR
	"Cannot clone iterator ''{0}''.",

	/*
	 * Note to translators:  The following represents an internal error
	 * situation in XSLTC.  The processor attempted to create an iterator
	 * for a particular axis (see definition above) that it does not
	 * support.
	 */
	// AXIS_SUPPORT_ERR
	"Iterator for axis ''{0}'' not supported.",

	/*
	 * Note to translators:  The following represents an internal error
	 * situation in XSLTC.  The processor attempted to create an iterator
	 * for a particular axis (see definition above) that it does not
	 * support.
	 */
	// TYPED_AXIS_SUPPORT_ERR
	"Iterator for typed axis ''{0}'' not supported.",

	/*
	 * Note to translators:  This message is reported if the stylesheet
	 * being processed attempted to construct an XML document with an
	 * attribute in a place other than on an element.  The substitution text
	 * specifies the name of the attribute.
	 */
	// STRAY_ATTRIBUTE_ERR
	"Attribute ''{0}'' outside of element.",

	/*
	 * Note to translators:  As with the preceding message, a namespace
	 * declaration has the form of an attribute and is only permitted to
	 * appear on an element.  The substitution text {0} is the namespace
	 * prefix and {1} is the URI that was being used in the erroneous
	 * namespace declaration.
	 */
	// STRAY_NAMESPACE_ERR
	"Namespace declaration ''{0}''=''{1}'' outside of element.",

	/*
	 * Note to translators:  The stylesheet contained a reference to a
	 * namespace prefix that was undefined.  The value of the substitution
	 * text is the name of the prefix.
	 */
	// NAMESPACE_PREFIX_ERR
	"Namespace for prefix ''{0}'' has not been declared.",

	/*
	 * Note to translators:  The following represents an internal error.
	 * DOMAdapter is a Java class in XSLTC.
	 */
	// DOM_ADAPTER_INIT_ERR
	"DOMAdapter created using wrong type of source DOM.",

	/*
	 * Note to translators:  The following message indicates that the XML
	 * parser that is providing input to XSLTC cannot be used because it
	 * does not describe to XSLTC the structure of the input XML document's
	 * DTD.
	 */
        // PARSER_DTD_SUPPORT_ERR
        "The SAX parser you are using does not handle DTD declaration events.",

	/*
	 * Note to translators:  The following message indicates that the XML
	 * parser that is providing input to XSLTC cannot be used because it
	 * does not distinguish between ordinary XML attributes and namespace
	 * declarations.
	 */
        // NAMESPACES_SUPPORT_ERR
        "The SAX parser you are using does not have support for XML Namespaces.",

        /*
         * Note to translators:  The substitution text is the URI that was in
         * error.
         */
        // CANT_RESOLVE_RELATIVE_URI_ERR
        "Could not resolve the URI reference ''{0}''."
    };

    private static Vector _keys;

    static {
	_keys = new Vector();
	_keys.addElement(BasisLibrary.ERROR_MESSAGES_KEY);
    }

    public Enumeration getKeys() {
	return _keys.elements();
    }

    public Object handleGetObject(String key) {
	if (key == null) return null;
	if (key.equals(BasisLibrary.ERROR_MESSAGES_KEY)) return errorMessages;
	return(null);
    }

}
