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