Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* This file is part of the project "Hilbert II" - http://www.qedeq.org
*
* Copyright 2000-2013, Michael Meyling .
*
* "Hilbert II" is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
package org.qedeq.base.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.qedeq.base.trace.Trace;
import org.qedeq.base.utility.YodaUtility;
/**
* A collection of useful static methods for URL s.
*
* @author Michael Meyling
*/
public final class UrlUtility {
/** This class, for debugging purpose. */
private static final Class CLASS = UrlUtility.class;
/**
* Constructor, should never be called.
*/
private UrlUtility() {
// don't call me
}
/**
* Convert file in URL.
*
* @param file File.
* @return URL.
*/
public static URL toUrl(final File file) {
try {
return file.getAbsoluteFile().toURI().toURL();
} catch (MalformedURLException e) { // should only happen if there is a bug in the JDK
throw new RuntimeException(e);
}
}
/**
* Convert URL path in file path.
*
* @param url Convert this URL path.
* @return File path.
*/
public static File transformURLPathToFilePath(final URL url) {
try {
return new File(URLDecoder.decode(url.getFile(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* Create relative address from origin to next.
* The resulting file path has "/" as directory name separator.
* If the resulting file path is the same as origin specifies, we return "".
* Otherwise the result will always have an "/" as last character.
*
* @param origin This is the original location. Must be a directory.
* @param next This should be the next location. Must also be a directory.
* @return Relative (or if necessary absolute) file path.
*/
public static final String createRelativePath(final File origin, final File next) {
if (origin.equals(next)) {
return "";
}
final Path org = new Path(origin.getPath().replace(File.separatorChar, '/'), "");
final Path ne = new Path(next.getPath().replace(File.separatorChar, '/'), "");
return org.createRelative(ne.toString()).toString();
}
/**
* Simplify file URL by returning a file path.
*
* @param url URL to simplify.
* @return File path (if protocol is "file"). Otherwise just return url.
*/
public static String easyUrl(final String url) {
String result = url;
try {
final URL u = new URL(url);
// is this a file URL?
if (u.getProtocol().equalsIgnoreCase("file")) {
return transformURLPathToFilePath(u).getCanonicalPath();
}
} catch (RuntimeException e) {
// ignore
} catch (IOException e) {
// ignore
}
return result;
}
/**
* Make local copy of an URL.
*
* @param url Save this URL.
* @param f Save into this file. An existing file is overwritten.
* @param proxyHost Use this proxy host.
* @param proxyPort Use this port at proxy host.
* @param nonProxyHosts This are hosts not to be proxied.
* @param connectTimeout Connection timeout.
* @param readTimeout Read timeout.
* @param listener Here completion events are fired.
* @throws IOException Saving failed.
*/
public static void saveUrlToFile(final String url, final File f, final String proxyHost,
final String proxyPort, final String nonProxyHosts, final int connectTimeout,
final int readTimeout, final LoadingListener listener)
throws IOException {
final String method = "saveUrlToFile()";
Trace.begin(CLASS, method);
// if we are not web started and running under Java 1.4 we use apache commons
// httpclient library (so we can set timeouts)
if (!isSetConnectionTimeOutSupported()
&& !IoUtility.isWebStarted()) {
saveQedeqFromWebToBufferApache(url, f, proxyHost, proxyPort, nonProxyHosts, connectTimeout,
readTimeout, listener);
Trace.end(CLASS, method);
return;
}
// set proxy properties according to kernel configuration (if not webstarted)
if (!IoUtility.isWebStarted()) {
if (proxyHost != null) {
System.setProperty("http.proxyHost", proxyHost);
}
if (proxyPort != null) {
System.setProperty("http.proxyPort", proxyPort);
}
if (nonProxyHosts != null) {
System.setProperty("http.nonProxyHosts", nonProxyHosts);
}
}
FileOutputStream out = null;
InputStream in = null;
try {
final URLConnection connection = new URL(url).openConnection();
if (connection instanceof HttpURLConnection) {
final HttpURLConnection httpConnection = (HttpURLConnection) connection;
// if we are running at least under Java 1.5 the following code should be executed
if (isSetConnectionTimeOutSupported()) {
try {
YodaUtility.executeMethod(httpConnection, "setConnectTimeout",
new Class[] {Integer.TYPE}, new Object[] {new Integer(
connectTimeout)});
} catch (NoSuchMethodException e) {
Trace.fatal(CLASS, method,
"URLConnection.setConnectTimeout was previously found", e);
} catch (InvocationTargetException e) {
Trace.fatal(CLASS, method,
"URLConnection.setConnectTimeout throwed an error", e);
}
}
// if we are running at least under Java 1.5 the following code should be executed
if (isSetReadTimeoutSupported()) {
try {
YodaUtility.executeMethod(httpConnection, "setReadTimeout",
new Class[] {Integer.TYPE}, new Object[] {new Integer(
readTimeout)});
} catch (NoSuchMethodException e) {
Trace.fatal(CLASS, method,
"URLConnection.setReadTimeout was previously found", e);
} catch (InvocationTargetException e) {
Trace.fatal(CLASS, method,
"URLConnection.setReadTimeout throwed an error", e);
}
}
int responseCode = httpConnection.getResponseCode();
if (responseCode == 200) {
in = httpConnection.getInputStream();
} else {
in = httpConnection.getErrorStream();
final String errorText = IoUtility.loadStreamWithoutException(in, 1000);
throw new IOException("Response code from HTTP server was " + responseCode
+ (errorText.length() > 0 ? "\nResponse text from HTTP server was:\n"
+ errorText : ""));
}
} else {
Trace.paramInfo(CLASS, method, "connection.getClass", connection.getClass()
.toString());
in = connection.getInputStream();
}
if (!url.equals(connection.getURL().toString())) {
throw new FileNotFoundException("\"" + url + "\" was substituted by "
+ "\"" + connection.getURL() + "\" from server");
}
final double maximum = connection.getContentLength();
IoUtility.createNecessaryDirectories(f);
out = new FileOutputStream(f);
final byte[] buffer = new byte[4096];
int bytesRead; // bytes read during one buffer read
int position = 0; // current reading position within the whole document
// continue writing
while ((bytesRead = in.read(buffer)) != -1) {
position += bytesRead;
out.write(buffer, 0, bytesRead);
if (maximum > 0) {
double completeness = position / maximum;
if (completeness < 0) {
completeness = 0;
}
if (completeness > 100) {
completeness = 1;
}
listener.loadingCompletenessChanged(completeness);
}
}
listener.loadingCompletenessChanged(1);
} finally {
IoUtility.close(out);
out = null;
IoUtility.close(in);
in = null;
Trace.end(CLASS, method);
}
}
/**
* Make local copy of a http accessable URL. This method uses apaches HttpClient,
* but it dosn't work under webstart with proxy configuration. If we don't use this
* method, the apache commons-httpclient library can be removed
*
* @param url Save this URL.
* @param f Save into this file. An existing file is overwritten.
* @param proxyHost Use this proxy host.
* @param proxyPort Use this port at proxy host.
* @param nonProxyHosts This are hosts not to be proxied.
* @param connectTimeout Connection timeout.
* @param readTimeout Read timeout.
* @param listener Here completion events are fired.
* @throws IOException Saving failed.
*/
private static void saveQedeqFromWebToBufferApache(final String url, final File f,
final String proxyHost, final String proxyPort,
final String nonProxyHosts, final int connectTimeout, final int readTimeout,
final LoadingListener listener)
throws IOException {
final String method = "saveQedeqFromWebToBufferApache()";
Trace.begin(CLASS, method);
// Create an instance of HttpClient.
HttpClient client = new HttpClient();
// set proxy properties according to kernel configuration (if not webstarted)
if (!IoUtility.isWebStarted() && proxyHost != null && proxyHost.length() > 0) {
final String pHost = proxyHost;
int pPort = 80;
if (proxyPort != null) {
try {
pPort = Integer.parseInt(proxyPort);
} catch (RuntimeException e) {
Trace.fatal(CLASS, method, "proxy port not numeric: "
+ proxyPort, e);
}
}
if (pHost.length() > 0) {
client.getHostConfiguration().setProxy(pHost, pPort);
}
}
// Create a method instance.
GetMethod httpMethod = new GetMethod(url);
try {
// Provide custom retry handler is necessary
httpMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
httpMethod.getParams().setSoTimeout(connectTimeout);
// Throws IOException on TimeOut.
int statusCode = client.executeMethod(httpMethod);
if (statusCode != HttpStatus.SC_OK) {
throw new FileNotFoundException("Problems loading: " + url + "\n"
+ httpMethod.getStatusLine());
}
// Read the response body.
byte[] responseBody = httpMethod.getResponseBody();
IoUtility.createNecessaryDirectories(f);
IoUtility.saveFileBinary(f, responseBody);
listener.loadingCompletenessChanged(1);
} finally {
// Release the connection.
httpMethod.releaseConnection();
Trace.end(CLASS, method);
}
}
/**
* This class ist just for solving the lazy loading problem thread save.
* see
* Initialization_on_demand_holder_idiom.
*/
private static final class LazyHolderTimeoutMethods {
/** Lazy initialized constant that knows about the existence of the method
* URLConnection.setConnectTimeout. This depends on the currently running
* JVM. */
private static final boolean IS_SET_CONNECTION_TIMEOUT_SUPPORTED = YodaUtility.existsMethod(
URLConnection.class, "setConnectTimeout",
new Class[] {Integer.TYPE});
/** Lazy initialized constant that knows about the existence of the method
* URLConnection.setReadTimeout. This depends on the currently running
* JVM. */
private static final boolean IS_SET_READ_TIMEOUT_SUSPPORTED = YodaUtility.existsMethod(
URLConnection.class, "setReadTimeout",
new Class[] {Integer.TYPE});
}
/**
* Is setting of connection timeout supported in current environment?
*
* @return Setting connection timeout supported?
*/
public static boolean isSetConnectionTimeOutSupported() {
return LazyHolderTimeoutMethods.IS_SET_CONNECTION_TIMEOUT_SUPPORTED;
}
/**
* Is setting of read timeout supported in current environment?
*
* @return Setting read timeout supported?
*/
public static boolean isSetReadTimeoutSupported() {
return LazyHolderTimeoutMethods.IS_SET_READ_TIMEOUT_SUSPPORTED;
}
}