/*
Copyright (C) 2010 maik.jablonski@gmail.com
This program 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 3 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.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package jfix.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Common utility methods to handle urls.
*/
public class Urls {
private static Properties mimeTypes = new Properties();
static {
try {
mimeTypes.load(Urls.class
.getResourceAsStream("mime-types.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Translates given string into application/x-www-form-urlencoded format
* using a specific encoding scheme.
*/
public static String encode(String str, String enc) {
try {
return URLEncoder.encode(str, enc);
} catch (Exception e) {
return str;
}
}
/**
* Decodes given application/x-www-form-urlencoded string using a specific
* encoding scheme.
*/
public static String decode(String str, String enc) {
try {
return URLDecoder.decode(str, enc);
} catch (Exception e) {
return str;
}
}
/**
* Check is given url is valid (= url needs no encoding).
*/
public static boolean isValid(String url) {
return isValid(url, "UTF-8");
}
/**
* Check is given url is valid for given encoding (= url needs no encoding).
*/
public static boolean isValid(String url, String enc) {
return Validations.isNotEmpty(url) && url.equals(Urls.encode(url, enc));
}
/**
* Returns the content-type for given filename by using mime-type.properties
* as dictionary for filename-extension.
*/
public static String guessContentTypeFromName(String filename) {
if (filename == null) {
return null;
}
int index = filename.lastIndexOf(".") + 1;
if (index != 0) {
String extension = filename.substring(index).toLowerCase();
if (mimeTypes.containsKey(extension)) {
return mimeTypes.getProperty(extension).split(",")[0];
}
}
return "application/octet-stream";
}
/**
* Returns the file-extension for given filename. If no extension is
* present, the full filename is returned.
*/
public static String getExtension(String filename) {
int extension = filename.lastIndexOf(".");
if (extension > 0) {
return filename.substring(extension + 1);
} else {
return filename;
}
}
/**
* Returns content from given url as string. The url can contain
* username:password after the protocol, so that basic authorization is
* possible.
*
* Example for url with basic authorization:
*
* http://username:password@www.domain.org/index.html
*/
public static String readString(String url, int timeout) {
Reader reader = null;
try {
URLConnection uc = new URL(url).openConnection();
if (uc instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) uc;
httpConnection.setConnectTimeout(timeout * 1000);
httpConnection.setReadTimeout(timeout * 1000);
}
Matcher matcher = Pattern.compile("://(\\w+:\\w+)@").matcher(url);
if (matcher.find()) {
String auth = matcher.group(1);
String encoding = Base64.encodeBytes(auth.getBytes());
uc.setRequestProperty("Authorization", "Basic " + encoding);
}
String charset = (uc.getContentType() != null && uc
.getContentType().contains("charset=")) ? uc
.getContentType().split("charset=")[1] : "utf-8";
reader = new BufferedReader(new InputStreamReader(
uc.getInputStream(), charset));
StringBuilder sb = new StringBuilder();
for (int chr; (chr = reader.read()) != -1;) {
sb.append((char) chr);
}
return sb.toString();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
/**
* Returns true if given url can be connected via HTTP within given timeout
* (specified in seconds). Otherwise the url might be broken.
*/
public static boolean isConnectable(String url, int timeout) {
try {
URLConnection connection = new URL(url).openConnection();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setConnectTimeout(timeout * 1000);
httpConnection.setReadTimeout(timeout * 1000);
httpConnection.connect();
int response = httpConnection.getResponseCode();
httpConnection.disconnect();
return response == HttpURLConnection.HTTP_OK;
}
} catch (Exception e) {
return false;
}
return false;
}
/**
* Returns the status code for connecting given url with given timeout.
* Returns 0 if an IOException occurs.
*/
public static int getStatus(String url, int timeout) {
try {
URLConnection connection = new URL(url).openConnection();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setConnectTimeout(timeout * 1000);
httpConnection.setReadTimeout(timeout * 1000);
httpConnection.connect();
int response = httpConnection.getResponseCode();
httpConnection.disconnect();
return response;
}
} catch (IOException e) {
// pass
}
return 0;
}
}