mobile/android/thirdparty/ch/boye/httpclientandroidlib/conn/scheme/Scheme.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 * ====================================================================
michael@0 3 * Licensed to the Apache Software Foundation (ASF) under one
michael@0 4 * or more contributor license agreements. See the NOTICE file
michael@0 5 * distributed with this work for additional information
michael@0 6 * regarding copyright ownership. The ASF licenses this file
michael@0 7 * to you under the Apache License, Version 2.0 (the
michael@0 8 * "License"); you may not use this file except in compliance
michael@0 9 * with the License. You may obtain a copy of the License at
michael@0 10 *
michael@0 11 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 12 *
michael@0 13 * Unless required by applicable law or agreed to in writing,
michael@0 14 * software distributed under the License is distributed on an
michael@0 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
michael@0 16 * KIND, either express or implied. See the License for the
michael@0 17 * specific language governing permissions and limitations
michael@0 18 * under the License.
michael@0 19 * ====================================================================
michael@0 20 *
michael@0 21 * This software consists of voluntary contributions made by many
michael@0 22 * individuals on behalf of the Apache Software Foundation. For more
michael@0 23 * information on the Apache Software Foundation, please see
michael@0 24 * <http://www.apache.org/>.
michael@0 25 *
michael@0 26 */
michael@0 27 package ch.boye.httpclientandroidlib.conn.scheme;
michael@0 28
michael@0 29 import java.util.Locale;
michael@0 30
michael@0 31 import ch.boye.httpclientandroidlib.annotation.Immutable;
michael@0 32
michael@0 33 import ch.boye.httpclientandroidlib.util.LangUtils;
michael@0 34
michael@0 35 /**
michael@0 36 * Encapsulates specifics of a protocol scheme such as "http" or "https". Schemes are identified
michael@0 37 * by lowercase names. Supported schemes are typically collected in a {@link SchemeRegistry
michael@0 38 * SchemeRegistry}.
michael@0 39 * <p>
michael@0 40 * For example, to configure support for "https://" URLs, you could write code like the following:
michael@0 41 * <pre>
michael@0 42 * Scheme https = new Scheme("https", 443, new MySecureSocketFactory());
michael@0 43 * SchemeRegistry.DEFAULT.register(https);
michael@0 44 * </pre>
michael@0 45 *
michael@0 46 * @since 4.0
michael@0 47 */
michael@0 48 @Immutable
michael@0 49 public final class Scheme {
michael@0 50
michael@0 51 /** The name of this scheme, in lowercase. (e.g. http, https) */
michael@0 52 private final String name;
michael@0 53
michael@0 54 /** The socket factory for this scheme */
michael@0 55 private final SchemeSocketFactory socketFactory;
michael@0 56
michael@0 57 /** The default port for this scheme */
michael@0 58 private final int defaultPort;
michael@0 59
michael@0 60 /** Indicates whether this scheme allows for layered connections */
michael@0 61 private final boolean layered;
michael@0 62
michael@0 63 /** A string representation, for {@link #toString toString}. */
michael@0 64 private String stringRep;
michael@0 65 /*
michael@0 66 * This is used to cache the result of the toString() method
michael@0 67 * Since the method always generates the same value, there's no
michael@0 68 * need to synchronize, and it does not affect immutability.
michael@0 69 */
michael@0 70
michael@0 71 /**
michael@0 72 * Creates a new scheme.
michael@0 73 * Whether the created scheme allows for layered connections
michael@0 74 * depends on the class of <code>factory</code>.
michael@0 75 *
michael@0 76 * @param name the scheme name, for example "http".
michael@0 77 * The name will be converted to lowercase.
michael@0 78 * @param port the default port for this scheme
michael@0 79 * @param factory the factory for creating sockets for communication
michael@0 80 * with this scheme
michael@0 81 *
michael@0 82 * @since 4.1
michael@0 83 */
michael@0 84 public Scheme(final String name, final int port, final SchemeSocketFactory factory) {
michael@0 85 if (name == null) {
michael@0 86 throw new IllegalArgumentException("Scheme name may not be null");
michael@0 87 }
michael@0 88 if ((port <= 0) || (port > 0xffff)) {
michael@0 89 throw new IllegalArgumentException("Port is invalid: " + port);
michael@0 90 }
michael@0 91 if (factory == null) {
michael@0 92 throw new IllegalArgumentException("Socket factory may not be null");
michael@0 93 }
michael@0 94 this.name = name.toLowerCase(Locale.ENGLISH);
michael@0 95 this.socketFactory = factory;
michael@0 96 this.defaultPort = port;
michael@0 97 this.layered = factory instanceof LayeredSchemeSocketFactory;
michael@0 98 }
michael@0 99
michael@0 100 /**
michael@0 101 * Creates a new scheme.
michael@0 102 * Whether the created scheme allows for layered connections
michael@0 103 * depends on the class of <code>factory</code>.
michael@0 104 *
michael@0 105 * @param name the scheme name, for example "http".
michael@0 106 * The name will be converted to lowercase.
michael@0 107 * @param factory the factory for creating sockets for communication
michael@0 108 * with this scheme
michael@0 109 * @param port the default port for this scheme
michael@0 110 *
michael@0 111 * @deprecated Use {@link #Scheme(String, int, SchemeSocketFactory)}
michael@0 112 */
michael@0 113 @Deprecated
michael@0 114 public Scheme(final String name,
michael@0 115 final SocketFactory factory,
michael@0 116 final int port) {
michael@0 117
michael@0 118 if (name == null) {
michael@0 119 throw new IllegalArgumentException
michael@0 120 ("Scheme name may not be null");
michael@0 121 }
michael@0 122 if (factory == null) {
michael@0 123 throw new IllegalArgumentException
michael@0 124 ("Socket factory may not be null");
michael@0 125 }
michael@0 126 if ((port <= 0) || (port > 0xffff)) {
michael@0 127 throw new IllegalArgumentException
michael@0 128 ("Port is invalid: " + port);
michael@0 129 }
michael@0 130
michael@0 131 this.name = name.toLowerCase(Locale.ENGLISH);
michael@0 132 if (factory instanceof LayeredSocketFactory) {
michael@0 133 this.socketFactory = new LayeredSchemeSocketFactoryAdaptor(
michael@0 134 (LayeredSocketFactory) factory);
michael@0 135 this.layered = true;
michael@0 136 } else {
michael@0 137 this.socketFactory = new SchemeSocketFactoryAdaptor(factory);
michael@0 138 this.layered = false;
michael@0 139 }
michael@0 140 this.defaultPort = port;
michael@0 141 }
michael@0 142
michael@0 143 /**
michael@0 144 * Obtains the default port.
michael@0 145 *
michael@0 146 * @return the default port for this scheme
michael@0 147 */
michael@0 148 public final int getDefaultPort() {
michael@0 149 return defaultPort;
michael@0 150 }
michael@0 151
michael@0 152
michael@0 153 /**
michael@0 154 * Obtains the socket factory.
michael@0 155 * If this scheme is {@link #isLayered layered}, the factory implements
michael@0 156 * {@link LayeredSocketFactory LayeredSocketFactory}.
michael@0 157 *
michael@0 158 * @return the socket factory for this scheme
michael@0 159 *
michael@0 160 * @deprecated Use {@link #getSchemeSocketFactory()}
michael@0 161 */
michael@0 162 @Deprecated
michael@0 163 public final SocketFactory getSocketFactory() {
michael@0 164 if (this.socketFactory instanceof SchemeSocketFactoryAdaptor) {
michael@0 165 return ((SchemeSocketFactoryAdaptor) this.socketFactory).getFactory();
michael@0 166 } else {
michael@0 167 if (this.layered) {
michael@0 168 return new LayeredSocketFactoryAdaptor(
michael@0 169 (LayeredSchemeSocketFactory) this.socketFactory);
michael@0 170 } else {
michael@0 171 return new SocketFactoryAdaptor(this.socketFactory);
michael@0 172 }
michael@0 173 }
michael@0 174 }
michael@0 175
michael@0 176 /**
michael@0 177 * Obtains the socket factory.
michael@0 178 * If this scheme is {@link #isLayered layered}, the factory implements
michael@0 179 * {@link LayeredSocketFactory LayeredSchemeSocketFactory}.
michael@0 180 *
michael@0 181 * @return the socket factory for this scheme
michael@0 182 *
michael@0 183 * @since 4.1
michael@0 184 */
michael@0 185 public final SchemeSocketFactory getSchemeSocketFactory() {
michael@0 186 return this.socketFactory;
michael@0 187 }
michael@0 188
michael@0 189 /**
michael@0 190 * Obtains the scheme name.
michael@0 191 *
michael@0 192 * @return the name of this scheme, in lowercase
michael@0 193 */
michael@0 194 public final String getName() {
michael@0 195 return name;
michael@0 196 }
michael@0 197
michael@0 198 /**
michael@0 199 * Indicates whether this scheme allows for layered connections.
michael@0 200 *
michael@0 201 * @return <code>true</code> if layered connections are possible,
michael@0 202 * <code>false</code> otherwise
michael@0 203 */
michael@0 204 public final boolean isLayered() {
michael@0 205 return layered;
michael@0 206 }
michael@0 207
michael@0 208 /**
michael@0 209 * Resolves the correct port for this scheme.
michael@0 210 * Returns the given port if it is valid, the default port otherwise.
michael@0 211 *
michael@0 212 * @param port the port to be resolved,
michael@0 213 * a negative number to obtain the default port
michael@0 214 *
michael@0 215 * @return the given port or the defaultPort
michael@0 216 */
michael@0 217 public final int resolvePort(int port) {
michael@0 218 return port <= 0 ? defaultPort : port;
michael@0 219 }
michael@0 220
michael@0 221 /**
michael@0 222 * Return a string representation of this object.
michael@0 223 *
michael@0 224 * @return a human-readable string description of this scheme
michael@0 225 */
michael@0 226 @Override
michael@0 227 public final String toString() {
michael@0 228 if (stringRep == null) {
michael@0 229 StringBuilder buffer = new StringBuilder();
michael@0 230 buffer.append(this.name);
michael@0 231 buffer.append(':');
michael@0 232 buffer.append(Integer.toString(this.defaultPort));
michael@0 233 stringRep = buffer.toString();
michael@0 234 }
michael@0 235 return stringRep;
michael@0 236 }
michael@0 237
michael@0 238 @Override
michael@0 239 public final boolean equals(Object obj) {
michael@0 240 if (this == obj) return true;
michael@0 241 if (obj instanceof Scheme) {
michael@0 242 Scheme that = (Scheme) obj;
michael@0 243 return this.name.equals(that.name)
michael@0 244 && this.defaultPort == that.defaultPort
michael@0 245 && this.layered == that.layered;
michael@0 246 } else {
michael@0 247 return false;
michael@0 248 }
michael@0 249 }
michael@0 250
michael@0 251 @Override
michael@0 252 public int hashCode() {
michael@0 253 int hash = LangUtils.HASH_SEED;
michael@0 254 hash = LangUtils.hashCode(hash, this.defaultPort);
michael@0 255 hash = LangUtils.hashCode(hash, this.name);
michael@0 256 hash = LangUtils.hashCode(hash, this.layered);
michael@0 257 return hash;
michael@0 258 }
michael@0 259
michael@0 260 }

mercurial