|
1 /* |
|
2 * ==================================================================== |
|
3 * Licensed to the Apache Software Foundation (ASF) under one |
|
4 * or more contributor license agreements. See the NOTICE file |
|
5 * distributed with this work for additional information |
|
6 * regarding copyright ownership. The ASF licenses this file |
|
7 * to you under the Apache License, Version 2.0 (the |
|
8 * "License"); you may not use this file except in compliance |
|
9 * with the License. You may obtain a copy of the License at |
|
10 * |
|
11 * http://www.apache.org/licenses/LICENSE-2.0 |
|
12 * |
|
13 * Unless required by applicable law or agreed to in writing, |
|
14 * software distributed under the License is distributed on an |
|
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
16 * KIND, either express or implied. See the License for the |
|
17 * specific language governing permissions and limitations |
|
18 * under the License. |
|
19 * ==================================================================== |
|
20 * |
|
21 * This software consists of voluntary contributions made by many |
|
22 * individuals on behalf of the Apache Software Foundation. For more |
|
23 * information on the Apache Software Foundation, please see |
|
24 * <http://www.apache.org/>. |
|
25 * |
|
26 */ |
|
27 |
|
28 package ch.boye.httpclientandroidlib; |
|
29 |
|
30 import java.io.Serializable; |
|
31 import ch.boye.httpclientandroidlib.util.CharArrayBuffer; |
|
32 |
|
33 /** |
|
34 * Represents a protocol version. The "major.minor" numbering |
|
35 * scheme is used to indicate versions of the protocol. |
|
36 * <p> |
|
37 * This class defines a protocol version as a combination of |
|
38 * protocol name, major version number, and minor version number. |
|
39 * Note that {@link #equals} and {@link #hashCode} are defined as |
|
40 * final here, they cannot be overridden in derived classes. |
|
41 * </p> |
|
42 * |
|
43 * @since 4.0 |
|
44 */ |
|
45 public class ProtocolVersion implements Serializable, Cloneable { |
|
46 |
|
47 private static final long serialVersionUID = 8950662842175091068L; |
|
48 |
|
49 |
|
50 /** Name of the protocol. */ |
|
51 protected final String protocol; |
|
52 |
|
53 /** Major version number of the protocol */ |
|
54 protected final int major; |
|
55 |
|
56 /** Minor version number of the protocol */ |
|
57 protected final int minor; |
|
58 |
|
59 |
|
60 /** |
|
61 * Create a protocol version designator. |
|
62 * |
|
63 * @param protocol the name of the protocol, for example "HTTP" |
|
64 * @param major the major version number of the protocol |
|
65 * @param minor the minor version number of the protocol |
|
66 */ |
|
67 public ProtocolVersion(String protocol, int major, int minor) { |
|
68 if (protocol == null) { |
|
69 throw new IllegalArgumentException |
|
70 ("Protocol name must not be null."); |
|
71 } |
|
72 if (major < 0) { |
|
73 throw new IllegalArgumentException |
|
74 ("Protocol major version number must not be negative."); |
|
75 } |
|
76 if (minor < 0) { |
|
77 throw new IllegalArgumentException |
|
78 ("Protocol minor version number may not be negative"); |
|
79 } |
|
80 this.protocol = protocol; |
|
81 this.major = major; |
|
82 this.minor = minor; |
|
83 } |
|
84 |
|
85 /** |
|
86 * Returns the name of the protocol. |
|
87 * |
|
88 * @return the protocol name |
|
89 */ |
|
90 public final String getProtocol() { |
|
91 return protocol; |
|
92 } |
|
93 |
|
94 /** |
|
95 * Returns the major version number of the protocol. |
|
96 * |
|
97 * @return the major version number. |
|
98 */ |
|
99 public final int getMajor() { |
|
100 return major; |
|
101 } |
|
102 |
|
103 /** |
|
104 * Returns the minor version number of the HTTP protocol. |
|
105 * |
|
106 * @return the minor version number. |
|
107 */ |
|
108 public final int getMinor() { |
|
109 return minor; |
|
110 } |
|
111 |
|
112 |
|
113 /** |
|
114 * Obtains a specific version of this protocol. |
|
115 * This can be used by derived classes to instantiate themselves instead |
|
116 * of the base class, and to define constants for commonly used versions. |
|
117 * <br/> |
|
118 * The default implementation in this class returns <code>this</code> |
|
119 * if the version matches, and creates a new {@link ProtocolVersion} |
|
120 * otherwise. |
|
121 * |
|
122 * @param major the major version |
|
123 * @param minor the minor version |
|
124 * |
|
125 * @return a protocol version with the same protocol name |
|
126 * and the argument version |
|
127 */ |
|
128 public ProtocolVersion forVersion(int major, int minor) { |
|
129 |
|
130 if ((major == this.major) && (minor == this.minor)) { |
|
131 return this; |
|
132 } |
|
133 |
|
134 // argument checking is done in the constructor |
|
135 return new ProtocolVersion(this.protocol, major, minor); |
|
136 } |
|
137 |
|
138 |
|
139 /** |
|
140 * Obtains a hash code consistent with {@link #equals}. |
|
141 * |
|
142 * @return the hashcode of this protocol version |
|
143 */ |
|
144 public final int hashCode() { |
|
145 return this.protocol.hashCode() ^ (this.major * 100000) ^ this.minor; |
|
146 } |
|
147 |
|
148 |
|
149 /** |
|
150 * Checks equality of this protocol version with an object. |
|
151 * The object is equal if it is a protocl version with the same |
|
152 * protocol name, major version number, and minor version number. |
|
153 * The specific class of the object is <i>not</i> relevant, |
|
154 * instances of derived classes with identical attributes are |
|
155 * equal to instances of the base class and vice versa. |
|
156 * |
|
157 * @param obj the object to compare with |
|
158 * |
|
159 * @return <code>true</code> if the argument is the same protocol version, |
|
160 * <code>false</code> otherwise |
|
161 */ |
|
162 public final boolean equals(Object obj) { |
|
163 if (this == obj) { |
|
164 return true; |
|
165 } |
|
166 if (!(obj instanceof ProtocolVersion)) { |
|
167 return false; |
|
168 } |
|
169 ProtocolVersion that = (ProtocolVersion) obj; |
|
170 |
|
171 return ((this.protocol.equals(that.protocol)) && |
|
172 (this.major == that.major) && |
|
173 (this.minor == that.minor)); |
|
174 } |
|
175 |
|
176 |
|
177 /** |
|
178 * Checks whether this protocol can be compared to another one. |
|
179 * Only protocol versions with the same protocol name can be |
|
180 * {@link #compareToVersion compared}. |
|
181 * |
|
182 * @param that the protocol version to consider |
|
183 * |
|
184 * @return <code>true</code> if {@link #compareToVersion compareToVersion} |
|
185 * can be called with the argument, <code>false</code> otherwise |
|
186 */ |
|
187 public boolean isComparable(ProtocolVersion that) { |
|
188 return (that != null) && this.protocol.equals(that.protocol); |
|
189 } |
|
190 |
|
191 |
|
192 /** |
|
193 * Compares this protocol version with another one. |
|
194 * Only protocol versions with the same protocol name can be compared. |
|
195 * This method does <i>not</i> define a total ordering, as it would be |
|
196 * required for {@link java.lang.Comparable}. |
|
197 * |
|
198 * @param that the protocl version to compare with |
|
199 * |
|
200 * @return a negative integer, zero, or a positive integer |
|
201 * as this version is less than, equal to, or greater than |
|
202 * the argument version. |
|
203 * |
|
204 * @throws IllegalArgumentException |
|
205 * if the argument has a different protocol name than this object, |
|
206 * or if the argument is <code>null</code> |
|
207 */ |
|
208 public int compareToVersion(ProtocolVersion that) { |
|
209 if (that == null) { |
|
210 throw new IllegalArgumentException |
|
211 ("Protocol version must not be null."); |
|
212 } |
|
213 if (!this.protocol.equals(that.protocol)) { |
|
214 throw new IllegalArgumentException |
|
215 ("Versions for different protocols cannot be compared. " + |
|
216 this + " " + that); |
|
217 } |
|
218 |
|
219 int delta = getMajor() - that.getMajor(); |
|
220 if (delta == 0) { |
|
221 delta = getMinor() - that.getMinor(); |
|
222 } |
|
223 return delta; |
|
224 } |
|
225 |
|
226 |
|
227 /** |
|
228 * Tests if this protocol version is greater or equal to the given one. |
|
229 * |
|
230 * @param version the version against which to check this version |
|
231 * |
|
232 * @return <code>true</code> if this protocol version is |
|
233 * {@link #isComparable comparable} to the argument |
|
234 * and {@link #compareToVersion compares} as greater or equal, |
|
235 * <code>false</code> otherwise |
|
236 */ |
|
237 public final boolean greaterEquals(ProtocolVersion version) { |
|
238 return isComparable(version) && (compareToVersion(version) >= 0); |
|
239 } |
|
240 |
|
241 |
|
242 /** |
|
243 * Tests if this protocol version is less or equal to the given one. |
|
244 * |
|
245 * @param version the version against which to check this version |
|
246 * |
|
247 * @return <code>true</code> if this protocol version is |
|
248 * {@link #isComparable comparable} to the argument |
|
249 * and {@link #compareToVersion compares} as less or equal, |
|
250 * <code>false</code> otherwise |
|
251 */ |
|
252 public final boolean lessEquals(ProtocolVersion version) { |
|
253 return isComparable(version) && (compareToVersion(version) <= 0); |
|
254 } |
|
255 |
|
256 |
|
257 /** |
|
258 * Converts this protocol version to a string. |
|
259 * |
|
260 * @return a protocol version string, like "HTTP/1.1" |
|
261 */ |
|
262 public String toString() { |
|
263 CharArrayBuffer buffer = new CharArrayBuffer(16); |
|
264 buffer.append(this.protocol); |
|
265 buffer.append('/'); |
|
266 buffer.append(Integer.toString(this.major)); |
|
267 buffer.append('.'); |
|
268 buffer.append(Integer.toString(this.minor)); |
|
269 return buffer.toString(); |
|
270 } |
|
271 |
|
272 public Object clone() throws CloneNotSupportedException { |
|
273 return super.clone(); |
|
274 } |
|
275 |
|
276 } |