1 /*
   2  * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.net;
  27 
  28 /**
  29  * This class represents a proxy setting, typically a type (http, socks) and
  30  * a socket address.
  31  * A <code>Proxy</code> is an immutable object.
  32  *
  33  * @see     java.net.ProxySelector
  34  * @author Yingxian Wang
  35  * @author Jean-Christophe Collet
  36  * @since   1.5
  37  */
  38 public class Proxy {
  39 
  40     /**
  41      * Represents the proxy type.
  42      *
  43      * @since 1.5
  44      */
  45     public enum Type {
  46         /**
  47          * Represents a direct connection, or the absence of a proxy.
  48          */
  49         DIRECT,
  50         /**
  51          * Represents proxy for high level protocols such as HTTP or FTP.
  52          */
  53         HTTP,
  54         /**
  55          * Represents a SOCKS (V4 or V5) proxy.
  56          */
  57         SOCKS
  58     };
  59 
  60     private Type type;
  61     private SocketAddress sa;
  62 
  63     /**
  64      * A proxy setting that represents a <code>DIRECT</code> connection,
  65      * basically telling the protocol handler not to use any proxying.
  66      * Used, for instance, to create sockets bypassing any other global
  67      * proxy settings (like SOCKS):
  68      * <P>
  69      * <code>Socket s = new Socket(Proxy.NO_PROXY);</code><br>
  70      * <P>
  71      */
  72     public final static Proxy NO_PROXY = new Proxy();
  73 
  74     // Creates the proxy that represents a <code>DIRECT</code> connection.
  75     private Proxy() {
  76         type = type.DIRECT;
  77         sa = null;
  78     }
  79 
  80     /**
  81      * Creates an entry representing a PROXY connection.
  82      * Certain combinations are illegal. For instance, for types Http, and
  83      * Socks, a SocketAddress <b>must</b> be provided.
  84      * <P>
  85      * Use the <code>Proxy.NO_PROXY</code> constant
  86      * for representing a direct connection.
  87      *
  88      * @param type the <code>Type</code> of the proxy
  89      * @param sa the <code>SocketAddress</code> for that proxy
  90      * @throws IllegalArgumentException when the type and the address are
  91      * incompatible
  92      */
  93     public Proxy(Type type, SocketAddress sa) {
  94         if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress))
  95             throw new IllegalArgumentException("type " + type + " is not compatible with address " + sa);
  96         this.type = type;
  97         this.sa = sa;
  98     }
  99 
 100     /**
 101      * Returns the proxy type.
 102      *
 103      * @return a Type representing the proxy type
 104      */
 105     public Type type() {
 106         return type;
 107     }
 108 
 109     /**
 110      * Returns the socket address of the proxy, or
 111      * <code>null</code> if its a direct connection.
 112      *
 113      * @return a <code>SocketAddress</code> representing the socket end
 114      *         point of the proxy
 115      */
 116     public SocketAddress address() {
 117         return sa;
 118     }
 119 
 120     /**
 121      * Constructs a string representation of this Proxy.
 122      * This String is constructed by calling toString() on its type
 123      * and concatenating " @ " and the toString() result from its address
 124      * if its type is not <code>DIRECT</code>.
 125      *
 126      * @return  a string representation of this object.
 127      */
 128     public String toString() {
 129         if (type() == Type.DIRECT)
 130             return "DIRECT";
 131         return type() + " @ " + address();
 132     }
 133 
 134         /**
 135      * Compares this object against the specified object.
 136      * The result is <code>true</code> if and only if the argument is
 137      * not <code>null</code> and it represents the same proxy as
 138      * this object.
 139      * <p>
 140      * Two instances of <code>Proxy</code> represent the same
 141      * address if both the SocketAddresses and type are equal.
 142      *
 143      * @param   obj   the object to compare against.
 144      * @return  <code>true</code> if the objects are the same;
 145      *          <code>false</code> otherwise.
 146      * @see java.net.InetSocketAddress#equals(java.lang.Object)
 147      */
 148     public final boolean equals(Object obj) {
 149         if (obj == null || !(obj instanceof Proxy))
 150             return false;
 151         Proxy p = (Proxy) obj;
 152         if (p.type() == type()) {
 153             if (address() == null) {
 154                 return (p.address() == null);
 155             } else
 156                 return address().equals(p.address());
 157         }
 158         return false;
 159     }
 160 
 161     /**
 162      * Returns a hashcode for this Proxy.
 163      *
 164      * @return  a hash code value for this Proxy.
 165      */
 166     public final int hashCode() {
 167         if (address() == null)
 168             return type().hashCode();
 169         return type().hashCode() + address().hashCode();
 170     }
 171 }