KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jsch > internal > core > ResponsiveSocketFactory


1 /*******************************************************************************
2  * Copyright (c) 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jsch.internal.core;
12
13 import java.io.*;
14 import java.lang.reflect.*;
15 import java.net.*;
16
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.osgi.util.NLS;
19
20 import com.jcraft.jsch.SocketFactory;
21
22 public class ResponsiveSocketFactory implements SocketFactory {
23   private static final String JavaDoc JAVA_NET_PROXY="java.net.Proxy"; //$NON-NLS-1$
24
private static final int DEFAULT_TIMEOUT=60; // Seconds
25
InputStream in = null;
26   OutputStream out = null;
27   private IProgressMonitor monitor;
28   private final int timeout;
29   private static Class JavaDoc proxyClass;
30   private static boolean hasProxyClass = true;
31   public ResponsiveSocketFactory(IProgressMonitor monitor, int timeout) {
32     if (monitor == null)
33       monitor = new NullProgressMonitor();
34     this.monitor = monitor;
35     this.timeout=timeout;
36   }
37   public InputStream getInputStream(Socket socket) throws IOException {
38     if (in == null)
39       in = socket.getInputStream();
40     return in;
41   }
42   public OutputStream getOutputStream(Socket socket) throws IOException {
43     if (out == null)
44       out = socket.getOutputStream();
45     return out;
46   }
47   public Socket createSocket(String JavaDoc host, int port) throws IOException, UnknownHostException {
48     Socket socket = null;
49     socket = createSocket(host, port, timeout / 1000, monitor);
50     // Null out the monitor so we don't hold onto anything
51
// (i.e. the SSH2 session will keep a handle to the socket factory around
52
monitor = new NullProgressMonitor();
53     // Set the socket timeout
54
socket.setSoTimeout(timeout);
55     return socket;
56   }
57   
58   /**
59    * Helper method that will time out when making a socket connection.
60    * This is required because there is no way to provide a timeout value
61    * when creating a socket and in some instances, they don't seem to
62    * timeout at all.
63    */

64   private Socket createSocket(final String JavaDoc host, final int port, int timeout, IProgressMonitor monitor) throws UnknownHostException, IOException {
65     
66     // Start a thread to open a socket
67
final Socket[] socket = new Socket[] { null };
68     final Exception JavaDoc[] exception = new Exception JavaDoc[] {null };
69     final Thread JavaDoc thread = new Thread JavaDoc(new Runnable JavaDoc() {
70       public void run() {
71         try {
72           Socket newSocket = internalCreateSocket(host, port);
73           synchronized (socket) {
74             if (Thread.interrupted()) {
75               // we we're either canceled or timed out so just close the socket
76
newSocket.close();
77             } else {
78               socket[0] = newSocket;
79             }
80           }
81         } catch (UnknownHostException e) {
82           exception[0] = e;
83         } catch (IOException e) {
84           exception[0] = e;
85         }
86       }
87     });
88     thread.start();
89     
90     // Wait the appropriate number of seconds
91
if (timeout == 0) timeout = DEFAULT_TIMEOUT;
92     for (int i = 0; i < timeout; i++) {
93       try {
94         // wait for the thread to complete or 1 second, which ever comes first
95
thread.join(1000);
96       } catch (InterruptedException JavaDoc e) {
97         // I think this means the thread was interrupted but not necessarily timed out
98
// so we don't need to do anything
99
}
100       synchronized (socket) {
101         // if the user canceled, clean up before preempting the operation
102
if (monitor.isCanceled()) {
103           if (thread.isAlive()) {
104             thread.interrupt();
105           }
106           if (socket[0] != null) {
107             socket[0].close();
108           }
109           // this method will throw the proper exception
110
Policy.checkCanceled(monitor);
111         }
112       }
113     }
114     // If the thread is still running (i.e. we timed out) signal that it is too late
115
synchronized (socket) {
116       if (thread.isAlive()) {
117         thread.interrupt();
118       }
119     }
120     if (exception[0] != null) {
121       if (exception[0] instanceof UnknownHostException)
122         throw (UnknownHostException)exception[0];
123       else
124         throw (IOException)exception[0];
125     }
126     if (socket[0] == null) {
127       throw new InterruptedIOException(NLS.bind(Messages.Util_timeout, new String JavaDoc[] { host }));
128     }
129     return socket[0];
130   }
131   
132   /* private */ Socket internalCreateSocket(final String JavaDoc host, final int port)
133       throws UnknownHostException, IOException{
134     Class JavaDoc proxyClass = getProxyClass();
135     if (proxyClass != null) {
136       // We need to disable proxy support for the socket
137
try{
138         
139         // Obtain the value of the NO_PROXY static field of the proxy class
140
Field field = proxyClass.getField("NO_PROXY"); //$NON-NLS-1$
141
Object JavaDoc noProxyObject = field.get(null);
142         Constructor constructor = Socket.class.getConstructor(new Class JavaDoc[] { proxyClass });
143         Object JavaDoc o = constructor.newInstance(new Object JavaDoc[] { noProxyObject });
144         if(o instanceof Socket){
145           Socket socket=(Socket)o;
146           socket.connect(new InetSocketAddress(host, port), timeout * 1000);
147           return socket;
148         }
149       }
150       catch(SecurityException JavaDoc e){
151         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
152
}
153       catch(NoSuchFieldException JavaDoc e){
154         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
155
}
156       catch(IllegalArgumentException JavaDoc e){
157         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
158
}
159       catch(IllegalAccessException JavaDoc e){
160         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
161
}
162       catch(NoSuchMethodException JavaDoc e){
163         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
164
}
165       catch(InstantiationException JavaDoc e){
166         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
167
}
168       catch(InvocationTargetException e){
169         JSchCorePlugin.log(IStatus.ERROR, NLS.bind("An internal error occurred while connecting to {0}", host), e); //$NON-NLS-1$
170
}
171       
172     }
173     return new Socket(host, port);
174   }
175   
176   private synchronized Class JavaDoc getProxyClass() {
177     if (hasProxyClass && proxyClass == null) {
178       try{
179         proxyClass = Class.forName(JAVA_NET_PROXY);
180       }
181       catch(ClassNotFoundException JavaDoc e){
182         // We couldn't find the class so we'll assume we are using pre-1.5 JRE
183
hasProxyClass = false;
184       }
185     }
186     return proxyClass;
187   }
188
189 }
190
Popular Tags