/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 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 Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author G. Todd Miller
 * @author Erwin Bolwidt <ejb@klomp.org>
 * @author Morten Jorgensen
 *
 */

package org.apache.xalan.xsltc.compiler.util;

import org.apache.xalan.xsltc.compiler.Stylesheet;
import org.apache.xalan.xsltc.compiler.SyntaxTreeNode;

import java.net.URL;
import java.util.Locale;
import java.util.ResourceBundle;
import java.text.MessageFormat;

public final class ErrorMsg {

    private int _code;
    private int _line;
    private String _message = null;
    private String _url = null;
    Object[] _params = null;

    // Compiler error messages
    public static final int MULTIPLE_STYLESHEET_ERR = 0;
    public static final int TEMPLATE_REDEF_ERR      = 1;
    public static final int TEMPLATE_UNDEF_ERR      = 2;
    public static final int VARIABLE_REDEF_ERR      = 3;
    public static final int VARIABLE_UNDEF_ERR      = 4;
    public static final int CLASS_NOT_FOUND_ERR     = 5;
    public static final int METHOD_NOT_FOUND_ERR    = 6;
    public static final int ARGUMENT_CONVERSION_ERR = 7;
    public static final int FILE_NOT_FOUND_ERR      = 8;
    public static final int INVALID_URI_ERR         = 9;
    public static final int FILE_ACCESS_ERR         = 10;
    public static final int MISSING_ROOT_ERR        = 11;
    public static final int NAMESPACE_UNDEF_ERR     = 12;
    public static final int FUNCTION_RESOLVE_ERR    = 13;
    public static final int NEED_LITERAL_ERR        = 14;
    public static final int XPATH_PARSER_ERR        = 15;
    public static final int REQUIRED_ATTR_ERR       = 16;
    public static final int ILLEGAL_CHAR_ERR        = 17;
    public static final int ILLEGAL_PI_ERR          = 18;
    public static final int STRAY_ATTRIBUTE_ERR     = 19;
    public static final int ILLEGAL_ATTRIBUTE_ERR   = 20;
    public static final int CIRCULAR_INCLUDE_ERR    = 21;
    public static final int RESULT_TREE_SORT_ERR    = 22;
    public static final int SYMBOLS_REDEF_ERR       = 23;
    public static final int XSL_VERSION_ERR         = 24;
    public static final int CIRCULAR_VARIABLE_ERR   = 25;
    public static final int ILLEGAL_BINARY_OP_ERR   = 26;
    public static final int ILLEGAL_ARG_ERR         = 27;
    public static final int DOCUMENT_ARG_ERR        = 28;
    public static final int MISSING_WHEN_ERR        = 29;
    public static final int MULTIPLE_OTHERWISE_ERR  = 30;
    public static final int STRAY_OTHERWISE_ERR     = 31;
    public static final int STRAY_WHEN_ERR          = 32;
    public static final int WHEN_ELEMENT_ERR        = 33;
    public static final int UNNAMED_ATTRIBSET_ERR   = 34;
    public static final int ILLEGAL_CHILD_ERR       = 35;
    public static final int ILLEGAL_ELEM_NAME_ERR   = 36;
    public static final int ILLEGAL_ATTR_NAME_ERR   = 37;
    public static final int ILLEGAL_TEXT_NODE_ERR   = 38;
    public static final int SAX_PARSER_CONFIG_ERR   = 39;
    public static final int INTERNAL_ERR            = 40;
    public static final int UNSUPPORTED_XSL_ERR     = 41;
    public static final int UNSUPPORTED_EXT_ERR     = 42;
    public static final int MISSING_XSLT_URI_ERR    = 43;
    public static final int MISSING_XSLT_TARGET_ERR = 44;
    public static final int NOT_IMPLEMENTED_ERR     = 45;
    public static final int NOT_STYLESHEET_ERR      = 46;
    public static final int ELEMENT_PARSE_ERR       = 47;
    public static final int KEY_USE_ATTR_ERR        = 48;
    public static final int OUTPUT_VERSION_ERR      = 49;
    public static final int ILLEGAL_RELAT_OP_ERR    = 50;
    public static final int ATTRIBSET_UNDEF_ERR     = 51;
    public static final int ATTR_VAL_TEMPLATE_ERR   = 52;
    public static final int UNKNOWN_SIG_TYPE_ERR    = 53;
    public static final int DATA_CONVERSION_ERR     = 54;

    // JAXP/TrAX error messages
    public static final int NO_TRANSLET_CLASS_ERR   = 55;
    public static final int NO_MAIN_TRANSLET_ERR    = 56;
    public static final int TRANSLET_CLASS_ERR      = 57;
    public static final int TRANSLET_OBJECT_ERR     = 58;
    public static final int ERROR_LISTENER_NULL_ERR = 59;
    public static final int JAXP_UNKNOWN_SOURCE_ERR = 60;
    public static final int JAXP_NO_SOURCE_ERR      = 61;
    public static final int JAXP_COMPILE_ERR        = 62;
    public static final int JAXP_INVALID_ATTR_ERR   = 63;
    public static final int JAXP_SET_RESULT_ERR     = 64;
    public static final int JAXP_NO_TRANSLET_ERR    = 65;
    public static final int JAXP_NO_HANDLER_ERR     = 66;
    public static final int JAXP_NO_RESULT_ERR      = 67;
    public static final int JAXP_UNKNOWN_PROP_ERR   = 68;
    public static final int SAX2DOM_ADAPTER_ERR     = 69;
    public static final int XSLTC_SOURCE_ERR        = 70;

    // Command-line error messages
    public static final int COMPILE_STDIN_ERR       = 71;
    public static final int COMPILE_USAGE_STR       = 72;
    public static final int TRANSFORM_USAGE_STR     = 73;

    // Recently added error messages
    public static final int STRAY_SORT_ERR          = 74;
    public static final int UNSUPPORTED_ENCODING    = 75;
    public static final int SYNTAX_ERR              = 76;

    // All error messages are localized and are stored in resource bundles.
    // This array and the following 4 strings are read from that bundle.
    private static String[] _errorMessages;
    private static String   _compileError;
    private static String   _compileWarning;
    private static String   _runtimeError;
    
    public final static String ERROR_MESSAGES_KEY   = "error-messages";
    public final static String COMPILER_ERROR_KEY   = "compile-error";
    public final static String COMPILER_WARNING_KEY = "compile-warning";
    public final static String RUNTIME_ERROR_KEY    = "runtime-error";

    static {
	ResourceBundle bundle = ResourceBundle.getBundle("org.apache.xalan.xsltc.compiler.util.ErrorMessages", Locale.getDefault());
	_errorMessages  = bundle.getStringArray(ERROR_MESSAGES_KEY);
	_compileError   = bundle.getString(COMPILER_ERROR_KEY);
	_compileWarning = bundle.getString(COMPILER_WARNING_KEY);
	_runtimeError   = bundle.getString(RUNTIME_ERROR_KEY);
    }

    public ErrorMsg(int code) {
	_code = code;
	_line = 0;
    }
	
    public ErrorMsg(String message) {
	_code = -1;
	_message = message;
	_line = 0;
    }

    public ErrorMsg(String message, int line) {
	_code = -1;
	_message = message;
	_line = line;
    }

    public ErrorMsg(int code, int line, Object param) {
	_code = code;
	_line = line;
	_params = new Object[] { param };
    }

    public ErrorMsg(int code, Object param) {
	this(code);
	_params = new Object[1];
	_params[0] = param;
    }

    public ErrorMsg(int code, Object param1, Object param2) {
	this(code);
	_params = new Object[2];
	_params[0] = param1;
	_params[1] = param2;
    }

    public ErrorMsg(int code, SyntaxTreeNode node) {
	_code = code;
	_url  = getFileName(node);
	_line = node.getLineNumber();
    }

    public ErrorMsg(int code, Object param1, SyntaxTreeNode node) {
	_code = code;
	_url  = getFileName(node);
	_line = node.getLineNumber();
	_params = new Object[1];
	_params[0] = param1;
    }

    public ErrorMsg(int code, Object param1, Object param2,
		    SyntaxTreeNode node) {
	_code = code;
	_url  = getFileName(node);
	_line = node.getLineNumber();
	_params = new Object[2];
	_params[0] = param1;
	_params[1] = param2;
    }

    public static String getCompileErrorMessage() {
	return _compileError;
    }

    public static String getCompileWarningMessage() {
	return _compileWarning;
    }

    public static String getTransletErrorMessage() {
	return _runtimeError;
    }

    private String getFileName(SyntaxTreeNode node) {
	Stylesheet stylesheet = node.getStylesheet();
	if (stylesheet != null)
	    return stylesheet.getSystemId();
	else
	    return null;
    }

    private String formatLine() {
	StringBuffer result = new StringBuffer();
	if (_url != null) {
	    result.append(_url);
	    result.append(": ");
	}
	if (_line > 0) {
	    result.append("line ");
	    result.append(Integer.toString(_line));
	    result.append(": ");
	}
	return result.toString();
    }
	
    /**
     * This version of toString() uses the _params instance variable
     * to format the message. If the <code>_code</code> is negative
     * the use _message as the error string.
     */
    public String toString() {
	String suffix = (_params == null) ? 
	    (_code >= 0 ? new String(_errorMessages[_code]) : _message)
	    : MessageFormat.format(_errorMessages[_code], _params);
	return formatLine() + suffix;
    }
	
    public String toString(Object obj) {
	Object params[] = new Object[1];
	params[0] = obj.toString();
	String suffix = MessageFormat.format(_errorMessages[_code], params);
	return formatLine() + suffix;
    }
	
    public String toString(Object obj0, Object obj1) {
	Object params[] = new Object[2];
	params[0] = obj0.toString();
	params[1] = obj1.toString();
	String suffix = MessageFormat.format(_errorMessages[_code], params);
	return formatLine() + suffix;
    }
}

