KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > util > 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.team.internal.ccvs.core.util;
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 import org.eclipse.team.internal.ccvs.core.*;
20
21 import com.jcraft.jsch.SocketFactory;
22
23 /**
24  * Class copied from "org.eclipse.jsch.internal.core"
25  */

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

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