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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 package ch.boye.httpclientandroidlib.conn.scheme;
    29 import java.util.Locale;
    31 import ch.boye.httpclientandroidlib.annotation.Immutable;
    33 import ch.boye.httpclientandroidlib.util.LangUtils;
    35 /**
    36  * Encapsulates specifics of a protocol scheme such as "http" or "https". Schemes are identified
    37  * by lowercase names. Supported schemes are typically collected in a {@link SchemeRegistry
    38  * SchemeRegistry}.
    39  * <p>
    40  * For example, to configure support for "https://" URLs, you could write code like the following:
    41  * <pre>
    42  * Scheme https = new Scheme("https", 443, new MySecureSocketFactory());
    43  * SchemeRegistry.DEFAULT.register(https);
    44  * </pre>
    45  *
    46  * @since 4.0
    47  */
    48 @Immutable
    49 public final class Scheme {
    51     /** The name of this scheme, in lowercase. (e.g. http, https) */
    52     private final String name;
    54     /** The socket factory for this scheme */
    55     private final SchemeSocketFactory socketFactory;
    57     /** The default port for this scheme */
    58     private final int defaultPort;
    60     /** Indicates whether this scheme allows for layered connections */
    61     private final boolean layered;
    63     /** A string representation, for {@link #toString toString}. */
    64     private String stringRep;
    65     /*
    66      *  This is used to cache the result of the toString() method
    67      *  Since the method always generates the same value, there's no
    68      *  need to synchronize, and it does not affect immutability.
    69     */
    71     /**
    72      * Creates a new scheme.
    73      * Whether the created scheme allows for layered connections
    74      * depends on the class of <code>factory</code>.
    75      *
    76      * @param name      the scheme name, for example "http".
    77      *                  The name will be converted to lowercase.
    78      * @param port      the default port for this scheme
    79      * @param factory   the factory for creating sockets for communication
    80      *                  with this scheme
    81      *
    82      * @since 4.1
    83      */
    84     public Scheme(final String name, final int port, final SchemeSocketFactory factory) {
    85         if (name == null) {
    86             throw new IllegalArgumentException("Scheme name may not be null");
    87         }
    88         if ((port <= 0) || (port > 0xffff)) {
    89             throw new IllegalArgumentException("Port is invalid: " + port);
    90         }
    91         if (factory == null) {
    92             throw new IllegalArgumentException("Socket factory may not be null");
    93         }
    94         this.name = name.toLowerCase(Locale.ENGLISH);
    95         this.socketFactory = factory;
    96         this.defaultPort = port;
    97         this.layered = factory instanceof LayeredSchemeSocketFactory;
    98     }
   100     /**
   101      * Creates a new scheme.
   102      * Whether the created scheme allows for layered connections
   103      * depends on the class of <code>factory</code>.
   104      *
   105      * @param name      the scheme name, for example "http".
   106      *                  The name will be converted to lowercase.
   107      * @param factory   the factory for creating sockets for communication
   108      *                  with this scheme
   109      * @param port      the default port for this scheme
   110      *
   111      * @deprecated Use {@link #Scheme(String, int, SchemeSocketFactory)}
   112      */
   113     @Deprecated
   114     public Scheme(final String name,
   115                   final SocketFactory factory,
   116                   final int port) {
   118         if (name == null) {
   119             throw new IllegalArgumentException
   120                 ("Scheme name may not be null");
   121         }
   122         if (factory == null) {
   123             throw new IllegalArgumentException
   124                 ("Socket factory may not be null");
   125         }
   126         if ((port <= 0) || (port > 0xffff)) {
   127             throw new IllegalArgumentException
   128                 ("Port is invalid: " + port);
   129         }
   131         this.name = name.toLowerCase(Locale.ENGLISH);
   132         if (factory instanceof LayeredSocketFactory) {
   133             this.socketFactory = new LayeredSchemeSocketFactoryAdaptor(
   134                     (LayeredSocketFactory) factory);
   135             this.layered = true;
   136         } else {
   137             this.socketFactory = new SchemeSocketFactoryAdaptor(factory);
   138             this.layered = false;
   139         }
   140         this.defaultPort = port;
   141     }
   143     /**
   144      * Obtains the default port.
   145      *
   146      * @return  the default port for this scheme
   147      */
   148     public final int getDefaultPort() {
   149         return defaultPort;
   150     }
   153     /**
   154      * Obtains the socket factory.
   155      * If this scheme is {@link #isLayered layered}, the factory implements
   156      * {@link LayeredSocketFactory LayeredSocketFactory}.
   157      *
   158      * @return  the socket factory for this scheme
   159      *
   160      * @deprecated Use {@link #getSchemeSocketFactory()}
   161      */
   162     @Deprecated
   163     public final SocketFactory getSocketFactory() {
   164         if (this.socketFactory instanceof SchemeSocketFactoryAdaptor) {
   165             return ((SchemeSocketFactoryAdaptor) this.socketFactory).getFactory();
   166         } else {
   167             if (this.layered) {
   168                 return new LayeredSocketFactoryAdaptor(
   169                         (LayeredSchemeSocketFactory) this.socketFactory);
   170             } else {
   171                 return new SocketFactoryAdaptor(this.socketFactory);
   172             }
   173         }
   174     }
   176     /**
   177      * Obtains the socket factory.
   178      * If this scheme is {@link #isLayered layered}, the factory implements
   179      * {@link LayeredSocketFactory LayeredSchemeSocketFactory}.
   180      *
   181      * @return  the socket factory for this scheme
   182      *
   183      * @since 4.1
   184      */
   185     public final SchemeSocketFactory getSchemeSocketFactory() {
   186         return this.socketFactory;
   187     }
   189     /**
   190      * Obtains the scheme name.
   191      *
   192      * @return  the name of this scheme, in lowercase
   193      */
   194     public final String getName() {
   195         return name;
   196     }
   198     /**
   199      * Indicates whether this scheme allows for layered connections.
   200      *
   201      * @return <code>true</code> if layered connections are possible,
   202      *         <code>false</code> otherwise
   203      */
   204     public final boolean isLayered() {
   205         return layered;
   206     }
   208     /**
   209      * Resolves the correct port for this scheme.
   210      * Returns the given port if it is valid, the default port otherwise.
   211      *
   212      * @param port      the port to be resolved,
   213      *                  a negative number to obtain the default port
   214      *
   215      * @return the given port or the defaultPort
   216      */
   217     public final int resolvePort(int port) {
   218         return port <= 0 ? defaultPort : port;
   219     }
   221     /**
   222      * Return a string representation of this object.
   223      *
   224      * @return  a human-readable string description of this scheme
   225      */
   226     @Override
   227     public final String toString() {
   228         if (stringRep == null) {
   229             StringBuilder buffer = new StringBuilder();
   230             buffer.append(this.name);
   231             buffer.append(':');
   232             buffer.append(Integer.toString(this.defaultPort));
   233             stringRep = buffer.toString();
   234         }
   235         return stringRep;
   236     }
   238     @Override
   239     public final boolean equals(Object obj) {
   240         if (this == obj) return true;
   241         if (obj instanceof Scheme) {
   242             Scheme that = (Scheme) obj;
   243             return this.name.equals(that.name)
   244                 && this.defaultPort == that.defaultPort
   245                 && this.layered == that.layered;
   246         } else {
   247             return false;
   248         }
   249     }
   251     @Override
   252     public int hashCode() {
   253         int hash = LangUtils.HASH_SEED;
   254         hash = LangUtils.hashCode(hash, this.defaultPort);
   255         hash = LangUtils.hashCode(hash, this.name);
   256         hash = LangUtils.hashCode(hash, this.layered);
   257         return hash;
   258     }
   260 }

mercurial