3261N/A * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * <p>The address of a JMX API connector server. Instances of this class 0N/A * are immutable.</p> 0N/A * <p>The address is an <em>Abstract Service URL</em> for SLP, as 0N/A * defined in RFC 2609 and amended by RFC 3111. It must look like 0N/A * <code>service:jmx:<em>protocol</em>:<em>sap</em></code> 0N/A * <p>Here, <code><em>protocol</em></code> is the transport 0N/A * protocol to be used to connect to the connector server. It is 0N/A * a string of one or more ASCII characters, each of which is a 0N/A * letter, a digit, or one of the characters <code>+</code> or 0N/A * <code>-</code>. The first character must be a letter. 0N/A * Uppercase letters are converted into lowercase ones.</p> 0N/A * <p><code><em>sap</em></code> is the address at which the connector 0N/A * server is found. This address uses a subset of the syntax defined 0N/A * by RFC 2609 for IP-based protocols. It is a subset because the 0N/A * <code>user@host</code> syntax is not supported.</p> 0N/A * <p>The other syntaxes defined by RFC 2609 are not currently 0N/A * supported by this class.</p> 0N/A * <p>The supported syntax is:</p> 0N/A * <code>//<em>[host[</em>:<em>port]][url-path]</em></code> 0N/A * <p>Square brackets <code>[]</code> indicate optional parts of 0N/A * the address. Not all protocols will recognize all optional 0N/A * <p>The <code><em>host</em></code> is a host name, an IPv4 numeric 0N/A * host address, or an IPv6 numeric address enclosed in square 0N/A * <p>The <code><em>port</em></code> is a decimal port number. 0 0N/A * means a default or anonymous port, depending on the protocol.</p> 0N/A * <p>The <code><em>host</em></code> and <code><em>port</em></code> 0N/A * can be omitted. The <code><em>port</em></code> cannot be supplied 0N/A * without a <code><em>host</em></code>.</p> 0N/A * <p>The <code><em>url-path</em></code>, if any, begins with a slash 0N/A * (<code>/</code>) or a semicolon (<code>;</code>) and continues to 0N/A * the end of the address. It can contain attributes using the 0N/A * semicolon syntax specified in RFC 2609. Those attributes are not 0N/A * parsed by this class and incorrect attribute syntax is not 0N/A * <p>Although it is legal according to RFC 2609 to have a 0N/A * <code><em>url-path</em></code> that begins with a semicolon, not 0N/A * all implementations of SLP allow it, so it is recommended to avoid 0N/A * <p>Case is not significant in the initial 0N/A * <code>service:jmx:<em>protocol</em></code> string or in the host 0N/A * part of the address. Depending on the protocol, case can be 0N/A * significant in the <code><em>url-path</em></code>.</p> 0N/A * "Service Templates and <code>Service:</code> Schemes"</a> 0N/A * "Service Location Protocol Modifications for IPv6"</a> 0N/A * <p>Constructs a <code>JMXServiceURL</code> by parsing a Service URL 0N/A * @param serviceURL the URL string to be parsed. 0N/A * @exception NullPointerException if <code>serviceURL</code> is 0N/A * @exception MalformedURLException if <code>serviceURL</code> 0N/A * does not conform to the syntax for an Abstract Service URL or 0N/A * if it is not a valid name for a JMX Remote API service. A 0N/A * <code>JMXServiceURL</code> must begin with the string 0N/A * <code>"service:jmx:"</code> (case-insensitive). It must not 0N/A * contain any characters that are not printable ASCII characters. 0N/A /* Check that there are no non-ASCII characters in the URL, 0N/A following RFC 2609. */ 0N/A if (c <
32 || c >=
127) {
0N/A "non-ASCII character 0x" +
0N/A // Parse the required prefix 0N/A 0,
// serviceURL offset 0N/A 0,
// requiredPrefix offset 0N/A // Parse the protocol name 0N/A // Parse the host name 0N/A "be numeric IPv6 address");
0N/A // Parse the port number 0N/A "without host name");
0N/A // Parse the URL path 0N/A * <p>Constructs a <code>JMXServiceURL</code> with the given protocol, 0N/A * host, and port. This constructor is equivalent to 0N/A * {@link #JMXServiceURL(String, String, int, String) 0N/A * JMXServiceURL(protocol, host, port, null)}.</p> 0N/A * @param protocol the protocol part of the URL. If null, defaults 0N/A * to <code>jmxmp</code>. 0N/A * @param host the host part of the URL. If null, defaults to the 0N/A * local host name, as determined by 0N/A * <code>InetAddress.getLocalHost().getHostName()</code>. If it 0N/A * is a numeric IPv6 address, it can optionally be enclosed in 0N/A * square brackets <code>[]</code>. 0N/A * @param port the port part of the URL. 0N/A * @exception MalformedURLException if one of the parts is 0N/A * syntactically incorrect, or if <code>host</code> is null and it 0N/A * is not possible to find the local host name, or if 0N/A * <code>port</code> is negative. 0N/A * <p>Constructs a <code>JMXServiceURL</code> with the given parts. 0N/A * @param protocol the protocol part of the URL. If null, defaults 0N/A * to <code>jmxmp</code>. 0N/A * @param host the host part of the URL. If null, defaults to the 0N/A * local host name, as determined by 0N/A * <code>InetAddress.getLocalHost().getHostName()</code>. If it 0N/A * is a numeric IPv6 address, it can optionally be enclosed in 0N/A * square brackets <code>[]</code>. 0N/A * @param port the port part of the URL. 0N/A * @param urlPath the URL path part of the URL. If null, defaults to 0N/A * @exception MalformedURLException if one of the parts is 0N/A * syntactically incorrect, or if <code>host</code> is null and it 0N/A * is not possible to find the local host name, or if 0N/A * <code>port</code> is negative. 0N/A /* We might have a hostname that violates DNS naming 0N/A rules, for example that contains an `_'. While we 0N/A could be strict and throw an exception, this is rather 0N/A user-hostile. Instead we use its numerical IP address. 0N/A We can only reasonably do this for the host==null case. 0N/A If we're given an explicit host name that is illegal we 0N/A have to reject it. (Bug 5057532.) */ 0N/A "Replacing illegal local host name " +
0N/A host +
" with numeric IP address " +
0N/A "(see RFC 1034)", e);
0N/A /* Use the numeric address, which could be either IPv4 0N/A or IPv6. validateHost will accept either. */ 0N/A "does not end with ]");
0N/A "be numeric IPv6 address");
0N/A "without host name");
0N/A /* We assume J2SE >= 1.4 here. Otherwise you can't 0N/A use the address anyway. We can't call 0N/A InetAddress.getByName without checking for a 0N/A numeric IPv6 address, because we mustn't try to do 0N/A a DNS lookup in case the address is not actually 0N/A /* We should really catch UnknownHostException 0N/A here, but a bug in JDK 1.4 causes it to throw 0N/A ArrayIndexOutOfBoundsException, e.g. if the 0N/A /* Tiny state machine to check valid host name. This 0N/A checks the hostname grammar from RFC 1034 (DNS), 0N/A page 11. A hostname is a dot-separated list of one 0N/A or more labels, where each label consists of 0N/A letters, numbers, or hyphens. A label cannot begin 0N/A or end with a hyphen. Empty hostnames are not 0N/A allowed. Note that numeric IPv4 addresses are a 0N/A special case of this grammar. 0N/A The state is entirely captured by the last 0N/A character seen, with a virtual `.' preceding the 0N/A name. We represent any alphanumeric character by 0N/A We need a special hack to check, as required by the 0N/A RFC 2609 (SLP) grammar, that the last component of 0N/A the hostname begins with a letter. Respecting the 0N/A intent of the RFC, we only do this if there is more 0N/A than one component. If your local hostname begins 0N/A with a digit, we don't reject it. */ 0N/A else if (c ==
'-') {
0N/A break;
// will throw exception 0N/A }
else if (c ==
'.') {
0N/A break;
// will throw exception 0N/A /* Must be a numeric IPv4 address. In addition to 0N/A the explicitly-thrown exceptions, we can get 0N/A NoSuchElementException from the calls to 0N/A tok.nextToken and NumberFormatException from 0N/A the call to Integer.parseInt. Using exceptions 0N/A for control flow this way is a bit evil but it 0N/A does simplify things enormously. */ 0N/A for (
int i =
0; i <
4; i++) {
0N/A if (n <
0 || n >
255)
0N/A * <p>The protocol part of the Service URL. 0N/A * @return the protocol part of the Service URL. This is never null. 0N/A * <p>The host part of the Service URL. If the Service URL was 0N/A * constructed with the constructor that takes a URL string 0N/A * parameter, the result is the substring specifying the host in 0N/A * that URL. If the Service URL was constructed with a 0N/A * constructor that takes a separate host parameter, the result is 0N/A * the string that was specified. If that string was null, the 0N/A * <code>InetAddress.getLocalHost().getHostName()</code>.</p> 0N/A * <p>In either case, if the host was specified using the 0N/A * <code>[...]</code> syntax for numeric IPv6 addresses, the 0N/A * square brackets are not included in the return value here.</p> 0N/A * @return the host part of the Service URL. This is never null. 0N/A * <p>The port of the Service URL. If no port was 0N/A * specified, the returned value is 0.</p> 0N/A * @return the port of the Service URL, or 0 if none. 0N/A * <p>The URL Path part of the Service URL. This is an empty 0N/A * string, or a string beginning with a slash (<code>/</code>), or 0N/A * a string beginning with a semicolon (<code>;</code>). 0N/A * @return the URL Path part of the Service URL. This is never 0N/A * <p>The string representation of this Service URL. If the value 0N/A * returned by this method is supplied to the 0N/A * <code>JMXServiceURL</code> constructor, the resultant object is 0N/A * equal to this one.</p> 0N/A * <p>The <code><em>host</em></code> part of the returned string 0N/A * is the value returned by {@link #getHost()}. If that value 0N/A * specifies a numeric IPv6 address, it is surrounded by square 0N/A * brackets <code>[]</code>.</p> 0N/A * <p>The <code><em>port</em></code> part of the returned string 0N/A * is the value returned by {@link #getPort()} in its shortest 0N/A * decimal form. If the value is zero, it is omitted.</p> 0N/A * @return the string representation of this Service URL. 0N/A /* We don't bother synchronizing the access to toString. At worst, 0N/A n threads will independently compute and store the same value. */ 0N/A * <p>Indicates whether some other object is equal to this one. 0N/A * This method returns true if and only if <code>obj</code> is an 0N/A * instance of <code>JMXServiceURL</code> whose {@link 0N/A * #getProtocol()}, {@link #getHost()}, {@link #getPort()}, and 0N/A * {@link #getURLPath()} methods return the same values as for 0N/A * this object. The values for {@link #getProtocol()} and {@link 0N/A * #getHost()} can differ in case without affecting equality. 0N/A * @param obj the reference object with which to compare. 0N/A * @return <code>true</code> if this object is the same as the 0N/A * <code>obj</code> argument; <code>false</code> otherwise. 0N/A /* True if this string, assumed to be a valid argument to 0N/A * InetAddress.getByName, is a numeric IPv6 address. 0N/A // address contains colon if and only if it's a numeric IPv6 address 0N/A // like String.indexOf but returns string length not -1 if not present 0N/A /* J2SE 1.4 adds lots of handy methods to BitSet that would 0N/A allow us to simplify here, e.g. by not writing loops, but 0N/A we want to work on J2SE 1.3 too. */ 0N/A for (
char c =
'0'; c <=
'9'; c++)
0N/A for (
char c =
'A'; c <=
'Z'; c++)
0N/A for (
char c =
'a'; c <=
'z'; c++)
0N/A * The value returned by {@link #getProtocol()}. 0N/A * The value returned by {@link #getHost()}. 0N/A * The value returned by {@link #getPort()}. 0N/A * The value returned by {@link #getURLPath()}. 0N/A * Cached result of {@link #toString()}.