/*

 * CommonUtils.java

 *

 * Created on 18 de agosto de 2003, 13:39

 */



package q02b.exe.arquitectura.webCommon.utils;



import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.StringReader;

import java.util.ArrayList;

import java.util.Map;

import java.util.StringTokenizer;



/**

 * Clase de utilidades varias.

 * @author  SERGIO.NAVARRO

 */

public abstract class Q02bCommonUtils {

    public static final String DEFAULT_SEPARATORS = ";,";

    

    /**

     * Esta constante nos indica la versión de jdk que está ejecutando la arquitectura.

     */

    /*

    public static String[] JDK_VERSION = null;

    

    static{

        String s = System.getProperty("jdk.version");

        StringTokenizer st = new StringTokenizer(s,".");

        ArrayList list = new ArrayList();

        

        while(st.hasMoreTokens()){

            list.add(st.nextToken());

        }

        

        JDK_VERSION = (String[]) list.toArray(new String[list.size()]);

        

        

    }*/



    

    /** Parsea un string de tipo A=B;C=D;E=F , devolviendo un array de tipo:

     * { {"A","B"} , {"C","D"} , {"E","F"}}

     * <p>

     * El string a parsear representa una serie de propiedades, separadas por , ; ó :

     * @param property String con las propiedades con el formato: A=B[SEPARADOR]C=D[SEPARADOR]E=F

     * @return Array de Strings de dos dimensiones con las propiedades parseadas

     */    

    public static String[][] parseOneLinePropertyString(String property){

        return parseOneLinePropertyString(property,null);

    }

    

    

    /** Parsea un string de tipo A=B;C=D;E=F , devolviendo un array de tipo:

     * { {"A","B"} , {"C","D"} , {"E","F"}}

     * <p>

     * El string a parsear representa una serie de propiedades, separadas por una serie

     * de separadores.

     * <br>

     * Si alguno de los valores es igual al valor de la constante Constantes.ARQ_DB_NULL, se cambiará su valor

     * por null

     * @param property String con las propiedades con el formato: A=B[SEPARADOR]C=D[SEPARADOR]E=F

     * @param separators String con los separadores. Por defecto es ";.:"

     * @return Array de Strings de dos dimensiones con las propiedades parseadas

     */    

    public static String[][] parseOneLinePropertyString(String property,String separators){

        StringTokenizer st = new StringTokenizer(property, (separators==null ? DEFAULT_SEPARATORS : separators) );

        String token = null;

        String[][] res = new String[st.countTokens()][2];        

        int pos = 0;

        int index = 0;

        

        while(st.hasMoreTokens()){

            token = st.nextToken().trim();

            pos = token.indexOf("=");

        

            if(pos+1==token.length()){//Si no hay nada a la derecha del igual....

                res[index][0]=token;

                res[index][1]="";

            }else{

                res[index][0]=token.substring(0,pos);

                res[index][1]=token.substring(pos+1);

                if(res[index][1].equals(Q02bConstantes.ARQ_DB_NULL)){ res[index][1]=null;} 

            }

            

            index++;

            

        }

        

        st = null;

        token = null;

        

        return res;

    }

    

	/**

	 * Parse un String con el siguiente formato: key=value;key=value;key=value y devuelve el objeto Map

	 * cargado con los pares key value

	 * @param property String con los pares clave/valor separados por ; ó ,

	 * @return Objeto Map cargado con los pares clave/valor

	 */

    public static java.util.Map parseOneLinePropertyStringToMap(String property){

        return parseOneLinePropertyStringToMap(property,DEFAULT_SEPARATORS);

    }

    

	/**

	 * Parse un String con el siguiente formato: key=value;key=value;key=value y devuelve el objeto Map

	 * cargado con los pares key value

	 * @param property String con los pares clave/valor separados por cualquiera de los caracteres contenidos en el

	 * string separators

	 * @return Objeto Map cargado con los pares clave/valor

	 */

    public static java.util.Map parseOneLinePropertyStringToMap(String property,String separators){

        String[][] data = parseOneLinePropertyString(property,separators);

        java.util.HashMap map = new java.util.HashMap();

        

        for(int i=0;i<data.length;i++){

            map.put(data[i][0],data[i][1]);

        }

        

        data = null;

        

        return map;

    }

    

    /**

     * Devuelve un mapa con los parámetros de un objeto request. Si alguno de los parámetros tiene como valor

     * el valor de la constante Constantes.ARQ_DB_NULL, lo sustitye por null.

     * @param request Objeto request de donde obtener los parámetros

     * @return Mapa con los parámetros

     */

    public static final java.util.Map getRequestParameterMap(javax.servlet.ServletRequest request){

        java.util.Enumeration enumeration = request.getParameterNames();

        java.util.HashMap map = new java.util.HashMap();

        

        String key = null;

        String value = null;

        

        while(enumeration.hasMoreElements()){

            key = enumeration.nextElement().toString();

            value = request.getParameter(key);

            

            if(Q02bConstantes.ARQ_DB_NULL.equals(value)){

                value = null;

            }

            

            map.put(key , value);

        }

        

        enumeration = null;

        key = null;

        value = null;

        

        return map;

    }

    

    /**

     * Devuelve un String con el contenido de un map en el formato clave=valor;clave=valor

     * @param map Mapa a parsear

     * @param separator Separador de propiedades a utilizar.

     * @return String con los datos del mapa

     */

    public static final String mapToOneLinePropertyString(Map map,String separator){

        Object[] keys = map.keySet().toArray();

        

        StringBuffer res = new StringBuffer();

        

        for (int i = 0; i < keys.length; i++) {

            if(i>0){ res.append(separator);}

            res.append(keys[i].toString()).append("=").append(map.get(keys[i]));

        }

        

        keys = null;

        return res.toString();

    }

    

    /**

     * Sustituye todas las ocurrencias del String s1 por s2 en el string src. Se utiliza con jdk1.3, ya que

     * para el jdk 1.4 la clase String ya tiene un método replace all

     * @param src String origen

     * @param s1 String a sustitutir

     * @param s2 String por el que sustituir

     * @return String sustituido

     */

    public static final String replaceAll(String src,String s1,String s2){

        //return src.replaceAll(s1,s2);

        /*Orginal sergio error con combos hardcoded int pos = 0;

        int max = src.length();

        StringBuffer sb = new StringBuffer();

        

        int pos2 = 0;

        while(pos<max){

            pos2 = src.indexOf(s1,pos);

            if(pos2<0){

                pos = max;

            }else{

                sb.append(src.substring(pos,pos2)).append(s2);

                pos = pos2 + s2.length();

            }

        }

        

        return sb.toString();*/

    	while(src.indexOf(s1) != -1)

    	{

    	src = replaceFirst(src, s1, s2);

    	}

    	return src;

    	}



    	/** 

    	* Replaces first occurance of a substring with another substring within a source string.

    	* 

    	* @param source Source string

    	* @param oldVal Substring to be replaced

    	* @param newVal Substring to be replaced by

    	* @return Replaced string

    	*/

    	public static String replaceFirst(String source, String oldVal, String newVal)

    	{





    	StringBuffer SB = new StringBuffer(source);

    	try{

    	if (oldVal == null){ return source;}

    	int nameindex = source.indexOf(oldVal);

    	SB.replace(nameindex, nameindex + oldVal.length(), newVal);

    	return new String(SB);

    	}

    	finally {

    	SB=null;

    	} 

    	}



	public static final String[] split(String s , String separator,boolean separatorIsRegExp){

		return null;



	}



    /**

     * Separa el string s en strings según el separador separator, y los devuelve en un array.

     * Se utiliza con jdk1.3, ya que para el jdk 1.4 la clase String ya tiene un método split. Ojo, porque en el

     * método split de String, el parámetro separator es una expresión regular!!!

     * @param s String a procesar

     * @param separator Separador

     * @return Array de Strings procesados. Null si el separador es null o ""

     */

    public static final String[] split(String s , String separator){

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

        

        int pos = 0;

        int pos2 = 0;

        int max = s.length();

        int seplen = separator.length();

        

        ArrayList res = new ArrayList();

        

        while(pos2<=max){

            if(pos2==max){

                res.add("");

                break;

            }

            

            pos = s.indexOf(separator,pos2);

            if(pos>=0){

                res.add(s.substring(pos2,pos));

                pos2 = pos+seplen;

            }else{

                res.add(s.substring(pos2));

                break;

            }

        }

        

        return (String[])res.toArray(new String[res.size()]);

    }

    

	/**

     * Comprime el codigo pasado como parametro, esto es, quitar espacios en blanco, comentarios JS, retornos de carro

     * @param s String a procesar con 

     * @return la cadena original

     */    

	public static final String comprimirJSJava(String javascript) throws java.io.IOException{

        BufferedReader input = new BufferedReader(new StringReader(javascript));

        String linea = null;

        

        StringBuffer out = new StringBuffer();

        

        while((linea = input.readLine())!=null){

            linea = linea.trim();

            if(linea.startsWith("//")){ continue;}

            if(linea.length()==0){ continue;}

            out.append(linea);

        }

        

        return out.toString();

    }



    	/**

	 * Devuelve el contenido de un fichero de texto

	 * @param file Fichero a leer

	 * @param encoding Encoding del fichero. Si es null, el valor será iso-8859-1

	 * @return Contenido del fichero

	 * @throws IOException Si se produce algún error

	 */

	public static final String readTextFile(File file,String encoding) throws IOException{

        return new String(readFile(file),encoding==null ? "iso-8859-1" : encoding);

	}



	/**

	 * Devuelve el contenido de un fichero de texto

	 * @param file Fichero a leer

	 * @return Contenido del fichero

	 * @throws IOException Si se produce algún error

	 */

	public static final byte[] readFile(File file) throws IOException{

	    FileInputStream fis = null;

	    byte[] buffer=new byte[1024];

	    ByteArrayOutputStream baos = new ByteArrayOutputStream();

	    

	    try{

		fis = new java.io.FileInputStream(file);

	        int avail = 0;

	        while((avail=fis.available())>0){

	            avail = avail>1024?1024:avail;

	            

	            fis.read(buffer,0,avail);

	            baos.write(buffer,0,avail);

	        }

	        

	        return baos.toByteArray();

	    }finally{

	        try{

	            fis.close();

	        }catch(Throwable ex){}

	    }

	}

    

    /*

    public static void main(String[] args){

        String[] res = null;

        res = CommonUtils.split("a.b.c.d.e.f",".");

        

        

        

        String s = CommonUtils.replaceAll("abcdefghiajklmnoa","a","%");

        s = "abcdefghiajklmnoa".replaceAll("a","%");

        

    }*/

}

