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/tools/jstat/Arguments.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/jstat/Arguments.java+445−0
@@ -0,0 +1,445 @@
1+/*
2+ * Copyright (c) 2004, 2010, 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.tools.jstat;
27+
28+import java.io.*;
29+import java.net.*;
30+import java.util.*;
31+import java.util.regex.*;
32+import sun.jvmstat.monitor.Monitor;
33+import sun.jvmstat.monitor.VmIdentifier;
34+
35+/**
36+ * Class for processing command line arguments and providing method
37+ * level access to arguments.
38+ *
39+ * @author Brian Doherty
40+ * @since 1.5
41+ */
42+public class Arguments {
43+
44+ private static final boolean debug = Boolean.getBoolean("jstat.debug");
45+ private static final boolean showUnsupported =
46+ Boolean.getBoolean("jstat.showUnsupported");
47+
48+ private static final String JVMSTAT_USERDIR = ".jvmstat";
49+ private static final String OPTIONS_FILENAME = "jstat_options";
50+ private static final String UNSUPPORTED_OPTIONS_FILENAME = "jstat_unsupported_options";
51+ private static final String ALL_NAMES = "\\w*";
52+
53+ private Comparator<Monitor> comparator;
54+ private int headerRate;
55+ private boolean help;
56+ private boolean list;
57+ private boolean options;
58+ private boolean constants;
59+ private boolean constantsOnly;
60+ private boolean strings;
61+ private boolean timestamp;
62+ private boolean snap;
63+ private boolean verbose;
64+ private String specialOption;
65+ private String names;
66+
67+ private OptionFormat optionFormat;
68+
69+ private int count = -1;
70+ private int interval = -1;
71+ private String vmIdString;
72+
73+ private VmIdentifier vmId;
74+
75+ public static void printUsage(PrintStream ps) {
76+ ps.println("Usage: jstat -help|-options");
77+ ps.println(" jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]");
78+ ps.println();
79+ ps.println("Definitions:");
80+ ps.println(" <option> An option reported by the -options option");
81+ ps.println(" <vmid> Virtual Machine Identifier. A vmid takes the following form:");
82+ ps.println(" <lvmid>[@<hostname>[:<port>]]");
83+ ps.println(" Where <lvmid> is the local vm identifier for the target");
84+ ps.println(" Java virtual machine, typically a process id; <hostname> is");
85+ ps.println(" the name of the host running the target Java virtual machine;");
86+ ps.println(" and <port> is the port number for the rmiregistry on the");
87+ ps.println(" target host. See the jvmstat documentation for a more complete");
88+ ps.println(" description of the Virtual Machine Identifier.");
89+ ps.println(" <lines> Number of samples between header lines.");
90+ ps.println(" <interval> Sampling interval. The following forms are allowed:");
91+ ps.println(" <n>[\"ms\"|\"s\"]");
92+ ps.println(" Where <n> is an integer and the suffix specifies the units as ");
93+ ps.println(" milliseconds(\"ms\") or seconds(\"s\"). The default units are \"ms\".");
94+ ps.println(" <count> Number of samples to take before terminating.");
95+ ps.println(" -J<flag> Pass <flag> directly to the runtime system.");
96+
97+ // undocumented options:
98+ // -list [<vmid>] - list counter names
99+ // -snap <vmid> - snapshot counter values as name=value pairs
100+ // -name <pattern> - output counters matching given pattern
101+ // -a - sort in ascending order (default)
102+ // -d - sort in descending order
103+ // -v - verbose output (-snap)
104+ // -constants - output constants with -name output
105+ // -strings - output strings with -name output
106+ }
107+
108+ private static int toMillis(String s) throws IllegalArgumentException {
109+
110+ String[] unitStrings = { "ms", "s" }; // ordered from most specific to
111+ // least specific
112+ String unitString = null;
113+ String valueString = s;
114+
115+ for (int i = 0; i < unitStrings.length; i++) {
116+ int index = s.indexOf(unitStrings[i]);
117+ if (index > 0) {
118+ unitString = s.substring(index);
119+ valueString = s.substring(0, index);
120+ break;
121+ }
122+ }
123+
124+ try {
125+ int value = Integer.parseInt(valueString);
126+
127+ if (unitString == null || unitString.compareTo("ms") == 0) {
128+ return value;
129+ } else if (unitString.compareTo("s") == 0) {
130+ return value * 1000;
131+ } else {
132+ throw new IllegalArgumentException(
133+ "Unknow time unit: " + unitString);
134+ }
135+ } catch (NumberFormatException e) {
136+ throw new IllegalArgumentException(
137+ "Could not convert interval: " + s);
138+ }
139+ }
140+
141+ public Arguments(String[] args) throws IllegalArgumentException {
142+ int argc = 0;
143+
144+ if (args.length < 1) {
145+ throw new IllegalArgumentException("invalid argument count");
146+ }
147+
148+ if ((args[0].compareTo("-?") == 0)
149+ || (args[0].compareTo("-help") == 0)) {
150+ help = true;
151+ return;
152+ } else if (args[0].compareTo("-options") == 0) {
153+ options = true;
154+ return;
155+ } else if (args[0].compareTo("-list") == 0) {
156+ list = true;
157+ if (args.length > 2) {
158+ throw new IllegalArgumentException("invalid argument count");
159+ }
160+ // list can take one arg - a vmid - fall through for arg processing
161+ argc++;
162+ }
163+
164+ for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
165+ String arg = args[argc];
166+
167+ if (arg.compareTo("-a") == 0) {
168+ comparator = new AscendingMonitorComparator();
169+ } else if (arg.compareTo("-d") == 0) {
170+ comparator = new DescendingMonitorComparator();
171+ } else if (arg.compareTo("-t") == 0) {
172+ timestamp = true;
173+ } else if (arg.compareTo("-v") == 0) {
174+ verbose = true;
175+ } else if ((arg.compareTo("-constants") == 0)
176+ || (arg.compareTo("-c") == 0)) {
177+ constants = true;
178+ } else if ((arg.compareTo("-strings") == 0)
179+ || (arg.compareTo("-s") == 0)) {
180+ strings = true;
181+ } else if (arg.startsWith("-h")) {
182+ String value;
183+ if (arg.compareTo("-h") != 0) {
184+ value = arg.substring(2);
185+ } else {
186+ argc++;
187+ if (argc >= args.length) {
188+ throw new IllegalArgumentException(
189+ "-h requires an integer argument");
190+ }
191+ value = args[argc];
192+ }
193+ try {
194+ headerRate = Integer.parseInt(value);
195+ } catch (NumberFormatException e) {
196+ headerRate = -1;
197+ }
198+ if (headerRate < 0) {
199+ throw new IllegalArgumentException(
200+ "illegal -h argument: " + value);
201+ }
202+ } else if (arg.startsWith("-name")) {
203+ if (arg.startsWith("-name=")) {
204+ names = arg.substring(7);
205+ } else {
206+ argc++;
207+ if (argc >= args.length) {
208+ throw new IllegalArgumentException(
209+ "option argument expected");
210+ }
211+ names = args[argc];
212+ }
213+ } else {
214+ /*
215+ * there are scenarios here: special jstat_options file option
216+ * or the rare case of a negative lvmid. The negative lvmid
217+ * can occur in some operating environments (such as Windows
218+ * 95/98/ME), so we provide for this case here by checking if
219+ * the argument has any numerical characters. This assumes that
220+ * there are no special jstat_options that contain numerical
221+ * characters in their name.
222+ */
223+
224+ // extract the lvmid part of possible lvmid@host.domain:port
225+ String lvmidStr = null;
226+ int at_index = args[argc].indexOf('@');
227+ if (at_index < 0) {
228+ lvmidStr = args[argc];
229+ } else {
230+ lvmidStr = args[argc].substring(0, at_index);
231+ }
232+
233+ // try to parse the lvmid part as an integer
234+ try {
235+ int vmid = Integer.parseInt(lvmidStr);
236+ // it parsed, assume a negative lvmid and continue
237+ break;
238+ } catch (NumberFormatException nfe) {
239+ // it didn't parse. check for the -snap or jstat_options
240+ // file options.
241+ if ((argc == 0) && (args[argc].compareTo("-snap") == 0)) {
242+ snap = true;
243+ } else if (argc == 0) {
244+ specialOption = args[argc].substring(1);
245+ } else {
246+ throw new IllegalArgumentException(
247+ "illegal argument: " + args[argc]);
248+ }
249+ }
250+ }
251+ }
252+
253+ // prevent 'jstat <pid>' from being accepted as a valid argument
254+ if (!(specialOption != null || list || snap || names != null)) {
255+ throw new IllegalArgumentException("-<option> required");
256+ }
257+
258+ switch (args.length - argc) {
259+ case 3:
260+ if (snap) {
261+ throw new IllegalArgumentException("invalid argument count");
262+ }
263+ try {
264+ count = Integer.parseInt(args[args.length-1]);
265+ } catch (NumberFormatException e) {
266+ throw new IllegalArgumentException("illegal count value: "
267+ + args[args.length-1]);
268+ }
269+ interval = toMillis(args[args.length-2]);
270+ vmIdString = args[args.length-3];
271+ break;
272+ case 2:
273+ if (snap) {
274+ throw new IllegalArgumentException("invalid argument count");
275+ }
276+ interval = toMillis(args[args.length-1]);
277+ vmIdString = args[args.length-2];
278+ break;
279+ case 1:
280+ vmIdString = args[args.length-1];
281+ break;
282+ case 0:
283+ if (!list) {
284+ throw new IllegalArgumentException("invalid argument count");
285+ }
286+ break;
287+ default:
288+ throw new IllegalArgumentException("invalid argument count");
289+ }
290+
291+ // set count and interval to their default values if not set above.
292+ if (count == -1 && interval == -1) {
293+ // default is for a single sample
294+ count = 1;
295+ interval = 0;
296+ }
297+
298+ // validate arguments
299+ if (comparator == null) {
300+ comparator = new AscendingMonitorComparator();
301+ }
302+
303+ // allow ',' characters to separate names, convert to '|' chars
304+ names = (names == null) ? ALL_NAMES : names.replace(',', '|');
305+
306+ // verify that the given pattern parses without errors
307+ try {
308+ Pattern pattern = Pattern.compile(names);
309+ } catch (PatternSyntaxException e) {
310+ throw new IllegalArgumentException("Bad name pattern: "
311+ + e.getMessage());
312+ }
313+
314+ // verify that the special option is valid and get it's formatter
315+ if (specialOption != null) {
316+ OptionFinder finder = new OptionFinder(optionsSources());
317+ optionFormat = finder.getOptionFormat(specialOption, timestamp);
318+ if (optionFormat == null) {
319+ throw new IllegalArgumentException("Unknown option: -"
320+ + specialOption);
321+ }
322+ }
323+
324+ // verify that the vm identifier is valied
325+ try {
326+ vmId = new VmIdentifier(vmIdString);
327+ } catch (URISyntaxException e) {
328+ IllegalArgumentException iae = new IllegalArgumentException(
329+ "Malformed VM Identifier: " + vmIdString);
330+ iae.initCause(e);
331+ throw iae;
332+ }
333+ }
334+
335+ public Comparator<Monitor> comparator() {
336+ return comparator;
337+ }
338+
339+ public boolean isHelp() {
340+ return help;
341+ }
342+
343+ public boolean isList() {
344+ return list;
345+ }
346+
347+ public boolean isSnap() {
348+ return snap;
349+ }
350+
351+ public boolean isOptions() {
352+ return options;
353+ }
354+
355+ public boolean isVerbose() {
356+ return verbose;
357+ }
358+
359+ public boolean printConstants() {
360+ return constants;
361+ }
362+
363+ public boolean isConstantsOnly() {
364+ return constantsOnly;
365+ }
366+
367+ public boolean printStrings() {
368+ return strings;
369+ }
370+
371+ public boolean showUnsupported() {
372+ return showUnsupported;
373+ }
374+
375+ public int headerRate() {
376+ return headerRate;
377+ }
378+
379+ public String counterNames() {
380+ return names;
381+ }
382+
383+ public VmIdentifier vmId() {
384+ return vmId;
385+ }
386+
387+ public String vmIdString() {
388+ return vmIdString;
389+ }
390+
391+ public int sampleInterval() {
392+ return interval;
393+ }
394+
395+ public int sampleCount() {
396+ return count;
397+ }
398+
399+ public boolean isTimestamp() {
400+ return timestamp;
401+ }
402+
403+ public boolean isSpecialOption() {
404+ return specialOption != null;
405+ }
406+
407+ public String specialOption() {
408+ return specialOption;
409+ }
410+
411+ public OptionFormat optionFormat() {
412+ return optionFormat;
413+ }
414+
415+ public List<URL> optionsSources() {
416+ List<URL> sources = new ArrayList<URL>();
417+ int i = 0;
418+
419+ String filename = OPTIONS_FILENAME;
420+
421+ try {
422+ String userHome = System.getProperty("user.home");
423+ String userDir = userHome + "/" + JVMSTAT_USERDIR;
424+ File home = new File(userDir + "/" + filename);
425+ sources.add(home.toURI().toURL());
426+ } catch (Exception e) {
427+ if (debug) {
428+ System.err.println(e.getMessage());
429+ e.printStackTrace();
430+ }
431+ throw new IllegalArgumentException("Internal Error: Bad URL: "
432+ + e.getMessage());
433+ }
434+ URL u = this.getClass().getResource("resources/" + filename);
435+ assert u != null;
436+ sources.add(u);
437+
438+ if (showUnsupported) {
439+ u = this.getClass().getResource("resources/" + UNSUPPORTED_OPTIONS_FILENAME);
440+ assert u != null;
441+ sources.add(u);
442+ }
443+ return sources;
444+ }
445+}