1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.apache.commons.httpclient.protocol;
32
33 import java.io.IOException;
34 import java.net.InetAddress;
35 import java.net.Socket;
36 import java.net.UnknownHostException;
37
38 import org.apache.commons.httpclient.ConnectTimeoutException;
39 import org.apache.commons.httpclient.params.HttpConnectionParams;
40
41 /***
42 * The default class for creating protocol sockets. This class just uses the
43 * {@link java.net.Socket socket} constructors.
44 *
45 * @author Michael Becke
46 *
47 * @since 2.0
48 */
49 public class DefaultProtocolSocketFactory implements ProtocolSocketFactory {
50
51 /***
52 * The factory singleton.
53 */
54 private static final DefaultProtocolSocketFactory factory = new DefaultProtocolSocketFactory();
55
56 /***
57 * Gets an singleton instance of the DefaultProtocolSocketFactory.
58 * @return a DefaultProtocolSocketFactory
59 */
60 static DefaultProtocolSocketFactory getSocketFactory() {
61 return factory;
62 }
63
64 /***
65 * Constructor for DefaultProtocolSocketFactory.
66 */
67 public DefaultProtocolSocketFactory() {
68 super();
69 }
70
71 /***
72 * @see #createSocket(java.lang.String,int,java.net.InetAddress,int)
73 */
74 public Socket createSocket(
75 String host,
76 int port,
77 InetAddress localAddress,
78 int localPort
79 ) throws IOException, UnknownHostException {
80 return new Socket(host, port, localAddress, localPort);
81 }
82
83 /***
84 * Attempts to get a new socket connection to the given host within the given time limit.
85 * <p>
86 * This method employs several techniques to circumvent the limitations of older JREs that
87 * do not support connect timeout. When running in JRE 1.4 or above reflection is used to
88 * call Socket#connect(SocketAddress endpoint, int timeout) method. When executing in older
89 * JREs a controller thread is executed. The controller thread attempts to create a new socket
90 * within the given limit of time. If socket constructor does not return until the timeout
91 * expires, the controller terminates and throws an {@link ConnectTimeoutException}
92 * </p>
93 *
94 * @param host the host name/IP
95 * @param port the port on the host
96 * @param localAddress the local host name/IP to bind the socket to
97 * @param localPort the port on the local machine
98 * @param params {@link HttpConnectionParams Http connection parameters}
99 *
100 * @return Socket a new socket
101 *
102 * @throws IOException if an I/O error occurs while creating the socket
103 * @throws UnknownHostException if the IP address of the host cannot be
104 * determined
105 * @throws ConnectTimeoutException if socket cannot be connected within the
106 * given time limit
107 *
108 * @since 3.0
109 */
110 public Socket createSocket(
111 final String host,
112 final int port,
113 final InetAddress localAddress,
114 final int localPort,
115 final HttpConnectionParams params
116 ) throws IOException, UnknownHostException, ConnectTimeoutException {
117 if (params == null) {
118 throw new IllegalArgumentException("Parameters may not be null");
119 }
120 int timeout = params.getConnectionTimeout();
121 if (timeout == 0) {
122 return createSocket(host, port, localAddress, localPort);
123 } else {
124
125 Socket socket = ReflectionSocketFactory.createSocket(
126 "javax.net.SocketFactory", host, port, localAddress, localPort, timeout);
127 if (socket == null) {
128 socket = ControllerThreadSocketFactory.createSocket(
129 this, host, port, localAddress, localPort, timeout);
130 }
131 return socket;
132 }
133 }
134
135 /***
136 * @see ProtocolSocketFactory#createSocket(java.lang.String,int)
137 */
138 public Socket createSocket(String host, int port)
139 throws IOException, UnknownHostException {
140 return new Socket(host, port);
141 }
142
143 /***
144 * All instances of DefaultProtocolSocketFactory are the same.
145 */
146 public boolean equals(Object obj) {
147 return ((obj != null) && obj.getClass().equals(getClass()));
148 }
149
150 /***
151 * All instances of DefaultProtocolSocketFactory have the same hash code.
152 */
153 public int hashCode() {
154 return getClass().hashCode();
155 }
156
157 }