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     /** @hide Visible for testing only */
setDefault(SocketFactory factory)108     public static void setDefault(SocketFactory factory) {
109         synchronized (SocketFactory.class) {
110             theFactory = factory;
111         }
112     }
113 
114 
115     /**
116      * Creates an unconnected socket.
117      *
118      * @return the unconnected socket
119      * @throws IOException if the socket cannot be created
120      * @see java.net.Socket#connect(java.net.SocketAddress)
121      * @see java.net.Socket#connect(java.net.SocketAddress, int)
122      * @see java.net.Socket#Socket()
123      */
createSocket()124     public Socket createSocket() throws IOException {
125         //
126         // bug 6771432:
127         // The Exception is used by HttpsClient to signal that
128         // unconnected sockets have not been implemented.
129         //
130         UnsupportedOperationException uop = new
131                 UnsupportedOperationException();
132         SocketException se =  new SocketException(
133                 "Unconnected sockets not implemented");
134         se.initCause(uop);
135         throw se;
136     }
137 
138 
139     /**
140      * Creates a socket and connects it to the specified remote host
141      * at the specified remote port.  This socket is configured using
142      * the socket options established for this factory.
143      * <p>
144      * If there is a security manager, its <code>checkConnect</code>
145      * method is called with the host address and <code>port</code>
146      * as its arguments. This could result in a SecurityException.
147      *
148      * @param host the server host name with which to connect, or
149      *        <code>null</code> for the loopback address.
150      * @param port the server port
151      * @return the <code>Socket</code>
152      * @throws IOException if an I/O error occurs when creating the socket
153      * @throws SecurityException if a security manager exists and its
154      *         <code>checkConnect</code> method doesn't allow the operation.
155      * @throws UnknownHostException if the host is not known
156      * @throws IllegalArgumentException if the port parameter is outside the
157      *         specified range of valid port values, which is between 0 and
158      *         65535, inclusive.
159      * @see SecurityManager#checkConnect
160      * @see java.net.Socket#Socket(String, int)
161      */
createSocket(String host, int port)162     public abstract Socket createSocket(String host, int port)
163     throws IOException, UnknownHostException;
164 
165 
166     /**
167      * Creates a socket and connects it to the specified remote host
168      * on the specified remote port.
169      * The socket will also be bound to the local address and port supplied.
170      * This socket is configured using
171      * the socket options established for this factory.
172      * <p>
173      * If there is a security manager, its <code>checkConnect</code>
174      * method is called with the host address and <code>port</code>
175      * as its arguments. This could result in a SecurityException.
176      *
177      * @param host the server host name with which to connect, or
178      *        <code>null</code> for the loopback address.
179      * @param port the server port
180      * @param localHost the local address the socket is bound to
181      * @param localPort the local port the socket is bound to
182      * @return the <code>Socket</code>
183      * @throws IOException if an I/O error occurs when creating the socket
184      * @throws SecurityException if a security manager exists and its
185      *         <code>checkConnect</code> method doesn't allow the operation.
186      * @throws UnknownHostException if the host is not known
187      * @throws IllegalArgumentException if the port parameter or localPort
188      *         parameter is outside the specified range of valid port values,
189      *         which is between 0 and 65535, inclusive.
190      * @see SecurityManager#checkConnect
191      * @see java.net.Socket#Socket(String, int, java.net.InetAddress, int)
192      */
193     public abstract Socket
createSocket(String host, int port, InetAddress localHost, int localPort)194     createSocket(String host, int port, InetAddress localHost, int localPort)
195     throws IOException, UnknownHostException;
196 
197 
198     /**
199      * Creates a socket and connects it to the specified port number
200      * at the specified address.  This socket is configured using
201      * the socket options established for this factory.
202      * <p>
203      * If there is a security manager, its <code>checkConnect</code>
204      * method is called with the host address and <code>port</code>
205      * as its arguments. This could result in a SecurityException.
206      *
207      * @param host the server host
208      * @param port the server port
209      * @return the <code>Socket</code>
210      * @throws IOException if an I/O error occurs when creating the socket
211      * @throws SecurityException if a security manager exists and its
212      *         <code>checkConnect</code> method doesn't allow the operation.
213      * @throws IllegalArgumentException if the port parameter is outside the
214      *         specified range of valid port values, which is between 0 and
215      *         65535, inclusive.
216      * @throws NullPointerException if <code>host</code> is null.
217      * @see SecurityManager#checkConnect
218      * @see java.net.Socket#Socket(java.net.InetAddress, int)
219      */
createSocket(InetAddress host, int port)220     public abstract Socket createSocket(InetAddress host, int port)
221     throws IOException;
222 
223 
224     /**
225      * Creates a socket and connect it to the specified remote address
226      * on the specified remote port.  The socket will also be bound
227      * to the local address and port suplied.  The socket is configured using
228      * the socket options established for this factory.
229      * <p>
230      * If there is a security manager, its <code>checkConnect</code>
231      * method is called with the host address and <code>port</code>
232      * as its arguments. This could result in a SecurityException.
233      *
234      * @param address the server network address
235      * @param port the server port
236      * @param localAddress the client network address
237      * @param localPort the client port
238      * @return the <code>Socket</code>
239      * @throws IOException if an I/O error occurs when creating the socket
240      * @throws SecurityException if a security manager exists and its
241      *         <code>checkConnect</code> method doesn't allow the operation.
242      * @throws IllegalArgumentException if the port parameter or localPort
243      *         parameter is outside the specified range of valid port values,
244      *         which is between 0 and 65535, inclusive.
245      * @throws NullPointerException if <code>address</code> is null.
246      * @see SecurityManager#checkConnect
247      * @see java.net.Socket#Socket(java.net.InetAddress, int,
248      *     java.net.InetAddress, int)
249      */
250     public abstract Socket
createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)251     createSocket(InetAddress address, int port,
252         InetAddress localAddress, int localPort)
253     throws IOException;
254 }
255 
256 
257 //
258 // The default factory has NO intelligence about policies like tunneling
259 // out through firewalls (e.g. SOCKS V4 or V5) or in through them
260 // (e.g. using SSL), or that some ports are reserved for use with SSL.
261 //
262 // Note that at least JDK 1.1 has a low level "plainSocketImpl" that
263 // knows about SOCKS V4 tunneling, so this isn't a totally bogus default.
264 //
265 // ALSO:  we may want to expose this class somewhere so other folk
266 // can reuse it, particularly if we start to add highly useful features
267 // such as ability to set connect timeouts.
268 //
269 class DefaultSocketFactory extends SocketFactory {
270 
createSocket()271     public Socket createSocket() {
272         return new Socket();
273     }
274 
createSocket(String host, int port)275     public Socket createSocket(String host, int port)
276     throws IOException, UnknownHostException
277     {
278         return new Socket(host, port);
279     }
280 
createSocket(InetAddress address, int port)281     public Socket createSocket(InetAddress address, int port)
282     throws IOException
283     {
284         return new Socket(address, port);
285     }
286 
createSocket(String host, int port, InetAddress clientAddress, int clientPort)287     public Socket createSocket(String host, int port,
288         InetAddress clientAddress, int clientPort)
289     throws IOException, UnknownHostException
290     {
291         return new Socket(host, port, clientAddress, clientPort);
292     }
293 
createSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort)294     public Socket createSocket(InetAddress address, int port,
295         InetAddress clientAddress, int clientPort)
296     throws IOException
297     {
298         return new Socket(address, port, clientAddress, clientPort);
299     }
300 }
301