/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.axis2.util;

import java.text.Collator;
import java.util.Arrays;
import java.util.Locale;
import java.util.List;
import java.util.ArrayList;
/**
 * JavaUtils
 */
public class JavaUtils {
    /**
     * These are java keywords as specified at the following URL (sorted alphabetically).
     * http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#229308
     * Note that false, true, and null are not strictly keywords; they are literal values,
     * but for the purposes of this array, they can be treated as literals.
     *    ****** PLEASE KEEP THIS LIST SORTED IN ASCENDING ORDER ******
     */
    static final String keywords[] =
            {
                    "abstract",  "assert",       "boolean",    "break",      "byte",      "case",
                    "catch",     "char",         "class",      "const",     "continue",
                    "default",   "do",           "double",     "else",      "extends",
                    "false",     "final",        "finally",    "float",     "for",
                    "goto",      "if",           "implements", "import",    "instanceof",
                    "int",       "interface",    "long",       "native",    "new",
                    "null",      "package",      "private",    "protected", "public",
                    "return",    "short",        "static",     "strictfp",  "super",
                    "switch",    "synchronized", "this",       "throw",     "throws",
                    "transient", "true",         "try",        "void",      "volatile",
                    "while"
            };

    /** Collator for comparing the strings */
    static final Collator englishCollator = Collator.getInstance(Locale.ENGLISH);

    /** Use this character as suffix */
    static final char keywordPrefix = '_';

    /**
     * Is this an XML punctuation character?
     */
    private static boolean isPunctuation(char c)
    {
        return '-' == c
                || '.' == c
                || ':' == c
                || '\u00B7' == c
                || '\u0387' == c
                || '\u06DD' == c
                || '\u06DE' == c;
    } // isPunctuation

    /**
     * Checks if the input string is a valid java keyword.
     * @return Returns boolean.
     */
    public static boolean isJavaKeyword(String keyword) {
        return (Arrays.binarySearch(keywords, keyword, englishCollator) >= 0);
    }

    /**
     * Turns a java keyword string into a non-Java keyword string.  (Right now
     * this simply means appending an underscore.)
     */
    public static String makeNonJavaKeyword(String keyword){
        return  keywordPrefix + keyword;
    }

    public static String xmlNameToJava(String name) {
        // protect ourselves from garbage
        if (name == null || name.length() == 0)
            return name;

        char[] nameArray = name.toCharArray();
        int nameLen = name.length();
        StringBuffer result = new StringBuffer(nameLen);
        boolean wordStart = false;

        // The mapping indicates to convert first character.
        int i = 0;
        while (i < nameLen
                && (isPunctuation(nameArray[i])
                || !Character.isJavaIdentifierStart(nameArray[i]))) {
            i++;
        }
        if (i < nameLen) {
            // Decapitalization code used to be here, but we use the
            // Introspector function now after we filter out all bad chars.

            result.append(nameArray[i]);
            //wordStart = !Character.isLetter(nameArray[i]);
            wordStart = !Character.isLetter(nameArray[i]) && nameArray[i] != "_".charAt(0);
        }
        else {
            // The identifier cannot be mapped strictly according to
            // JSR 101
            if (Character.isJavaIdentifierPart(nameArray[0])) {
                result.append("_").append(nameArray[0]);
            }
            else {
                // The XML identifier does not contain any characters
                // we can map to Java.  Using the length of the string
                // will make it somewhat unique.
                result.append("_").append(nameArray.length);
            }
        }

        // The mapping indicates to skip over
        // all characters that are not letters or
        // digits.  The first letter/digit
        // following a skipped character is
        // upper-cased.
        for (++i; i < nameLen; ++i) {
            char c = nameArray[i];

            // if this is a bad char, skip it and remember to capitalize next
            // good character we encounter
            if (isPunctuation(c) || !Character.isJavaIdentifierPart(c)) {
                wordStart = true;
                continue;
            }
            if (wordStart && Character.isLowerCase(c)) {
                result.append(Character.toUpperCase(c));
            }
            else {
                result.append(c);
            }
            // If c is not a character, but is a legal Java
            // identifier character, capitalize the next character.
            // For example:  "22hi" becomes "22Hi"
            //wordStart = !Character.isLetter(c);
            wordStart = !Character.isLetter(c) && c != "_".charAt(0);
        }

        // covert back to a String
        String newName = result.toString();

        // check for Java keywords
        if (isJavaKeyword(newName))
            newName = makeNonJavaKeyword(newName);

        return newName;
    } // xmlNameToJava

    /**
     * Capitalizes the first character of the name.
     *
     * @param name
     * @return Returns String.
     */
    public static String capitalizeFirstChar(String name) {

        if ((name == null) || name.length() == 0) {
            return name;
        }

        char start = name.charAt(0);

        if (Character.isLowerCase(start)) {
            start = Character.toUpperCase(start);

            return start + name.substring(1);
        }

        return name;
    }    // capitalizeFirstChar

    /**
     * Tests the String 'value':
     *   return 'false' if its 'false', '0', or 'no' - else 'true'
     * 
     * Follow in 'C' tradition of boolean values:
     * false is specific (0), everything else is true;
     */
    public static final boolean isTrue(String value) {
        return !isFalseExplicitly(value);
    }

    /**
     * Tests the String 'value':
     *   return 'true' if its 'true', '1', or 'yes' - else 'false'
     */
    public static final boolean isTrueExplicitly(String value) {
        return value != null  &&
               (value.equalsIgnoreCase("true")  ||
                value.equals("1")  ||
                value.equalsIgnoreCase("yes"));
    }

    /**
     * Tests the Object 'value':
     *   if its null, return default.
     *   if its a Boolean, return booleanValue()
     *   if its an Integer,  return 'false' if its '0' else 'true'
     *   if its a String, return isTrueExplicitly((String)value).
     *   All other types return 'true'
     */
    public static final boolean isTrueExplicitly(Object value, boolean defaultVal) {
        if ( value == null ) return defaultVal;
        if ( value instanceof Boolean ) {
            return ((Boolean)value).booleanValue();
        }
        if ( value instanceof Integer ) {
            return ((Integer)value).intValue() != 0;
        }
        if ( value instanceof String ) {
            return isTrueExplicitly( (String)value );
        }
        return true;
    }
    
    public static final boolean isTrueExplicitly(Object value) {
        return isTrueExplicitly(value, false);
    }

    /**
     * Tests the Object 'value':
     *   if its null, return default.
     *   if its a Boolean, return booleanValue()
     *   if its an Integer,  return 'false' if its '0' else 'true'
     *   if its a String, return 'false' if its 'false', 'no', or '0' - else 'true'
     *   All other types return 'true'
     */
    public static final boolean isTrue(Object value, boolean defaultVal) {
        return !isFalseExplicitly(value, !defaultVal);
    }
    
    public static final boolean isTrue(Object value) {
        return isTrue(value, false);
    }
    
    /**
     * Tests the String 'value':
     *   return 'true' if its 'false', '0', or 'no' - else 'false'
     * 
     * Follow in 'C' tradition of boolean values:
     * false is specific (0), everything else is true;
     */
    public static final boolean isFalse(String value) {
        return isFalseExplicitly(value);
    }

    /**
     * Tests the String 'value':
     *   return 'true' if its null, 'false', '0', or 'no' - else 'false'
     */
    public static final boolean isFalseExplicitly(String value) {
        return value == null  ||
               value.equalsIgnoreCase("false")  ||
               value.equals("0")  ||
               value.equalsIgnoreCase("no");
    }
    
    /**
     * Tests the Object 'value':
     *   if its null, return default.
     *   if its a Boolean, return !booleanValue()
     *   if its an Integer,  return 'true' if its '0' else 'false'
     *   if its a String, return isFalseExplicitly((String)value).
     *   All other types return 'false'
     */
    public static final boolean isFalseExplicitly(Object value, boolean defaultVal) {
        if ( value == null ) return defaultVal;
        if ( value instanceof Boolean ) {
            return !((Boolean)value).booleanValue();
        }
        if ( value instanceof Integer ) {
            return ((Integer)value).intValue() == 0;
        }
        if ( value instanceof String ) {
            return isFalseExplicitly( (String)value );
        }
        return false;
    }
    
    public static final boolean isFalseExplicitly(Object value) {
        return isFalseExplicitly(value, true);
    }

    /**
     * Tests the Object 'value':
     *   if its null, return default.
     *   if its a Boolean, return booleanValue()
     *   if its an Integer,  return 'false' if its '0' else 'true'
     *   if its a String, return 'false' if its 'false', 'no', or '0' - else 'true'
     *   All other types return 'true'
     */
    public static final boolean isFalse(Object value, boolean defaultVal) {
        return isFalseExplicitly(value, defaultVal);
    }
    
    public static final boolean isFalse(Object value) {
        return isFalse(value, true);
    }

    public static boolean isJavaId(String id) {
        if (id == null || id.length() == 0 || isJavaKeyword(id))
            return false;
        if (!Character.isJavaIdentifierStart(id.charAt(0)))
            return false;
        for (int i=1; i<id.length(); i++)
            if (!Character.isJavaIdentifierPart(id.charAt(i)))
                return false;
        return true;
    }

    /**
     * An empty immutable <code>String</code> array.
     */
    public static final String[] EMPTY_STRING_ARRAY = new String[0];

    /**
     * <p>Splits the provided text into an array, separator specified.
     * This is an alternative to using StringTokenizer.</p>
     * <p/>
     * <p>The separator is not included in the returned String array.
     * Adjacent separators are treated as one separator.</p>
     * <p/>
     * <p>A <code>null</code> input String returns <code>null</code>.</p>
     * <p/>
     * <pre>
     * StringUtils.split(null, *)         = null
     * StringUtils.split("", *)           = []
     * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
     * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
     * StringUtils.split("a:b:c", '.')    = ["a:b:c"]
     * StringUtils.split("a\tb\nc", null) = ["a", "b", "c"]
     * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]
     * </pre>
     *
     * @param str           the String to parse, may be null
     * @param separatorChar the character used as the delimiter,
     *                      <code>null</code> splits on whitespace
     * @return an array of parsed Strings, <code>null</code> if null String input
     */
    public static String[] split(String str, char separatorChar) {
        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len == 0) {
            return EMPTY_STRING_ARRAY;
        }
        List list = new ArrayList();
        int i = 0, start = 0;
        boolean match = false;
        while (i < len) {
            if (str.charAt(i) == separatorChar) {
                if (match) {
                    list.add(str.substring(start, i));
                    match = false;
                }
                start = ++i;
                continue;
            }
            match = true;
            i++;
        }
        if (match) {
            list.add(str.substring(start, i));
        }
        return (String[]) list.toArray(new String[list.size()]);
    }

    public static Class getWrapperClass(Class primitive)
    {
        if (primitive == int.class)
            return java.lang.Integer.class;
        else if (primitive == short.class)
            return java.lang.Short.class;
        else if (primitive == boolean.class)
            return java.lang.Boolean.class;
        else if (primitive == byte.class)
            return java.lang.Byte.class;
        else if (primitive == long.class)
            return java.lang.Long.class;
        else if (primitive == double.class)
            return java.lang.Double.class;
        else if (primitive == float.class)
            return java.lang.Float.class;
        else if (primitive == char.class)
            return java.lang.Character.class;
        
        return null;
    }

	/**
	 * Scans the parameter string for the parameter search ignoring case when
	 * comparing characters.
	 *
	 * @param string
	 * @param search
	 *            If test is empty -1 is always returned.
	 * @return -1 if the string was not found or the index of the first matching
	 *         character
	 */
	public static int indexOfIgnoreCase(final String string,
			final String search) {
		int index = -1;
		final int stringLength = string.length();
		final int testLength = search.length();
		if (stringLength > 1 || testLength > 1) {
			final char firstCharOfTest = Character.toLowerCase(search.charAt(0));
			final int lastStringCharacterToCheck = stringLength - testLength + 1;

			for (int i = 0; i < lastStringCharacterToCheck; i++) {
				if (firstCharOfTest == Character.toLowerCase(string.charAt(i))) {
					index = i;
					for (int j = 1; j < testLength; j++) {
						final char c = string.charAt(i + j);
						final char otherChar = search.charAt(j);
						if (Character.toLowerCase(c) != Character.toLowerCase(otherChar)) {
							index = -1;
							break;
						}
					}
					if( -1 != index ){
						break;
					}
				}
			}
		}
		return index;
	}
}
