Component.java :  » Web-Server » simple » simple » http » serve » Java Open Source

Java Open Source » Web Server » simple 
simple » simple » http » serve » Component.java
/*
 * Component.java February 2001
 *
 * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General 
 * Public License along with this library; if not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 * Boston, MA  02111-1307  USA
 */
 
package simple.http.serve;

import java.io.FileNotFoundException;
import java.io.IOException;
import simple.http.Response;
import simple.http.Request;

/**
 * This is an abstract <code>Resource</code> that handles the basic 
 * HTTP status reports. For example messages like '404 Not Found' 
 * are represented using this abstraction. This <code>Resource</code> 
 * can be subclassed to give a <code>Resource</code> the ability to 
 * handle all generic status reports for 3xx, 4xx and 5xx defined by
 * RFC 2616.
 * <p>
 * This uses a various <code>Report</code> objects to generate error
 * and status messages using the <code>Format</code> supplied. This
 * also enables exceptions that propagate from the service objects
 * to be classified and for descriptions of those exceptions to be
 * represented as <code>Report</code> objects that can be be used to
 * generate a formatted message that can be presented to the client.
 *
 * @author Niall Gallagher
 */ 
public abstract class Component implements Resource {

   /**
    * The <code>Context</code> that this resource is in.
    */
   protected Context context;

   /**
    * Constructor that creates a <code>Component</code> without
    * any <code>Context</code> object. This is used so that if the
    * resource is a <code>ProtocolHandler</code> or some other form
    * of resource that does not require a context then this will
    * allow that resource to inherit the functionality of this. The
    * typical implementation however will not use this constructor.
    * If this is used and a context is not set then there will be
    * an exception in <code>handle(Request,Response,int)</code>.
    */
   protected Component() {
      super();           
   }
   
   /**
    * Constructor for the <code>Component</code> is given the
    * <code>Context</code> so that it can generate status reports.
    * Every implementation of the <code>Component</code> needs
    * to be constructed with a <code>Context</code> to ensure that
    * the generation of error and status messages is successful.
    *
    * @param context the context that this resource is in
    */
   protected Component(Context context){
      this.context = context;
   }

   /**
    * This <code>handle</code> is provided so that if any errors
    * occur when processing a HTTP transaction a '500 Server Error'
    * message will be sent to the client. This is used to invoke
    * the <code>process</code> method which subclasses should 
    * implement to process the HTTP transaction. If the exception
    * is a <code>SecurityException</code> '403 Forbidden' is used
    * and a <code>FileNotFoundException</code> is '404 Not Found'.
    * <p>
    * Any <code>Exception</code> thrown from the <code>process</code>
    * method will be captured and the <code>Request</code> and 
    * <code>Response</code> are handled by the default error handler
    * method <code>handle(Request,Response,int)</code> with the code
    * 500 which indicates the HTTP/1.1 error message 'Server Error'
    * <p>
    * This does not throw ant <code>Exception</code> however any
    * user should handle <code>RuntimeException</code>'s that may
    * be thrown from <code>handle(Request,Response,int)</code>.
    *
    * @param req the <code>Request</code> object to be processed
    * @param resp the <code>Response</code> object to be processed
    */
   public void handle(Request req, Response resp) {
      try{
         process(req, resp);
      }catch(SecurityException cause){
         handle(req, resp, new ErrorReport(cause, 403));
      }catch(FileNotFoundException cause){
         handle(req, resp, new ErrorReport(cause, 404));
      }catch(Throwable cause){
         handle(req, resp, new ErrorReport(cause, 500));
      }
   }
   
   /**
    * This is used to generate the status report from a status code.
    * The set of status reports that can have a valid response are the 
    * messages that are defined in RFC 2616. If the status code given 
    * does not have a valid entry then this will result in an status
    * message description of 'Unknown'.
    * <p>
    * This does not throw <code>Exception</code>'s but users should
    * be prepared to handle any <code>RuntimeException</code>'s that 
    * could propagate from this. If the <code>Response</code> has
    * been committed then this will return quietly. Typically there
    * will be an <code>IOException</code> writing the content body if
    * the stream has been closed. This will not report such exceptions.
    *
    * @param req the <code>Request</code> object to be processed
    * @param resp the <code>Response</code> object to be processed
    * @param code this is the HTTP status code of the response
    */   
   public void handle(Request req, Response resp, int code){
      handle(req, resp, new StatusReport(code));
   }
   
   /**
    * This is used to generate a formatted message using a report to
    * describe the change in status. This uses the <code>Format</code> 
    * object to prepare a formatted message that can be presented to
    * the client. This message will describe the status using the 
    * issued <code>Report</code> obejct. If the status code given 
    * does not have a valid entry then this will result in an status
    * message description of 'Unknown'.
    * <p>
    * This does not throw <code>Exception</code>'s but users should
    * be prepared to handle any <code>RuntimeException</code>'s that 
    * could propagate from this. If the <code>Response</code> has
    * been committed then this will return quietly. Typically there
    * will be an <code>IOException</code> writing the content body if
    * the stream has been closed. This will not report such exceptions.
    *
    * @param req the <code>Request</code> object to be processed
    * @param resp the <code>Response</code> object to be processed
    * @param report this is used to describe the change in status
    */
   public void handle(Request req, Response resp, Report report){
      try{
         if(!resp.isCommitted()) {
            resp.reset();
            process(req, resp, report);                     
         }
         resp.getOutputStream().close();         
      }catch(IOException e){         
      }catch(Exception e){
         e.printStackTrace();
      }
   }

   /**
    * This method is used to handle the HTTP status reports so that 
    * if any <code>Exception</code> occurs the <code>handle</code>
    * method can capture and deal with the exception.
    * <p>
    * Subclasses should treat this as the <code>handle</code> method 
    * of the <code>ProtocolHandler</code>. Exceptions that cannot be
    * recovered from, particularly <code>RuntimeException</code>'s
    * should be left propagate so the <code>handle</code> method can
    * deal with the <code>Exception</code> appropriately.
    *
    * @param req the <code>Request</code> object to be processed
    * @param resp the <code>Response</code> object to be processed
    * @param code this is the HTTP status code of the response
    *
    * @exception Exception this can throw an error for anything
    */
   protected void process(Request req, Response resp, int code) throws Exception{
      process(req, resp, new StatusReport(code));
   }
   
   /**
    * This method is used to handle the HTTP status reports so that 
    * if any <code>Exception</code> occurs the <code>handle</code>
    * method can capture and deal with the exception.
    * <p>
    * Subclasses should treat this as the <code>handle</code> method 
    * of the <code>ProtocolHandler</code>. Exceptions that cannot be
    * recovered from, particularly <code>RuntimeException</code>'s
    * should be left propagate so the <code>handle</code> method can
    * deal with the <code>Exception</code> appropriately.
    *
    * @param req the <code>Request</code> object to be processed
    * @param resp the <code>Response</code> object to be processed
    * @param report this is used to describe the change in status
    *
    * @exception Exception this can throw an error for anything
    */
   protected void process(Request req, Response resp, Report report) throws Exception{
      Format format = context.getFormat();
      byte[] page = format.getMessage(
         context, req.getURI(), report);     
         
      resp.setCode(report.getCode());
      resp.setText(report.getText());
      resp.setDate("Date", System.currentTimeMillis());
      resp.setContentLength(page.length);
      resp.set("Content-Type", format.getContentType());
      resp.getOutputStream().write(page);
      resp.getOutputStream().close();     
   }   
   
   /**
    * This method is used to handle the HTTP transaction by subclasses
    * of the <code>Component</code>. This is used so that if there
    * are any <code>Exception</code>'s thrown while processing the
    * HTTP transaction they can be captured and the HTTP status line
    * will convey the status to the client.
    * <p>
    * Subclasses should treat this as the <code>handle</code> method 
    * of the <code>ProtocolHandler</code>. Exceptions that cannot be
    * recovered from, particularly <code>RuntimeException</code>'s
    * should be left propagate so the <code>handle</code> method can
    * prepare an appropriate response.
    *
    * @param req the <code>Request</code> object to be processed
    * @param resp the <code>Response</code> object to be processed
    *
    * @exception Exception this can throw an error for anything
    */
   protected abstract void process(Request req, Response resp)
      throws Exception;   
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.