KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > protocol > ReflectionSocketFactory


1 /*
2  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/protocol/ReflectionSocketFactory.java,v 1.4 2004/12/21 23:15:21 olegk Exp $
3  * $Revision: 480424 $
4  * $Date: 2006-11-29 05:56:49 +0000 (Wed, 29 Nov 2006) $
5  *
6  * ====================================================================
7  *
8  * Licensed to the Apache Software Foundation (ASF) under one or more
9  * contributor license agreements. See the NOTICE file distributed with
10  * this work for additional information regarding copyright ownership.
11  * The ASF licenses this file to You under the Apache License, Version 2.0
12  * (the "License"); you may not use this file except in compliance with
13  * the License. You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * ====================================================================
23  *
24  * This software consists of voluntary contributions made by many
25  * individuals on behalf of the Apache Software Foundation. For more
26  * information on the Apache Software Foundation, please see
27  * <http://www.apache.org/>.
28  *
29  */

30
31 package org.apache.commons.httpclient.protocol;
32
33 import java.io.IOException JavaDoc;
34 import java.lang.reflect.Constructor JavaDoc;
35 import java.lang.reflect.InvocationTargetException JavaDoc;
36 import java.lang.reflect.Method JavaDoc;
37 import java.net.InetAddress JavaDoc;
38 import java.net.Socket JavaDoc;
39 import java.net.UnknownHostException JavaDoc;
40
41 import org.apache.commons.httpclient.ConnectTimeoutException;
42
43 /**
44  * This helper class uses refelction in order to execute Socket methods
45  * available in Java 1.4 and above
46  *
47  * @author Oleg Kalnichevski
48  *
49  * @since 3.0
50  */

51 public final class ReflectionSocketFactory {
52
53     private static boolean REFLECTION_FAILED = false;
54     
55     private static Constructor JavaDoc INETSOCKETADDRESS_CONSTRUCTOR = null;
56     private static Method JavaDoc SOCKETCONNECT_METHOD = null;
57     private static Method JavaDoc SOCKETBIND_METHOD = null;
58     private static Class JavaDoc SOCKETTIMEOUTEXCEPTION_CLASS = null;
59
60     private ReflectionSocketFactory() {
61         super();
62     }
63
64     /**
65      * This method attempts to execute Socket method available since Java 1.4
66      * using reflection. If the methods are not available or could not be executed
67      * <tt>null</tt> is returned
68      *
69      * @param socketfactoryName name of the socket factory class
70      * @param host the host name/IP
71      * @param port the port on the host
72      * @param localAddress the local host name/IP to bind the socket to
73      * @param localPort the port on the local machine
74      * @param timeout the timeout value to be used in milliseconds. If the socket cannot be
75      * completed within the given time limit, it will be abandoned
76      *
77      * @return a connected Socket
78      *
79      * @throws IOException if an I/O error occurs while creating the socket
80      * @throws UnknownHostException if the IP address of the host cannot be
81      * determined
82      * @throws ConnectTimeoutException if socket cannot be connected within the
83      * given time limit
84      *
85      */

86     public static Socket JavaDoc createSocket(
87         final String JavaDoc socketfactoryName,
88         final String JavaDoc host,
89         final int port,
90         final InetAddress JavaDoc localAddress,
91         final int localPort,
92         int timeout)
93      throws IOException JavaDoc, UnknownHostException JavaDoc, ConnectTimeoutException
94     {
95         if (REFLECTION_FAILED) {
96             //This is known to have failed before. Do not try it again
97
return null;
98         }
99         // This code uses reflection to essentially do the following:
100
//
101
// SocketFactory socketFactory = Class.forName(socketfactoryName).getDefault();
102
// Socket socket = socketFactory.createSocket();
103
// SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
104
// SocketAddress remoteaddr = new InetSocketAddress(host, port);
105
// socket.bind(localaddr);
106
// socket.connect(remoteaddr, timeout);
107
// return socket;
108
try {
109             Class JavaDoc socketfactoryClass = Class.forName(socketfactoryName);
110             Method JavaDoc method = socketfactoryClass.getMethod("getDefault",
111                 new Class JavaDoc[] {});
112             Object JavaDoc socketfactory = method.invoke(null,
113                 new Object JavaDoc[] {});
114             method = socketfactoryClass.getMethod("createSocket",
115                 new Class JavaDoc[] {});
116             Socket JavaDoc socket = (Socket JavaDoc) method.invoke(socketfactory, new Object JavaDoc[] {});
117             
118             if (INETSOCKETADDRESS_CONSTRUCTOR == null) {
119                 Class JavaDoc addressClass = Class.forName("java.net.InetSocketAddress");
120                 INETSOCKETADDRESS_CONSTRUCTOR = addressClass.getConstructor(
121                     new Class JavaDoc[] { InetAddress JavaDoc.class, Integer.TYPE });
122             }
123                 
124             Object JavaDoc remoteaddr = INETSOCKETADDRESS_CONSTRUCTOR.newInstance(
125                 new Object JavaDoc[] { InetAddress.getByName(host), new Integer JavaDoc(port)});
126
127             Object JavaDoc localaddr = INETSOCKETADDRESS_CONSTRUCTOR.newInstance(
128                     new Object JavaDoc[] { localAddress, new Integer JavaDoc(localPort)});
129
130             if (SOCKETCONNECT_METHOD == null) {
131                 SOCKETCONNECT_METHOD = Socket JavaDoc.class.getMethod("connect",
132                     new Class JavaDoc[] {Class.forName("java.net.SocketAddress"), Integer.TYPE});
133             }
134
135             if (SOCKETBIND_METHOD == null) {
136                 SOCKETBIND_METHOD = Socket JavaDoc.class.getMethod("bind",
137                     new Class JavaDoc[] {Class.forName("java.net.SocketAddress")});
138             }
139             SOCKETBIND_METHOD.invoke(socket, new Object JavaDoc[] { localaddr});
140             SOCKETCONNECT_METHOD.invoke(socket, new Object JavaDoc[] { remoteaddr, new Integer JavaDoc(timeout)});
141             return socket;
142         }
143         catch (InvocationTargetException JavaDoc e) {
144             Throwable JavaDoc cause = e.getTargetException();
145             if (SOCKETTIMEOUTEXCEPTION_CLASS == null) {
146                 try {
147                     SOCKETTIMEOUTEXCEPTION_CLASS = Class.forName("java.net.SocketTimeoutException");
148                 } catch (ClassNotFoundException JavaDoc ex) {
149                     // At this point this should never happen. Really.
150
REFLECTION_FAILED = true;
151                     return null;
152                 }
153             }
154             if (SOCKETTIMEOUTEXCEPTION_CLASS.isInstance(cause)) {
155                 throw new ConnectTimeoutException(
156                     "The host did not accept the connection within timeout of "
157                     + timeout + " ms", cause);
158             }
159             if (cause instanceof IOException JavaDoc) {
160                 throw (IOException JavaDoc)cause;
161             }
162             return null;
163         }
164         catch (Exception JavaDoc e) {
165             REFLECTION_FAILED = true;
166             return null;
167         }
168     }
169 }
170
Popular Tags