1 /*
2  * Copyright (c) 1997, 2010, 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 
27 package javax.net;
28 
29 import java.io.IOException;
30 import java.net.InetAddress;
31 import java.net.Socket;
32 import java.net.SocketException;
33 import java.net.UnknownHostException;
34 
35 /**
36  * This class creates sockets.  It may be subclassed by other factories,
37  * which create particular subclasses of sockets and thus provide a general
38  * framework for the addition of public socket-level functionality.
39  *
40  * <P> Socket factories are a simple way to capture a variety of policies
41  * related to the sockets being constructed, producing such sockets in
42  * a way which does not require special configuration of the code which
43  * asks for the sockets:  <UL>
44  *
45  *      <LI> Due to polymorphism of both factories and sockets, different
46  *      kinds of sockets can be used by the same application code just
47  *      by passing it different kinds of factories.
48  *
49  *      <LI> Factories can themselves be customized with parameters used
50  *      in socket construction.  So for example, factories could be
51  *      customized to return sockets with different networking timeouts
52  *      or security parameters already configured.
53  *
54  *      <LI> The sockets returned to the application can be subclasses
55  *      of java.net.Socket, so that they can directly expose new APIs
56  *      for features such as compression, security, record marking,
57  *      statistics collection, or firewall tunneling.
58  *
59  *      </UL>
60  *
61  * <P> Factory classes are specified by environment-specific configuration
62  * mechanisms.  For example, the <em>getDefault</em> method could return
63  * a factory that was appropriate for a particular user or applet, and a
64  * framework could use a factory customized to its own purposes.
65  *
66  * @since 1.4
67  * @see ServerSocketFactory
68  *
69  * @author David Brownell
70  */
71 public abstract class SocketFactory
72 {
73     //
74     // NOTE:  JDK 1.1 bug in class GC, this can get collected
75     // even though it's always accessible via getDefault().
76     //
77     private static SocketFactory                theFactory;
78 
79     /**
80      * Creates a <code>SocketFactory</code>.
81      */
SocketFactory()82     protected SocketFactory() { /* NOTHING */ }
83 
84 
85     /**
86      * Returns a copy of the environment's default socket factory.
87      *
88      * @return the default <code>SocketFactory</code>
89      */
getDefault()90     public static SocketFactory getDefault()
91     {
92         synchronized (SocketFactory.class) {
93             if (theFactory == null) {
94                 //
95                 // Different implementations of this method SHOULD
96                 // work rather differently.  For example, driving
97                 // this from a system property, or using a different
98                 // implementation than JavaSoft's.
99                 //
100                 theFactory = new DefaultSocketFactory();
101             }
102         }
103 
104         return theFactory;
105     }
106 
107     // Android-added: Added method for testing default socket factory.
108     /** @hide Visible for testing only */
setDefault(SocketFactory factory)109     public static void setDefault(SocketFactory factory) {
110         synchronized (SocketFactory.class) {
111             theFactory = factory;
112         }
113     }
114 
115 
116     /**
117      * Creates an unconnected socket.
118      *
119      * @return the unconnected socket
120      * @throws IOException if the socket cannot be created
121      * @see java.net.Socket#connect(java.net.SocketAddress)
122      * @see java.net.Socket#connect(java.net.SocketAddress, int)
123      * @see java.net.Socket#Socket()
124      */
createSocket()125     public Socket createSocket() throws IOException {
126         //
127         // bug 6771432:
128         // The Exception is used by HttpsClient to signal that
129         // unconnected sockets have not been implemented.
130         //
131         UnsupportedOperationException uop = new
132                 UnsupportedOperationException();
133         SocketException se =  new SocketException(
134                 "Unconnected sockets not implemented");
135         se.initCause(uop);
136         throw se;
137     }
138 
139 
140     /**
141      * Creates a socket and connects it to the specified remote host
142      * at the specified remote port.  This socket is configured using
143      * the socket options established for this factory.
144      * <p>
145      * If there is a security manager, its <code>checkConnect</code>
146      * method is called with the host address and <code>port</code>
147      * as its arguments. This could result in a SecurityException.
148      *
149      * @param host the server host name with which to connect, or
150      *        <code>null</code> for the loopback address.
151      * @param port the server port
152      * @return the <code>Socket</code>
153      * @throws IOException if an I/O error occurs when creating the socket
154      * @throws SecurityException if a security manager exists and its
155      *         <code>checkConnect</code> method doesn't allow the operation.
156      * @throws UnknownHostException if the host is not known
157      * @throws IllegalArgumentException if the port parameter is outside the
158      *         specified range of valid port values, which is between 0 and
159      *         65535, inclusive.
160      * @see SecurityManager#checkConnect
161      * @see java.net.Socket#Socket(String, int)
162      */
createSocket(String host, int port)163     public abstract Socket createSocket(String host, int port)
164     throws IOException, UnknownHostException;
165 
166 
167     /**
168      * Creates a socket and connects it to the specified remote host
169      * on the specified remote port.
170      * The socket will also be bound to the local address and port supplied.
171      * This socket is configured using
172      * the socket options established for this factory.
173      * <p>
174      * If there is a security manager, its <code>checkConnect</code>
175      * method is called with the host address and <code>port</code>
176      * as its arguments. This could result in a SecurityException.
177      *
178      * @param host the server host name with which to connect, or
179      *        <code>null</code> for the loopback address.
180      * @param port the server port
181      * @param localHost the local address the socket is bound to
182      * @param localPort the local port the socket is bound to
183      * @return the <code>Socket</code>
184      * @throws IOException if an I/O error occurs when creating the socket
185      * @throws SecurityException if a security manager exists and its
186      *         <code>checkConnect</code> method doesn't allow the operation.
187      * @throws UnknownHostException if the host is not known
188      * @throws IllegalArgumentException if the port parameter or localPort
189      *         parameter is outside the specified range of valid port values,
190      *         which is between 0 and 65535, inclusive.
191      * @see SecurityManager#checkConnect
192      * @see java.net.Socket#Socket(String, int, java.net.InetAddress, int)
193      */
194     public abstract Socket
createSocket(String host, int port, InetAddress localHost, int localPort)195     createSocket(String host, int port, InetAddress localHost, int localPort)
196     throws IOException, UnknownHostException;
197 
198 
199     /**
200      * Creates a socket and connects it to the specified port number
201      * at the specified address.  This socket is configured using
202      * the socket options established for this factory.
203      * <p>
204      * If there is a security manager, its <code>checkConnect</code>
205      * method is called with the host address and <code>port</code>
206      * as its arguments. This could result in a SecurityException.
207      *
208      * @param host the server host
209      * @param port the server port
210      * @return the <code>Socket</code>
211      * @throws IOException if an I/O error occurs when creating the socket
212      * @throws SecurityException if a security manager exists and its
213      *         <code>checkConnect</code> method doesn't allow the operation.
214      * @throws IllegalArgumentException if the port parameter is outside the
215      *         specified range of valid port values, which is between 0 and
216      *         65535, inclusive.
217      * @throws NullPointerException if <code>host</code> is null.
218      * @see SecurityManager#checkConnect
219      * @see java.net.Socket#Socket(java.net.InetAddress, int)
220      */
createSocket(InetAddress host, int port)221     public abstract Socket createSocket(InetAddress host, int port)
222     throws IOException;
223 
224 
225     /**
226      * Creates a socket and connect it to the specified remote address
227      * on the specified remote port.  The socket will also be bound
228      * to the local address and port suplied.  The socket is configured using
229      * the socket options established for this factory.
230      * <p>
231      * If there is a security manager, its <code>checkConnect</code>
232      * method is called with the host address and <code>port</code>
233      * as its arguments. This could result in a SecurityException.
234      *
235      * @param address the server network address
236      * @param port the server port
237      * @param localAddress the client network address
238      * @param localPort the client port
239      * @return the <code>Socket</code>
240      * @throws IOException if an I/O error occurs when creating the socket
241      * @throws SecurityException if a security manager exists and its
242      *         <code>checkConnect</code> method doesn't allow the operation.
243      * @throws IllegalArgumentException if the port parameter or localPort
244      *         parameter is outside the specified range of valid port values,
245      *         which is between 0 and 65535, inclusive.
246      * @throws NullPointerException if <code>address</code> is null.
247      * @see SecurityManager#checkConnect
248      * @see java.net.Socket#Socket(java.net.InetAddress, int,
249      *     java.net.InetAddress, int)
250      */
251     public abstract Socket
createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)252     createSocket(InetAddress address, int port,
253         InetAddress localAddress, int localPort)
254     throws IOException;
255 }
256 
257 
258 //
259 // The default factory has NO intelligence about policies like tunneling
260 // out through firewalls (e.g. SOCKS V4 or V5) or in through them
261 // (e.g. using SSL), or that some ports are reserved for use with SSL.
262 //
263 // Note that at least JDK 1.1 has a low level "plainSocketImpl" that
264 // knows about SOCKS V4 tunneling, so this isn't a totally bogus default.
265 //
266 // ALSO:  we may want to expose this class somewhere so other folk
267 // can reuse it, particularly if we start to add highly useful features
268 // such as ability to set connect timeouts.
269 //
270 class DefaultSocketFactory extends SocketFactory {
271 
createSocket()272     public Socket createSocket() {
273         return new Socket();
274     }
275 
createSocket(String host, int port)276     public Socket createSocket(String host, int port)
277     throws IOException, UnknownHostException
278     {
279         return new Socket(host, port);
280     }
281 
createSocket(InetAddress address, int port)282     public Socket createSocket(InetAddress address, int port)
283     throws IOException
284     {
285         return new Socket(address, port);
286     }
287 
createSocket(String host, int port, InetAddress clientAddress, int clientPort)288     public Socket createSocket(String host, int port,
289         InetAddress clientAddress, int clientPort)
290     throws IOException, UnknownHostException
291     {
292         return new Socket(host, port, clientAddress, clientPort);
293     }
294 
createSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort)295     public Socket createSocket(InetAddress address, int port,
296         InetAddress clientAddress, int clientPort)
297     throws IOException
298     {
299         return new Socket(address, port, clientAddress, clientPort);
300     }
301 }
302