/**
   * Process the call to the servlet.
   *
   * <p>With regard to reading data from the request, a {@link javax.servlet.ServletInputStream}
   * object for binary data can be obtained by {@link HttpServletRequest#getInputStream()} or a
   * {@link java.io.BufferedReader} can be obtained for character data by using {@link
   * HttpServletRequest#getReader}.
   *
   * <p>With regard to writing data to the response a {@link javax.servlet.ServletOutputStream}
   * object for binary data can be obtained using {@link HttpServletResponse#getOutputStream()}
   * while a {@link java.io.PrintWriter} object can be obtained using {@link
   * HttpServletResponse#getWriter()}.
   *
   * <p>The {@link java.io.ByteArrayOutputStream} class can be used as a means of collecting the
   * bytes contained in the attached file.
   *
   * <p>It would be desirable to have tests for enctype and method.
   *
   * @param req Request object
   * @param res Response object
   * @throws IOException if io problems
   */
  public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
    ThisPage thisPage = new ThisPage(req, res, config);
    GenericPrinter output = thisPage.getPrinter();
    if (!req.getMethod().equalsIgnoreCase("post")) {
      output.println("<html><head>");
      output.println("<title>Must use POST method</title>");
      output.println("</head><body>");
      output.println("<h1>Must use POST method</h1>");
      output.println("<p>Request used " + req.getMethod() + " method</p>");
      output.println("<p>Must use POST method</p>");
      output.println("</body></html>");
      thisPage.sendContents();
      return;
    } else if (req.getHeader("content-type") == null) {
      output.println("<html><head>");
      output.println("<title>Missing content-type header</title>");
      output.println("</head><body>");
      output.println("<h1>Missing content-type header</h1>");
      output.println(
          "<p>Must use content-type header " + "to specify multipart/form-data encoding</p>");
      output.println("</body></html>");
      thisPage.sendContents();
      return;
    } else if (!req.getHeader("content-type").toLowerCase().startsWith("multipart/form-data")) {
      output.println("<html><head>");
      output.println("<title>Must use multipart/form-data encoding</title>");
      output.println("</head><body>");
      output.println("<h1>Must use multipart/form-data encoding</h1>");
      output.println("<p>content-type is " + req.getHeader("content-type") + " </p>");
      output.println("<p>Must use multipart/form-data encoding</p>");
      output.println("</body></html>");
      thisPage.sendContents();
      return;
    }
    String boundary = extractBoundary(req);
    if (boundary == null) {
      thisPage.addMessage("Unable to extract boundary value");
      thisPage.addMessage(req.getHeader("content-type"));
      thisPage.errorMessage();
      return;
    }
    int counter = 0;
    byte buffer[] = new byte[4096];
    byte extract[];
    int bytesRead = -1;
    ServletInputStream input = req.getInputStream();
    bytesRead = input.readLine(buffer, 0, buffer.length);
    if (!new String(buffer, 0, bytesRead, "ISO8859_1").startsWith("--" + boundary)) {
      thisPage.addMessage(
          "Should be separator "
              + "--"
              + boundary
              + " : "
              + " found "
              + new String(buffer, 0, bytesRead));
      thisPage.errorMessage();
      return;
    }
    while (true) {
      counter++;
      Contents part = new Contents();
      thisPage.addMessage("Starting part " + Integer.toString(counter) + " of form");
      while (true) {

        bytesRead = input.readLine(buffer, 0, buffer.length);
        if (bytesRead < 0) {
          thisPage.addMessage("Unexpected end of packet");
          thisPage.errorMessage();
          return;
        } else {
          String value = new String(buffer, 0, bytesRead, "ISO8859_1");
          if (value.endsWith("\r\n")) {
            value = stripEOL(value);
          }
          if (value.length() == 0) {
            extract = readPart(input, thisPage, part.getTransferEncoding());
            if (thisPage.getTerminateRequest()) {
              return;
            }
            part.setContents(extract);
            thisPage.addElement(part);
            break;
          } else {
            thisPage.addMessage("service method - Parsing line: " + value);
            part.parseLine(value);
          }
        }
      }
      if (thisPage.getEndOfPacket()) {
        break;
      }
    }
    if (thisPage.getTerminateRequest()) {
      return;
    }
    starter(thisPage);
    if (thisPage.getTerminateRequest()) {
      return;
    }
    processor(thisPage);
    if (thisPage.getTerminateRequest()) {
      return;
    }
    ender(thisPage);
    if (thisPage.getTerminateRequest()) {
      return;
    }
    if (thisPage.getRedirectAddress() != null) {
      thisPage
          .getResponse()
          .sendRedirect(thisPage.getResponse().encodeRedirectURL(thisPage.getRedirectAddress()));
    }
  }
 /**
  * This method generates the web page based on the contents of the request packet.
  *
  * <p>This method will be overwritten to enable various actions to take place as the information
  * is uploaded.
  *
  * <p>For the result of File requests, write the contents to a file.
  *
  * <p>I am having a problem with the loading of binary files.
  *
  * @param thisPage Information on this HTTP request
  * @throws IOException if io errors
  */
 protected void processor(ThisPage thisPage) throws IOException {
   Enumeration<String> keys = thisPage.getPartNames();
   HttpServletRequest req = thisPage.getRequest();
   ServletConfig config = thisPage.getConfig();
   String targetDirectory = config.getInitParameter("directory");
   GenericPrinter output = thisPage.getPrinter();
   output.println("<html><head>");
   output.println("<title>Dummy Upload Program</title>");
   output.println("</head><body>");
   output.println("<p>It is assumed that the processor method of the ");
   output.println("bradleyross.library.servlets.UploadServlet class will ");
   output.println("be overridden to provide the desired function.  This ");
   output.println("sample version is designed for testing the applications ");
   output.println("and to allow demonstration of the capabilities.</p>");
   output.println("<p>Target directory for upload tests is " + targetDirectory + "</p>");
   output.println("<h2>Headers</h2>");
   output.println("<table border=\"1\">");
   Enumeration<?> list1 = req.getHeaderNames();
   while (list1.hasMoreElements()) {
     String name = (String) list1.nextElement();
     Enumeration<?> list2 = req.getHeaders(name);
     while (list2.hasMoreElements()) {
       String value = (String) list2.nextElement();
       output.println("<tr><td>" + name + "</td><td>" + value + "</td></tr>");
     }
   }
   output.println("</table>");
   output.println("<h2>Parts of form</h2>");
   output.println("<p>The following are the parts of the multipart form</p>");
   output.println("<ul>");
   while (keys.hasMoreElements()) {
     String name = keys.nextElement();
     String mime = thisPage.getElement(name).getMime();
     String fileName = thisPage.getElement(name).getFilename();
     String encoding = thisPage.getElement(name).getTransferEncoding();
     output.println("<li><p>" + name + "</p>");
     if (fileName == null) {
       output.println("<p>Filename not specified</p>");
     } else {
       output.println("<p>Filename is " + fileName + "</p>");
     }
     if (mime == null) {
       output.println("<p>Content type not specified</p>");
       mime = new String();
     } else {
       output.println("<p>Content-type: " + mime + "</p>");
     }
     if (encoding == null) {
       output.println("<p>Transfer encoding not specified</p>");
     } else {
       output.println("<p>Content-transfer-encoding: " + encoding + "</p>");
     }
     if (mime.toUpperCase().startsWith("TEXT")) {
       output.println(
           "<p>" + StringHelpers.escapeHTML(thisPage.getElement(name).toString()) + "</p></li>");
     }
     output.println(
         "<p>Size of contents: " + Integer.toString(thisPage.getElement(name).getContentsSize()));
     if (fileName != null && targetDirectory != null) {
       try {
         boolean validEntry = true;
         File outputFile = null;
         if (targetDirectory.length() == 0 || fileName.length() == 0) {
           validEntry = false;
         }
         if (validEntry) {
           outputFile = new File(targetDirectory, fileName);
           output.println(
               "<p>Name of file is "
                   + StringHelpers.escapeHTML(outputFile.getCanonicalPath())
                   + "</p>");
         }
         if (!validEntry) {;
         } else if (outputFile == null) {
           output.println("<p>Unable to open output file</p>");
         } else {
           FileOutputStream outputStream = new FileOutputStream(outputFile);
           byte transfer[] = thisPage.getElement(name).getContents();
           if (transfer == null) {
             output.println("<p>Unable to get file contents</p>");
           } else {
             outputStream.write(thisPage.getElement(name).getContents());
           }
           outputStream.close();
         }
       } catch (IOException e) {
         output.println("<p>Error while writing file</p>");
         output.println(
             StringHelpers.escapeHTML(
                 "<p>" + e.getClass().getName() + " " + e.getMessage() + "</p>"));
       }
     } else {;
     }
   }
   output.println("</ul>");
   output.println("<h2>Messages</h2>");
   output.println(
       "<p>These messages are normally printed only if an error occurs during the processing ");
   output.println(
       "of the HTTP transaction.  They are included here to test the behavior of the servlet.</p><ol>");
   Vector<String> messages = thisPage.getMessageList();
   messages.trimToSize();
   for (int i = 0; i < messages.size(); i++) {
     output.println("<li><p>" + StringHelpers.escapeHTML(messages.elementAt(i)) + "</p></li>");
   }
   output.println("</ol>");
   output.println("</body></html>");
   thisPage.sendContents();
 }
 /**
  * Test driver.
  *
  * @param args Not used
  */
 public static void main(String args[]) {
   StringWriter writer;
   System.out.println("Trying GenericPrinter for PrintStream System.out");
   GenericPrinter instance = new GenericPrinter(System.out);
   instance.println(instance.getUnderlyingObject().getClass().getName());
   instance.println("Test");
   instance.println(true);
   System.out.println("Trying GenericPrinter for StringWriter");
   writer = new StringWriter();
   instance = new GenericPrinter(writer);
   instance.println(instance.getUnderlyingObject().getClass().getName());
   instance.println("Test");
   instance.println(true);
   System.out.println(instance.getUnderlyingObject().toString());
   System.out.println("Using PrintWriter");
   writer = new StringWriter();
   instance = new GenericPrinter(new PrintWriter(writer));
   instance.println(instance.getUnderlyingObject().getClass().getName());
   instance.println("Test");
   instance.println(true);
   System.out.println(writer.toString());
   System.out.println("End of program");
 }