/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-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 "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" 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" or
 *    "Apache Jetspeed", 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.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.jetspeed.util;

import java.util.StringTokenizer;
import java.util.Map;

/**
 * This class provides static util methods for String manaipulation that 
 * aren't part of the default JDK functionalities.
 *
 * @author <a href="mailto:raphael@apache.org">Raphaël Luta</a>
 * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a> 
 * @version $Id: StringUtils.java,v 1.8 2003/03/04 00:05:15 sgala Exp $
 */
public class StringUtils 
{
    /**
     * Replaces all the occurences of a substring found within a string by a 
     * replacement string
     *
     * @deprecated (Generates too much garbage)
     * @param original the string in where the replace will take place
     * @param find the substring to find and replace
     * @param replacement the replacement string for all occurences of find
     * @return the original string where all the occurences of find are replaced by
     *          replacement
     */
    public static String replaceAll(String original, String find, String replacement)
    {
        StringBuffer buffer = new StringBuffer(original);

        int idx = original.length();
        int offset = find.length();
        
        while( ( idx=original.lastIndexOf(find, idx-1) ) > -1 )
        {
            buffer.replace(idx,idx+offset, replacement);
        }

        return buffer.toString();
    }
    /**
     * Replaces all the occurences of a substring found 
     * within a StringBuffer by a 
     * replacement string
     *
     * @param buffer the StringBuffer in where the replace will take place
     * @param find the substring to find and replace
     * @param replacement the replacement string for all occurences of find
     * @return the original StringBuffer where all the
     * occurences of find are replaced by replacement
     */
    public static StringBuffer replaceAll(StringBuffer buffer, String find, String replacement)
    {

        int bufidx = buffer.length() - 1;
        int offset = find.length();
        while( bufidx > -1 ) { 
            int findidx = offset -1;
            while( findidx > -1 ) {
                if( bufidx == -1 ) {
                    //Done
                    return buffer;
                }
                if( buffer.charAt( bufidx ) == find.charAt( findidx ) ) {
                    findidx--; //Look for next char
                    bufidx--; 
                } else {
                    findidx = offset - 1; //Start looking again
                    bufidx--;
                    if( bufidx == -1 ) {
                        //Done
                        return buffer;
                    }
                    continue;
                }
            }
            //Found
            //System.out.println( "replacing from " + (bufidx + 1) +
            //                    " to " + (bufidx + 1 + offset ) +
            //                    " with '" + replacement + "'" );
            buffer.replace( bufidx+1, 
                            bufidx+1+offset, 
                            replacement);
            //start looking again
        }
        //No more matches
        return buffer;
            
    }

   /**
     *  Takes an array of tokens and converts into separator-separated string.
     *
     * @param String[] The array of strings input.
     * @param String The string separator.
     * @return String A string containing tokens separated by seperator.
     */
    public static final String arrayToString(String[] array, String separators)
    {
        StringBuffer sb = new StringBuffer("");
        String empty = "";
        
        if (array == null)
            return empty;

        if (separators == null)
            separators = ",";

        for (int ix=0; ix < array.length; ix++) 
        {
            if (array[ix] != null && !array[ix].equals("")) 
            {
                sb.append(array[ix] + separators);
            }
        }
        String str = sb.toString();
        if (!str.equals("")) 
        {
            str = str.substring(0, (str.length() - separators.length()));
        }
        return str;
    }

    /**
      *  Converts a delimited string into an array of string tokens.
      *                    
      * @param String[] The 'separator' separated string.
      * @param String The string separator.
      * @return String A string array of the original tokens.
      */
    public static final String[] stringToArray(String str, String separators)
    {
        StringTokenizer tokenizer;
        String[] array = null;
        int count = 0;

        if (str == null)
            return array;

        if (separators == null)
            separators = ",";

        tokenizer = new StringTokenizer(str, separators);
        if ((count = tokenizer.countTokens()) <= 0) {
            return array;
        }
        
        array = new String[count];
        
        int ix = 0;
        while (tokenizer.hasMoreTokens()) 
        {
            array[ix] = tokenizer.nextToken();
            ix++;
        }

        return array;
    }

    /**
     * Remove a given set of characters from a String.
     *
     * @param String The input string to be cleansed of 'removeChars'.
     * @param String The characters to be removed.
     * @return String The new string cleansed of 'removeChars'.
     */
    public static String removeChars (String data, String removeChars)
    {
        String temp = null;
        StringBuffer out = new StringBuffer();
        temp = data;

        StringTokenizer st = new StringTokenizer(temp, removeChars);
        while (st.hasMoreTokens())
        {
            String element = (String) st.nextElement();
            out.append(element);
        }
        return out.toString();
    }

    /* 
     * Given a filename, strips the .extension 
     *
     */
    public static String stripExtension(String filename)
    {
        int index = filename.lastIndexOf('.');
        if (index > -1)
        {
            return filename.substring(0, index);
        }
        return filename;
    }               

    /**
     * Performs variable substitution for a string. String is scanned for ${variable_name} and if one is found,
     * it is replaced with corresponding value from the vars hashtable.
     * 
     * @param origString unmodified string
     * @param vars Hashtable of replacement values
     * @return modified string
     * @exception Exception
     */
    public static String replaceVars(String origString, Map vars) 
    {

        StringBuffer finalString = new StringBuffer();
        int index = 0;
        int i = 0;
        String key = null;
        String value = null;
        while ((index = origString.indexOf("${", i)) > -1) 
        {
            key = origString.substring(index + 2, origString.indexOf("}", index+3));
            value = (String) vars.get(key);
            finalString.append(origString.substring(i, index));
            if (value != null) 
            {
                finalString.append(value);
            } 
            else 
            {
                finalString.append("${"+key+"}");
            }
            i = index + 3 + key.length();
        }
        finalString.append (origString.substring(i));

        return finalString.toString();
    }

}
