1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package java.net;
17 
18 /**
19  * This class represents proxy server settings. A created instance of {@code
20  * Proxy} stores a type and an address and is immutable. There are three types
21  * of proxies:
22  * <ul>
23  * <li>DIRECT</li>
24  * <li>HTTP</li>
25  * <li>SOCKS</li></ul
26  */
27 public class Proxy {
28 
29     /**
30      * Represents the proxy type setting {@code Proxy.Type.DIRECT}. It tells
31      * protocol handlers that there is no proxy to be used. The address is set
32      * to {@code null}.
33      */
34     public static final Proxy NO_PROXY = new Proxy();
35 
36     private Proxy.Type type;
37 
38     private SocketAddress address;
39 
40     /**
41      * Creates a new {@code Proxy} instance. {@code SocketAddress} must NOT be
42      * {@code null} when {@code type} is either {@code Proxy.Type.HTTP} or
43      * {@code Proxy.Type.SOCKS}. To create a {@code Proxy} instance representing
44      * the proxy type {@code Proxy.Type.DIRECT}, use {@code Proxy.NO_PROXY}
45      * instead of this constructor.
46      *
47      * @param type
48      *            the proxy type of this instance.
49      * @param sa
50      *            the proxy address of this instance.
51      * @throws IllegalArgumentException
52      *             if the parameter {@code type} is set to {@code
53      *             Proxy.Type.DIRECT} or the value for {@code SocketAddress} is
54      *             {@code null}.
55      */
Proxy(Proxy.Type type, SocketAddress sa)56     public Proxy(Proxy.Type type, SocketAddress sa) {
57         /*
58          * Don't use DIRECT type to construct a proxy instance directly.
59          * SocketAddress must NOT be null.
60          */
61         if (type == Type.DIRECT || sa == null) {
62             throw new IllegalArgumentException("Illegal Proxy.Type or SocketAddress argument");
63         }
64         this.type = type;
65         address = sa;
66     }
67 
68     /*
69      * Constructs a Proxy instance, which is Proxy.DIRECT type with null
70      * SocketAddress. This constructor is used for NO_PROXY.
71      */
Proxy()72     private Proxy() {
73         type = Type.DIRECT;
74         address = null;
75     }
76 
77     /**
78      * Gets the type of this {@code Proxy} instance.
79      *
80      * @return the stored proxy type.
81      */
type()82     public Proxy.Type type() {
83         return type;
84     }
85 
86     /**
87      * Gets the address of this {@code Proxy} instance.
88      *
89      * @return the stored proxy address or {@code null} if the proxy type is
90      *         {@code DIRECT}.
91      */
address()92     public SocketAddress address() {
93         return address;
94     }
95 
96     /**
97      * Gets a textual representation of this {@code Proxy} instance. The string
98      * includes the two parts {@code type.toString()} and {@code
99      * address.toString()} if {@code address} is not {@code null}.
100      *
101      * @return the representing string of this proxy.
102      */
103     @Override
toString()104     public String toString() {
105         StringBuilder builder = new StringBuilder();
106         if (type != null) {
107             builder.append(type.toString());
108         }
109         builder.append("@");
110         if (type != Proxy.Type.DIRECT && address != null) {
111             builder.append(address.toString());
112         }
113         return builder.toString();
114     }
115 
116     /**
117      * Compares the specified {@code obj} to this {@code Proxy} instance and
118      * returns whether they are equal or not. The given object must be an
119      * instance of {@code Proxy} with the same address and the same type value
120      * to be equal.
121      *
122      * @param obj
123      *            the object to compare with this instance.
124      * @return {@code true} if the given object represents the same {@code
125      *         Proxy} as this instance, {@code false} otherwise.
126      * @see #hashCode
127      */
128     @Override
equals(Object obj)129     public final boolean equals(Object obj) {
130         if (this == obj) {
131             return true;
132         }
133         if (!(obj instanceof Proxy)) {
134             return false;
135         }
136         Proxy another = (Proxy) obj;
137         // address is null when and only when it's NO_PROXY.
138         return (type == another.type) && address.equals(another.address);
139     }
140 
141     /**
142      * Gets the hashcode for this {@code Proxy} instance.
143      *
144      * @return the hashcode value for this Proxy instance.
145      */
146     @Override
hashCode()147     public final int hashCode() {
148         int ret = 0;
149         ret += type.hashCode();
150         if (address != null) {
151             ret += address.hashCode();
152         }
153         return ret;
154     }
155 
156     /**
157      * {@code Enum} class for the proxy type. Possible options are {@code
158      * DIRECT}, {@code HTTP} and {@code SOCKS}.
159      */
160     public enum Type {
161         /**
162          * Direct connection. Connect without any proxy.
163          */
164         DIRECT,
165 
166         /**
167          * HTTP type proxy. It's often used by protocol handlers such as HTTP,
168          * HTTPS and FTP.
169          */
170         HTTP,
171 
172         /**
173          * SOCKS type proxy.
174          */
175         SOCKS
176     }
177 }
178