javaxt.utils.URL Maven / Gradle / Ivy
package javaxt.utils;
import java.util.HashMap;
import java.util.List;
//******************************************************************************
//** URL Class - By Peter Borissow
//******************************************************************************
/**
* Used to parse urls, extract querystring parameters, etc. Partial
* implementation of the java.net.URL class. Provides a querystring parser that
* is not part of the java.net.URL class. Can be used to parse non-http URLs,
* including JDBC connection strings.
*
******************************************************************************/
public class URL {
private HashMap> parameters;
private String protocol;
private String host;
private Integer port;
private String path;
// **************************************************************************
// ** Constructor
// **************************************************************************
/** Creates a new instance of URL using a java.net.URL */
public URL(java.net.URL url) {
this(url.toString());
}
// **************************************************************************
// ** Constructor
// **************************************************************************
/** Creates a new instance of URL using string representing a url. */
public URL(String url) {
url = url.trim();
parameters = new HashMap>();
if (url.contains("://")) {
protocol = url.substring(0, url.indexOf("://"));
url = url.substring(url.indexOf("://") + 3);
} else {
if (url.startsWith("jdbc")) {
protocol = url.substring(0, url.indexOf(";"));
url = url.substring(url.indexOf(";") + 1);
}
}
if (url.contains("?")) {
String query = url.substring(url.indexOf("?") + 1);
url = url.substring(0, url.indexOf("?"));
parameters = parseQueryString(query);
} else {
if (url.contains(";")) { // found jdbc delimiter
url = url.substring(0, url.indexOf(";"));
}
}
if (url.contains("/")) {
path = url.substring(url.indexOf("/"));
url = url.substring(0, url.indexOf("/"));
}
if (url.contains(":")) {
try {
port = Integer.valueOf(url.substring(url.indexOf(":") + 1));
url = url.substring(0, url.indexOf(":"));
} catch (Exception e) {
}
}
host = url;
}
// **************************************************************************
// ** exists
// **************************************************************************
/**
* Used to test whether the url endpoint exists. Currently only supports
* HTTP URLs.
*/
public boolean exists() {
try {
java.net.URLConnection conn = new java.net.URL(this.toString()).openConnection();
conn.setConnectTimeout(5000);
conn.getInputStream();
return true;
} catch (Exception e) {
// System.err.println(e.toString());
// System.err.println("URL not found: " + this.toString());
}
return false;
}
// **************************************************************************
// ** parseQueryString
// **************************************************************************
/**
* Used to parse a url query string and create a list of name/value pairs.
* Note that the keys are all lowercase.
*/
public static HashMap> parseQueryString(String query) {
// Create an empty hashmap
HashMap> parameters = new HashMap>();
if (query == null)
return parameters;
// Decode the querystring. Note that the urlDecoder doesn't decode
// everything (e.g. "&")
query = decode(query);
// Special case for query strings with "&" instead of "&" delimiters
boolean amp = query.contains("&");
if (amp)
query = query.replace("&", "&");
// Parse the querystring, one character at a time. Note that the
// tokenizer
// implemented here is very inefficient. Need something better/faster.
if (query.startsWith("&"))
query = query.substring(1);
query += "&";
StringBuffer word = new StringBuffer();
String c = "";
for (int i = 0; i < query.length(); i++) {
c = query.substring(i, i + 1);
if (!c.equals("&")) {
word.append(c); // word = word + c;
} else {
// System.out.println(word);
int x = word.indexOf("=");
if (x >= 0) {
String key = word.substring(0, x).toLowerCase();
String value = decode(word.substring(x + 1));
// Special case for JDBC connection strings that contain
// extra params after the query
if (amp && value.contains(";"))
value = value.substring(0, value.indexOf(";"));
List values = parameters.get(key);
if (values == null)
values = new java.util.LinkedList();
values.add(value);
parameters.put(key, values);
} else {
parameters.put(word.toString(), null);
}
word = new StringBuffer(); // word = "";
}
}
return parameters;
}
private static String decode(String str) {
try {
return java.net.URLDecoder.decode(str, "UTF-8");
} catch (Exception e) {
// This should never happen. Try to decode the string manually?
String find[] = new String[] { "%2C", "%2F", "%3A" };
String replace[] = new String[] { ",", "/", ":" };
for (int i = 0; i < find.length; i++) {
str = str.replace(find[i], replace[i]);
}
return str;
}
}
private static String encode(String str) {
try {
return java.net.URLEncoder.encode(str, "UTF-8").replaceAll("\\+", "%20");
} catch (Exception e) {
return str;
}
}
// **************************************************************************
// ** setParameter
// **************************************************************************
/**
* Used to set or update a value for a given parameter in the query string.
* If append is true, the value will be added to other values for this key.
*/
public void setParameter(String key, String value, boolean append) {
if (value != null)
value = decode(value);
key = key.toLowerCase();
if (append) {
List values = parameters.get(key);
java.util.Iterator it = values.iterator();
while (it.hasNext()) {
if (it.next().equalsIgnoreCase(value)) {
append = false;
break;
}
}
if (append) {
values.add(value);
parameters.put(key, values);
}
} else {
if (value != null) {
List values = new java.util.LinkedList();
values.add(value);
parameters.put(key, values);
}
}
}
// **************************************************************************
// ** setParameter
// **************************************************************************
/**
* Used to set or update a value for a given parameter.
*/
public void setParameter(String key, String value) {
setParameter(key, value, false);
}
// **************************************************************************
// ** getParameter
// **************************************************************************
/**
* Returns the value of a specific variable supplied in the query string.
*
* @param key
* Query string parameter name. Performs a case insensitive
* search for the keyword.
*
* @return Returns a comma delimited list of values associated with the
* given key. Returns a zero length string if the key is not found
* or if the value is null.
*/
public String getParameter(String key) {
StringBuffer str = new StringBuffer();
List values = parameters.get(key.toLowerCase());
if (values != null) {
for (int i = 0; i < values.size(); i++) {
str.append(values.get(i));
if (i < values.size() - 1)
str.append(",");
}
return str.toString();
} else {
return "";
}
}
// **************************************************************************
// ** getParameter
// **************************************************************************
/**
* Returns the value of a specific variable supplied in the query string.
*
* @param keys
* An array containing multiple possible parameter names.
* Performs a case insensitive search for each parameter name and
* returns the value for the first match.
*/
public String getParameter(String[] keys) {
StringBuffer str = new StringBuffer();
for (String key : keys) {
List values = parameters.get(key.toLowerCase());
if (values != null) {
for (int i = 0; i < values.size(); i++) {
str.append(values.get(i) + ",");
}
}
}
String value = str.toString();
if (value.endsWith(","))
value = value.substring(0, value.length() - 1);
return value;
}
// **************************************************************************
// ** getParameters
// **************************************************************************
/**
* Returns a list of parameters found in query string.
*/
public HashMap> getParameters() {
return parameters;
}
// **************************************************************************
// ** removeParameter
// **************************************************************************
/**
* Used to remove a parameter from the query string
*/
public String removeParameter(String key) {
StringBuffer str = new StringBuffer();
List values = parameters.remove(key.toLowerCase());
if (values != null) {
for (int i = 0; i < values.size(); i++) {
str.append(values.get(i));
if (i < values.size() - 1)
str.append(",");
}
return str.toString();
} else {
return "";
}
}
// **************************************************************************
// ** getHost
// **************************************************************************
/**
* Returns the host name or IP address found in the URL.
*/
public String getHost() {
return host;
}
// **************************************************************************
// ** setHost
// **************************************************************************
/**
* Used to update the host name or IP address found in the URL.
*/
public void setHost(String host) {
if (host.contains(":")) {
port = Integer.valueOf(host.substring(host.indexOf(":") + 1));
host = host.substring(0, host.indexOf(":"));
}
this.host = host;
}
// **************************************************************************
// ** getPort
// **************************************************************************
/**
* Returns the server port found in the URL.
*/
public Integer getPort() {
return port;
}
// **************************************************************************
// ** setPort
// **************************************************************************
/**
* Used to update the port found in the URL.
*/
public void setPort(int port) {
this.port = port;
}
// **************************************************************************
// ** setProtocol
// **************************************************************************
/**
* Used to update the protocol found in the URL.
*/
public void setProtocol(String protocol) {
this.protocol = protocol;
}
// **************************************************************************
// ** getProtocol
// **************************************************************************
/**
* Returns the protocol found in the URL.
*/
public String getProtocol() {
return protocol;
}
// **************************************************************************
// ** getQueryString
// **************************************************************************
/**
* Returns the query string in the URL, or an empty string if none exists.
*/
public String getQueryString() {
StringBuffer str = new StringBuffer();
java.util.HashSet keys = getKeys();
java.util.Iterator it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
String value = this.getParameter(key);
if (value.length() == 0) {
if (parameters.get(key.toLowerCase()) == null) {
value = null;
}
}
str.append(encode(key));
if (value != null) {
str.append("=");
str.append(encode(value));
}
if (it.hasNext())
str.append("&");
}
return str.toString();
}
// **************************************************************************
// ** setQueryString
// **************************************************************************
/**
* Used to update the query string in the URL.
*/
public void setQueryString(String query) {
if (query == null) {
parameters = new HashMap>();
} else {
query = query.trim();
if (query.startsWith("?"))
query = query.substring(1).trim();
if (query.length() > 0) {
parameters = parseQueryString(query);
}
}
}
// **************************************************************************
// ** getKeys
// **************************************************************************
/**
* Returns a list of parameter names found in the query string.
*/
public java.util.HashSet getKeys() {
java.util.HashSet keys = new java.util.HashSet();
java.util.Iterator it = parameters.keySet().iterator();
while (it.hasNext()) {
keys.add(it.next());
}
return keys;
}
// **************************************************************************
// ** getPath
// **************************************************************************
/**
* Return the path portion of the URL, starting with a "/" character. The
* path does not include the query string. If no path is found, returns a
* null.
*/
public String getPath() {
return path;
}
// **************************************************************************
// ** setPath
// **************************************************************************
/**
* Used to update the path portion of the URL. If the supplied path starts
* with "./" or "../", only part of the path will be replaced. Otherwise,
* the entire path will be replaced.
*
* When supplying a relative path (path starting with "./" or "../"), the
* url parser assumes that directories in the original path are terminated
* with a "/". For example:
*
*
* http://www.example.com/path/
*
*
* If a path is not terminated with a "/", the parser assumes that the last
* "/" separates a path from a file. Example:
*
*
* http://www.example.com/path/file.html
*
*
* For example, if the original url looks like this:
*
*
* http://www.example.com/path/
*
*
* If you provide a relative path like "../index.html", will yield this:
*
*
* http://www.example.com/index.html
*
*
* Note that if the supplied path contains a query string, the original
* query string will be replaced with the new one.
*/
public void setPath(String path) {
if (path == null) {
path = "";
} else {
path = path.trim();
if (path.contains("?")) {
String query = path.substring(path.indexOf("?") + 1);
path = path.substring(0, path.indexOf("?"));
parameters = parseQueryString(query);
}
if (path.contains(";")) { // found jdbc delimiter
path = path.substring(0, path.indexOf(";"));
}
if (!path.startsWith("/")) {
if (path.startsWith("./") || path.startsWith("../")) {
String RelPath = path;
// Remove "./" prefix in the RelPath
if (RelPath.length() > 2) {
if (RelPath.substring(0, 2).equals("./")) {
RelPath = RelPath.substring(2, RelPath.length());
}
}
// Build Path
String urlPath = "";
String newPath = "";
if (RelPath.substring(0, 1).equals("/")) {
newPath = RelPath;
} else {
urlPath = "/";
String dir = "";
String orgPath = getPath();
if (orgPath == null)
orgPath = "";
if (orgPath.length() > 1 && !orgPath.endsWith("/")) {
orgPath = orgPath.substring(0, orgPath.lastIndexOf("/"));
}
String[] arr = orgPath.split("/");
String[] arrRelPath = RelPath.split("/");
for (int i = 0; i <= (arr.length - arrRelPath.length); i++) {
dir = arr[i];
if (dir.length() > 0) {
urlPath += dir + "/";
}
}
// This can be cleaned-up a bit...
if (RelPath.substring(0, 1).equals("/")) {
newPath = RelPath.substring(1, RelPath.length());
} else if (RelPath.substring(0, 2).equals("./")) {
newPath = RelPath.substring(2, RelPath.length());
} else if (RelPath.substring(0, 3).equals("../")) {
newPath = RelPath.replace("../", "");
} else {
newPath = RelPath;
}
}
// System.out.println("urlPath: " + urlPath);
// System.out.println("newPath: " + newPath);
path = urlPath + newPath;
} else {
path = "/" + path;
}
}
}
this.path = path;
}
// **************************************************************************
// ** toString
// **************************************************************************
/**
* Returns the URL as a string.
*/
@Override
public String toString() {
// Update Host
String host = this.host;
if (port != null && port > 0)
host += ":" + port;
// Update Path
String path = "";
if (getPath() != null)
path = getPath();
// Update Query String
String query = getQueryString();
if (query.length() > 0)
query = "?" + query;
// Assemble URL
return protocol + "://" + host + path + query;
}
// **************************************************************************
// ** toURL
// **************************************************************************
/**
* Returns a properly encoded URL for HTTP requests
*/
public java.net.URL toURL() {
java.net.URL url = null;
try {
Integer port = this.port;
if (port == null) {
if (protocol.equalsIgnoreCase("http"))
port = 80;
else if (protocol.equalsIgnoreCase("https"))
port = 443;
else if (protocol.equalsIgnoreCase("ftp"))
port = 23;
else {
try {
port = new java.net.URL(protocol + "://" + host).getPort();
} catch (Exception e) {
}
}
}
url = new java.net.URI(protocol, null, host, port, path, null, null).toURL();
// Encode and append QueryString as needed
String query = getQueryString();
if (query.length() > 0) {
url = new java.net.URL(url.toString() + "?" + query);
}
} catch (Exception e) {
// e.printStackTrace();
}
return url;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy