Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/jvmstat/monitor/VmIdentifier.java
38918 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 <tt>lvmid</tt>, which uniquely identifies the target42* Java Virtual Machine on a host. The optional components of the VmIdentifier43* include:44* <ul>45* <li><p><tt>protocol</tt> - The communications protocol. A VmIdentifier46* omitting the protocol must be resolved against a HostIdentifier47* using {@link HostIdentifier#resolve}.48* </p></li>49* <li><p><tt>hostname</tt> - 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* </p></li>53* <li><p><tt>port</tt> - The port for the communications protocol.54* Treatment of the <tt>port</tt> parameter is implementation55* (protocol) specific. A VmIdentifier omitting the protocol should56* be resolved against a HostIdentifier using57* {@link HostIdentifier#resolve}.58* </p></li>59* <li><p><tt>servername</tt> - 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* </p></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* <p>73* With the exception of <em>file:</em> based VmIdentifier strings, all74* VmIdentifier strings must include a <tt>lvmid</tt>. Attempting to construct75* a non-file based VmIdentifier that doesn't include a <tt>lvmid</tt>76* component will result in a <tt>MonitorException</tt>.77* </p>78* <p>79* Here are some examples of VmIdentifier strings.80* <ul>81* <li><p>Relative URIs</p></li>82* <ul>83* <li><p><em>1234</em> - Specifies the Java Virtual Machine84* identified by lvmid <em>1234</em> on an unnamed host.85* This string is transformed into the absolute form86* <em>//1234</em>, which must be resolved against a87* HostIdentifier.88* </p></li>89* <li><p><em>1234@hostname</em> - Specifies the Java Virtual90* Machine identified by lvmid <em>1234</em> on host91* <em>hostname</em> with an unnamed protocol.92* This string is transformed into the absolute form93* <em>//1234@hostname</em>, which must be resolved against94* a HostIdentifier.95* </p></li>96* <li><p><em>1234@hostname:2099</em> - Specifies the Java Virtual97* Machine identified by lvmid <em>1234</em> on host98* <em>hostname</em> with an unnamed protocol, but with99* port <em>2099</em>. This string is transformed into100* the absolute form <em>//1234@hostname:2099</em>, which101* must be resolved against a HostIdentifier.102* </p></li>103* </ul>104* <li><p>Absolute URIs</p></li>105* <ul>106* <li><p><em>rmi://1234@hostname:2099/remoteobjectname</em> -107* Specifies the Java Virtual Machine identified by lvmid108* <em>1234</em> on host <em>hostname</em> accessed109* using the <em>rmi:</em> protocol through the rmi remote110* object named <em>remoteobjectname</em> as registered with111* the <em>rmiserver</em> on port <em>2099</em> on host112* <em>hostname</em>.113* </p></li>114* <li><p><em>file:/path/file</em> - Identifies a Java Virtual Machine115* through accessing a special file based protocol to use as116* the communications mechanism.117* </p></li>118* </ul>119* </ul>120* </p>121*122* @see URI123* @see HostIdentifier124* @author Brian Doherty125* @since 1.5126*/127public class VmIdentifier {128private URI uri;129130/**131* creates a canonical representation of the uriString. This method132* performs certain translations depending on the type of URI generated133* by the string.134*/135private URI canonicalize(String uriString) throws URISyntaxException {136if (uriString == null) {137uriString = "local://0@localhost";138return new URI(uriString);139}140141URI u = new URI(uriString);142143if (u.isAbsolute()) {144if (u.isOpaque()) {145/*146* rmi:1234@hostname/path#fragment converted to147* rmi://1234@hostname/path#fragment148*/149u = new URI(u.getScheme(), "//" + u.getSchemeSpecificPart(),150u.getFragment());151}152} else {153/*154* make the uri absolute, if possible. A relative URI doesn't155* specify the scheme part, so it's safe to prepend a "//" and156* try again.157*/158if (!uriString.startsWith("//")) {159if (u.getFragment() == null) {160u = new URI("//" + u.getSchemeSpecificPart());161} else {162u = new URI("//" + u.getSchemeSpecificPart() + "#"163+ u.getFragment());164}165}166}167return u;168}169170/**171* check that the VmIdentifier includes a unique numerical identifier172* for the target JVM.173*/174private void validate() throws URISyntaxException {175// file:// uri, which is a special case where the lvmid is not required.176String s = getScheme();177if ((s != null) && (s.compareTo("file") == 0)) {178return;179}180if (getLocalVmId() == -1) {181throw new URISyntaxException(uri.toString(), "Local vmid required");182}183}184185/**186* Create a VmIdentifier instance from a string value.187*188* @param uriString a string representing a target Java Virtual Machine.189* The syntax of the string must conforms to the rules190* specified in the class documentation.191* @throws URISyntaxException Thrown when the uriString or its canonical192* form is poorly formed.193*/194public VmIdentifier(String uriString) throws URISyntaxException {195URI u;196try {197u = canonicalize(uriString);198} catch (URISyntaxException e) {199/*200* a vmid of the form 1234@hostname:1098 causes an exception,201* so try again with a leading "//"202*/203if (uriString.startsWith("//")) {204throw e;205}206u = canonicalize("//"+uriString);207}208209uri = u;210211// verify that we have a valid lvmid212validate();213}214215/**216* Create a VmIdentifier instance from a URI object.217*218* @param uri a well formed, absolute URI indicating the219* target Java Virtual Machine.220* @throws URISyntaxException Thrown if the URI is missing some221* required component.222*/223public VmIdentifier(URI uri) throws URISyntaxException {224this.uri = uri;225validate();226}227228/**229* Return the corresponding HostIdentifier for this VmIdentifier.230* <p>231* This method constructs a HostIdentifier object from the VmIdentifier.232* If the VmIdentifier is not specific about the protocol or other233* components of the URI, then the resulting HostIdentifier will234* be constructed based on this missing information. Typically, the235* missing components will have result in the HostIdentifier assigning236* assumed defaults that allow the VmIdentifier to be resolved according237* to those defaults.238* </p>239* <p>240* For example, a VmIdentifier that specifies only a <tt>lvmid</tt>241* will result in a HostIdentifier for <em>localhost</em> utilizing242* the default local protocol, <em>local:</em>. A VmIdentifier that243* specifies both a <tt>vmid</tt> and a <tt>hostname</tt> will result244* in a HostIdentifier for the specified host with the default remote245* protocol, <em>rmi:</em>, using the protocol defaults for the246* <tt>port</tt> and <tt>servername</tt> components.247* </p>248*249* @return HostIdentifier - the host identifier for the host containing250* the Java Virtual Machine represented by this251* VmIdentifier.252* @throws URISyntaxException Thrown if a bad host URI is constructed.253* This exception may get encapsulated into254* a MonitorException in a future version.255*/256public HostIdentifier getHostIdentifier() throws URISyntaxException {257StringBuffer sb = new StringBuffer();258if (getScheme() != null) {259sb.append(getScheme()).append(":");260}261sb.append("//").append(getHost());262if (getPort() != -1) {263sb.append(":").append(getPort());264}265if (getPath() != null) {266sb.append(getPath());267}268return new HostIdentifier(sb.toString());269}270271/**272* Return the Scheme, or protocol, portion of this VmIdentifier.273*274* @return String - the scheme for this VmIdentifier.275* @see URI#getScheme()276*/277public String getScheme() {278return uri.getScheme();279}280281/**282* Return the Scheme Specific Part of this VmIdentifier.283*284* @return String - the Scheme Specific Part for this VmIdentifier.285* @see URI#getSchemeSpecificPart()286*/287public String getSchemeSpecificPart() {288return uri.getSchemeSpecificPart();289}290291/**292* Return the UserInfo part of this VmIdentifier.293*294* @return String - the UserInfo part for this VmIdentifier.295* @see URI#getUserInfo()296*/297public String getUserInfo() {298return uri.getUserInfo();299}300301/**302* Return the Host part of this VmIdentifier.303*304* @return String - the Host part for this VmIdentifier.305* @see URI#getHost()306*/307public String getHost() {308return uri.getHost();309}310311/**312* Return the Port part of this VmIdentifier.313*314* @return int - the Port part for this VmIdentifier.315* @see URI#getPort()316*/317public int getPort() {318return uri.getPort();319}320321/**322* Return the Authority part of this VmIdentifier.323*324* @return String - the Authority part for this VmIdentifier.325* @see URI#getAuthority()326*/327public String getAuthority() {328return uri.getAuthority();329}330331/**332* Return the Path part of this VmIdentifier.333*334* @return String - the Path part for this VmIdentifier.335* @see URI#getPath()336*/337public String getPath() {338return uri.getPath();339}340341/**342* Return the Query part of this VmIdentifier.343*344* @return String - the Query part for this VmIdentifier.345* @see URI#getQuery()346*/347public String getQuery() {348return uri.getQuery();349}350351/**352* Return the Fragment part of this VmIdentifier.353*354* @return String - the Fragment part for this VmIdentifier.355* @see URI#getFragment()356*/357public String getFragment() {358return uri.getFragment();359}360361/**362* Return the Local Virtual Machine Identifier for this VmIdentifier.363* The Local Virtual Machine Identifier is also known as the364* <em>lvmid</em>.365*366* @return int - the lvmid for this VmIdentifier.367*/368public int getLocalVmId() {369int result = -1;370try {371if (uri.getUserInfo() == null) {372result = Integer.parseInt(uri.getAuthority());373} else {374result = Integer.parseInt(uri.getUserInfo());375}376} catch (NumberFormatException e) { }377return result;378}379380/**381* Return the mode indicated in this VmIdentifier.382*383* @return String - the mode string. If no mode is specified, then "r"384* is returned. otherwise, the specified mode is returned.385*/386public String getMode() {387String query = getQuery();388if (query != null) {389String[] queryArgs = query.split("\\+");390for (int i = 0; i < queryArgs.length; i++) {391if (queryArgs[i].startsWith("mode=")) {392int index = queryArgs[i].indexOf('=');393return queryArgs[i].substring(index+1);394}395}396}397return "r";398}399400/**401* Return the URI associated with the VmIdentifier.402*403* @return URI - the URI.404* @see URI405*/406public URI getURI() {407return uri;408}409410/**411* Return the hash code for this VmIdentifier. The hash code is412* identical to the hash code for the contained URI.413*414* @return int - the hashcode.415* @see URI#hashCode()416*/417public int hashCode() {418return uri.hashCode();419}420421/**422* Test for quality with other objects.423*424* @param object the object to be test for equality.425* @return boolean - returns true if the given object is of type426* VmIdentifier and its URI field is equal to427* this object's URI field. Otherwise, return false.428*429* @see URI#equals(Object)430*/431public boolean equals(Object object) {432if (object == this) {433return true;434}435if (!(object instanceof VmIdentifier)) {436return false;437}438return uri.equals(((VmIdentifier)object).uri);439}440441/**442* Convert to a string representation. Conversion is identical to443* calling getURI().toString(). This may change in a future release.444*445* @return String - a String representation of the VmIdentifier.446*447* @see URI#toString()448*/449public String toString() {450return uri.toString();451}452}453454455