Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/jstat/Arguments.java
38918 views
/*1* Copyright (c) 2004, 2010, 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.tools.jstat;2627import java.io.*;28import java.net.*;29import java.util.*;30import java.util.regex.*;31import sun.jvmstat.monitor.Monitor;32import sun.jvmstat.monitor.VmIdentifier;3334/**35* Class for processing command line arguments and providing method36* level access to arguments.37*38* @author Brian Doherty39* @since 1.540*/41public class Arguments {4243private static final boolean debug = Boolean.getBoolean("jstat.debug");44private static final boolean showUnsupported =45Boolean.getBoolean("jstat.showUnsupported");4647private static final String JVMSTAT_USERDIR = ".jvmstat";48private static final String OPTIONS_FILENAME = "jstat_options";49private static final String UNSUPPORTED_OPTIONS_FILENAME = "jstat_unsupported_options";50private static final String ALL_NAMES = "\\w*";5152private Comparator<Monitor> comparator;53private int headerRate;54private boolean help;55private boolean list;56private boolean options;57private boolean constants;58private boolean constantsOnly;59private boolean strings;60private boolean timestamp;61private boolean snap;62private boolean verbose;63private String specialOption;64private String names;6566private OptionFormat optionFormat;6768private int count = -1;69private int interval = -1;70private String vmIdString;7172private VmIdentifier vmId;7374public static void printUsage(PrintStream ps) {75ps.println("Usage: jstat -help|-options");76ps.println(" jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]");77ps.println();78ps.println("Definitions:");79ps.println(" <option> An option reported by the -options option");80ps.println(" <vmid> Virtual Machine Identifier. A vmid takes the following form:");81ps.println(" <lvmid>[@<hostname>[:<port>]]");82ps.println(" Where <lvmid> is the local vm identifier for the target");83ps.println(" Java virtual machine, typically a process id; <hostname> is");84ps.println(" the name of the host running the target Java virtual machine;");85ps.println(" and <port> is the port number for the rmiregistry on the");86ps.println(" target host. See the jvmstat documentation for a more complete");87ps.println(" description of the Virtual Machine Identifier.");88ps.println(" <lines> Number of samples between header lines.");89ps.println(" <interval> Sampling interval. The following forms are allowed:");90ps.println(" <n>[\"ms\"|\"s\"]");91ps.println(" Where <n> is an integer and the suffix specifies the units as ");92ps.println(" milliseconds(\"ms\") or seconds(\"s\"). The default units are \"ms\".");93ps.println(" <count> Number of samples to take before terminating.");94ps.println(" -J<flag> Pass <flag> directly to the runtime system.");9596// undocumented options:97// -list [<vmid>] - list counter names98// -snap <vmid> - snapshot counter values as name=value pairs99// -name <pattern> - output counters matching given pattern100// -a - sort in ascending order (default)101// -d - sort in descending order102// -v - verbose output (-snap)103// -constants - output constants with -name output104// -strings - output strings with -name output105}106107private static int toMillis(String s) throws IllegalArgumentException {108109String[] unitStrings = { "ms", "s" }; // ordered from most specific to110// least specific111String unitString = null;112String valueString = s;113114for (int i = 0; i < unitStrings.length; i++) {115int index = s.indexOf(unitStrings[i]);116if (index > 0) {117unitString = s.substring(index);118valueString = s.substring(0, index);119break;120}121}122123try {124int value = Integer.parseInt(valueString);125126if (unitString == null || unitString.compareTo("ms") == 0) {127return value;128} else if (unitString.compareTo("s") == 0) {129return value * 1000;130} else {131throw new IllegalArgumentException(132"Unknow time unit: " + unitString);133}134} catch (NumberFormatException e) {135throw new IllegalArgumentException(136"Could not convert interval: " + s);137}138}139140public Arguments(String[] args) throws IllegalArgumentException {141int argc = 0;142143if (args.length < 1) {144throw new IllegalArgumentException("invalid argument count");145}146147if ((args[0].compareTo("-?") == 0)148|| (args[0].compareTo("-help") == 0)) {149help = true;150return;151} else if (args[0].compareTo("-options") == 0) {152options = true;153return;154} else if (args[0].compareTo("-list") == 0) {155list = true;156if (args.length > 2) {157throw new IllegalArgumentException("invalid argument count");158}159// list can take one arg - a vmid - fall through for arg processing160argc++;161}162163for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {164String arg = args[argc];165166if (arg.compareTo("-a") == 0) {167comparator = new AscendingMonitorComparator();168} else if (arg.compareTo("-d") == 0) {169comparator = new DescendingMonitorComparator();170} else if (arg.compareTo("-t") == 0) {171timestamp = true;172} else if (arg.compareTo("-v") == 0) {173verbose = true;174} else if ((arg.compareTo("-constants") == 0)175|| (arg.compareTo("-c") == 0)) {176constants = true;177} else if ((arg.compareTo("-strings") == 0)178|| (arg.compareTo("-s") == 0)) {179strings = true;180} else if (arg.startsWith("-h")) {181String value;182if (arg.compareTo("-h") != 0) {183value = arg.substring(2);184} else {185argc++;186if (argc >= args.length) {187throw new IllegalArgumentException(188"-h requires an integer argument");189}190value = args[argc];191}192try {193headerRate = Integer.parseInt(value);194} catch (NumberFormatException e) {195headerRate = -1;196}197if (headerRate < 0) {198throw new IllegalArgumentException(199"illegal -h argument: " + value);200}201} else if (arg.startsWith("-name")) {202if (arg.startsWith("-name=")) {203names = arg.substring(7);204} else {205argc++;206if (argc >= args.length) {207throw new IllegalArgumentException(208"option argument expected");209}210names = args[argc];211}212} else {213/*214* there are scenarios here: special jstat_options file option215* or the rare case of a negative lvmid. The negative lvmid216* can occur in some operating environments (such as Windows217* 95/98/ME), so we provide for this case here by checking if218* the argument has any numerical characters. This assumes that219* there are no special jstat_options that contain numerical220* characters in their name.221*/222223// extract the lvmid part of possible [email protected]:port224String lvmidStr = null;225int at_index = args[argc].indexOf('@');226if (at_index < 0) {227lvmidStr = args[argc];228} else {229lvmidStr = args[argc].substring(0, at_index);230}231232// try to parse the lvmid part as an integer233try {234int vmid = Integer.parseInt(lvmidStr);235// it parsed, assume a negative lvmid and continue236break;237} catch (NumberFormatException nfe) {238// it didn't parse. check for the -snap or jstat_options239// file options.240if ((argc == 0) && (args[argc].compareTo("-snap") == 0)) {241snap = true;242} else if (argc == 0) {243specialOption = args[argc].substring(1);244} else {245throw new IllegalArgumentException(246"illegal argument: " + args[argc]);247}248}249}250}251252// prevent 'jstat <pid>' from being accepted as a valid argument253if (!(specialOption != null || list || snap || names != null)) {254throw new IllegalArgumentException("-<option> required");255}256257switch (args.length - argc) {258case 3:259if (snap) {260throw new IllegalArgumentException("invalid argument count");261}262try {263count = Integer.parseInt(args[args.length-1]);264} catch (NumberFormatException e) {265throw new IllegalArgumentException("illegal count value: "266+ args[args.length-1]);267}268interval = toMillis(args[args.length-2]);269vmIdString = args[args.length-3];270break;271case 2:272if (snap) {273throw new IllegalArgumentException("invalid argument count");274}275interval = toMillis(args[args.length-1]);276vmIdString = args[args.length-2];277break;278case 1:279vmIdString = args[args.length-1];280break;281case 0:282if (!list) {283throw new IllegalArgumentException("invalid argument count");284}285break;286default:287throw new IllegalArgumentException("invalid argument count");288}289290// set count and interval to their default values if not set above.291if (count == -1 && interval == -1) {292// default is for a single sample293count = 1;294interval = 0;295}296297// validate arguments298if (comparator == null) {299comparator = new AscendingMonitorComparator();300}301302// allow ',' characters to separate names, convert to '|' chars303names = (names == null) ? ALL_NAMES : names.replace(',', '|');304305// verify that the given pattern parses without errors306try {307Pattern pattern = Pattern.compile(names);308} catch (PatternSyntaxException e) {309throw new IllegalArgumentException("Bad name pattern: "310+ e.getMessage());311}312313// verify that the special option is valid and get it's formatter314if (specialOption != null) {315OptionFinder finder = new OptionFinder(optionsSources());316optionFormat = finder.getOptionFormat(specialOption, timestamp);317if (optionFormat == null) {318throw new IllegalArgumentException("Unknown option: -"319+ specialOption);320}321}322323// verify that the vm identifier is valied324try {325vmId = new VmIdentifier(vmIdString);326} catch (URISyntaxException e) {327IllegalArgumentException iae = new IllegalArgumentException(328"Malformed VM Identifier: " + vmIdString);329iae.initCause(e);330throw iae;331}332}333334public Comparator<Monitor> comparator() {335return comparator;336}337338public boolean isHelp() {339return help;340}341342public boolean isList() {343return list;344}345346public boolean isSnap() {347return snap;348}349350public boolean isOptions() {351return options;352}353354public boolean isVerbose() {355return verbose;356}357358public boolean printConstants() {359return constants;360}361362public boolean isConstantsOnly() {363return constantsOnly;364}365366public boolean printStrings() {367return strings;368}369370public boolean showUnsupported() {371return showUnsupported;372}373374public int headerRate() {375return headerRate;376}377378public String counterNames() {379return names;380}381382public VmIdentifier vmId() {383return vmId;384}385386public String vmIdString() {387return vmIdString;388}389390public int sampleInterval() {391return interval;392}393394public int sampleCount() {395return count;396}397398public boolean isTimestamp() {399return timestamp;400}401402public boolean isSpecialOption() {403return specialOption != null;404}405406public String specialOption() {407return specialOption;408}409410public OptionFormat optionFormat() {411return optionFormat;412}413414public List<URL> optionsSources() {415List<URL> sources = new ArrayList<URL>();416int i = 0;417418String filename = OPTIONS_FILENAME;419420try {421String userHome = System.getProperty("user.home");422String userDir = userHome + "/" + JVMSTAT_USERDIR;423File home = new File(userDir + "/" + filename);424sources.add(home.toURI().toURL());425} catch (Exception e) {426if (debug) {427System.err.println(e.getMessage());428e.printStackTrace();429}430throw new IllegalArgumentException("Internal Error: Bad URL: "431+ e.getMessage());432}433URL u = this.getClass().getResource("resources/" + filename);434assert u != null;435sources.add(u);436437if (showUnsupported) {438u = this.getClass().getResource("resources/" + UNSUPPORTED_OPTIONS_FILENAME);439assert u != null;440sources.add(u);441}442return sources;443}444}445446447