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

Java Open Source » Web Server » simple 
simple » simple » http » ResponseHeader.java
/*
 * ResponseHeader.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;

import simple.util.parse.DateParser;
import simple.util.parse.ListParser;

/**
 * This is a <code>ResponseHeader</code> object that is used to store
 * and retrive message header information about a given response. This
 * implements the <code>StatusLine</code> and <code>GenericHeader</code> 
 * interfaces which provide methods to access key components within a
 * HTTP message header.
 * <p>
 * The <code>StstusLine</code> interface provides specific methods for
 * dealing with the HTTP status line. The <code>StatusLine</code> also
 * contains methods for manipulating the version that the response has.
 *
 * @author Niall Gallagher
 */ 
abstract class ResponseHeader implements Response {

   /**
    * Provides quick search an retreval for HTTP headers.
    */
   private HeaderList list;

   /**
    * This is used to parse the header values of dates.
    */
   private DateParser date;
   
   /**
    * This represents the status lines description.
    */
   private String text;
   
   /**
    * This represents the ststus code of the header.
    */
   private int code;
   
   /**
    * This represents the major version number.
    */
   private int major;   
   
   /**
    * This represents the minor version number.
    */
   private int minor;     

   /**
    * This creates a <code>ResponseHeader</code> object that 
    * can be used manipulate a HTTP <code>ResponseHeader</code>.
    */ 
   protected ResponseHeader(){    
      this.list = new HeaderList();
      this.date = new DateParser();
      this.major = minor = 1;
      this.text = "OK";
      this.code = 200;
   }
   
   /**
    * This represents the status code of the HTTP response. 
    * The response code represents the type of message that is
    * being sent to the client. For a description of the codes
    * see RFC 2616 section 10, Status Code Definitions. 
    *
    * @return the status code that this HTTP response has
    */ 
   public int getCode(){      
      return code;
   }  
     
   /**
    * This method allows the status for the response to be 
    * changed. This MUST be reflected the the response content
    * given to the client. For a description of the codes see
    * RFC 2616 section 10, Status Code Definitions.
    *
    * @param code the new status code for the HTTP response
    */ 
   public void setCode(int code){
      this.code = code;
   }

   /**
    * This can be used to retrive the text of a HTTP status
    * line. This is the text description for the status code.
    * This should match the status code specified by the RFC.
    *
    * @return the message description of the response
    */ 
   public String getText(){
      return text;
   } 

   /**
    * This is used to set the text of the HTTP status line.
    * This should match the status code specified by the RFC.
    *
    * @param text the descriptive text message of the status
    */ 
   public void setText(String text){
      this.text = text;
   }

   /**
    * This can be used to get the major number from a HTTP
    * version. The major version corrosponds to the major 
    * type that is the 1 of a HTTP/1.0 version string.
    *
    * @return the major version number for the response
    */ 
   public int getMajor(){
      return major;
   }

   /**
    * This can be used to specify the major version. This
    * should be the major version of the HTTP request.
    *
    * @param major this is the major number desired
    */ 
   public void setMajor(int major){
      this.major = major;
   }

   /**
    * This can be used to get the minor number from a HTTP
    * version. The major version corrosponds to the minor
    * type that is the 0 of a HTTP/1.0 version string.
    *
    * @return the major version number for the response
    */ 
   public int getMinor(){
      return minor;
   }
   
   /**
    * This can be used to specify the minor version. This
    * should not be set to zero if the HTTP request was 
    * for HTTP/1.1. The response must be equal or higher.
    *
    * @param minor this is the minor number desired
    */ 
   public void setMinor(int minor){
      this.minor = minor;
   }   

   /**
    * This can be used to determine how many HTTP message headers
    * this object contains. The <code>headerCount</code> represents 
    * the number of individual HTTP message headers that this has.
    *
    * @return returns the number of HTTP message headers this has
    */  
   public int headerCount() {
      return list.headerCount();
   }
   
   /**
    * This can be used to get the value of the HTTP message header 
    * at the specified index. This is a convinence method that 
    * avoids having to deal with a HTTP message header object. If 
    * the offset used specified is invalid then an exception may be 
    * thrown.
    *
    * @param off the offset of the HTTP message header value to be
    * returned
    *
    * @return this returns the value that the HTTP message header
    */    
   public String getValue(int off) {
      return list.getValue(off);
   }

   /**
    * This is used to get the name value of the HTTP message header
    * at the specified index. This is used in conjunction with the
    * <code>getValue(int)</code> method so that the contents of the 
    * HTTP message header can be fully examined.
    *
    * @param off the offset of the HTTP message header name value 
    *
    * @return this returns the name of the header at that index 
    */
   public String getName(int off) {
      return list.getName(off);
   }

   /**
    * This can be used to find the first occurence of the specified 
    * HTTP message header. This will search through the list of 
    * HTTP message headers that this contains and when it encounters 
    * a HTTP message header with the name specified it returns the 
    * index of that HTTP message header. The index will change when 
    * a remove is used. So the index is valid only for the until the 
    * next remove method or possible the next add method.
    *
    * @param name name of the HTTP message header being searched for
    *
    * @return returns the position of the first HTTP message header
    */     
   public int indexOf(String name){
      return list.indexOf(name);
   }
   
   /**
    * This can be used to find the first occurence of the specified 
    * HTTP message header from a given index. This will search through 
    * the list of HTTP message headers that occur after the index. 
    * When it encounters a HTTP message header with the name specified 
    * it returns the index of that HTTP message header. The index will 
    * change when a remove is used. So the index is valid only until a 
    * remove or add method is used.
    *
    * @param name name of the HTTP message header being searched for
    * @param from the index from which the search will start
    *
    * @return this returns the position of the HTTP message header
    */    
   public int indexOf(String name, int from) {
      return list.indexOf(name, from);
   }
   
   /**
    * This can be used to add a HTTP message header to this object.
    * The name and value of the HTTP message header will be used to
    * create a HTTP message header object which can be retrived using
    * the <code>indexOf</code> in combination with the get methods.
    *
    * @param name the name of the HTTP message header to be added
    * @param val the value the HTTP message header will have
    */      
   public void add(String name, String val){
      list.add(new PlainHeader(name, val));
   }
   
   /**
    * This can be used to set a HTTP message header to this object.
    * The name and value of the HTTP message header will be used to
    * create a HTTP message header object which can be retrived using
    * the <code>indexOf</code> in combination with the get methods.
    * This will perform a <code>removeAll</code> using the issued
    * header name before the header value is set.    
    *
    * @param name the name of the HTTP message header to be added
    * @param val the value the HTTP message header will have
    */    
   public void set(String name, String val){
      removeAll(name);
      add(name, val);
   }
   
   /**
    * This can be used to add a HTTP message header to this object.
    * The name and value of the HTTP message header will be used to
    * create a HTTP message header object which can be retrived using
    * the <code>indexOf</code> in combination with the get methods.
    *
    * @param name the name of the HTTP message header to be added
    * @param val the value the HTTP message header will have
    */    
   public void add(String name, int val){
      add(name, String.valueOf(val));
   }
   
   /**
    * This can be used to set a HTTP message header to this object.
    * The name and value of the HTTP message header will be used to
    * create a HTTP message header object which can be retrived using
    * the <code>indexOf</code> in combination with the get methods.
    * This will perform a <code>removeAll</code> using the issued
    * header name before the header value is set.       
    *
    * @param name the name of the HTTP message header to be added
    * @param val the value the HTTP message header will have
    */ 
   public void set(String name, int val){
      removeAll(name);
      add(name, val);
   }
   
   
   /**
    * This is used as a convienence method for adding a header that
    * needs to be parsed into a HTTP-date string. This will convert
    * the date given into a date string defined in RFC 2616 sec 3.3.1.
    *
    * @param name the name of the HTTP message header to be added
    * @param time the value the HTTP message header will have when
    * parsed into RFC 1123 format
    */   
   public void addDate(String name, long time){
      date.parse(time);
      add(name, date.toString());
   }
   
   /**
    * This is used as a convienence method for setting a header that
    * needs to be parsed into a HTTP-date string. This will convert
    * the date given into a date string defined in RFC 2616 sec 3.3.1.
    * This will perform a <code>removeAll</code> using the issued
    * header name before the header value is set.
    *
    * @param name the name of the HTTP message header to be added
    * @param time the value the HTTP message header will have when
    * parsed into RFC 1123 format
    */
   public void setDate(String name, long time){
      removeAll(name);
      addDate(name, time);
   }

   /**
    * This can be used to remove the HTTP message header at the
    * specified index. This will invalidate any value recived by 
    * an <code>indexOf</code> method previous to this. If the 
    * index specified is not valid then an 
    * <code>IndexOutOfBoundsException</code> may be thrown.
    *
    * @param off index of the HTTP message header to be removed
    */  
   public void remove(int off){
      list.remove(off);
   }
   
   /**
    * This can be used to remove all HTTP message headers with 
    * the specified name. This will search through the list of 
    * HTTP message header an remove the HTTP message headers
    * from the list. This will invalidate any previous indexes
    * recived.
    *
    * @param name name of the HTTP message headers to be removed
    */    
   public void removeAll(String name){
      list.removeAll(name);
   }

   /**
    * This can be used to get the value of the first HTTP message header
    * that has the specified name. This is a convinence method that 
    * avoids having to deal with a HTTP message header object and
    * the <code>indexOf</code> methods. this returns null if theres
    * not HTTP message header.
    *
    * @param name the HTTP message header to get the value from
    *
    * @return this returns the value that the HTTP message header
    */ 
   public String getValue(String name) {
      return list.getValue(name);
   }
   
   /**
    * This can be used to get the values of HTTP message headers
    * that have the specified name. This is a convenience method that 
    * will present that values as tokens extracted from the header.
    * This has obvious performance benifits as it avoids having to 
    * deal with <code>substring</code> and <code>trim</code> calls.
    * <p>
    * The tokens returned by this method are ordered according to
    * there HTTP quality values, or "q" values, see RFC 2616 section
    * 3.9. This also strips out the quality parameter from tokens
    * returned. So "image/html; q=0.9" results in "image/html". If
    * there are no "q" values present then order is preserved. 
    *
    * @param name the name of the headers that are to be retrieved
    *
    * @return ordered array of tokens extracted from the header(s)
    */
   public String[] getValues(String name){
      return getValues(list.getValues(name));
   }

   /**
    * This method will parse the given list of HTTP header values
    * into usable tokens. Although the conversion from the complete
    * HTTP header values to descrete tokens is costly the overall
    * benifit to performance is obvious. 
    * <p>
    * Rather that calling the <code>getValue(String)</code> method
    * and parsing a token with the <code>String.substring</code> 
    * or <code>String.trim</code> methods the tokens can be used
    * immediately, this avoids errors and overheads.
    *
    * @param list this is the list of HTTP header values to parse
    *
    * @return this wll return an ordered list of extracted tokens
    */
   private String[] getValues(String[] list) {
      return new ListParser(list).list();
   }
  
   /**
    * This can be used to get the value of the HTTP message header 
    * at the specified index. This is a convinence method that 
    * avoids having to deal with a HTTP message header object. If 
    * the offset used specified is invalid then an exception may be 
    * thrown.
    *
    * @param off the offset of the HTTP message header value to be
    * returned
    *
    * @return this returns the date as a long from the parsed value 
    * of that HTTP message header
    */
   public long getDate(int off) {
      String value = getValue(off);
      if(value == null) {
         return -1;
      }
      date.parse(value);
      return date.toLong();
   }
   
   /**
    * This can be used to get the date of the first HTTP message header
    * that has the specified name. This is a convinence method that 
    * avoids having to deal with parsing the value of the requested
    * HTTP message header. This also avoids having to deal with the
    * <code>indexOf</code> methods. This returns -1 if theres not a
    * HTTP message header.
    *
    * @param name the HTTP message header to get the value from
    *
    * @return this returns the date as a long from the parsed value 
    * of that HTTP message header
    */ 
   public long getDate(String name){   
      String value = getValue(name);
      if(value == null) {
         return -1;
      }
      date.parse(value);
      return date.toLong();
   }

   /**
    * This is used to see if there is a HTTP message header with the
    * given name in this container. If there is a HTTP message header
    * with the specified name then this returns true otherwize false.
    *
    * @param name the HTTP message header to get the value from
    *
    * @return this returns true if the HTTP message header exists
    */ 
   public boolean contains(String name) {
      return indexOf(name) != -1;
   }

   /**
    * This is used to see if there is a HTTP message header with the
    * given name in this container, if it exists this will check to
    * see if the provided value exists. This is used for a comma
    * seperated list of values found within the HTTP header value.
    * If the header and token exits this returns true otherwise false.
    *
    * @param name the HTTP message header to get the value from
    * @param value this value to find within the HTTP value
    *
    * @return this returns true if the HTTP message value exists
    */    
   public boolean contains(String name, String value) {
      String[] list = getValues(name);
      
      for(int i = 0; i < list.length; i++){
         if(list[i].equalsIgnoreCase(value))
            return true;              
      }
      return false;      
   }
   
   /**
    * This is used to clear all HTTP message headers from the 
    * message header. This will leave no data remaining, i.e.
    * <code>headerCount</code> is zero after this method is 
    * invoked, this is a convienence method.
    */
   public void clear(){
      while(headerCount()>0){
         remove(0);
      }
   }

   /** 
    * This constructs the HTTP message header according to the 
    * format of RFC 2616. This returns a <code>String</code> that 
    * contains each header formatted according to the HTTP/1.1 
    * header format. The header will contain the status line 
    * followed by each header and ended with the CRLF.
    * <p>
    * It is important that this perform the header generation
    * quickly. This is used by the <code>MonitoredResponse</code>
    * to output the HTTP mesage header and thus this becomes a
    * criticial performance point.
    *
    * @return the HTTP response header as a string object
    */   
   public String toString() {
      int size = headerCount()*50;
      StringBuffer buf =new StringBuffer(size); 
      buf.append("HTTP/");
      buf.append(major).append(".");
      buf.append(minor).append(" ");
      buf.append(code).append(" ");
      buf.append(text).append("\r\n");
      for(int i = 0,len = headerCount(); i< len;i++){
         Header head = list.get(i);         
         buf.append(head.getName());
         buf.append(": ");
         buf.append(head.getValue());
         buf.append("\r\n");
      }
      buf.append("\r\n");
      return buf.toString();
   }   
}    
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.