/*  Copyright (c) 2000, 2002 by Oracle Corporation. All Rights Reserved. */

package oracle.portal.provider.v1.http; 

import java.util.Properties; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.BufferedInputStream; 
import java.util.StringTokenizer; 
import java.util.HashMap;
import oracle.portal.provider.v1.PortletRenderRequest; 
import oracle.portal.provider.v1.PortletException;
import oracle.portal.provider.v1.Provider; 
import oracle.portal.provider.v1.AccessControlException; 
import oracle.portal.provider.v1.PortletRendererUtil; 
import oracle.portal.provider.v1.PortletReference; 
import oracle.portal.provider.v1.PortletParameter; 
import oracle.portal.provider.v1.URLPortletParameter; 
import oracle.portal.provider.v1.DefaultContainerRenderer;
import java.io.UnsupportedEncodingException;

/**
 * <p><b> URLServicesUtils </b> class contains metadata which is common
 * across modules.
 * It handles logging specific issues such as logging different messages
 * with respect to debuglevel parameter specified.
 *
 */
public class UrlServicesUtils 
{ 
    
    // Constants used In URLProvider
    
    // Defines maximum number of allowed cookies
    public static final int MAXCOOKIES = 20; 
    public static final String EXTERNAL = "ExternalApp"; 
    public static final String BASIC_AUTHENTICATION = "Basic"; 
    
    // User agent for netscape
    public static final String CONTENT_TYPE_HEADER_FIELD = "User-Agent"; 
    
    //Flag for indicating that user is not registered
    public static final String REGISTERED_FLAG = "registered_user"; 
    
    // Constants used by UrlSecurityManager
    public static final String REGISTERED_AUTHTYPE = "registered"; 
    public static final String PUBLIC_PORTLET = "public"; 
    
    //Content Types
    public static final String HTML = "text/html"; 
    public static final String XML = "text/xml"; 
    public static final String TRUE = "true"; 
    public static final String FALSE = "false"; 
    
    //Constants used by HTML Filter
    public static final String HREF_LOWERCASE = "href="; 
    public static final String HREF_UPPERCASE = "HREF="; 
    public static final String FORWARD_SLASH = "/"; 
    
    //Constants for debug level.
    public static final int BASIC_LOGGING = 1; 
    public static final int HIGHER_LOGGING = 2; 
    public static final int HTML_CONTENTS_LOGGING = 3; 
    public static final int XHTML_CONTENTS_LOGGING = 5; 
    public static final String TABLE_TAG_START = "<table"; 
    public static final String TABLE_TAG_END = "/table>"; 
    public static final String TABLE_BACKGROUND_COLOR = "TabBackgroundColor"; 

    //Content encoding related constants.
    public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
    public static final String DEFAULT_IANA_ENCODING = "ISO-8859-1";
    public static final String PAGE_URL = "pageUrl";
    public static final String EXTERNAL_APP = "url.external.app";
    private static HashMap IANA_TABLE = new HashMap();
    public static final String SELECT_SUBMIT = "select_submit";

    // Static initializer block
    static
    {
      //
      // Initialize the IANA to Java CS name table.
      //
  
      // Arabic (ISO)
      IANA_TABLE.put("iso-8859-6".toLowerCase(),       "ISO8859_6");
      IANA_TABLE.put("ISO_8859-6:1987".toLowerCase(),  "ISO8859_6");
      IANA_TABLE.put("iso-ir-127".toLowerCase(),       "ISO8859_6");
      IANA_TABLE.put("ISO_8859-6".toLowerCase(),       "ISO8859_6");
      IANA_TABLE.put("ECMA-114".toLowerCase(),         "ISO8859_6");
      IANA_TABLE.put("ASMO-708".toLowerCase(),         "ISO8859_6");
      IANA_TABLE.put("arabic".toLowerCase(),           "ISO8859_6");
      IANA_TABLE.put("csISOLatinArabic".toLowerCase(), "ISO8859_6");
    
      // Arabic (Windows)
      IANA_TABLE.put("windows-1256".toLowerCase(), "Cp1256");
    
      // Baltic (ISO)
      IANA_TABLE.put("iso-8859-4".toLowerCase(),      "ISO8859_4");
      IANA_TABLE.put("csISOLatin4".toLowerCase(),     "ISO8859_4");
      IANA_TABLE.put("iso-ir-110".toLowerCase(),      "ISO8859_4");
      IANA_TABLE.put("ISO_8859-4".toLowerCase(),      "ISO8859_4");
      IANA_TABLE.put("ISO_8859-4:1988".toLowerCase(), "ISO8859_4");
      IANA_TABLE.put("l4".toLowerCase(),              "ISO8859_4");
      IANA_TABLE.put("latin4".toLowerCase(),          "ISO8859_4");
    
      // Baltic (Windows)
      IANA_TABLE.put("windows-1257".toLowerCase(), "Cp1257");
    
      // Central European (DOS)
      IANA_TABLE.put("ibm852".toLowerCase(),   "Cp852");
      IANA_TABLE.put("cp852".toLowerCase(),    "Cp852");
      IANA_TABLE.put("852".toLowerCase(),      "Cp852");
      IANA_TABLE.put("csPcp852".toLowerCase(), "Cp852");
    
      // Central European (ISO)
      IANA_TABLE.put("iso-8859-2".toLowerCase(),      "ISO8859_2");
      IANA_TABLE.put("csISOLatin2".toLowerCase(),     "ISO8859_2");
      IANA_TABLE.put("iso-ir-101".toLowerCase(),      "ISO8859_2");
      IANA_TABLE.put("iso8859-2".toLowerCase(),       "ISO8859_2");
      IANA_TABLE.put("iso_8859-2".toLowerCase(),      "ISO8859_2");
      IANA_TABLE.put("iso_8859-2:1987".toLowerCase(), "ISO8859_2");
      IANA_TABLE.put("l2".toLowerCase(),              "ISO8859_2");
      IANA_TABLE.put("latin2".toLowerCase(),          "ISO8859_2");
    
      // Central European (Windows)
      IANA_TABLE.put("windows-1250".toLowerCase(), "Cp1250");
      IANA_TABLE.put("x-cp1250".toLowerCase(),     "Cp1250");
    
      // Chinese Simplified (GB2312)
      IANA_TABLE.put("gb2312".toLowerCase(),          "EUC_CN");
      IANA_TABLE.put("chinese".toLowerCase(),         "EUC_CN");
      IANA_TABLE.put("csGB2312".toLowerCase(),        "EUC_CN");
      IANA_TABLE.put("csISO58GB231280".toLowerCase(), "EUC_CN");
      IANA_TABLE.put("GB2312".toLowerCase(),          "EUC_CN");
      IANA_TABLE.put("GB_2312-80".toLowerCase(),      "EUC_CN");
      IANA_TABLE.put("iso-ir-58".toLowerCase(),       "EUC_CN");
    
      // Chinese Simplified (Windows)
      IANA_TABLE.put("gbk".toLowerCase(), "GBK");
    
      // Chinese Traditional
      IANA_TABLE.put("big5".toLowerCase(),     "Big5");
      IANA_TABLE.put("csbig5".toLowerCase(),   "Big5");
      IANA_TABLE.put("x-x-big5".toLowerCase(), "Big5");
    
      // Chinese
      IANA_TABLE.put("iso-2022-cn".toLowerCase(), "ISO2022CN");
      IANA_TABLE.put("csISO2022CN".toLowerCase(), "ISO2022CN");
    
      // Chinese Traditional (EUC-TW)
      IANA_TABLE.put("EUC-TW".toLowerCase(), "EUC_TW");
    
      // Cyrillic (DOS)
      IANA_TABLE.put("cp866".toLowerCase(),    "Cp866");
      IANA_TABLE.put("ibm866".toLowerCase(),   "Cp866");
      IANA_TABLE.put("866".toLowerCase(),      "Cp866");
      IANA_TABLE.put("csIBM866".toLowerCase(), "Cp866");
    
      // Cyrillic (ISO)
      IANA_TABLE.put("iso-8859-5".toLowerCase(),         "ISO8859_5");
      IANA_TABLE.put("csISOLatinCyrillic".toLowerCase(), "ISO8859_5");
      IANA_TABLE.put("cyrillic".toLowerCase(),           "ISO8859_5");
      IANA_TABLE.put("iso-ir-144".toLowerCase(),         "ISO8859_5");
      IANA_TABLE.put("ISO_8859-5".toLowerCase(),         "ISO8859_5");
      IANA_TABLE.put("ISO_8859-5:1988".toLowerCase(),    "ISO8859_5");
    
      // Cyrillic (KOI8-R)
      IANA_TABLE.put("koi8-r".toLowerCase(),  "KOI8_R");
      IANA_TABLE.put("csKOI8R".toLowerCase(), "KOI8_R");
      IANA_TABLE.put("koi".toLowerCase(),     "KOI8_R");
    
      // Cyrillic Alphabet (Windows)
      IANA_TABLE.put("windows-1251".toLowerCase(), "Cp1251");
      IANA_TABLE.put("x-cp1251".toLowerCase(),     "Cp1251");
    
      // Greek (ISO)
      IANA_TABLE.put("iso-8859-7".toLowerCase(),      "ISO8859_7");
      IANA_TABLE.put("csISOLatinGreek".toLowerCase(), "ISO8859_7");
      IANA_TABLE.put("ECMA-118".toLowerCase(),        "ISO8859_7");
      IANA_TABLE.put("ELOT_928".toLowerCase(),        "ISO8859_7");
      IANA_TABLE.put("greek".toLowerCase(),           "ISO8859_7");
      IANA_TABLE.put("greek8".toLowerCase(),          "ISO8859_7");
      IANA_TABLE.put("iso-ir-126".toLowerCase(),      "ISO8859_7");
      IANA_TABLE.put("ISO_8859-7".toLowerCase(),      "ISO8859_7");
      IANA_TABLE.put("ISO_8859-7:1987".toLowerCase(), "ISO8859_7");
      IANA_TABLE.put("csISOLatinGreek".toLowerCase(), "ISO8859_7");
        
      // Greek (Windows)
      IANA_TABLE.put("windows-1253".toLowerCase(), "Cp1253");

      // Hebrew (ISO)
      IANA_TABLE.put("iso-8859-8".toLowerCase(),       "ISO8859_8");
      IANA_TABLE.put("csISOLatinHebrew".toLowerCase(), "ISO8859_8");
      IANA_TABLE.put("hebrew".toLowerCase(),           "ISO8859_8");
      IANA_TABLE.put("iso-ir-138".toLowerCase(),       "ISO8859_8");
      IANA_TABLE.put("ISO_8859-8".toLowerCase(),       "ISO8859_8");
      IANA_TABLE.put("visual".toLowerCase(),           "ISO8859_8");
      IANA_TABLE.put("ISO-8859-8".toLowerCase(),       "ISO8859_8");
      IANA_TABLE.put("Visual".toLowerCase(),           "ISO8859_8");
      IANA_TABLE.put("ISO_8859-8:1988".toLowerCase(),  "ISO8859_8");
        
      // Hebrew (Windows)
      IANA_TABLE.put("windows-1255".toLowerCase(), "Cp1255");

      // Japanese (JIS)
      IANA_TABLE.put("iso-2022-jp".toLowerCase(), "ISO2022JP");
      IANA_TABLE.put("csISO2022JP".toLowerCase(), "ISO2022JP");
    
      // Japanese (EUC)
      IANA_TABLE.put("euc-jp".toLowerCase(),              "EUC_JP");
      IANA_TABLE.put("csEUCPkdFmtJapanese".toLowerCase(), "EUC_JP");
      IANA_TABLE.put(
          "Extended_UNIX_Code_Packed_Format_for_Japanese".toLowerCase(), 
          "EUC_JP");
      IANA_TABLE.put("x-euc".toLowerCase(),               "EUC_JP");
      IANA_TABLE.put("x-euc-jp".toLowerCase(),            "EUC_JP");
    
      // Japanese (Shift-JIS)
      IANA_TABLE.put("shift_jis".toLowerCase(),    "SJIS");
      IANA_TABLE.put("csShiftJIS".toLowerCase(),   "SJIS");
      IANA_TABLE.put("ms_Kanji".toLowerCase(),     "SJIS");
      IANA_TABLE.put("shift-jis".toLowerCase(),    "SJIS");
      IANA_TABLE.put("x-sjis".toLowerCase(),       "SJIS");
    
      // Japanese (Windows) - new in JDK 1.2
      IANA_TABLE.put("Windows-31J".toLowerCase(),  "MS932");
      IANA_TABLE.put("csWindows31J".toLowerCase(), "MS932");
      IANA_TABLE.put("x-ms-cp932".toLowerCase(),   "MS932");

      // Korean
      IANA_TABLE.put("ks_c_5601-1987".toLowerCase(), "EUC_KR");
      IANA_TABLE.put("csKSC56011987".toLowerCase(),  "EUC_KR");
      IANA_TABLE.put("korean".toLowerCase(),         "EUC_KR");
      IANA_TABLE.put("ks_c_5601".toLowerCase(),      "EUC_KR");
      IANA_TABLE.put("euc-kr".toLowerCase(),         "EUC_KR");
      IANA_TABLE.put("csEUCKR".toLowerCase(),        "EUC_KR");
    
      // Korean (ISO)
      IANA_TABLE.put("iso-2022-kr".toLowerCase(), "ISO2022KR");
      IANA_TABLE.put("csISO2022KR".toLowerCase(), "ISO2022KR"); 
   
      // Latin 3 (ISO)
      IANA_TABLE.put("iso-8859-3".toLowerCase(),      "ISO8859_3");
      IANA_TABLE.put("ISO_8859-3".toLowerCase(),      "ISO8859_3");
      IANA_TABLE.put("ISO_8859-3:1988".toLowerCase(), "ISO8859_3");
      IANA_TABLE.put("iso-ir-109".toLowerCase(),      "ISO8859_3");
      IANA_TABLE.put("latin3".toLowerCase(),          "ISO8859_3");
      IANA_TABLE.put("l3".toLowerCase(),              "ISO8859_3");
      IANA_TABLE.put("csISOLatin3".toLowerCase(),     "ISO8859_3");
    
      // Thai
      IANA_TABLE.put("TIS-620".toLowerCase(), "TIS620");
    
      // Thai (Windows)
      IANA_TABLE.put("windows-874".toLowerCase(), "MS874");
    
      // Turkish (Windows)
      IANA_TABLE.put("windows-1254".toLowerCase(), "Cp1254");
    
      // Turkish (ISO)
      IANA_TABLE.put("iso-8859-9".toLowerCase(),      "ISO8859_9");
      IANA_TABLE.put("latin5".toLowerCase(),          "ISO8859_9");
      IANA_TABLE.put("l5".toLowerCase(),              "ISO8859_9");
      IANA_TABLE.put("csISOLatin5".toLowerCase(),     "ISO8859_9");
      IANA_TABLE.put("ISO_8859-9".toLowerCase(),      "ISO8859_9");
      IANA_TABLE.put("iso-ir-148".toLowerCase(),      "ISO8859_9");
      IANA_TABLE.put("ISO_8859-9:1989".toLowerCase(), "ISO8859_9");
    
      // Universal (UTF-8)
      IANA_TABLE.put("utf-8".toLowerCase(),               "UTF8");
      IANA_TABLE.put("unicode-1-1-utf-8".toLowerCase(),   "UTF8");
      IANA_TABLE.put("unicode-2-0-utf-8".toLowerCase(),   "UTF8");
      IANA_TABLE.put("x-unicode-2-0-utf-8".toLowerCase(), "UTF8");
    
      // Vietnamese (Windows)
      IANA_TABLE.put("windows-1258".toLowerCase(), "Cp1258");
    
      // Western (ASCII)
      IANA_TABLE.put("us-ascii".toLowerCase(),         "ASCII");
      IANA_TABLE.put("ANSI_X3.4-1968".toLowerCase(),   "ASCII");
      IANA_TABLE.put("ANSI_X3.4-1986".toLowerCase(),   "ASCII");
      IANA_TABLE.put("ascii".toLowerCase(),            "ASCII");
      IANA_TABLE.put("cp367".toLowerCase(),            "ASCII");
      IANA_TABLE.put("csASCII".toLowerCase(),          "ASCII");
      IANA_TABLE.put("IBM367".toLowerCase(),           "ASCII");
      IANA_TABLE.put("ISO646-US".toLowerCase(),        "ASCII");
      IANA_TABLE.put("ISO_646.irv:1991".toLowerCase(), "ASCII");
      IANA_TABLE.put("iso-ir-6".toLowerCase(),         "ASCII");
      IANA_TABLE.put("us".toLowerCase(),               "ASCII");
    
      // Western Alphabet (windows)
      IANA_TABLE.put("windows-1252".toLowerCase(), "Cp1252");
      IANA_TABLE.put("x-ansi".toLowerCase(),       "Cp1252");    
    
      // Western Alphabet
      IANA_TABLE.put("iso-8859-1".toLowerCase(),      "ISO8859_1");
      IANA_TABLE.put("cp819".toLowerCase(),           "ISO8859_1");
      IANA_TABLE.put("ibm819".toLowerCase(),          "ISO8859_1");
      IANA_TABLE.put("iso-ir-100".toLowerCase(),      "ISO8859_1");
      IANA_TABLE.put("iso8859-1".toLowerCase(),       "ISO8859_1");
      IANA_TABLE.put("iso_8859-1".toLowerCase(),      "ISO8859_1");
      IANA_TABLE.put("iso_8859-1:1987".toLowerCase(), "ISO8859_1");
      IANA_TABLE.put("latin1".toLowerCase(),          "ISO8859_1");
      IANA_TABLE.put("l1".toLowerCase(),              "ISO8859_1");
      IANA_TABLE.put("csISOLatin1".toLowerCase(),     "ISO8859_1");
        
      // Universal (UTF16 in XML)
      IANA_TABLE.put("utf-16".toLowerCase(), "UnicodeLittle");
    
      // Universal (UCS2 in XML)
      IANA_TABLE.put("ISO-10646-UCS-2".toLowerCase(), "UnicodeLittle");
      IANA_TABLE.put("csUnicode".toLowerCase(),       "UnicodeLittle");
    }
    protected static void logMessage(Provider p, String msg, int msgDebugLevel) 
    { 
        //By default make it higher logging.
        logMessage(p,msg,msgDebugLevel,HIGHER_LOGGING); 
    } 
    
    /**
     * Method for logging exceptions and their description into Web. 
     *
     * It works as follows ...
     * There are four types of logging. They are :
     * a) BASIC_LOGGING - 
     *    where in only method entry and exit statements are written.
     * b) HIGHER_LOGGING - 
    *     which logs method execution flow statements.
     * c) HTML_CONTENTS_LOGGING - 
     *    which will write Html contents read from url to log file.
     * d) XHTML_CONTENTS_LOGGING - 
     *    Logging of XHTML contents from XmlFilter.
     *
     * @param p Provider object
     * @param msg Message to be logged
     * @param msgDebugLevel Debug level
     * @param type type of message (BASIC,HIGHER,HTML OR XHTML)
     */
    protected static void logMessage(Provider p, 
        String msg, 
        int msgDebugLevel, 
        int type) 
    { 
        
        // Basic logging for debuglevel >= 1
        if (type == BASIC_LOGGING && msgDebugLevel >= BASIC_LOGGING) 
        { 
            p.log(msg); 
        } 
        // Higher logging for debuglevel >= 2
        else if (type == HIGHER_LOGGING && msgDebugLevel >= HIGHER_LOGGING) 
        { 
            p.log(msg); 
        } 
        // log XHtml contents only if the debuglevel is 5 
        // as well as type is XHTML.
        else if (type == XHTML_CONTENTS_LOGGING && 
            msgDebugLevel == XHTML_CONTENTS_LOGGING) 
        { 
            p.log(msg); 
        } 
        // log Html contents only if the debuglevel is >= 3 
        // as well as type is HTML.
        else if (type == HTML_CONTENTS_LOGGING &&
            msgDebugLevel >= HTML_CONTENTS_LOGGING) 
        { 
            p.log(msg); 
        } 
    } //end of logMessage
    
    /**
     * Method for logging exceptions and their description into Web
     * Server's log file.
     * @param p Provider object
     * @param msg Message to be logged
     * @param e Exception thrown
     * @param msgDebugLevel Debug level
     *
     */
    protected static void logMessage(Provider p, String msg, Exception e, int msgDebugLevel) 
    { 
        
        // Output based on message level
        //Log Stack Trace if debuglevel is specified.
        if (msgDebugLevel >= BASIC_LOGGING) 
        { 
            p.log(msg,e); 
        } 
        else  
        { 
            
            //Log exception messages if no debuglevel is specified.
            p.log(msg + e.getMessage()); 
        } 
    } //end of logMessage

    //Retuns debuglevel from PortletRenderRequest
    protected static int readDebugLevel(PortletRenderRequest pr) 
    { 
        return readDebugLevel(pr.getProvider()); 
    } 
    
    //Retuns debuglevel from Provider
    protected static int readDebugLevel(Provider p) 
    { 
        return ((URLProvider)p).getDebugLevel(); 
    } 

    /**
     * Method to construct portlet parameter form based on paramters
     * declared through provider.xml.
     *
     * The constructed HTML Content string is returned to the caller, which
     * in turn renders in the portlet.
     *
     * @param pr PortletRenderRequest to get portlet instance name
     * @param qualified true/false based on if the paramters are qualified.
     * @return String constructed parameter form content.
     */
    public static String showPortletParameters(PortletRenderRequest pr, 
        boolean qualified) 
    { 
        PortletParameter params[] = pr.getPortlet().getInputParameters(); 
        if (params == null) 
            return ""; 
        StringBuffer parameterContent = new StringBuffer(); 
        String hashedRefName = hashString(pr.getPortletReference().getName()); 
        parameterContent.append ("<SCRIPT language=\"JavaScript1.1\" > \n"); 
        parameterContent.append (" function submitParams"); 
        parameterContent.append (hashedRefName); 
        parameterContent.append ("()\n"); 
        parameterContent.append (" {\n"); 
        parameterContent.append(" var elems = document.paramform"); 
        parameterContent.append(hashedRefName); 
        parameterContent.append(".elements;\n"); 
        parameterContent.append("var list;\n"); 
        parameterContent.append(" var l_name = \"");
        parameterContent.append(
            HttpPortletRendererUtil.portletParameter(
                pr, 
                SELECT_SUBMIT));
        parameterContent.append("\";\n");
        parameterContent.append("for(i=0; i<elems.length; i++)\n");
        parameterContent.append("{\n");
        parameterContent.append("    if(elems[i].name == l_name)\n");
        parameterContent.append("    {\n");
        parameterContent.append("        list = elems[i];\n");
        parameterContent.append("    }\n");
        parameterContent.append("}");
        parameterContent.append(" var p_form = document.paramform"); 
        parameterContent.append (hashedRefName); 
        parameterContent.append (";\n"); 
        parameterContent.append (" var index = list.selectedIndex;\n"); 
        parameterContent.append (" p_form.method = "); 
        parameterContent.append (" list.options[index].text;\n"); 
        parameterContent.append (" p_form.submit();\n"); 
        parameterContent.append (" }\n"); 
        parameterContent.append ("</SCRIPT>\n"); 
        parameterContent.append ("<FORM NAME=\"paramform"); 
        parameterContent.append (hashedRefName); 
        parameterContent.append("\" METHOD = \"GET\" "); 
        parameterContent.append ("ACTION=\"" + 
        HttpPortletRendererUtil.htmlFormActionLink( 
        pr,PortletRendererUtil.PAGE_LINK) + "\""); 
        parameterContent.append (">\n"); 
        parameterContent.append ( 
        HttpPortletRendererUtil.htmlFormHiddenFields 
        (pr,PortletRendererUtil.PAGE_LINK)); 
        parameterContent.append ("\n"); 
        parameterContent.append("<TABLE WIDTH=\"60%\" BORDER = \"0\""); 
        parameterContent.append(" CELLPADDING=\"5\" CELLSPACING = \"5\""); 
        parameterContent.append(" WIDTH=\"100%\" > \n"); 
        parameterContent.append("<TR><TD COLSPAN=\"2\" > "); 
        parameterContent.append("<FONT class=\"PortletHeading1\" > "); 
        parameterContent.append("Portal Page Parameters :</FONT></TD></TR>"); 
        parameterContent.append("<TR><TD COLSPAN=\"2\""); 
        parameterContent.append("<FONT class=\"PortletText1\" > "); 
        parameterContent.append("Edit portlet parameters given below and submit them"); 
        parameterContent.append(" using either GET or POST method."); 
        parameterContent.append(" (*) Marked parameters are mandatory.</TD></TR>"); 
        if (params != null) 
        { 
            for (int i = 0; i < params.length; i++) 
            { 
                URLPortletParameter parameter= 
                (URLPortletParameter)params[i]; 
                parameterContent.append("<TR><TD>\n"); 
                parameterContent.append("<FONT class=\"PortletText1\" > \n"); 
                parameterContent.append(parameter.getDisplayName()); 
                if (parameter.isMandatory())
                { 
                    parameterContent.append(" * "); 
                } 
                parameterContent.append("</TD>\n"); 
                parameterContent.append("\n"); 
                parameterContent.append("<TD><INPUT TYPE=\"text\" "); 
                parameterContent.append("NAME=\""); 
                String name = 
                    PortletRendererUtil.portletParameter(pr, parameter.getName());
                String value = pr.getQualifiedParameter(parameter.getName());
                if (qualified) 
                { 
                    name = PortletRendererUtil.portletParameter( 
                               pr, parameter.getName()); 
                    value = pr.getQualifiedParameter(parameter.getName()); 
                } 
                else  
                { 
                    name = parameter.getName(); 
                    value = pr.getParameter(name); 
                } 
                if (value == null) 
                value = ""; 
                parameterContent.append(name); 
                parameterContent.append("\" SIZE = \"20\" VALUE = \""); 
                parameterContent.append(value + "\" ></ TD ></ TR > \n"); 
            } 
        } 
        String submitType = null; 
        if (qualified) 
        { 
            submitType = pr.getQualifiedParameter(SELECT_SUBMIT); 
        } 
        else  
        { 
            submitType = pr.getParameter(SELECT_SUBMIT); 
        } 
        parameterContent.append("<TR>\n"); 
        parameterContent.append("<TD><FONT class=\"PortletText1\" > Submit type : "); 
        parameterContent.append("</FONT></TD>\n"); 
        parameterContent.append("<TD><SELECT SIZE=\"1\" NAME = \""); 
        if (qualified) 
        { 
            parameterContent.append(
                PortletRendererUtil.portletParameter( 
                    pr, 
                    SELECT_SUBMIT)); 
        } 
        else  
        { 
            parameterContent.append(SELECT_SUBMIT); 
        } 
        if (submitType == null) 
        submitType = "GET"; 
        parameterContent.append("\" > \n"); 
        parameterContent.append("<OPTION"); 
        if (submitType.equals("GET")) 
        { 
            parameterContent.append(" SELECTED"); 
        } 
        parameterContent.append(">GET</OPTION>\n"); 
        parameterContent.append("<OPTION"); 
        if (submitType.equals("POST")) 
        { 
            parameterContent.append(" SELECTED"); 
        } 
        parameterContent.append(">POST</OPTION>\n"); 
        parameterContent.append("</SELECT>\n"); 
        parameterContent.append("<INPUT TYPE=\"button\" VALUE = \"Submit\""); 
        parameterContent.append(" ONCLICK=\"javascript : submitParams"); 
        parameterContent.append (hashedRefName); 
        parameterContent.append ("();\" ></ TD > \n"); 
        parameterContent.append("</TR>"); 
        parameterContent.append("</TABLE>"); 
        parameterContent.append("</FORM>\n"); 
        return parameterContent.toString(); 
    } 
    /**
     * Method converts a hashes a string to another string which contains
     * the sum of individual character integer values.
     *
     * This utility is used in making qualified portlet paramters.
     * @param str string to be hashed.
     * @return String hashed string.
     */
    public static String hashString(String str) 
    { 
        long hashValue = 0; 
        for (int i = 0; i < str.length(); i++) 
        { 
            hashValue += (int)str.charAt(i); 
        } 
        return String.valueOf(Math.abs(hashValue)); 
    } 
    
   /**
    * Extract the character set name from a standard HTTP Content-Type header
    * String.
    *
    * If none could be determined this function will return "ascii".
    *
    * @param contentType Standard HTTP Content-Type string.
    * @return the Character set name contained in the string or "ascii".
    */
    public static String getCharsetFromContentType(String contentType)
    {
        int pos;
        String csName;

        if ((pos = contentType.toLowerCase().indexOf("charset=")) > 0)
        {
            csName = contentType.substring(pos + 8);
            if ((pos = csName.indexOf(" ")) > 0)
            {
              csName = csName.substring(0, pos-1);
            }
        }
        else
        {
            //
            // Assume it's ISO-8859-1 if not present, as required by RFC 2616 (HTTP
            // 1.1 spec)
            //
            csName = DEFAULT_IANA_ENCODING;
        }
        return csName;
    }


   /**
    * Convert an character set string in IANA, or IANA alias, form into a Java
    * name suitable for the Java-based CS-conversion rules.
    *
    * @param IANAName the name of the IANA character set.
    * @return the Java-based equivalent.
    * @exception UnsupportedEncodingException if there is no mapping.
    */
    public static String getEncodingFromContentType(String contentType)
      throws UnsupportedEncodingException
    {
        return convertIANAtoJava(getCharsetFromContentType(contentType));
    }

   /**
    * Convert an character set string in IANA, or IANA alias, form into a Java
    * name suitable for the Java-based CS-conversion rules.
    *
    * @param IANAName the name of the IANA character set.
    * @return the Java-based equivalent.
    * @exception UnsupportedEncodingException if there is no mapping.
    */
    public static String convertIANAtoJava(String IANAName)
      throws UnsupportedEncodingException
    {
        String foo = (String)IANA_TABLE.get(IANAName.toLowerCase());

        if (foo != null)
          return foo;

        throw new UnsupportedEncodingException(
          "Unsupported character encoding: \"" + IANAName + "\"");
    }
    /**
     * Helper method which returns the string contents out of input stream.
     * @param urlStream inputstream to be converted
     * @param encoding encoding to be applied to the inputstream
     * @param provider provider reference, to log messages.
     * @param debugLevel debug level to log messages.
     * @return Inputstream converted into StringBuffer
     *
     */
    public static StringBuffer convertStreamToStringBuffer(
        InputStream urlStream, 
        String encoding,
        Provider provider,
        int debugLevel) 
    { 
        StringBuffer urlContent = new StringBuffer(); 
        BufferedReader reader = null; 
        try  
        { 
            UrlServicesUtils.logMessage(provider, "ConvertStreamToStringBuffer: Inside", 
            debugLevel, 
            UrlServicesUtils.BASIC_LOGGING); 
            UrlServicesUtils.logMessage(provider, "Character encoding = " + encoding, 
                debugLevel); 
            reader = new BufferedReader( new InputStreamReader(urlStream, encoding)); 
            String line = null; 
            while ((line = reader.readLine()) != null) 
            { 
                urlContent.append(line); 
                urlContent.append(System.getProperty("line.separator")); 
            } 
            UrlServicesUtils.logMessage(provider, 
            "ConvertStreamToStringBuffer:Before close", 
            debugLevel); 
        } 
        catch (IOException ie) 
        { 
            UrlServicesUtils.logMessage( 
            provider, 
            "ConvertStreamToString: IOException In converting "+ 
            " stream to StringBuffer", ie,debugLevel); 
            
            //return null if any exception occurs.
            return null; 
        } 
        finally  
        { 
            try { urlStream.close(); if(reader != null) reader.close(); } 
            catch (IOException e) {}
        } 
        UrlServicesUtils.logMessage(provider, "ConvertStreamToStringBuffer: Leaving", 
        debugLevel,UrlServicesUtils.BASIC_LOGGING); 
        return urlContent; 
    } //end of convertStreamToStringBuffer
    
} //end of UrlServicesUtils