HttpVersion.java
  1  /*
  2   * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/HttpVersion.java,v 1.6 2004/12/20 19:52:50 olegk Exp $
  3   * $Revision: 480424 $
  4   * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
  5   *
  6   * ====================================================================
  7   *
  8   *  Licensed to the Apache Software Foundation (ASF) under one or more
  9   *  contributor license agreements.  See the NOTICE file distributed with
 10   *  this work for additional information regarding copyright ownership.
 11   *  The ASF licenses this file to You under the Apache License, Version 2.0
 12   *  (the "License"); you may not use this file except in compliance with
 13   *  the License.  You may obtain a copy of the License at
 14   *
 15   *      http://www.apache.org/licenses/LICENSE-2.0
 16   *
 17   *  Unless required by applicable law or agreed to in writing, software
 18   *  distributed under the License is distributed on an "AS IS" BASIS,
 19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 20   *  See the License for the specific language governing permissions and
 21   *  limitations under the License.
 22   * ====================================================================
 23   *
 24   * This software consists of voluntary contributions made by many
 25   * individuals on behalf of the Apache Software Foundation.  For more
 26   * information on the Apache Software Foundation, please see
 27   * <http://www.apache.org/>.
 28   *
 29   */
 30  
 31  package org.apache.commons.httpclient;
 32  
 33  /**
 34   *  <p>HTTP version, as specified in RFC 2616.</p>
 35   *  <p>
 36   *  HTTP uses a "&lt;major&gt;.&lt;minor&gt;" numbering scheme to indicate
 37   *  versions of the protocol. The protocol versioning policy is intended to
 38   *  allow the sender to indicate the format of a message and its capacity for
 39   *  understanding further HTTP communication, rather than the features
 40   *  obtained via that communication. No change is made to the version
 41   *  number for the addition of message components which do not affect
 42   *  communication behavior or which only add to extensible field values.
 43   *  The &lt;minor&gt; number is incremented when the changes made to the
 44   *  protocol add features which do not change the general message parsing
 45   *  algorithm, but which may add to the message semantics and imply
 46   *  additional capabilities of the sender. The &lt;major&gt; number is
 47   *  incremented when the format of a message within the protocol is
 48   *  changed. See RFC 2145 [36] for a fuller explanation.
 49   *  </p>
 50   *  <p>
 51   *  The version of an HTTP message is indicated by an HTTP-Version field
 52   *  in the first line of the message.
 53   *  </p>
 54   *  <pre>
 55   *     HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
 56   *  </pre>
 57   *  <p>
 58   *   Note that the major and minor numbers MUST be treated as separate
 59   *   integers and that each MAY be incremented higher than a single digit.
 60   *   Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is
 61   *   lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and
 62   *   MUST NOT be sent.
 63   *  </p>
 64   * 
 65   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
 66   * 
 67   * @version $Revision: 480424 $ $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
 68   *
 69   * @since 3.0
 70   */
 71  public class HttpVersion implements Comparable {
 72  
 73      /** Major version number of the HTTP protocol */
 74      private int major = 0;
 75  
 76      /** Minor version number of the HTTP protocol */
 77      private int minor = 0;
 78  
 79      /** HTTP protocol version 0.9 */
 80      public static final HttpVersion HTTP_0_9 = new HttpVersion(0, 9);  
 81  
 82      /** HTTP protocol version 1.0 */
 83      public static final HttpVersion HTTP_1_0 = new HttpVersion(1, 0);  
 84  
 85      /** HTTP protocol version 1.1 */
 86      public static final HttpVersion HTTP_1_1 = new HttpVersion(1, 1);  
 87      
 88      /**
 89       * Create an HTTP protocol version designator.
 90       *
 91       * @param major   the major version number of the HTTP protocol
 92       * @param minor   the minor version number of the HTTP protocol
 93       * 
 94       * @throws IllegalArgumentException if either major or minor version number is negative
 95       */
 96      public HttpVersion(int major, int minor) {
 97          if (major < 0) {
 98              throw new IllegalArgumentException("HTTP major version number may not be negative");
 99          }
100          this.major = major;
101          if (minor < 0) {
102              throw new IllegalArgumentException("HTTP minor version number may not be negative");
103          }
104          this.minor = minor;
105      }
106      
107      /**
108       * Returns the major version number of the HTTP protocol.
109       * 
110       * @return the major version number.
111       */
112      public int getMajor() {
113          return major;
114      }
115  
116      /**
117       * Returns the minor version number of the HTTP protocol.
118       * 
119       * @return the minor version number.
120       */
121      public int getMinor() {
122          return minor;
123      }
124  
125      /**
126       * @see java.lang.Object#hashCode()
127       */
128      public int hashCode() {
129          return this.major * 100000 + this.minor;
130      }
131          
132      /**
133       * @see java.lang.Object#equals(java.lang.Object)
134       */
135      public boolean equals(Object obj) {
136          if (this == obj) {
137              return true;
138          }
139          if (!(obj instanceof HttpVersion)) {
140              return false;
141          }
142          return equals((HttpVersion)obj);  
143      }
144  
145      /**
146       * Compares this HTTP protocol version with another one.
147       * 
148       * @param anotherVer the version to be compared with.
149       *  
150       * @return a negative integer, zero, or a positive integer as this version is less than, 
151       *    equal to, or greater than the specified version.     
152       */
153      public int compareTo(HttpVersion anotherVer) {
154          if (anotherVer == null) {
155              throw new IllegalArgumentException("Version parameter may not be null"); 
156          }
157          int delta = getMajor() - anotherVer.getMajor();
158          if (delta == 0) {
159              delta = getMinor() - anotherVer.getMinor();
160          }
161          return delta;
162      }
163  
164      /**
165       * @see java.lang.Comparable#compareTo(java.lang.Object)
166       */
167      public int compareTo(Object o) {
168          return compareTo((HttpVersion)o);
169      }
170  
171      /**
172       * Test if the HTTP protocol version is equal to the given number.
173       * 
174       * @return <tt>true</tt> if HTTP protocol version is given to the given number, 
175       *         <tt>false</tt> otherwise.
176       */
177      public boolean equals(HttpVersion version) {
178          return compareTo(version) == 0;  
179      }
180  
181      /**
182       * Test if the HTTP protocol version is greater or equal to the given number.
183       * 
184       * @return <tt>true</tt> if HTTP protocol version is greater or equal given to the 
185       *         given number, <tt>false</tt> otherwise.
186       */
187      public boolean greaterEquals(HttpVersion version) {
188          return compareTo(version) >= 0;
189      }
190  
191      /**
192       * Test if the HTTP protocol version is less or equal to the given number.
193       * 
194       * @return <tt>true</tt> if HTTP protocol version is less or equal to given to the 
195       *         given number, <tt>false</tt> otherwise.
196       */
197      public boolean lessEquals(HttpVersion version) {
198          return compareTo(version) <= 0;
199      }
200  
201      /**
202       * @see java.lang.Object#toString()
203       */
204      public String toString() {
205          StringBuffer buffer = new StringBuffer();
206          buffer.append("HTTP/"); 
207          buffer.append(this.major); 
208          buffer.append('.'); 
209          buffer.append(this.minor); 
210          return buffer.toString();
211      }
212  
213      /**
214       * Parses the textual representation of the given HTTP protocol version.
215       * 
216       * @return HTTP protocol version.
217       * 
218       * @throws ProtocolException if the string is not a valid HTTP protocol version. 
219       */
220      public static HttpVersion parse(final String s) throws ProtocolException {
221          if (s == null) {
222              throw new IllegalArgumentException("String may not be null");
223          }
224          if (!s.startsWith("HTTP/")) {
225              throw new ProtocolException("Invalid HTTP version string: " + s);
226          }
227          int major, minor;
228          
229          int i1 = "HTTP/".length();
230          int i2 = s.indexOf(".", i1);
231          if (i2 == -1) {
232              throw new ProtocolException("Invalid HTTP version number: " + s);
233          }
234          try {
235              major = Integer.parseInt(s.substring(i1, i2)); 
236          } catch (NumberFormatException e) {
237              throw new ProtocolException("Invalid HTTP major version number: " + s);
238          }
239          i1 = i2 + 1;
240          i2 = s.length();
241          try {
242              minor = Integer.parseInt(s.substring(i1, i2)); 
243          } catch (NumberFormatException e) {
244              throw new ProtocolException("Invalid HTTP minor version number: " + s);
245          }
246          return new HttpVersion(major, minor);
247      }
248  
249  }