History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/jvmstat/monitor/HostIdentifier.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/jvmstat/monitor/HostIdentifier.java+569−0
@@ -0,0 +1,569 @@
1+/*
2+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.jvmstat.monitor;
27+
28+import java.net.*;
29+
30+/**
31+ * An abstraction that identifies a target host and communications
32+ * protocol. The HostIdentifier, or hostid, provides a convenient string
33+ * representation of the information needed to locate and communicate with
34+ * a target host. The string, based on a {@link URI}, may specify the
35+ * the communications protocol, host name, and protocol specific information
36+ * for a target host. The format for a HostIdentifier string is:
37+ * <pre>
38+ * [<I>protocol</I>:][[<I>//</I>]<I>hostname</I>][<I>:port</I>][<I>/servername</I>]
39+ * </pre>
40+ * There are actually no required components of this string, as a null string
41+ * is interpreted to mean a local connection to the local host and is equivalent
42+ * to the string <em>local://localhost</em>. The components of the
43+ * HostIdentifier are:
44+ * <ul>
45+ * <li><p><tt>protocol</tt> - The communications protocol. If omitted,
46+ * and a hostname is not specified, then default local protocol,
47+ * <em>local:</em>, is assumed. If the protocol is omitted and a
48+ * hostname is specified then the default remote protocol,
49+ * <em>rmi:</em> is assumed.
50+ * </p></li>
51+ * <li><p><tt>hostname</tt> - The hostname. If omitted, then
52+ * <em>localhost</em> is assumed. If the protocol is also omitted,
53+ * then default local protocol <em>local:</em> is also assumed.
54+ * If the hostname is not omitted but the protocol is omitted,
55+ * then the default remote protocol, <em>rmi:</em> is assumed.
56+ * </p></li>
57+ * <li><p><tt>port</tt> - The port for the communications protocol.
58+ * Treatment of the <tt>port</tt> parameter is implementation
59+ * (protocol) specific. It is unused by the default local protocol,
60+ * <em>local:</em>. For the default remote protocol, <em>rmi:</em>,
61+ * <tt>port</tt> indicates the port number of the <em>rmiregistry</em>
62+ * on the target host and defaults to port 1099.
63+ * </p></li>
64+ * <li><p><tt>servername</tt> - The treatment of the Path, Query, and
65+ * Fragment components of the HostIdentifier are implementation
66+ * (protocol) dependent. These components are ignored by the
67+ * default local protocol, <em>local:</em>. For the default remote
68+ * protocol, <em>rmi</em>, the Path component is interpreted as
69+ * the name of the RMI remote object. The Query component may
70+ * contain an access mode specifier <em>?mode=</em> specifying
71+ * <em>"r"</em> or <em>"rw"</em> access (write access currently
72+ * ignored). The Fragment part is ignored.
73+ * </p></li>
74+ * </ul>
75+ * <p>
76+ * All HostIdentifier objects are represented as absolute, hierarchical URIs.
77+ * The constructors accept relative URIs, but these will generally be
78+ * transformed into an absolute URI specifying a default protocol. A
79+ * HostIdentifier differs from a URI in that certain contractions and
80+ * illicit syntactical constructions are allowed. The following are all
81+ * valid HostIdentifier strings:
82+ *
83+ * <ul>
84+ * <li><p>&lt null &gt - transformed into "//localhost"</p></li>
85+ * <li><p>localhost - transformed into "//localhost"</p></li>
86+ * <li><p>hostname - transformed into "//hostname"</p></li>
87+ * <li><p>hostname:port - transformed into "//hostname:port"</p></li>
88+ * <li><p>proto:hostname - transformed into "proto://hostname"</p></li>
89+ * <li><p>proto:hostname:port - transformed into
90+ * "proto://hostname:port"</p></li>
91+ * <li><p>proto://hostname:port</p></li>
92+ * </ul>
93+ * </p>
94+ *
95+ * @see URI
96+ * @see VmIdentifier
97+ *
98+ * @author Brian Doherty
99+ * @since 1.5
100+ */
101+public class HostIdentifier {
102+ private URI uri;
103+
104+ /**
105+ * creates a canonical representation of the uriString. This method
106+ * performs certain translations depending on the type of URI generated
107+ * by the string.
108+ */
109+ private URI canonicalize(String uriString) throws URISyntaxException {
110+ if ((uriString == null) || (uriString.compareTo("localhost") == 0)) {
111+ uriString = "//localhost";
112+ return new URI(uriString);
113+ }
114+
115+ URI u = new URI(uriString);
116+
117+ if (u.isAbsolute()) {
118+ if (u.isOpaque()) {
119+ /*
120+ * this code is here to deal with a special case. For ease of
121+ * use, we'd like to be able to handle the case where the user
122+ * specifies hostname:port, not requiring the scheme part.
123+ * This introduces some subtleties.
124+ * hostname:port - scheme = hostname
125+ * - schemespecificpart = port
126+ * - hostname = null
127+ * - userinfo=null
128+ * however, someone could also enter scheme:hostname:port and
129+ * get into this code. the strategy is to consider this
130+ * syntax illegal and provide some code to defend against it.
131+ * Basically, we test that the string contains only one ":"
132+ * and that the ssp is numeric. If we get two colons, we will
133+ * attempt to insert the "//" after the first colon and then
134+ * try to create a URI from the resulting string.
135+ */
136+ String scheme = u.getScheme();
137+ String ssp = u.getSchemeSpecificPart();
138+ String frag = u.getFragment();
139+ URI u2 = null;
140+
141+ int c1index = uriString.indexOf(":");
142+ int c2index = uriString.lastIndexOf(":");
143+ if (c2index != c1index) {
144+ /*
145+ * this is the scheme:hostname:port case. Attempt to
146+ * transform this to scheme://hostname:port. If a path
147+ * part is part of the original strings, it will be
148+ * included in the SchemeSpecificPart. however, the
149+ * fragment part must be handled separately.
150+ */
151+ if (frag == null) {
152+ u2 = new URI(scheme + "://" + ssp);
153+ } else {
154+ u2 = new URI(scheme + "://" + ssp + "#" + frag);
155+ }
156+ return u2;
157+ }
158+ /*
159+ * here we have the <string>:<string> case, possibly with
160+ * optional path and fragment components. we assume that
161+ * the part following the colon is a number. we don't check
162+ * this condition here as it will get detected later anyway.
163+ */
164+ u2 = new URI("//" + uriString);
165+ return u2;
166+ } else {
167+ return u;
168+ }
169+ } else {
170+ /*
171+ * This is the case where we were given a hostname followed
172+ * by a path part, fragment part, or both a path and fragment
173+ * part. The key here is that no scheme part was specified.
174+ * For this case, if the scheme specific part does not begin
175+ * with "//", then we prefix the "//" to the given string and
176+ * attempt to create a URI from the resulting string.
177+ */
178+ String ssp = u.getSchemeSpecificPart();
179+ if (ssp.startsWith("//")) {
180+ return u;
181+ } else {
182+ return new URI("//" + uriString);
183+ }
184+ }
185+ }
186+
187+ /**
188+ * Create a HostIdentifier instance from a string value.
189+ *
190+ * @param uriString a string representing a target host. The syntax of
191+ * the string must conform to the rules specified in the
192+ * class documentation.
193+ *
194+ * @throws URISyntaxException Thrown when the uriString or its canonical
195+ * form is poorly formed. This exception may
196+ * get encapsulated into a MonitorException in
197+ * a future version.
198+ *
199+ */
200+ public HostIdentifier(String uriString) throws URISyntaxException {
201+ uri = canonicalize(uriString);
202+ }
203+
204+ /**
205+ * Create a HostIdentifier instance from component parts of a URI.
206+ *
207+ * @param scheme the {@link URI#getScheme} component of a URI.
208+ * @param authority the {@link URI#getAuthority} component of a URI.
209+ * @param path the {@link URI#getPath} component of a URI.
210+ * @param query the {@link URI#getQuery} component of a URI.
211+ * @param fragment the {@link URI#getFragment} component of a URI.
212+ *
213+ * @throws URISyntaxException Thrown when the uriString or its canonical
214+ * form is poorly formed. This exception may
215+ * get encapsulated into a MonitorException in
216+ * a future version.
217+ * @see URI
218+ */
219+ public HostIdentifier(String scheme, String authority, String path,
220+ String query, String fragment)
221+ throws URISyntaxException {
222+ uri = new URI(scheme, authority, path, query, fragment);
223+ }
224+
225+ /**
226+ * Create a HostIdentifier instance from a VmIdentifier.
227+ *
228+ * The necessary components of the VmIdentifier are extracted and
229+ * reassembled into a HostIdentifier. If a "file:" scheme (protocol)
230+ * is specified, the the returned HostIdentifier will always be
231+ * equivalent to HostIdentifier("file://localhost").
232+ *
233+ * @param vmid the VmIdentifier use to construct the HostIdentifier.
234+ */
235+ public HostIdentifier(VmIdentifier vmid) {
236+ /*
237+ * Extract all components of the VmIdentifier URI except the
238+ * user-info part of the authority (the lvmid).
239+ */
240+ StringBuilder sb = new StringBuilder();
241+ String scheme = vmid.getScheme();
242+ String host = vmid.getHost();
243+ String authority = vmid.getAuthority();
244+
245+ // check for 'file:' VmIdentifiers and handled as a special case.
246+ if ((scheme != null) && (scheme.compareTo("file") == 0)) {
247+ try {
248+ uri = new URI("file://localhost");
249+ } catch (URISyntaxException e) { };
250+ return;
251+ }
252+
253+ if ((host != null) && (host.compareTo(authority) == 0)) {
254+ /*
255+ * this condition occurs when the VmIdentifier specifies only
256+ * the authority (i.e. the lvmid ), and not a host name.
257+ */
258+ host = null;
259+ }
260+
261+ if (scheme == null) {
262+ if (host == null) {
263+ scheme = "local"; // default local scheme
264+ } else {
265+ /*
266+ * rmi is the default remote scheme. if the VmIdentifier
267+ * specifies some other protocol, this default is overridden.
268+ */
269+ scheme = "rmi";
270+ }
271+ }
272+
273+ sb.append(scheme).append("://");
274+
275+ if (host == null) {
276+ sb.append("localhost"); // default host name
277+ } else {
278+ sb.append(host);
279+ }
280+
281+ int port = vmid.getPort();
282+ if (port != -1) {
283+ sb.append(":").append(port);
284+ }
285+
286+ String path = vmid.getPath();
287+ if ((path != null) && (path.length() != 0)) {
288+ sb.append(path);
289+ }
290+
291+ String query = vmid.getQuery();
292+ if (query != null) {
293+ sb.append("?").append(query);
294+ }
295+
296+ String frag = vmid.getFragment();
297+ if (frag != null) {
298+ sb.append("#").append(frag);
299+ }
300+
301+ try {
302+ uri = new URI(sb.toString());
303+ } catch (URISyntaxException e) {
304+ // shouldn't happen, as we were passed a valid VmIdentifier
305+ throw new RuntimeException("Internal Error", e);
306+ }
307+ }
308+
309+ /**
310+ * Resolve a VmIdentifier with this HostIdentifier. A VmIdentifier, such
311+ * as <em>1234</em> or <em>1234@hostname</em> or any other string that
312+ * omits certain components of the URI string may be valid, but is certainly
313+ * incomplete. They are missing critical information for identifying the
314+ * the communications protocol, target host, or other parameters. A
315+ * VmIdentifier of this form is considered <em>unresolved</em>. This method
316+ * uses components of the HostIdentifier to resolve the missing components
317+ * of the VmIdentifier.
318+ * <p>
319+ * Specified components of the unresolved VmIdentifier take precedence
320+ * over their HostIdentifier counterparts. For example, if the VmIdentifier
321+ * indicates <em>1234@hostname:2099</em> and the HostIdentifier indicates
322+ * <em>rmi://hostname:1099/</em>, then the resolved VmIdentifier will
323+ * be <em>rmi://1234@hostname:2099</em>. Any component not explicitly
324+ * specified or assumed by the HostIdentifier, will remain unresolved in
325+ * resolved VmIdentifier.
326+ * <p>
327+ * A VmIdentifier specifying a <em>file:</em> scheme (protocol), is
328+ * not changed in any way by this method.
329+ *
330+ * @param vmid the unresolved VmIdentifier.
331+ * @return VmIdentifier - the resolved VmIdentifier. If vmid was resolved
332+ * on entry to this method, then the returned
333+ * VmIdentifier will be equal, but not identical, to
334+ * vmid.
335+ */
336+ public VmIdentifier resolve(VmIdentifier vmid)
337+ throws URISyntaxException, MonitorException {
338+ String scheme = vmid.getScheme();
339+ String host = vmid.getHost();
340+ String authority = vmid.getAuthority();
341+
342+ if ((scheme != null) && (scheme.compareTo("file") == 0)) {
343+ // don't attempt to resolve a file based VmIdentifier.
344+ return vmid;
345+ }
346+
347+ if ((host != null) && (host.compareTo(authority) == 0)) {
348+ /*
349+ * this condition occurs when the VmIdentifier specifies only
350+ * the authority (i.e. an lvmid), and not a host name.
351+ */
352+ host = null;
353+ }
354+
355+ if (scheme == null) {
356+ scheme = getScheme();
357+ }
358+
359+ URI nuri = null;
360+
361+ StringBuffer sb = new StringBuffer();
362+
363+ sb.append(scheme).append("://");
364+
365+ String userInfo = vmid.getUserInfo();
366+ if (userInfo != null) {
367+ sb.append(userInfo);
368+ } else {
369+ sb.append(vmid.getAuthority());
370+ }
371+
372+ if (host == null) {
373+ host = getHost();
374+ }
375+ sb.append("@").append(host);
376+
377+ int port = vmid.getPort();
378+ if (port == -1) {
379+ port = getPort();
380+ }
381+
382+ if (port != -1) {
383+ sb.append(":").append(port);
384+ }
385+
386+ String path = vmid.getPath();
387+ if ((path == null) || (path.length() == 0)) {
388+ path = getPath();
389+ }
390+
391+ if ((path != null) && (path.length() > 0)) {
392+ sb.append(path);
393+ }
394+
395+ String query = vmid.getQuery();
396+ if (query == null) {
397+ query = getQuery();
398+ }
399+ if (query != null) {
400+ sb.append("?").append(query);
401+ }
402+
403+ String fragment = vmid.getFragment();
404+ if (fragment == null) {
405+ fragment = getFragment();
406+ }
407+ if (fragment != null) {
408+ sb.append("#").append(fragment);
409+ }
410+
411+ String s = sb.toString();
412+ return new VmIdentifier(s);
413+ }
414+
415+ /**
416+ * Return the Scheme, or protocol, portion of this HostIdentifier.
417+ *
418+ * @return String - the scheme for this HostIdentifier.
419+ * @see URI#getScheme()
420+ */
421+ public String getScheme() {
422+ return uri.isAbsolute() ? uri.getScheme() : null;
423+ }
424+
425+ /**
426+ * Return the Scheme Specific Part of this HostIdentifier.
427+ *
428+ * @return String - the scheme specific part for this HostIdentifier.
429+ * @see URI#getSchemeSpecificPart()
430+ */
431+ public String getSchemeSpecificPart() {
432+ return uri.getSchemeSpecificPart();
433+ }
434+
435+ /**
436+ * Return the User Info part of this HostIdentifier.
437+ *
438+ * @return String - the user info part for this HostIdentifier.
439+ * @see URI#getUserInfo()
440+ */
441+ public String getUserInfo() {
442+ return uri.getUserInfo();
443+ }
444+
445+ /**
446+ * Return the Host part of this HostIdentifier.
447+ *
448+ * @return String - the host part for this HostIdentifier, or
449+ * "localhost" if the URI.getHost() returns null.
450+ * @see URI#getUserInfo()
451+ */
452+ public String getHost() {
453+ return (uri.getHost() == null) ? "localhost" : uri.getHost();
454+ }
455+
456+ /**
457+ * Return the Port for of this HostIdentifier.
458+ *
459+ * @return String - the port for this HostIdentifier
460+ * @see URI#getPort()
461+ */
462+ public int getPort() {
463+ return uri.getPort();
464+ }
465+
466+ /**
467+ * Return the Path part of this HostIdentifier.
468+ *
469+ * @return String - the path part for this HostIdentifier.
470+ * @see URI#getPath()
471+ */
472+ public String getPath() {
473+ return uri.getPath();
474+ }
475+
476+ /**
477+ * Return the Query part of this HostIdentifier.
478+ *
479+ * @return String - the query part for this HostIdentifier.
480+ * @see URI#getQuery()
481+ */
482+ public String getQuery() {
483+ return uri.getQuery();
484+ }
485+
486+ /**
487+ * Return the Fragment part of this HostIdentifier.
488+ *
489+ * @return String - the fragment part for this HostIdentifier.
490+ * @see URI#getFragment()
491+ */
492+ public String getFragment() {
493+ return uri.getFragment();
494+ }
495+
496+ /**
497+ * Return the mode indicated in this HostIdentifier.
498+ *
499+ * @return String - the mode string. If no mode is specified, then "r"
500+ * is returned. otherwise, the specified mode is returned.
501+ */
502+ public String getMode() {
503+ String query = getQuery();
504+ if (query != null) {
505+ String[] queryArgs = query.split("\\+");
506+ for (int i = 0; i < queryArgs.length; i++) {
507+ if (queryArgs[i].startsWith("mode=")) {
508+ int index = queryArgs[i].indexOf('=');
509+ return queryArgs[i].substring(index+1);
510+ }
511+ }
512+ }
513+ return "r";
514+ }
515+
516+ /**
517+ * Return the URI associated with the HostIdentifier.
518+ *
519+ * @return URI - the URI.
520+ * @see URI
521+ */
522+ public URI getURI() {
523+ return uri;
524+ }
525+
526+ /**
527+ * Return the hash code for this HostIdentifier. The hash code is
528+ * identical to the hash code for the contained URI.
529+ *
530+ * @return int - the hashcode.
531+ * @see URI#hashCode()
532+ */
533+ public int hashCode() {
534+ return uri.hashCode();
535+ }
536+
537+ /**
538+ * Test for quality with other objects.
539+ *
540+ * @param object the object to be test for equality.
541+ * @return boolean - returns true if the given object is of type
542+ * HostIdentifier and its URI field is equal to this
543+ * object's URI field. Otherwise, returns false.
544+ *
545+ * @see URI#equals(Object)
546+ */
547+ public boolean equals(Object object) {
548+ if (object == this) {
549+ return true;
550+ }
551+ if (!(object instanceof HostIdentifier)) {
552+ return false;
553+ }
554+ return uri.equals(((HostIdentifier)object).uri);
555+ }
556+
557+
558+ /**
559+ * Convert to a string representation. Conversion is identical to
560+ * calling getURI().toString(). This may change in a future release.
561+ *
562+ * @return String - a String representation of the HostIdentifier.
563+ *
564+ * @see URI#toString()
565+ */
566+ public String toString() {
567+ return uri.toString();
568+ }
569+}