Source code: org/apache/http/Scheme.java
1 /*
2 * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/tags/4.0-alpha2/src/java/org/apache/http/Scheme.java $
3 * $Revision: 328099 $
4 * $Date: 2005-10-24 19:36:14 +0200 (Mon, 24 Oct 2005) $
5 *
6 * ====================================================================
7 *
8 * Copyright 2002-2004 The Apache Software Foundation
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ====================================================================
22 *
23 * This software consists of voluntary contributions made by many
24 * individuals on behalf of the Apache Software Foundation. For more
25 * information on the Apache Software Foundation, please see
26 * <http://www.apache.org/>.
27 *
28 */
29 package org.apache.http;
30
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import org.apache.http.io.CharArrayBuffer;
36 import org.apache.http.io.SecureSocketFactory;
37 import org.apache.http.io.SocketFactory;
38 import org.apache.http.util.LangUtils;
39
40 /**
41 * A class to encapsulate the specifics of a protocol scheme. This class also
42 * provides the ability to customize the set and characteristics of the
43 * schemes used.
44 *
45 * <p>One use case for modifying the default set of protocols would be to set a
46 * custom SSL socket factory. This would look something like the following:
47 * <pre>
48 * Scheme myHTTPS = new Scheme( "https", new MySSLSocketFactory(), 443 );
49 *
50 * Scheme.registerScheme( "https", myHTTPS );
51 * </pre>
52 *
53 * @author Michael Becke
54 * @author Jeff Dever
55 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
56 *
57 * @since 2.0
58 */
59 public class Scheme {
60
61 /** The available schemes */
62 private static final Map SCHEMES = Collections.synchronizedMap(new HashMap());
63
64 /**
65 * Registers a new scheme with the given identifier. If a scheme with
66 * the given ID already exists it will be overridden. This ID is the same
67 * one used to retrieve the scheme from getScheme(String).
68 *
69 * @param id the identifier for this scheme
70 * @param scheme the scheme to register
71 *
72 * @see #getScheme(String)
73 */
74 public static void registerScheme(final String id, final Scheme scheme) {
75 if (id == null) {
76 throw new IllegalArgumentException("Id may not be null");
77 }
78 if (scheme == null) {
79 throw new IllegalArgumentException("Scheme may not be null");
80 }
81 SCHEMES.put(id, scheme);
82 }
83
84 /**
85 * Unregisters the scheme with the given ID.
86 *
87 * @param id the ID of the scheme to remove
88 */
89 public static void unregisterScheme(final String id) {
90 if (id == null) {
91 throw new IllegalArgumentException("Id may not be null");
92 }
93 SCHEMES.remove(id);
94 }
95
96 /**
97 * Gets the scheme with the given ID.
98 *
99 * @param id the scheme ID
100 *
101 * @return Scheme a scheme
102 *
103 * @throws IllegalStateException if a scheme with the ID cannot be found
104 */
105 public static Scheme getScheme(String id)
106 throws IllegalStateException {
107
108 if (id == null) {
109 throw new IllegalArgumentException("id is null");
110 }
111 Scheme scheme = (Scheme) SCHEMES.get(id);
112 if (scheme == null) {
113 throw new IllegalStateException("Unsupported scheme: '" + id + "'");
114 }
115 return scheme;
116 }
117
118 /** the scheme of this scheme (e.g. http, https) */
119 private String name;
120
121 /** The socket factory for this scheme */
122 private SocketFactory socketFactory;
123
124 /** The default port for this scheme */
125 private int defaultPort;
126
127 /** True if this scheme is secure */
128 private boolean secure;
129
130 /**
131 * Constructs a new Protocol. Whether the created scheme is secure depends on
132 * the class of <code>factory</code>.
133 *
134 * @param name the scheme name (e.g. http, https)
135 * @param factory the factory for creating sockets for communication using
136 * this scheme
137 * @param defaultPort the port this scheme defaults to
138 */
139 public Scheme(final String name, final SocketFactory factory, int defaultPort) {
140
141 if (name == null) {
142 throw new IllegalArgumentException("Scheme name may not be null");
143 }
144 if (factory == null) {
145 throw new IllegalArgumentException("Socket factory may not be null");
146 }
147 if (defaultPort <= 0) {
148 throw new IllegalArgumentException("Port is invalid: " + defaultPort);
149 }
150
151 this.name = name;
152 this.socketFactory = factory;
153 this.defaultPort = defaultPort;
154 this.secure = (factory instanceof SecureSocketFactory);
155 }
156
157 /**
158 * Returns the defaultPort.
159 * @return int
160 */
161 public int getDefaultPort() {
162 return defaultPort;
163 }
164
165 /**
166 * Returns the socketFactory. If secure the factory is a SecureSocketFactory.
167 * @return SocketFactory
168 */
169 public SocketFactory getSocketFactory() {
170 return socketFactory;
171 }
172
173 /**
174 * Returns the scheme.
175 * @return The scheme
176 */
177 public String getName() {
178 return name;
179 }
180
181 /**
182 * Returns true if this scheme is secure
183 * @return true if this scheme is secure
184 */
185 public boolean isSecure() {
186 return secure;
187 }
188
189 /**
190 * Resolves the correct port for this scheme. Returns the given port if
191 * valid or the default port otherwise.
192 *
193 * @param port the port to be resolved
194 *
195 * @return the given port or the defaultPort
196 */
197 public int resolvePort(int port) {
198 return port <= 0 ? getDefaultPort() : port;
199 }
200
201 /**
202 * Return a string representation of this object.
203 * @return a string representation of this object.
204 */
205 public String toString() {
206 CharArrayBuffer buffer = new CharArrayBuffer(32);
207 buffer.append(this.name);
208 buffer.append(':');
209 buffer.append(Integer.toString(this.defaultPort));
210 return buffer.toString();
211 }
212
213 /**
214 * Return true if the specified object equals this object.
215 * @param obj The object to compare against.
216 * @return true if the objects are equal.
217 */
218 public boolean equals(Object obj) {
219 if (obj == null) return false;
220 if (this == obj) return true;
221 if (obj instanceof Scheme) {
222 Scheme p = (Scheme) obj;
223 return (
224 defaultPort == p.getDefaultPort()
225 && name.equalsIgnoreCase(p.getName())
226 && secure == p.isSecure()
227 && socketFactory.equals(p.getSocketFactory()));
228
229 } else {
230 return false;
231 }
232
233 }
234
235 /**
236 * Return a hash code for this object
237 * @return The hash code.
238 */
239 public int hashCode() {
240 int hash = LangUtils.HASH_SEED;
241 hash = LangUtils.hashCode(hash, this.defaultPort);
242 hash = LangUtils.hashCode(hash, this.name.toLowerCase());
243 hash = LangUtils.hashCode(hash, this.secure);
244 hash = LangUtils.hashCode(hash, this.socketFactory);
245 return hash;
246 }
247 }