/* * Copyright 1999-2010 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * * See the License for the specific language governing permissions and limitations under the License. */ package org.globus.util; import java.net.MalformedURLException; import java.net.URL; /** * This class represents the URLs needed by various Globus services, * including: * <ul> * <li> GASS </li> * <li> GRAM </li> * <li> FTP </li> * <li> GSIFTP </li> * </ul> * * This class is not extended from URL since it is not intended to do stream * handling. Instead it is primarily for the parsing of Globus URLs and is * able to handle the extraction of user names and passwords from the URL * as well. It also can parse literal IPv6 addresses (as per RFC 2732). */ public class GlobusURL { protected String protocol = null; protected String host = null; protected String urlPath = null; protected String user = null; protected String pwd = null; protected String url = null; protected int port = -1; /** * Parses the url and extracts the url parts. * * @param url the url to parse. * @throws MalformedURLException if the url * is malformed. */ public GlobusURL(String url) throws MalformedURLException { int p1, p2; url = url.trim(); p1 = url.indexOf("://"); if (p1 == -1) { throw new MalformedURLException("Missing '[protocol]://'"); } protocol = url.substring(0, p1).toLowerCase(); p1 += 3; String base = null; p2 = url.indexOf('/', p1); if (p2 == -1) { /*throw new MalformedURLException("Missing '/' at [host]:[port]/");*/ base = url.substring(p1); urlPath = null; } else { base = url.substring(p1, p2); // this is after / p2++; if (p2 != url.length()) { urlPath = url.substring(p2); } else { urlPath = null; } } // this is [user]:[pwd]@[host]:[port] p1 = base.indexOf('@'); if (p1 == -1) { parseHostPort(base); } else { parseUserPwd( base.substring(0, p1) ); parseHostPort( base.substring(p1+1) ); } if (port == -1) { port = getPort(protocol); } if (protocol.equals("ftp") && user == null && pwd == null) { user = "anonymous"; pwd = "anon@anon.com"; } this.url = url; } /** * Creates a GlobusURL instance from URL instance. * <BR><B>Note: </B><I>Not all the url parts are * copied.</I> */ public GlobusURL(URL url) { // TODO: does not handle the password:user spec protocol = url.getProtocol(); host = url.getHost(); port = url.getPort(); urlPath = url.getFile(); } public static int getPort(String protocol) { if (protocol.equals("ftp")) { return 21; } else if (protocol.equals("gsiftp") || protocol.equals("gridftp")) { return 2811; } else if (protocol.equals("http")) { return 80; } else if (protocol.equals("https")) { return 443; } else if (protocol.equals("ldap")) { return 389; } else if (protocol.equals("ldaps")) { return 636; } else { return -1; } } private void parseHostPort(String str) throws MalformedURLException { int start = 0; if (str.length() > 0 && str.charAt(0) == '[') { start = str.indexOf(']'); if (start == -1) { throw new MalformedURLException( "Missing ']' in IPv6 address: " + str ); } } int p1 = str.indexOf(':', start); if (p1 == -1) { host = str; } else { host = str.substring(0, p1); String pp = str.substring(p1+1); try { port = Integer.parseInt(pp); } catch(NumberFormatException e) { throw new MalformedURLException("Invalid port number: " + pp); } } } private void parseUserPwd(String str) { int p1; p1 = str.indexOf(':'); if (p1 == -1) { user = Util.decode(str); } else { user = Util.decode(str.substring(0, p1)); pwd = Util.decode(str.substring(p1+1)); } } /** * Returns the string representation of * an url. * * @return the url as string. */ public String getURL() { return url; } /** * Returns the protocol of an url. * * @return the protocol part of the url. */ public String getProtocol() { return protocol; } /** * Returns the host name of an url. * * @return the host name part of the url. */ public String getHost() { return host; } /** * Returns the port number of an url. * * @return the port name of the url. -1 if * the port was not specified. */ public int getPort() { return port; } /** * Returns the url path part of an url. * * @return the url path part of the url. * Returns null if the url path is * not specified. */ public String getPath() { return urlPath; } /** * Returns the user name of an url. * * @return the user name if present in the url, * otherwise returns null. */ public String getUser() { return user; } /** * Returns the password of an url. * * @return the password if present in the url, * otherwise returns null. */ public String getPwd() { return pwd; } /** * Compares two urls. * * @param obj could be a string representation of an url * or an instance of this class. * @return true if the urls are the same, false otherwise. */ public boolean equals(Object obj) { GlobusURL cUrl = null; if (obj instanceof String) { try { cUrl = new GlobusURL((String)obj); } catch(MalformedURLException e) { return false; } } else if (obj instanceof GlobusURL) { cUrl = (GlobusURL)obj; } else { return false; } // do the comparison // compare ports if (getPort() != cUrl.getPort()) return false; if (!compare(getProtocol(), cUrl.getProtocol(), false)) return false; if (!compare(getHost(), cUrl.getHost(), false)) return false; if (!compare(urlPath, cUrl.urlPath, false)) return false; if (!compare(getUser(), cUrl.getUser(), false)) return false; if (!compare(getPwd(), cUrl.getPwd(), false)) return false; return true; } private boolean compare(String s1, String s2, boolean ignoreCase) { if (s1 == null) { return (s2 == null); } else if (s2 == null) { return false; } else { return (ignoreCase) ? s1.equalsIgnoreCase(s2) : s1.equals(s2); } } public int hashCode() { int value = this.port; if (this.protocol != null) { value += this.protocol.hashCode(); } if (this.host != null) { value += this.host.hashCode(); } if (this.urlPath != null) { value += this.urlPath.hashCode(); } if (this.user != null) { value += this.user.hashCode(); } if (this.pwd != null) { value += this.pwd.hashCode(); } return value; } public String toString() { StringBuffer info = new StringBuffer(); info.append("Protocol : " + protocol + "\n"); info.append("Host name : " + host + "\n"); info.append("Port number : " + port + "\n"); info.append("Url path : " + urlPath + "\n"); info.append("User : " + user + "\n"); info.append("Pwd : " + pwd + "\n"); return info.toString(); } }