View Javadoc

1   /*
2    * $HeadURL: $
3    * $Date: $
4    * $Revision: $
5    * $Author: $
6    * 
7    * Copyright (c) 2005 MindTree Consulting Ltd. 
8    * 
9    * This file is part of Insight.
10   * 
11   * Insight is free software: you can redistribute it and/or modify it under the 
12   * terms of the GNU General Public License as published by the Free Software 
13   * Foundation, either version 3 of the License, or (at your option) any later 
14   * version.
15   * 
16   * Insight is distributed in the hope that it will be useful, but 
17   * WITHOUT ANY WARRANTY; without even the implied warranty of 
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
19   * Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public License along with 
22   * Insight.  If not, see <http://www.gnu.org/licenses/>.
23   */
24  
25  package com.mindtree.techworks.insight.download;
26  
27  import java.io.File;
28  import java.io.FileNotFoundException;
29  import java.io.FileOutputStream;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.net.MalformedURLException;
33  import java.net.URL;
34  
35  import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
36  import org.apache.commons.httpclient.HostConfiguration;
37  import org.apache.commons.httpclient.HttpClient;
38  import org.apache.commons.httpclient.HttpException;
39  import org.apache.commons.httpclient.HttpStatus;
40  import org.apache.commons.httpclient.NTCredentials;
41  import org.apache.commons.httpclient.auth.AuthScope;
42  import org.apache.commons.httpclient.methods.GetMethod;
43  import org.apache.commons.httpclient.params.HttpMethodParams;
44  
45  import com.mindtree.techworks.insight.download.ProxyInfo.ProtocolProxyInfo;
46  import com.mindtree.techworks.insight.preferences.util.PreferenceInterpreter;
47  
48  
49  /**
50   * TODO
51   * 
52   * @see com.mindtree.techworks.insight.download.RemoteClient RemoteClient
53   * @author Bindul Bhowmik
54   * @version $Revision: 27 $ $Date: 2007-12-16 04:58:03 -0700 (Sun, 16 Dec 2007) $
55   */
56  public class HTTPRemoteClient extends RemoteClient {
57  
58  	//
59  	// Static block to register with the factory
60  	//
61  	static {
62  		// This class handles only HTTP filesets
63  		RemoteClientFactory.registerClient("HTTP_CLIENT",
64  				HTTPRemoteClient.class);
65  	}
66  
67  	//
68  	// Instance variables
69  	//
70  
71  	/**
72  	 * The HTTP fileset containing the host information
73  	 */
74  	private HTTPFileset fileset;
75  
76  	/**
77  	 * The HTTP Client used for the downloads
78  	 */
79  	private HttpClient httpClient;
80  
81  	//
82  	// Implemented abstract methods
83  	//
84  
85  	/**
86  	 * @see com.mindtree.techworks.insight.download.RemoteClient#setFileset(com.mindtree.techworks.insight.download.Fileset)
87  	 */
88  	protected void setFileset (Fileset fileset) throws RemoteClientException {
89  
90  		if (fileset.getType() != Fileset.HTTP_FILESET
91  				|| !(fileset instanceof HTTPFileset)) {
92  			throw new RemoteClientException(
93  					"This client can handle only HTTPFileset");
94  		}
95  		this.fileset = (HTTPFileset) fileset;
96  
97  		// Initialize the client
98  		initialize();
99  
100 	}
101 
102 	/**
103 	 * @see com.mindtree.techworks.insight.download.RemoteClient#downloadFile(java.lang.String)
104 	 */
105 	/*
106 	 * Return type chaged to String[] from String in synchronization with RemoteClient
107 	 */
108 	protected String[] downloadFile (String fileName)
109 			throws RemoteClientException {
110 
111 		// System is busy
112 		isBusy = true;
113 
114 		// Get the temporary file
115 		File destinationFile = null;
116 		FileOutputStream fos = null;
117 		InputStream is = null;
118 
119 		// Set authentication if required
120 		setAuthorization(fileName);
121 
122 		// Get the destination file
123 		try {
124 			destinationFile = getDestinationFile(fileName, '/');
125 			fos = new FileOutputStream(destinationFile);
126 		} catch (FileNotFoundException e) {
127 			// Should never get here...
128 			throw new RemoteClientException(
129 					"Could not write to temporary file.", e);
130 		} catch (IOException e) {
131 			throw new RemoteClientException("Could not create temporary file.",
132 					e);
133 		}
134 
135 		// Get the method
136 		GetMethod getMethod = new GetMethod(fileName);
137 
138 		// Retry logic
139 		DefaultHttpMethodRetryHandler retryHandler = new DefaultHttpMethodRetryHandler(0, false);
140 		httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);
141 
142 		try {
143 			// Execute
144 			int statusCode = httpClient.executeMethod(getMethod);
145 
146 			// Check the status code
147 			if (statusCode != HttpStatus.SC_OK) {
148 				throw new RemoteClientException(
149 						"Could not complete HTTP GET : "
150 								+ getMethod.getStatusLine());
151 			}
152 
153 			is = getMethod.getResponseBodyAsStream();
154 			int byteToRead;
155 			byteToRead = is.read();
156 			while (byteToRead != -1) {
157 				fos.write(byteToRead);
158 				byteToRead = is.read();
159 			}
160 
161 		} catch (HttpException e) {
162 			throw new RemoteClientException("Could not complete HTTP GET : "
163 					+ e.getMessage(), e);
164 		} catch (IOException e) {
165 			throw new RemoteClientException("Could not complete HTTP GET : "
166 					+ e.getMessage(), e);
167 		} finally {
168 			getMethod.releaseConnection();
169 			try {
170 				fos.close();
171 			} catch (IOException ioe) {
172 				// Cannot do anything here!
173 				ioe.printStackTrace(System.err);
174 			}
175 			try {
176 				if (null != is) {
177 					is.close();
178 				}
179 			} catch (IOException ioe) {
180 				// Cannot do anything here!
181 				ioe.printStackTrace(System.err);
182 			}
183 			isBusy = false;
184 		}
185 		/*
186 		 * Changed in support of wild cards. The new downloaded file set is returned as an array of strings.
187 		 */
188 		String[] stringArray = new String[1];
189 		stringArray[0] = destinationFile.getAbsolutePath();
190 		// Return the path to the downloaded file
191 		return stringArray;
192 	}
193 
194 	/**
195 	 * @see com.mindtree.techworks.insight.download.RemoteClient#closeConnection()
196 	 */
197 	protected void closeConnection () throws RemoteClientException {
198 
199 		// Nothing to do for HTTP Client
200 
201 	}
202 
203 	//
204 	// Util Methods
205 	//
206 
207 	/**
208 	 * Sets up the client and other configurations
209 	 */
210 	private void initialize () {
211 
212 		HostConfiguration hostConfiguration = new HostConfiguration();
213 		httpClient = new HttpClient();
214 
215 		// Proxy information
216 		if (!fileset.isIgnoreProxy()) {
217 			ProxyInfo proxyInfo = PreferenceInterpreter.getProxyInfo();
218 			ProtocolProxyInfo httpProxyInfo = proxyInfo.getHttpProxyInfo();
219 			// Set the proxy information if proxy is set in preferences.
220 			if (null != httpProxyInfo && httpProxyInfo.isSet()) {
221 				hostConfiguration.setProxy(httpProxyInfo.getHost(),
222 						httpProxyInfo.getPort());
223 
224 				if (proxyInfo.isAuthenticationRequired()) {
225 
226 					NTCredentials credentials = getNTCredentials(proxyInfo
227 							.getPasswordInformation().getUserName(),
228 							new StringBuffer().append(
229 									proxyInfo.getPasswordInformation()
230 											.getPassword()).toString(),
231 							httpProxyInfo.getHost());
232 
233 					// Set the proxy credentials
234 					AuthScope authscope = new AuthScope(httpProxyInfo.getHost(), httpProxyInfo.getPort());
235 					httpClient.getState().setProxyCredentials(authscope, credentials);
236 				}
237 			}
238 		}
239 
240 		httpClient.setHostConfiguration(hostConfiguration);
241 	}
242 
243 	/**
244 	 * Sets the authorization credentials on the HTTP client for the url passed.
245 	 * This method is used to set the password credentials on the client per
246 	 * host rather than set a default authentication credential, so that if the
247 	 * instance of the host is reused, hosts which do not require this
248 	 * authorization are not passed the credentials.
249 	 * 
250 	 * @param url The url from which host is to be taken for setting the
251 	 *            password credentials.
252 	 */
253 	private void setAuthorization (String url) {
254 
255 		// Authorization on the host
256 		if (fileset.isAuthenticationRequired()) {
257 			try {
258 				URL theURL = new URL(url);
259 				NTCredentials credentials = getNTCredentials(fileset
260 						.getUserName(), fileset.getPassword(), theURL.getHost());
261 				AuthScope authScope = new AuthScope(theURL.getHost(), (theURL
262 						.getPort() == -1) ? theURL.getDefaultPort() : theURL
263 						.getPort());
264 				httpClient.getState().setCredentials(authScope, credentials);
265 			} catch (MalformedURLException e) {
266 				// Just don't do authorization here!
267 				e.printStackTrace(System.err);
268 			}
269 		}
270 	}
271 
272 	/**
273 	 * Creates a NTCredentials object from the information passed. This is used
274 	 * for any authentication for the HTTPClient.
275 	 * 
276 	 * @param user The username
277 	 * @param password The password to use for authentication
278 	 * @param host The host on which this authorization is to be used.
279 	 * @return A {@link NTCredentials NTCredentials}object containing the
280 	 *         information.
281 	 */
282 	private NTCredentials getNTCredentials (String user, String password,
283 			String host) {
284 
285 		String domain = null;
286 		String userName = user;
287 
288 		// If the username contains the domain name, split them. For example,
289 		// if the username entered is 'DOMAIN\\user', at the end of this
290 		// operation, domain should contain 'DOMAIN' and userName 'user'
291 		if (userName.indexOf('\\') > -1) {
292 			domain = userName.substring(0, userName.indexOf('\\'));
293 			userName = userName.substring(userName.indexOf('\\') + 1);
294 		}
295 
296 		return new NTCredentials(userName, password, host, domain);
297 	}
298 
299 }