FileDocCategorySizeDatePackage
URLName.javaAPI DocJavaMail 1.4.321860Tue Nov 17 10:38:12 GMT 2009javax.mail

URLName

public class URLName extends Object
The name of a URL. This class represents a URL name and also provides the basic parsing functionality to parse most internet standard URL schemes.

Note that this class differs from java.net.URL in that this class just represents the name of a URL, it does not model the connection to a URL.

author
Christopher Cotton
author
Bill Shannon

Fields Summary
protected String
fullURL
The full version of the URL
private String
protocol
The protocol to use (ftp, http, nntp, imap, pop3 ... etc.) .
private String
username
The username to use when connecting
private String
password
The password to use when connecting.
private String
host
The host name to which to connect.
private InetAddress
hostAddress
The host's IP address, used in equals and hashCode. Computed on demand.
private boolean
hostAddressKnown
private int
port
The protocol port to connect to.
private String
file
The specified file name on that host.
private String
ref
# reference.
private int
hashCode
Our hash code.
private static boolean
doEncode
A way to turn off encoding, just in case...
static BitSet
dontNeedEncoding
The class contains a utility method for converting a String into a MIME format called "x-www-form-urlencoded" format.

To convert a String, each character is examined in turn:

  • The ASCII characters 'a' through 'z', 'A' through 'Z', '0' through '9', and ".", "-", "*", "_" remain the same.
  • The space character ' ' is converted into a plus sign '+'.
  • All other characters are converted into the 3-character string "%xy", where xy is the two-digit hexadecimal representation of the lower 8-bits of the character.
static final int
caseDiff
Constructors Summary
public URLName(String protocol, String host, int port, String file, String username, String password)
Creates a URLName object from the specified protocol, host, port number, file, username, and password. Specifying a port number of -1 indicates that the URL should use the default port for the protocol.


     
	try {
	    doEncode = !Boolean.getBoolean("mail.URLName.dontencode");
	} catch (Exception ex) {
	    // ignore any errors
	}
    
	this.protocol = protocol;
	this.host = host;
	this.port = port;
	int refStart;
	if (file != null && (refStart = file.indexOf('#")) != -1) {
	    this.file = file.substring(0, refStart);
	    this.ref = file.substring(refStart + 1);
	} else {
	    this.file = file;
	    this.ref = null;
	}
	this.username = doEncode ? encode(username) : username;
	this.password = doEncode ? encode(password) : password;
    
public URLName(URL url)
Construct a URLName from a java.net.URL object.

	this(url.toString());
    
public URLName(String url)
Construct a URLName from the string. Parses out all the possible information (protocol, host, port, file, username, password).

	parseString(url);
    
Methods Summary
private static java.lang.String_encode(java.lang.String s)

	int maxBytesPerChar = 10;
        StringBuffer out = new StringBuffer(s.length());
	ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
	OutputStreamWriter writer = new OutputStreamWriter(buf);

	for (int i = 0; i < s.length(); i++) {
	    int c = (int)s.charAt(i);
	    if (dontNeedEncoding.get(c)) {
		if (c == ' ") {
		    c = '+";
		}
		out.append((char)c);
	    } else {
		// convert to external encoding before hex conversion
		try {
		    writer.write(c);
		    writer.flush();
		} catch(IOException e) {
		    buf.reset();
		    continue;
		}
		byte[] ba = buf.toByteArray();
		for (int j = 0; j < ba.length; j++) {
		    out.append('%");
		    char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
		    // converting to use uppercase letter as part of
		    // the hex value if ch is a letter.
		    if (Character.isLetter(ch)) {
			ch -= caseDiff;
		    }
		    out.append(ch);
		    ch = Character.forDigit(ba[j] & 0xF, 16);
		    if (Character.isLetter(ch)) {
			ch -= caseDiff;
		    }
		    out.append(ch);
		}
		buf.reset();
	    }
	}

	return out.toString();
    
static java.lang.Stringdecode(java.lang.String s)
Decodes a "x-www-form-urlencoded" to a String.

param
s the String to decode
return
the newly decoded String

	if (s == null)
	    return null;
	if (indexOfAny(s, "+%") == -1)
	    return s;		// the common case

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case '+":
                    sb.append(' ");
                    break;
                case '%":
                    try {
                        sb.append((char)Integer.parseInt(
                                        s.substring(i+1,i+3),16));
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException(
			    "Illegal URL encoded value: " +
			    s.substring(i,i+3));
                    }
                    i += 2;
                    break;
                default:
                    sb.append(c);
                    break;
            }
        }
        // Undo conversion to external encoding
        String result = sb.toString();
        try {
            byte[] inputBytes = result.getBytes("8859_1");
            result = new String(inputBytes);
        } catch (UnsupportedEncodingException e) {
            // The system should always have 8859_1
        }
        return result;
    
static java.lang.Stringencode(java.lang.String s)
Translates a string into x-www-form-urlencoded format.

param
s String to be translated.
return
the translated String.


    /* The list of characters that are not encoded have been determined by
       referencing O'Reilly's "HTML: The Definitive Guide" (page 164). */

     
	dontNeedEncoding = new BitSet(256);
	int i;
	for (i = 'a"; i <= 'z"; i++) {
	    dontNeedEncoding.set(i);
	}
	for (i = 'A"; i <= 'Z"; i++) {
	    dontNeedEncoding.set(i);
	}
	for (i = '0"; i <= '9"; i++) {
	    dontNeedEncoding.set(i);
	}
	/* encoding a space to a + is done in the encode() method */
	dontNeedEncoding.set(' ");
	dontNeedEncoding.set('-");
	dontNeedEncoding.set('_");
	dontNeedEncoding.set('.");
	dontNeedEncoding.set('*");
    
	if (s == null)
	    return null;
	// the common case is no encoding is needed
	for (int i = 0; i < s.length(); i++) {
	    int c = (int)s.charAt(i);
	    if (c == ' " || !dontNeedEncoding.get(c))
		return _encode(s);
	}
	return s;
    
public booleanequals(java.lang.Object obj)
Compares two URLNames. The result is true if and only if the argument is not null and is a URLName object that represents the same URLName as this object. Two URLName objects are equal if they have the same protocol and the same host, the same port number on the host, the same username, and the same file on the host. The fields (host, username, file) are also considered the same if they are both null.

Hosts are considered equal if the names are equal (case independent) or if host name lookups for them both succeed and they both reference the same IP address.

Note that URLName has no knowledge of default port numbers for particular protocols, so "imap://host" and "imap://host:143" would not compare as equal.

Note also that the password field is not included in the comparison, nor is any reference field appended to the filename.

        if (!(obj instanceof URLName))
	    return false;
	URLName u2 = (URLName)obj;

	// compare protocols
	if (u2.protocol == null || !u2.protocol.equals(protocol))
	    return false;

	// compare hosts
	InetAddress a1 = getHostAddress(), a2 = u2.getHostAddress();
	// if we have internet address for both, and they're not the same, fail
	if (a1 != null && a2 != null) {
	    if (!a1.equals(a2))
		return false;
	// else, if we have host names for both, and they're not the same, fail
	} else if (host != null && u2.host != null) {
	    if (!host.equalsIgnoreCase(u2.host))
		return false;
	// else, if not both null
	} else if (host != u2.host) {
	    return false;
	}
	// at this point, hosts match

	// compare usernames
	if (!(username == u2.username ||
		(username != null && username.equals(u2.username))))
	    return false;

	// Forget about password since it doesn't
	// really denote a different store.

	// compare files
	String f1 = file == null ? "" : file;
	String f2 = u2.file == null ? "" : u2.file;

	if (!f1.equals(f2))
	    return false;

	// compare ports
	if (port != u2.port)
	    return false;

	// all comparisons succeeded, they're equal
        return true;
    
public java.lang.StringgetFile()
Returns the file name of this URLName. Returns null if this URLName has no file name.

	return file;
    
public java.lang.StringgetHost()
Returns the host of this URLName. Returns null if this URLName has no host.

	return host;
    
private synchronized java.net.InetAddressgetHostAddress()
Get the IP address of our host. Look up the name the first time and remember that we've done so, whether the lookup fails or not.

	if (hostAddressKnown)
	    return hostAddress;
	if (host == null)
	    return null;
	try {
	    hostAddress = InetAddress.getByName(host);
	} catch (UnknownHostException ex) {
	    hostAddress = null;
	}
	hostAddressKnown = true;
	return hostAddress;
    
public java.lang.StringgetPassword()
Returns the password of this URLName. Returns null if this URLName has no password.

	return doEncode ? decode(password) : password;
    
public intgetPort()
Returns the port number of this URLName. Returns -1 if the port is not set.

	return port;
    
public java.lang.StringgetProtocol()
Returns the protocol of this URLName. Returns null if this URLName has no protocol.

	return protocol;
    
public java.lang.StringgetRef()
Returns the reference of this URLName. Returns null if this URLName has no reference.

	return ref;
    
public java.net.URLgetURL()
Constructs a URL from the URLName.

        return new URL(getProtocol(), getHost(), getPort(), getFile());
    
public java.lang.StringgetUsername()
Returns the user name of this URLName. Returns null if this URLName has no user name.

	return doEncode ? decode(username) : username;
    
public inthashCode()
Compute the hash code for this URLName.

	if (hashCode != 0)
	    return hashCode;
	if (protocol != null)
	    hashCode += protocol.hashCode();
	InetAddress addr = getHostAddress();
	if (addr != null)
	    hashCode += addr.hashCode();
	else if (host != null)
	    hashCode += host.toLowerCase(Locale.ENGLISH).hashCode();
	if (username != null)
	    hashCode += username.hashCode();
	if (file != null)
	    hashCode += file.hashCode();
	hashCode += port;
	return hashCode;
    
private static intindexOfAny(java.lang.String s, java.lang.String any)
Return the first index of any of the characters in "any" in "s", or -1 if none are found. This should be a method on String.

	return indexOfAny(s, any, 0);
    
private static intindexOfAny(java.lang.String s, java.lang.String any, int start)

	try {
	    int len = s.length();
	    for (int i = start; i < len; i++) {
		if (any.indexOf(s.charAt(i)) >= 0)
		    return i;
	    }
	    return -1;
	} catch (StringIndexOutOfBoundsException e) {
	    return -1;
	}
    
protected voidparseString(java.lang.String url)
Method which does all of the work of parsing the string.

	// initialize everything in case called from subclass
	// (URLName really should be a final class)
	protocol = file = ref = host = username = password = null;
	port = -1;

	int len = url.length();

	// find the protocol
	// XXX - should check for only legal characters before the colon
	// (legal: a-z, A-Z, 0-9, "+", ".", "-")
	int protocolEnd = url.indexOf(':");
        if (protocolEnd != -1)
	    protocol = url.substring(0, protocolEnd);

	// is this an Internet standard URL that contains a host name?
	if (url.regionMatches(protocolEnd + 1, "//", 0, 2)) {
	    // find where the file starts
	    String fullhost = null;
	    int fileStart = url.indexOf('/", protocolEnd + 3);
	    if (fileStart != -1) {
		fullhost = url.substring(protocolEnd + 3, fileStart);
		if (fileStart + 1 < len)
		    file = url.substring(fileStart + 1);
		else
		    file = "";
	    } else
		fullhost = url.substring(protocolEnd + 3);

	    // examine the fullhost, for username password etc.
	    int i = fullhost.indexOf('@");
	    if (i != -1) {
		String fulluserpass = fullhost.substring(0, i);
		fullhost = fullhost.substring(i + 1);

		// get user and password
		int passindex = fulluserpass.indexOf(':");
		if (passindex != -1) {
		    username = fulluserpass.substring(0, passindex);
		    password = fulluserpass.substring(passindex + 1);
		} else {
		    username = fulluserpass;
		}
	    }
	    
	    // get the port (if there)
	    int portindex;
	    if (fullhost.length() > 0 && fullhost.charAt(0) == '[") {
		// an IPv6 address?
		portindex = fullhost.indexOf(':", fullhost.indexOf(']"));
	    } else {
		portindex = fullhost.indexOf(':");
	    }
	    if (portindex != -1) {
		String portstring = fullhost.substring(portindex + 1);
		if (portstring.length() > 0) {
		    try {
			port = Integer.parseInt(portstring);
		    } catch (NumberFormatException nfex) {
			port = -1;
		    }
		}
		
		host = fullhost.substring(0, portindex);
	    } else {
		host = fullhost;
	    }
	} else {
	    if (protocolEnd + 1 < len)
		file = url.substring(protocolEnd + 1);
	}

	// extract the reference from the file name, if any
	int refStart;
	if (file != null && (refStart = file.indexOf('#")) != -1) {
	    ref = file.substring(refStart + 1);
	    file = file.substring(0, refStart);
	}
    
public java.lang.StringtoString()
Constructs a string representation of this URLName.

	if (fullURL == null) {
	    // add the "protocol:"
	    StringBuffer tempURL = new StringBuffer();
	    if (protocol != null) {
		tempURL.append(protocol);
		tempURL.append(":");
	    }

	    if (username != null || host != null) {
		// add the "//"
		tempURL.append("//");
		
		// add the user:password@
		// XXX - can you just have a password? without a username?
		if (username != null) {
		    tempURL.append(username);
		
		    if (password != null){
			tempURL.append(":");
			tempURL.append(password);
		    }
		
		    tempURL.append("@");
		}
	    
		// add host
		if (host != null) {
		    tempURL.append(host);
		}
	    
		// add port (if needed)
		if (port != -1) {
		    tempURL.append(":");
		    tempURL.append(Integer.toString(port));
		}
		if (file != null)
		    tempURL.append("/");
	    }
	    
	    // add the file
	    if (file != null) {
		tempURL.append(file);
	    }
	    
	    // add the ref
	    if (ref != null) {
		tempURL.append("#");
		tempURL.append(ref);
	    }

	    // create the fullURL now
	    fullURL = tempURL.toString();
	}

	return fullURL;