URLNamepublic 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. |
Fields Summary |
---|
protected String | fullURLThe full version of the URL | private String | protocolThe protocol to use (ftp, http, nntp, imap, pop3 ... etc.) . | private String | usernameThe username to use when connecting | private String | passwordThe password to use when connecting. | private String | hostThe host name to which to connect. | private InetAddress | hostAddressThe host's IP address, used in equals and hashCode.
Computed on demand. | private boolean | hostAddressKnown | private int | portThe protocol port to connect to. | private String | fileThe specified file name on that host. | private String | ref# reference. | private int | hashCodeOur hash code. | private static boolean | doEncodeA way to turn off encoding, just in case... | static BitSet | dontNeedEncodingThe 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.String | decode(java.lang.String s)Decodes a "x-www-form-urlencoded"
to a 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.String | encode(java.lang.String s)Translates a string into x-www-form-urlencoded format.
/* 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 boolean | equals(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.String | getFile()Returns the file name of this URLName.
Returns null if this URLName has no file name.
return file;
| public java.lang.String | getHost()Returns the host of this URLName.
Returns null if this URLName has no host.
return host;
| private synchronized java.net.InetAddress | getHostAddress()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.String | getPassword()Returns the password of this URLName.
Returns null if this URLName has no password.
return doEncode ? decode(password) : password;
| public int | getPort()Returns the port number of this URLName.
Returns -1 if the port is not set.
return port;
| public java.lang.String | getProtocol()Returns the protocol of this URLName.
Returns null if this URLName has no protocol.
return protocol;
| public java.lang.String | getRef()Returns the reference of this URLName.
Returns null if this URLName has no reference.
return ref;
| public java.net.URL | getURL()Constructs a URL from the URLName.
return new URL(getProtocol(), getHost(), getPort(), getFile());
| public java.lang.String | getUsername()Returns the user name of this URLName.
Returns null if this URLName has no user name.
return doEncode ? decode(username) : username;
| public int | hashCode()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 int | indexOfAny(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 int | indexOfAny(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 void | parseString(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.String | toString()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;
|
|