SRServlet.SRSessionServlet (Java2HTML)
/**
* @author srangan
* @version 1.0
*
* Development Environment        :  JDeveloper 2.0
* Name of the Application        :  SRSessionServlet.java
* Creation/Modification History  :
*
*    srangan.in      11-MAY-1999      Created
*    Jagriti         10-Sep-2001      Modified  to include JDBC2.0 features.
*                                     Included DataSource usage using JNDI.
*
*
* This class implements a servlet that handles the Survey Response Component of
* the OTN Survey application.
*
* The Survey Definition is captured in the Survey, SurveyElement, Question
* and Choice classes in the SRServlet package.
*
* The servlet implemented by this class is session based. The various operations
* performed by this class are:
*   - When a user requests a survey, a new session is created, and the
*     Survey Definition is read from the database.
*     Methods associated with this functionality are:
*     o startSession() creates a new session
*     o generateSurveyForm() retrieves the survey definition from the database
*       by instantiating a SRServlet.Survey object, and calling the retrieveFromDB
*       method on the object.
*
*   - The class formats the HTML for a survey and returns it to the browser
*     o printSurveyForm()  formats the HTML survey form and returns to the browser
*   - When the user submits the responses for a survey, this class performs
*     validation. If validated, the responses are stored to the database, and
*     if not the errors are displayed.
*     o processResponse() - Validates the responses, by calling the
*       validateAndStoreChanges on all questions in the survey.
*
*       If validated, the saveResponse method on all questions are called to
*       save the responses in the database, else the printSurveyForm method
*       is called to display errors
*
**/

package SRServlet;

import javax.servlet.*;
import javax.servlet.http.*;

import java.io.*;
import java.util.*;

import java.sql.*;
import javax.sql.*; // JDBC 2.0 core APIs
import oracle.jdbc.driver.*;
import oracle.jdbc.pool.OracleDataSource;
import javax.naming.*; // Package for using JNDI



public class SRSessionServlet extends HttpServlet {

  public static String s_servletPath = null;
  Hashtable m_sessionCache; // Dictionary of all active sessions

  // Survey Cache, used to cache upto 3 surveys.
  SurveyCache[] m_surveyCache = new SurveyCache[3];

  /**
  * This method services the http requests meant for this servlet
  **/
  public void service(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {

    System.out.println("In Service");

    // Initialize the servlet path setting
    if (this.s_servletPath == null) {
      String l_servletPath =  request.getRequestURI();
      StringTokenizer st = new StringTokenizer(l_servletPath,"?");
      s_servletPath = st.nextToken();
    }

    // Display all the existing Surveys
    if (request.getParameter("ALLSURVEYS") != null) {
      this.displayAllSurveys(response);
    } else {
      // Find the session object associated with this request
      SRSession l_session = findSession(request);

      if (l_session == null ||  // Check if request is for a new session
          request.getParameter("SURVEY_ID") != null) {
        l_session = createSession(request, response);  // Create a session

        // If session successfully created generate the HTML survey form
        // and return to browser
        if (l_session != null) {
          // If the session was created for a preview only, close the session
          if (l_session.getPreview()) {
            // Obtain a handle to the output stream
            response.setContentType("text/html");
            PrintWriter out = new PrintWriter (response.getOutputStream());
            try {
              // Retrieve HTML for survey
              StringBuffer l_buffer = getSurveyHTML(l_session.getConnection(), l_session.getSurveyID());

              out.print(new String(l_buffer)); // Output the HTML
              out.print(ValidationJavaScript()); // Output the validation Java Script
            } catch (SQLException ex) {
              out.print("<HTML><BODY>Error generating Survey</BODY></HTML>");
            }
            out.close();
            endSession(l_session); // Close the preview session
          } else {
            generateSurveyForm(l_session, response); // Generate and Output the Survey HTML
          }
        }
      } else { // Session found. The request has to be responses for a survey
        // Process the response. If successfully processed, close the session
        if (processResponse(l_session, request, response))
          endSession(l_session);
      }
    }
  }

  /**
  * This method generates the HTML form for the Survey.
  **/
  public void generateSurveyForm(SRSession p_session, HttpServletResponse response)
                      throws ServletException, IOException {

    System.out.println("Generating Survey");
    // Obtain survey response output stream
    PrintWriter out = new PrintWriter (response.getOutputStream());
    response.setHeader("pragma","no-cache");
    response.setContentType("text/html");

    Connection l_conn = p_session.getConnection(); // Obtain the database connection

    try {
      long l_surID = p_session.getSurveyID(); // Survey ID
      Survey l_survey = null; // Object holds the survey definition
      StringBuffer l_buffer = null; // Object holds survey HTML

      // Check if the survey is present in the cache
      boolean found = false;
      for (int i=0;i<3;i++) {
        if (m_surveyCache[i] != null && m_surveyCache[i].m_surveyID == l_surID
            &&  !m_surveyCache[i].isExpired()) {    // Valid survey found
          m_surveyCache[i].setUsed(); // Set the last used time for the survey
          l_survey = m_surveyCache[i].m_survey; // Obtain the survey definition from cache
          l_buffer = m_surveyCache[i].m_htmlBuffer; // Obtain the survey HTML from cache
          found = true; // Set the found flag
          break;
        }
      }

      if (!found) { // Survey not found in cache

        // Retrieve Survey definition from the database
        l_survey = new Survey(p_session.getSurveyID());
        l_survey.retrieveFromDB(l_conn);

        // Query to retrieve pregenerated survey from the CLOB column,
        // survey_generated from the table survey_pregen
        PreparedStatement l_pstmt = l_conn.prepareStatement(
          "select use_pregen_ind , survey_generated from survey_pregen where survey_id = ?");
        l_pstmt.setLong(1, p_session.getSurveyID());
        ResultSet l_rst = l_pstmt.executeQuery();

        // If pregenerated survey found, and the use_pregen_ind flag is set to true,
        // Read survey HTML from the CLOB
        if (l_rst.next() && l_rst.getString(1).equals("Y")) {
          // Retrieve CLOB column to read survey HTML
          oracle.sql.CLOB l_clob = ((oracle.jdbc.driver.OracleResultSet)l_rst).getCLOB(2);

          // Open a character stream
          Reader l_surveyStream = l_clob.getCharacterStream();

          l_buffer = new StringBuffer(); // Holds the survey HTML
          char[] l_buff = new char[1000]; // Temporary buffer
          int l_nread = 0;

          // Read from the clob read stream, and read the survey HTML into the
          // StringBuffer, l_buffer.
          while ((l_nread=l_surveyStream.read(l_buff)) != -1) // Until done
            l_buffer.append(l_buff,0,l_nread);

          l_surveyStream.close(); // Close stream.

        } else { // Survey needs to be generated dynamically

          // Obtain the generated HTML from the printSurveyForm method
          l_buffer = printSurveyForm(l_survey, p_session.getPreview(), false);
        }
        l_pstmt.close(); // Closes statement and resultset

        // Save survey into cache. Find out which is the oldest survey in the
        // cache, if there is no vacant slot, and replace it with the current
        // survey
        long l_buf0 = (m_surveyCache[0]==null)?-1:m_surveyCache[0].m_lastUsed;
        long l_buf1 = (m_surveyCache[1]==null)?-1:m_surveyCache[1].m_lastUsed;
        long l_buf2 = (m_surveyCache[2]==null)?-1:m_surveyCache[2].m_lastUsed;
        int l_index = 0;
        if (l_buf0<l_buf1 && l_buf0<l_buf2)
          l_index = 0;
        else if (l_buf1<l_buf0 && l_buf1<l_buf2)
          l_index = 1;
        else if (l_buf2<l_buf1 && l_buf2<l_buf0)
          l_index = 2;

        // Enter into cache
        m_surveyCache[l_index] = new SurveyCache(l_surID, l_survey, l_buffer);
      }
      p_session.setSurvey(l_survey);   // Associate the Survey Object with the session

      out.print("<META HTTP-EQUIV=\"Set-Cookie\" CONTENT=\"SRSessionID="+p_session.key()+"\">\n");
      out.print(new String(l_buffer)); // Output the HTML


      out.print(ValidationJavaScript()); // Output the Validation JavaScript
      out.print("</HTML></BODY>");

    } catch (SQLException ex) { // Trap SQL errors
      ex.printStackTrace();
      out.println(" <P><B>Error generating Survey Form</B><p>\n");
    }
    out.close();
  }

  /**
  * This method returns a StringBuffer containing the Survey HTML
  * Used for Preview and PreGeneration
  **/
  public static StringBuffer getSurveyHTML(Connection p_conn, long p_surveyID)
                      throws IOException, SQLException {

    // Retrieve Survey definition
    Survey l_survey = new Survey(p_surveyID);
    l_survey.retrieveFromDB(p_conn); // Retrieve Survey contents from the db

    // Generate HTML
    StringBuffer l_buffer = printSurveyForm(l_survey, false, false); // Print out HTML form
    l_survey = null;

    System.gc();
    return l_buffer; // Return HTML buffer
  }

  /**
  * This method returns the HTML form for a Survey (p_survey).
  **/
  public static StringBuffer printSurveyForm(Survey p_survey, boolean p_previewFlag, boolean p_errorFlag) {

    StringBuffer l_buffer = new StringBuffer(4000); // Buffer to hold generated HTML
    Vector l_mandElemBuffer = new Vector(); // Vector to hold mandatory item list
    Vector l_submitVal = new Vector(); // Vector to hold the validation to be done on submission

    // Output HTML Header
    l_buffer.append("<HTML>\n");
    if (p_survey.m_ssheet != null)
      l_buffer.append("<LINK REL=STYLESHEET TYPE=\"text/css\" HREF=\""+
              p_survey.m_ssheet+"\">\n");
    l_buffer.append("<head><title>"+
                 p_survey.m_title+"</title>\n");
    l_buffer.append("<body>\n");

    // Output Survey Title
    l_buffer.append("\n");
    l_buffer.append("<font size=0>\n");
    l_buffer.append("<CENTER><table border=0 width=\"690\" cellspacing=1 cellpadding=4>\n");
    l_buffer.append("<TR><TD colspan=2 align=center>\n");
    if (p_survey.m_image != null)
      l_buffer.append("<img src=\""+p_survey.m_image+"\">\n");
    else
      l_buffer.append("<H1>"+getFormattedText(p_survey.m_fontFace, p_survey.m_fontColor,
                     p_survey.m_fontSize, p_survey.m_fontStyle,p_survey.m_title)+"</H1>");
    l_buffer.append("</TR></TD><TR><TD colspan=2>");

    // Output Survey Header
    if (p_survey.m_header != null && !p_survey.m_header.equals("null"))
      l_buffer.append(getFormattedText(p_survey.m_hdFontFace, p_survey.m_hdFontColor,
               p_survey.m_hdFontSize, p_survey.m_hdFontStyle, p_survey.m_header));
    l_buffer.append("<FORM onSubmit=\"return formValidate()\">\n");
    l_buffer.append("</TR></TD>\n");

    // Set HTML table widths depending on number of columns in the survey.
    // This is calculated based on the NewLine_IND column in Survey_contents.
    boolean l_nlFlag = true;

    int l_1stCol = 320;
    int l_2ndCol = 370;

    // Loop through the Survey Contents and output HTML for each item in the survey
    Vector l_contents = p_survey.m_surveyContents;
    for (int i=0;i<l_contents.size();i++) {
      SurveyElement l_se = (SurveyElement) l_contents.elementAt(i);
      putSurveyElement(l_buffer, l_se,l_nlFlag, new Integer(l_1stCol).toString(),
                       new Integer(l_2ndCol).toString(), l_mandElemBuffer, l_submitVal);
      if (l_se.m_nInd.equals("N"))
        l_nlFlag = false;
      else
        l_nlFlag = true;
    }

    // Output Submit and Reset buttons
    l_buffer.append("<TR><TD colspan=2 align=center>");
    if (!p_previewFlag)
      l_buffer.append("<INPUT TYPE=submit value=\""+p_survey.m_submitBtnText+"\">\n");
    else
      l_buffer.append("<INPUT TYPE=submit value=\""+p_survey.m_submitBtnText+"\">\n");
    l_buffer.append("<INPUT TYPE=reset value=\"Clear\"> \n");
    l_buffer.append("</FORM></CENTER>\n");

    // Output Survey Footer
    l_buffer.append("</TR></TD><TR><TD colspan=2>");
    if (p_survey.m_footer != null && !p_survey.m_footer.equals("null"))
    l_buffer.append(getFormattedText(p_survey.m_ftFontFace, p_survey.m_ftFontColor,
              p_survey.m_ftFontSize, p_survey.m_ftFontStyle, p_survey.m_footer));
    l_buffer.append("</TD></TR></TABLE>\n");


    l_buffer.append("<SCRIPT LANGUAGE=\"JavaScript1.1\">\n");
    l_buffer.append("mandElems = new Array();\n");
    for (int i=0; i<l_mandElemBuffer.size(); i++)
      l_buffer.append("mandElems["+i+"] = "+(String)l_mandElemBuffer.elementAt(i)+";\n");

    l_buffer.append("function formValidate() { \n");

    l_buffer.append("  for (i=0;i<mandElems.length;i++) {\n");
    l_buffer.append("    if (mandElems[i].value == \"\") { \n");
    l_buffer.append("      alert(\"Please enter answers to all mandatory questions (Marked with *)\");\n");
    l_buffer.append("      return false;\n");
    l_buffer.append("    }\n");
    l_buffer.append("  }\n");
    for (int i=0; i<l_submitVal.size(); i++) {
      l_buffer.append("if ("+(String)l_submitVal.elementAt(i)+" == 0)\n");
      l_buffer.append("      return false;\n");
    }
    l_buffer.append("  return true;\n");
    l_buffer.append("}\n");
    l_buffer.append("</SCRIPT>\n");

    return l_buffer;
  }

  /**
  * This method outputs an individual Survey Element depending on the type of element
  * (A display element or a question(which could be FreeText etc.))
  **/
  public static void putSurveyElement (StringBuffer l_buffer, SurveyElement p_elem, boolean p_nlFlag,
                                String p_1stCol, String p_2ndCol, Vector p_mandElemBuffer,
                                Vector p_submitVal) {

    if (p_elem.m_question == null) {  // Display Element
      l_buffer.append("<TR><TD colspan=2 width=\"100%\">\n");
      if (p_elem.m_displayElement.startsWith("Horizontal")) // Horizontal Rule
        l_buffer.append("<HR>\n");
      else if (p_elem.m_displayElement.startsWith("Blank")) // Blank Line
        l_buffer.append("<BR>\n");
      else if (p_elem.m_displayElement.startsWith("Text")) { // Text
        l_buffer.append(getFormattedText(p_elem.m_fontFace, p_elem.m_fontColor,
                     p_elem.m_fontSize, p_elem.m_fontStyle,p_elem.m_displayElement.substring(6)));
      l_buffer.append("</TD></TR>\n");
      }
    } else { // Question element

      Question l_qsn = p_elem.m_question; // Get the question object associated with this conten

      if (p_nlFlag) // Check if this question needs to be displayed in a NewLine
        l_buffer.append("<TR><TD width="+p_1stCol+" valign=top>\n");
      else // Same Line
        l_buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;");

      // Output Question Text
      if (l_qsn.m_mandatoryInd.equals("Y"))
        l_buffer.append(getFormattedText(p_elem.m_fontFace, p_elem.m_fontColor,
           p_elem.m_fontSize, p_elem.m_fontStyle,l_qsn.m_questionText+"(*)"));
      else
        l_buffer.append(getFormattedText(p_elem.m_fontFace, p_elem.m_fontColor,
           p_elem.m_fontSize, p_elem.m_fontStyle,l_qsn.m_questionText));
      if (p_nlFlag)
        l_buffer.append("</TD><TD align=left width="+p_2ndCol+">\n");
      else
        l_buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;");

      // Depending on the Response Type and Question format output the appropriate
      // HTML
      if (l_qsn.m_responseType.equals( "FreeText")) { // FreeText Question
        if (!l_qsn.m_questionFormat.equals("TextField") && // Check for valid Q format
            !l_qsn.m_questionFormat.equals("TextArea")) {
          l_buffer.append("<font color=red>Invalid question format for FreeText Question</font>\n");
        } else {
          if (l_qsn.m_questionFormat.equals("TextField")) { // TextField Format
            String l_name = "p_"+l_qsn.m_questionID;
            l_buffer.append("<input type=text name=\"p_"+l_qsn.m_questionID+"\" ");

            if (l_qsn.m_defaultValue != null)// else default to the Default Value
              l_buffer.append("value=\""+l_qsn.m_defaultValue+"\"");
            if (p_elem.m_numCols != null)// Initialize size of TF
              if (l_qsn.m_maxLength != null && Integer.parseInt(p_elem.m_numCols) >Integer.parseInt(l_qsn.m_maxLength))
                l_buffer.append("size="+l_qsn.m_maxLength);
              else
                l_buffer.append("size="+p_elem.m_numCols);
            if (l_qsn.m_maxLength != null) // Initialize MaxLength of TF
              l_buffer.append(" maxlength="+l_qsn.m_maxLength);


 // For a response Datatype number, check response vaildity
            String l_valid = "";
            if (l_qsn.m_responseDatatype.equalsIgnoreCase("number")) {
              if (l_qsn.m_formatMask == null)
                l_valid = "checkFloat(document.forms[0]."+l_name+")";
              else if (l_qsn.m_formatMask.equalsIgnoreCase("INTEGER"))
                l_valid = "checkInt(document.forms[0]."+l_name+")";
              else if (l_qsn.m_formatMask.equalsIgnoreCase("POSINTEGER"))
                l_valid = "checkPosInt(document.forms[0]."+l_name+") ";
              else if (l_qsn.m_formatMask.equalsIgnoreCase("NEGINTEGER"))
                l_valid = "checkNegInt(document.forms[0]."+l_name+") ";
              else if (l_qsn.m_formatMask.equalsIgnoreCase("REAL"))
                l_valid = "checkFloat(document.forms[0]."+l_name+") ";
              else if (l_qsn.m_formatMask.equalsIgnoreCase("POSREAL"))
                l_valid = "checkPosFloat(document.forms[0]."+l_name+") ";
              else if (l_qsn.m_formatMask.equalsIgnoreCase("NEGREAL"))
                l_valid = "checkNegFloat(document.forms[0]."+l_name+") ";
            } else if  (l_qsn.m_responseDatatype.equalsIgnoreCase("date")) {
              l_valid = "checkDate('"+l_qsn.m_formatMask+"', document.forms[0]."+l_name+") ";
            }


            if (!l_valid.equals(""))  {
              l_buffer.append(" onChange=\"javascript:"+l_valid+"\" ");
              p_submitVal.addElement(l_valid);
            }
            if (l_qsn.m_mandatoryInd.equals("Y"))
              p_mandElemBuffer.addElement("document.forms[0]."+l_name);

            l_buffer.append(">\n");
          } else { // TextArea format
            l_buffer.append("<textarea name=\"p_"+l_qsn.m_questionID+"\" rows="+p_elem.m_numRows+" cols="+p_elem.m_numCols+">\n");
            if (l_qsn.m_defaultValue != null) // else default to the Default Value
              l_buffer.append(l_qsn.m_defaultValue);
            l_buffer.append("</TEXTAREA>\n");
          }
        }
      } else if (l_qsn.m_responseType.equals( "OneofMany")) { //One of Many Question
        if (!l_qsn.m_questionFormat.equals("ComboBox") && // Check for valid format
            !l_qsn.m_questionFormat.equals("RadioGroup"))
          l_buffer.append("<font color=red>Invalid question format for One of Many Question</font>\n");
        else {
          if (l_qsn.m_questionFormat.equals("ComboBox")) { // Combo Box format
            l_buffer.append("<select name=\"p_"+l_qsn.m_questionID+"\">\n");
            Vector l_choices = l_qsn.m_choices; // Retrieve all choices for the question

            if (!l_qsn.m_mandatoryInd.equals("Y"))
              l_buffer.append("<OPTION VALUE=\"0\">Please Select\n"); // Nothing Chosen (for non-Mandatory)

            // Initialize the defaulted value. If coming from processResponse, this
            // value will be the prior response, else it will be the default value
            // attribute of question
            String l_setValTo = l_qsn.m_defaultValue;

            // Output OPTION tags for all choices
            for (int i=0;i<l_choices.size();i++) {
              Choice l_choice = (Choice)l_choices.elementAt(i);
              l_buffer.append("<option ");

              if (l_choice.m_value.equals(l_setValTo)) // Set the selected option
                l_buffer.append(" SELECTED ");

              // Output Choice Text
              l_buffer.append("value=\""+l_choice.m_value+"\">"+
                   getFormattedText(p_elem.m_chFontFace,p_elem.m_chFontColor,p_elem.m_chFontSize,
                                    p_elem.m_chFontStyle,l_choice.m_text)+
                   "\n");
            }
            l_buffer.append("</SELECT>\n");
          } else { // RadioGroup Format
            Vector l_choices = l_qsn.m_choices; // Retrieve all choices for the question

            // Get a some factors for smart formatting of choices in the
            // RadioGroup
            int l_widthFactor = Integer.parseInt(p_elem.m_chFontSize.substring(1));
            if (p_elem.m_chFontSize.substring(0,1).equals("-"))
              l_widthFactor = -l_widthFactor;
            l_widthFactor+=7;
            int l_curWidth = 0;

            // Initialize the defaulted value. If coming from processResponse, this
            // value will be the prior response, else it will be the default value
            // attribute of question
            String l_setValTo = l_qsn.m_defaultValue;

            // Output HTML tags for all choices
            for (int i=0;i<l_choices.size();i++) {
              Choice l_choice = (Choice)l_choices.elementAt(i);
              l_curWidth += l_choice.m_text.length()*l_widthFactor;
              if (l_curWidth > 220) {
                l_curWidth = l_choice.m_text.length()*l_widthFactor;;
                l_buffer.append("<BR>\n");
              }
              StringBuffer l_rgBuf = new StringBuffer();
              l_rgBuf.append("<input type=radio name= \"p_"+l_qsn.m_questionID+"\"");
              l_rgBuf.append(" value=\""+l_choice.m_value+"\"");
              if (l_choice.m_value.equals(l_setValTo)) // Set the defaulted choice
                l_rgBuf.append(" CHECKED>");
              else
                l_rgBuf.append(">");
              l_rgBuf.append(l_choice.m_text);
              l_buffer.append(getFormattedText(p_elem.m_chFontFace,p_elem.m_chFontColor,p_elem.m_chFontSize,
                                    p_elem.m_chFontStyle,new String(l_rgBuf)));

              l_buffer.append("&nbsp;&nbsp;\n");
            }
          }
        }
      } else if (l_qsn.m_responseType.equals( "ManyofMany")) { // ManyofMany question
        if (!l_qsn.m_questionFormat.equals("List") && // Check for valid formats
            !l_qsn.m_questionFormat.equals("CheckBoxes"))
          l_buffer.append("<font color=red>Invalid question format for Many of Many Question</font>\n");
        else {
          if (l_qsn.m_questionFormat.equals("List")) { // List format
            int l_size=Integer.parseInt(p_elem.m_numRows);
            l_buffer.append("<select name=\"p_"+l_qsn.m_questionID+"\" MULTIPLE size="+l_size+">\n");

            Vector l_choices = l_qsn.m_choices; // Retrieve all choice for the question
            // Loop through all the choices and output OPTION tag
            for (int i=0;i<l_choices.size();i++) {
              Choice l_choice = (Choice)l_choices.elementAt(i);
              l_buffer.append("<option ");

              if (l_choice.m_value.equals(l_qsn.m_defaultValue))
                l_buffer.append(" SELECTED ");
              l_buffer.append("value=\""+l_choice.m_value+"\">"+
                   getFormattedText(p_elem.m_chFontFace,p_elem.m_chFontColor,p_elem.m_chFontSize,
                                    p_elem.m_chFontStyle,l_choice.m_text)+
                   "\n");
            }
            l_buffer.append("</SELECT>\n");
          } else { // CheckBoxes
            Vector l_choices = l_qsn.m_choices; // Retrieve all the choices

            // Get some factors for smart formatting of choices in HTML
            int l_widthFactor = Integer.parseInt(p_elem.m_chFontSize.substring(1));
            if (p_elem.m_chFontSize.substring(0,1).equals("-"))
              l_widthFactor = -l_widthFactor;
            l_widthFactor+=7;
            int l_curWidth = 0;

            // Loop through the choices and output checkbox elements
            for (int i=0;i<l_choices.size();i++) {
              Choice l_choice = (Choice)l_choices.elementAt(i);
              l_curWidth += l_choice.m_text.length()*l_widthFactor;
              if (l_curWidth > 200) {
                l_curWidth = l_choice.m_text.length()*l_widthFactor;;
                l_buffer.append("<BR>\n");
              }
              StringBuffer l_rgBuf = new StringBuffer();
              l_rgBuf.append("<input type=checkbox name= \"p_"+l_qsn.m_questionID+"_"+l_choice.m_value+"\"");
              l_rgBuf.append(" value=\"C\"");


              if (l_choice.m_value.equals(l_qsn.m_defaultValue))
                l_rgBuf.append(" checked ");
              l_rgBuf.append(">");
              l_rgBuf.append(l_choice.m_text);
              l_buffer.append(getFormattedText(p_elem.m_chFontFace,p_elem.m_chFontColor,p_elem.m_chFontSize,
                                    p_elem.m_chFontStyle,new String(l_rgBuf)));

              l_buffer.append("&nbsp;&nbsp;\n");
            }
          }
        }
      }

      // If newline ind is set, go on to the next row
      if (p_elem.m_nInd.equals("Y"))
        l_buffer.append("</TD></TR>\n");
    }
  }

  /**
  * This method processes the responses, and validates the responses to each question
  * If valid the responses are saved to the database.
  * Returns true if responses were valid, and false if not.
  **/
  public boolean processResponse(SRSession p_session, HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {

    System.out.println("Processing Survey");
    response.setContentType("text/html");
    PrintWriter l_out = new PrintWriter (response.getOutputStream());

    Connection l_conn =  p_session.getConnection(); // Obtain Connection.
    try {

      // Create a RESPONSE_MASTER record for the response
      Statement l_stmt = l_conn.createStatement();
      ResultSet l_rst = l_stmt.executeQuery( // Get Sequence Number
        "select SRESP_SEQ.nextval from dual");
      long l_responseID = -1;
      if (l_rst.next())
        l_responseID = l_rst.getLong(1);
      l_stmt.close();
      PreparedStatement l_pstmt = l_conn.prepareStatement( // Insert the row
        "insert into response_master(id, response_date, memb_id, sur_id) "+
        "values(?,SYSDATE,?,?)");
      l_pstmt.setLong(1, l_responseID);
      l_pstmt.setString(2, p_session.getUserId());
      l_pstmt.setLong(3, p_session.getSurveyID());
      l_pstmt.execute();

      // Retrieve contents of the survey
      Survey l_survey = p_session.getSurvey();

      Vector l_contents = l_survey.m_surveyContents;

      // Loop through all the questions in the survey and
      // retrieve the responses to the question from the httpRequest object
      boolean l_error = false;
      for (int i=0; i<l_contents.size();i++) {
        SurveyElement l_elem = (SurveyElement)l_contents.elementAt(i);

        if (l_elem.m_question != null) { // Check that the survey content is a question
          Question l_qsn = l_elem.m_question;
          Vector l_responses = new Vector();

          // If response type is Many of Many, then there will multiple responses for
          // the question
          if (l_qsn.m_responseType.equals("ManyofMany")) {
            // If List format, then loop through all the parameter values
            if (l_qsn.m_questionFormat.equals("List")) {
              String[] l_choices = request.getParameterValues("p_"+l_qsn.m_questionID.toString());
              if (l_choices != null)
                for (int k=0;k<l_choices.length;k++)
                  l_responses.addElement(l_choices[k]);
              else
                l_responses.addElement("0");
            // If CheckBoxes format, loop through all the choices in the question and get
            // the values of each checkbox field in the form
            } else if (l_qsn.m_questionFormat.equals("CheckBoxes")) {
              Vector l_chs = l_qsn.m_choices;
              String l_prefix = "p_"+l_qsn.m_questionID.toString()+"_";
              for (int j=0;j<l_chs.size();j++) {
                Choice c = (Choice)l_chs.elementAt(j);
                if (request.getParameter(l_prefix+c.m_value) !=null &&
                    request.getParameter(l_prefix+c.m_value).equals("C"))
                  l_responses.addElement(c.m_value);
              }
              if (l_responses.size() == 0)
                l_responses.addElement("0");
            }
          } else { // If One of Many of FreeText, then only one response. Get the response.
            String l_resp = request.getParameter("p_"+l_qsn.m_questionID.toString());
            if (l_resp == null && l_qsn.m_questionFormat.equalsIgnoreCase("radiogroup"))
              l_resp = "0";

            l_responses.addElement(l_resp);
          }

          // Validate the response
          l_qsn.saveResponse(l_conn, l_responseID, l_responses);
        }
      }

      // Output ACK
      response.sendRedirect(p_session.getReturnPage());
    } catch (SQLException ex) { // Trap SQL errors
      l_out.println("<HTML><BODY>Error :<BR> SQL error when saving the survey response");
      l_out.println("<BR>"+ex.toString()+"</BODY></HTML>");
    }
    l_out.close();
    return true;
  }

  /**
  * Method invoked to terminate a Session. It removes the session from the Session Cache.
  **/
  protected void endSession (SRSession session) {
    try {
      session.getConnection().close();
        synchronized (m_sessionCache) {
            m_sessionCache.remove (session.key());
        }
    }  catch (SQLException ex) {
    }
  }

  /**
  * This method returns a text, encapsulated by the appropriate FONT tags.
  **/
  public static String getFormattedText(String p_face, String p_color, String p_size,
                                 String p_style, String p_text) {

    StringBuffer l_ret = new StringBuffer();
    l_ret.append("<FONT FACE=\""+p_face+"\" SIZE=\""+p_size+"\" COLOR=\""+p_color+"\">\n");
    if (p_style.equals("Regular"))
      l_ret.append(p_text);
    else if (p_style.equals("Bold"))
      l_ret.append("<B>"+p_text+"</B>");
    else if (p_style.equals("Italic"))
        l_ret.append("<em>"+p_text+"</em>");
    else if (p_style.equals("BoldItalic"))
        l_ret.append("<B><em>"+p_text+"</em></B>");
    l_ret.append("</font>");
    return new String(l_ret);
  }

  /**
  * This methid displays all the surveys in the system, from where they can be
  * previewed.
  **/
  public void displayAllSurveys(HttpServletResponse response) {
    try {
      response.setContentType("text/html");
      PrintWriter out = new PrintWriter (response.getOutputStream());

      out.println("<HTML><BODY><P><FONT SIZE=+1><B>");
      out.println("Available Surveys :<P></B></FONT>");
      Connection l_conn = dbConnection();
      Statement l_stmt = l_conn.createStatement();
      ResultSet l_rst = l_stmt.executeQuery(
           "SELECT ID, NAME, TITLE FROM SURVEYS");
      while (l_rst.next()) {

        out.println("Survey :"+l_rst.getString(2)+" ("+l_rst.getString(3)+") ");
        out.println("<A HREF=\""+s_servletPath+"?SURVEY_ID="+
                    l_rst.getString(1)+"&USER_ID=10&RETURN_PAGE=http://technet.oracle.com\">Preview</A><BR>\n");
      }
      l_stmt.close();
      l_conn.close();
      out.println("</BODY></HTML>\n");
      out.close();
    } catch (Exception e) {
    }
  }

  /**
  * This method finds the session with which a httprequest is associated
  **/
  public SRSession findSession(HttpServletRequest request) {

   // Get the Cookies associated with the request
   Cookie c[] = request.getCookies();

   SRSession session = null; // Intialize session to null

   // Loop through all the cookies, and if a session cookie found,
   // match with the appropriate session from the session cache
   for (int i=0;(c!= null)&&(i<c.length);i++) {
     if (c[i].getName().equals("SRSessionID")) { // Session cookie found
       session = (SRSession) m_sessionCache.get(c[i].getValue());
       break;
     }
   }

   if (session != null) {
     System.out.println("Session found");
     System.out.println("Session ID "+session.key());
     System.out.println("Survey ID "+session.getSurveyID());
     System.out.println("User ID "+session.getUserId());
   }

   return session;
  }

  /**
  * This method creates a new Survey Response session
  **/
  public SRSession createSession(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {

    // Retrieve the Survey ID and the Respondent ID
    String l_userID = request.getParameter("USER_ID");
    String l_surveyID = request.getParameter("SURVEY_ID");
    String l_returnPage = request.getParameter("RETURN_PAGE");

    System.out.println("Creating Session, "+l_surveyID +", "+l_userID);

    SRSession session = null;

    // Obtain a handle to the output stream for writing errors
    response.setContentType("text/html");
    PrintWriter out = new PrintWriter (response.getOutputStream());
    try {
       // Check if it is a valid survey request
       if (l_userID != null && l_surveyID != null) {
         // Check is survey exists in the database
         Connection l_conn = dbConnection();
         PreparedStatement l_stmt = l_conn.prepareStatement(
              "select name from surveys where id = ? and log_del_ind is null");
         l_stmt.setInt(1,Integer.parseInt(l_surveyID));
         ResultSet l_rst = l_stmt.executeQuery();
         if (l_rst.next()) { // Survey exists

           session = new SRSession (l_userID, l_surveyID, l_conn, l_returnPage); // Create a session
           if (l_userID.equals("PREVIEW")) // If preview request, set the flag in the session
             session.setPreview();
           m_sessionCache.put(session.key(),session); // Store the session key in the session cache
                                                     /*
             // Create a client cookie
                 Cookie c = new Cookie("SRSessionID", "XXX");
               c.setPath ("/");

           // Add the cookie to the response
           response.addCookie(c);                  */
         } else { // Survey ID not found in database
           out.print("<HTML><BODY>Invalid Survey ID</BODY></HTML>\n");
           out.close();
         }
         l_stmt.close();
       } else { // Missing parameters
         out.print("<HTML><BODY>Missing Survey ID</BODY></HTML>\n");
         out.close();
       }
    } catch (SQLException ex) { // Trap SQL errors
      out.println("<HTML><BODY>Error retrieving Survey");
      out.println(ex.toString()+"</BODY></HTML>\n");
      out.close();
    }

    return session;
  }

  /**
  * This method returns a database connection object.
  **/
  public Connection dbConnection() {

    Connection l_connection = null;
    try {
      // Data Source Name
        String SURVEY_DATASOURCE = "jdbc/Loneifso817DS";
        DataSource dataSource = null;

        InitialContext ic = new InitialContext();
        dataSource = (DataSource)ic.lookup(SURVEY_DATASOURCE);
        l_connection  = dataSource.getConnection();

        // sets the auto-commit property for the connection to be false. By default
        // the connections always auto-commit.
        l_connection.setAutoCommit(false);

    } catch (SQLException se) {
        System.out.println("SQL Error while connecting to the database : "+
                            se.toString());
    } catch (NamingException ne) {
        System.out.println("Naming exception Error while connecting to the database : "+
                            ne.toString());
    } catch (Exception ne) {
        System.out.println("Other Error while connecting to the database : "+
                            ne.toString());
    }

    return l_connection;
  }

  public static String ValidationJavaScript() {
  return "<SCRIPT LANGUAGE=\"JavaScript1.1\"> \n"+
    "var theDate = new Date();           \n"+
    "var theMonth = 0;                   \n"+
    "var theDay = 0;                     \n"+
    "var theYear = 0;                    \n"+
    "var dateCode = 0;                   \n"+
    "                                    \n"+
    "var re;                             \n"+
    "var mnth=\"\";                      \n"+
    "var date=\"\";                      \n"+
    "var year=\"\";                      \n"+
    "                                    \n"+
    "function checkDate(format, item) {  \n"+
    "                                    \n"+
    "  val = item.value;                 \n"+
    "  if (val == \"\")                  \n"+
    "    return 1;                       \n"+
    "                                    \n"+
    "  if (format == \"DD-MON-YYYY\") {  \n"+
    "    if (val.length == 10)           \n"+
    "      val=\"0\"+val;                \n"+
    "    re =/\\d\\d-(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)-\\d\\d\\d\\d/i;\n"+
    "    if(!re.test(val)) {                           \n"+
    "      alert(\"should be of Format DD-MON-YYYY\"); \n"+
    "      item.focus();                               \n"+
    "      return 0;                                   \n"+
    "    }                                             \n"+
    "    mnth = convertMonthToNumber(val.substring(3,6));\n"+
    "    date = val.substring(0,2);                      \n"+
    "    year = val.substring(7,11);                     \n"+
    "  } else if (format == \"DD-MM-YYYY\") {            \n"+
    "    if (val.length == 8)                            \n"+
    "      val=\"0\"+val.substring(0,2)+\"0\"+val.substring(2,8);\n"+
    "                                                            \n"+
    "    if (val.length == 9) {                                  \n"+
    "      if (val.substring(2,3) == \"-\")                      \n"+
    "        val=val.substring(0,3)+\"0\"+val.substring(3,9);    \n"+
    "      else                                                  \n"+
    "        val=\"0\"+val;                                      \n"+
    "    }                                                       \n"+
    "    re =/\\d\\d-\\d\\d-\\d\\d\\d\\d/i;                              \n"+
    "    if(!re.test(val)) {                                     \n"+
    "      alert(\"should be of Format DD-MM-YYYY\");            \n"+
    "      item.focus();                                         \n"+
    "      return 0;                                             \n"+
    "    }                                                       \n"+
    "    mnth = val.substring(3,5);                              \n"+