Path: blob/master/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/VmIdentifier.java
41159 views
/*1* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.jvmstat.monitor;2627import java.net.*;2829/**30* An abstraction that identifies a target Java Virtual Machine.31* The VmIdentifier, or vmid, provides a convenient string representation32* of the information needed to locate and communicate with a target33* Java Virtual Machine. The string, based on a {@link URI}, may specify34* the communications protocol, host name, local vm identifier, and protocol35* specific information for a target Java Virtual Machine. The format for36* a VmIdentifier string is:37* <pre>38* [<I>protocol</I>:][<I>//</I>]<I><B>lvmid</B></I>[<I>@hostname</I>][<I>:port</I>][<I>/servername</I>]39* </pre>40* The only required component of this string is the Local Virtual Machine41* Identifier, or {@code lvmid}, which uniquely identifies the target42* Java Virtual Machine on a host. The optional components of the VmIdentifier43* include:44* <ul>45* <li>{@code protocol} - The communications protocol. A VmIdentifier46* omitting the protocol must be resolved against a HostIdentifier47* using {@link HostIdentifier#resolve}.48* </li>49* <li>{@code hostname} - A hostname or IP address indicating the target50* host. A VmIdentifier omitting the protocol must be resolved51* against a HostIdentifier using {@link HostIdentifier#resolve}.52* </li>53* <li>{@code port} - The port for the communications protocol.54* Treatment of the {@code port} parameter is implementation55* (protocol) specific. A VmIdentifier omitting the protocol should56* be resolved against a HostIdentifier using57* {@link HostIdentifier#resolve}.58* </li>59* <li>{@code servername} - The treatment of the Path, Query, and60* Fragment components of the VmIdentifier are implementation61* (protocol) dependent. A VmIdentifier omitting the protocol should62* be resolved against a HostIdentifier using63* {@link HostIdentifier#resolve}.64* </li>65* </ul>66* <p>67* All VmIdentifier instances are constructed as absolute, hierarchical URIs.68* The constructors will accept relative (and even some malformed,69* though convenient) URI strings. Such strings are transformed into70* legitimate, absolute URI strings.71* <p>72* With the exception of <em>file:</em> based VmIdentifier strings, all73* VmIdentifier strings must include a {@code lvmid}. Attempting to construct74* a non-file based VmIdentifier that doesn't include a {@code lvmid}75* component will result in a {@code MonitorException}.76* <p>77* Here are some examples of VmIdentifier strings.78* <ul>79* <li>Relative URIs80* <ul>81* <li><em>1234</em> - Specifies the Java Virtual Machine82* identified by lvmid <em>1234</em> on an unnamed host.83* This string is transformed into the absolute form84* <em>//1234</em>, which must be resolved against a85* HostIdentifier.86* </li>87* <li><em>1234@hostname</em> - Specifies the Java Virtual88* Machine identified by lvmid <em>1234</em> on host89* <em>hostname</em> with an unnamed protocol.90* This string is transformed into the absolute form91* <em>//1234@hostname</em>, which must be resolved against92* a HostIdentifier.93* </li>94* <li><em>1234@hostname:2099</em> - Specifies the Java Virtual95* Machine identified by lvmid <em>1234</em> on host96* <em>hostname</em> with an unnamed protocol, but with97* port <em>2099</em>. This string is transformed into98* the absolute form <em>//1234@hostname:2099</em>, which99* must be resolved against a HostIdentifier.100* </li>101* </ul>102* </li>103* <li>Absolute URIs104* <ul>105* <li><em>rmi://1234@hostname:2099/remoteobjectname</em> -106* Specifies the Java Virtual Machine identified by lvmid107* <em>1234</em> on host <em>hostname</em> accessed108* using the <em>rmi:</em> protocol through the rmi remote109* object named <em>remoteobjectname</em> as registered with110* the <em>rmiserver</em> on port <em>2099</em> on host111* <em>hostname</em>.112* </li>113* <li><em>file:/path/file</em> - Identifies a Java Virtual Machine114* through accessing a special file based protocol to use as115* the communications mechanism.116* </li>117* </ul>118* </li>119* </ul>120*121* @see URI122* @see HostIdentifier123* @author Brian Doherty124* @since 1.5125*/126public class VmIdentifier {127private URI uri;128129/**130* creates a canonical representation of the uriString. This method131* performs certain translations depending on the type of URI generated132* by the string.133*/134private URI canonicalize(String uriString) throws URISyntaxException {135if (uriString == null) {136uriString = "local://0@localhost";137return new URI(uriString);138}139140URI u = new URI(uriString);141142if (u.isAbsolute()) {143if (u.isOpaque()) {144/*145* rmi:1234@hostname/path#fragment converted to146* rmi://1234@hostname/path#fragment147*/148u = new URI(u.getScheme(), "//" + u.getSchemeSpecificPart(),149u.getFragment());150}151} else {152/*153* make the uri absolute, if possible. A relative URI doesn't154* specify the scheme part, so it's safe to prepend a "//" and155* try again.156*/157if (!uriString.startsWith("//")) {158if (u.getFragment() == null) {159u = new URI("//" + u.getSchemeSpecificPart());160} else {161u = new URI("//" + u.getSchemeSpecificPart() + "#"162+ u.getFragment());163}164}165}166return u;167}168169/**170* check that the VmIdentifier includes a unique numerical identifier171* for the target JVM.172*/173private void validate() throws URISyntaxException {174// file:// uri, which is a special case where the lvmid is not required.175String s = getScheme();176if ((s != null) && (s.compareTo("file") == 0)) {177return;178}179if (getLocalVmId() == -1) {180throw new URISyntaxException(uri.toString(), "Local vmid required");181}182}183184/**185* Create a VmIdentifier instance from a string value.186*187* @param uriString a string representing a target Java Virtual Machine.188* The syntax of the string must conforms to the rules189* specified in the class documentation.190* @throws URISyntaxException Thrown when the uriString or its canonical191* form is poorly formed.192*/193public VmIdentifier(String uriString) throws URISyntaxException {194URI u;195try {196u = canonicalize(uriString);197} catch (URISyntaxException e) {198/*199* a vmid of the form 1234@hostname:1098 causes an exception,200* so try again with a leading "//"201*/202if (uriString.startsWith("//")) {203throw e;204}205u = canonicalize("//"+uriString);206}207208uri = u;209210// verify that we have a valid lvmid211validate();212}213214/**215* Create a VmIdentifier instance from a URI object.216*217* @param uri a well formed, absolute URI indicating the218* target Java Virtual Machine.219* @throws URISyntaxException Thrown if the URI is missing some220* required component.221*/222public VmIdentifier(URI uri) throws URISyntaxException {223this.uri = uri;224validate();225}226227/**228* Return the corresponding HostIdentifier for this VmIdentifier.229* <p>230* This method constructs a HostIdentifier object from the VmIdentifier.231* If the VmIdentifier is not specific about the protocol or other232* components of the URI, then the resulting HostIdentifier will233* be constructed based on this missing information. Typically, the234* missing components will have result in the HostIdentifier assigning235* assumed defaults that allow the VmIdentifier to be resolved according236* to those defaults.237* <p>238* For example, a VmIdentifier that specifies only a {@code lvmid}239* will result in a HostIdentifier for <em>localhost</em> utilizing240* the default local protocol, <em>local:</em>. A VmIdentifier that241* specifies both a {@code vmid} and a {@code hostname} will result242* in a HostIdentifier for the specified host with the default remote243* protocol, <em>rmi:</em>, using the protocol defaults for the244* {@code port} and {@code servername} components.245*246* @return HostIdentifier - the host identifier for the host containing247* the Java Virtual Machine represented by this248* VmIdentifier.249* @throws URISyntaxException Thrown if a bad host URI is constructed.250* This exception may get encapsulated into251* a MonitorException in a future version.252*/253public HostIdentifier getHostIdentifier() throws URISyntaxException {254StringBuilder sb = new StringBuilder();255if (getScheme() != null) {256sb.append(getScheme()).append(":");257}258sb.append("//").append(getHost());259if (getPort() != -1) {260sb.append(":").append(getPort());261}262if (getPath() != null) {263sb.append(getPath());264}265return new HostIdentifier(sb.toString());266}267268/**269* Return the Scheme, or protocol, portion of this VmIdentifier.270*271* @return String - the scheme for this VmIdentifier.272* @see URI#getScheme()273*/274public String getScheme() {275return uri.getScheme();276}277278/**279* Return the Scheme Specific Part of this VmIdentifier.280*281* @return String - the Scheme Specific Part for this VmIdentifier.282* @see URI#getSchemeSpecificPart()283*/284public String getSchemeSpecificPart() {285return uri.getSchemeSpecificPart();286}287288/**289* Return the UserInfo part of this VmIdentifier.290*291* @return String - the UserInfo part for this VmIdentifier.292* @see URI#getUserInfo()293*/294public String getUserInfo() {295return uri.getUserInfo();296}297298/**299* Return the Host part of this VmIdentifier.300*301* @return String - the Host part for this VmIdentifier.302* @see URI#getHost()303*/304public String getHost() {305return uri.getHost();306}307308/**309* Return the Port part of this VmIdentifier.310*311* @return int - the Port part for this VmIdentifier.312* @see URI#getPort()313*/314public int getPort() {315return uri.getPort();316}317318/**319* Return the Authority part of this VmIdentifier.320*321* @return String - the Authority part for this VmIdentifier.322* @see URI#getAuthority()323*/324public String getAuthority() {325return uri.getAuthority();326}327328/**329* Return the Path part of this VmIdentifier.330*331* @return String - the Path part for this VmIdentifier.332* @see URI#getPath()333*/334public String getPath() {335return uri.getPath();336}337338/**339* Return the Query part of this VmIdentifier.340*341* @return String - the Query part for this VmIdentifier.342* @see URI#getQuery()343*/344public String getQuery() {345return uri.getQuery();346}347348/**349* Return the Fragment part of this VmIdentifier.350*351* @return String - the Fragment part for this VmIdentifier.352* @see URI#getFragment()353*/354public String getFragment() {355return uri.getFragment();356}357358/**359* Return the Local Virtual Machine Identifier for this VmIdentifier.360* The Local Virtual Machine Identifier is also known as the361* <em>lvmid</em>.362*363* @return int - the lvmid for this VmIdentifier.364*/365public int getLocalVmId() {366int result = -1;367try {368if (uri.getUserInfo() == null) {369result = Integer.parseInt(uri.getAuthority());370} else {371result = Integer.parseInt(uri.getUserInfo());372}373} catch (NumberFormatException e) { }374return result;375}376377/**378* Return the mode indicated in this VmIdentifier.379*380* @return String - the mode string. If no mode is specified, then "r"381* is returned. otherwise, the specified mode is returned.382*/383public String getMode() {384String query = getQuery();385if (query != null) {386String[] queryArgs = query.split("\\+");387for (int i = 0; i < queryArgs.length; i++) {388if (queryArgs[i].startsWith("mode=")) {389int index = queryArgs[i].indexOf('=');390return queryArgs[i].substring(index+1);391}392}393}394return "r";395}396397/**398* Return the URI associated with the VmIdentifier.399*400* @return URI - the URI.401* @see URI402*/403public URI getURI() {404return uri;405}406407/**408* Return the hash code for this VmIdentifier. The hash code is409* identical to the hash code for the contained URI.410*411* @return int - the hashcode.412* @see URI#hashCode()413*/414public int hashCode() {415return uri.hashCode();416}417418/**419* Test for quality with other objects.420*421* @param object the object to be test for equality.422* @return boolean - returns true if the given object is of type423* VmIdentifier and its URI field is equal to424* this object's URI field. Otherwise, return false.425*426* @see URI#equals(Object)427*/428public boolean equals(Object object) {429if (object == this) {430return true;431}432if (!(object instanceof VmIdentifier)) {433return false;434}435return uri.equals(((VmIdentifier)object).uri);436}437438/**439* Convert to a string representation. Conversion is identical to440* calling getURI().toString(). This may change in a future release.441*442* @return String - a String representation of the VmIdentifier.443*444* @see URI#toString()445*/446public String toString() {447return uri.toString();448}449}450451452