feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
/**
* A typesafe enumeration for describing data alignment semantics
*
* @author Brian Doherty
* @since 1.5
*/
public abstract class Alignment {
private static int nextOrdinal = 0;
private static HashMap<String, Alignment> map = new HashMap<String, Alignment>();
private static final String blanks = " ";
private final String name;
private final int value = nextOrdinal++;
protected abstract String align(String s, int width);
/**
* Alignment representing a Centered alignment
*/
public static final Alignment CENTER = new Alignment("center") {
protected String align(String s, int width) {
int length = s.length();
if (length >= width) {
return s;
}
int pad = width - length;
int pad2 = pad / 2;
int padr = pad % 2;
if (pad2 == 0) {
// only 0 or 1 character to pad
return s + blanks.substring(0, padr);
} else {
// pad on both sides
return blanks.substring(0, pad2) + s +
blanks.substring(0, pad2 + padr);
}
}
};
/**
* Alignment representing a Left alignment
*/
public static final Alignment LEFT = new Alignment("left") {
protected String align(String s, int width) {
int length = s.length();
if (length >= width) {
return s;
}
int pad = width - length;
return s+blanks.substring(0, pad);
}
};
/**
* Alignment representing a Right alignment
*/
public static final Alignment RIGHT = new Alignment("right") {
protected String align(String s, int width) {
int length = s.length();
if (length >= width) {
return s;
}
int pad = width - length;
return blanks.substring(0, pad) + s;
}
};
/**
* Maps a string value to its corresponding Alignment object.
*
* @param s an string to match against Alignment objects.
* @return The Alignment object matching the given string.
*/
public static Alignment toAlignment(String s) {
return map.get(s);
}
/**
* Returns an enumeration of the keys for this enumerated type
*
* @return Set of Key Words for this enumeration.
*/
public static Set keySet() {
return map.keySet();
}
public String toString() {
return name;
}
private Alignment(String name) {
this.name = name;
map.put(name, this);
}
}

View File

@@ -0,0 +1,445 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import sun.jvmstat.monitor.Monitor;
import sun.jvmstat.monitor.VmIdentifier;
/**
* Class for processing command line arguments and providing method
* level access to arguments.
*
* @author Brian Doherty
* @since 1.5
*/
public class Arguments {
private static final boolean debug = Boolean.getBoolean("jstat.debug");
private static final boolean showUnsupported =
Boolean.getBoolean("jstat.showUnsupported");
private static final String JVMSTAT_USERDIR = ".jvmstat";
private static final String OPTIONS_FILENAME = "jstat_options";
private static final String UNSUPPORTED_OPTIONS_FILENAME = "jstat_unsupported_options";
private static final String ALL_NAMES = "\\w*";
private Comparator<Monitor> comparator;
private int headerRate;
private boolean help;
private boolean list;
private boolean options;
private boolean constants;
private boolean constantsOnly;
private boolean strings;
private boolean timestamp;
private boolean snap;
private boolean verbose;
private String specialOption;
private String names;
private OptionFormat optionFormat;
private int count = -1;
private int interval = -1;
private String vmIdString;
private VmIdentifier vmId;
public static void printUsage(PrintStream ps) {
ps.println("Usage: jstat -help|-options");
ps.println(" jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]");
ps.println();
ps.println("Definitions:");
ps.println(" <option> An option reported by the -options option");
ps.println(" <vmid> Virtual Machine Identifier. A vmid takes the following form:");
ps.println(" <lvmid>[@<hostname>[:<port>]]");
ps.println(" Where <lvmid> is the local vm identifier for the target");
ps.println(" Java virtual machine, typically a process id; <hostname> is");
ps.println(" the name of the host running the target Java virtual machine;");
ps.println(" and <port> is the port number for the rmiregistry on the");
ps.println(" target host. See the jvmstat documentation for a more complete");
ps.println(" description of the Virtual Machine Identifier.");
ps.println(" <lines> Number of samples between header lines.");
ps.println(" <interval> Sampling interval. The following forms are allowed:");
ps.println(" <n>[\"ms\"|\"s\"]");
ps.println(" Where <n> is an integer and the suffix specifies the units as ");
ps.println(" milliseconds(\"ms\") or seconds(\"s\"). The default units are \"ms\".");
ps.println(" <count> Number of samples to take before terminating.");
ps.println(" -J<flag> Pass <flag> directly to the runtime system.");
// undocumented options:
// -list [<vmid>] - list counter names
// -snap <vmid> - snapshot counter values as name=value pairs
// -name <pattern> - output counters matching given pattern
// -a - sort in ascending order (default)
// -d - sort in descending order
// -v - verbose output (-snap)
// -constants - output constants with -name output
// -strings - output strings with -name output
}
private static int toMillis(String s) throws IllegalArgumentException {
String[] unitStrings = { "ms", "s" }; // ordered from most specific to
// least specific
String unitString = null;
String valueString = s;
for (int i = 0; i < unitStrings.length; i++) {
int index = s.indexOf(unitStrings[i]);
if (index > 0) {
unitString = s.substring(index);
valueString = s.substring(0, index);
break;
}
}
try {
int value = Integer.parseInt(valueString);
if (unitString == null || unitString.compareTo("ms") == 0) {
return value;
} else if (unitString.compareTo("s") == 0) {
return value * 1000;
} else {
throw new IllegalArgumentException(
"Unknow time unit: " + unitString);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"Could not convert interval: " + s);
}
}
public Arguments(String[] args) throws IllegalArgumentException {
int argc = 0;
if (args.length < 1) {
throw new IllegalArgumentException("invalid argument count");
}
if ((args[0].compareTo("-?") == 0)
|| (args[0].compareTo("-help") == 0)) {
help = true;
return;
} else if (args[0].compareTo("-options") == 0) {
options = true;
return;
} else if (args[0].compareTo("-list") == 0) {
list = true;
if (args.length > 2) {
throw new IllegalArgumentException("invalid argument count");
}
// list can take one arg - a vmid - fall through for arg processing
argc++;
}
for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
String arg = args[argc];
if (arg.compareTo("-a") == 0) {
comparator = new AscendingMonitorComparator();
} else if (arg.compareTo("-d") == 0) {
comparator = new DescendingMonitorComparator();
} else if (arg.compareTo("-t") == 0) {
timestamp = true;
} else if (arg.compareTo("-v") == 0) {
verbose = true;
} else if ((arg.compareTo("-constants") == 0)
|| (arg.compareTo("-c") == 0)) {
constants = true;
} else if ((arg.compareTo("-strings") == 0)
|| (arg.compareTo("-s") == 0)) {
strings = true;
} else if (arg.startsWith("-h")) {
String value;
if (arg.compareTo("-h") != 0) {
value = arg.substring(2);
} else {
argc++;
if (argc >= args.length) {
throw new IllegalArgumentException(
"-h requires an integer argument");
}
value = args[argc];
}
try {
headerRate = Integer.parseInt(value);
} catch (NumberFormatException e) {
headerRate = -1;
}
if (headerRate < 0) {
throw new IllegalArgumentException(
"illegal -h argument: " + value);
}
} else if (arg.startsWith("-name")) {
if (arg.startsWith("-name=")) {
names = arg.substring(7);
} else {
argc++;
if (argc >= args.length) {
throw new IllegalArgumentException(
"option argument expected");
}
names = args[argc];
}
} else {
/*
* there are scenarios here: special jstat_options file option
* or the rare case of a negative lvmid. The negative lvmid
* can occur in some operating environments (such as Windows
* 95/98/ME), so we provide for this case here by checking if
* the argument has any numerical characters. This assumes that
* there are no special jstat_options that contain numerical
* characters in their name.
*/
// extract the lvmid part of possible lvmid@host.domain:port
String lvmidStr = null;
int at_index = args[argc].indexOf('@');
if (at_index < 0) {
lvmidStr = args[argc];
} else {
lvmidStr = args[argc].substring(0, at_index);
}
// try to parse the lvmid part as an integer
try {
int vmid = Integer.parseInt(lvmidStr);
// it parsed, assume a negative lvmid and continue
break;
} catch (NumberFormatException nfe) {
// it didn't parse. check for the -snap or jstat_options
// file options.
if ((argc == 0) && (args[argc].compareTo("-snap") == 0)) {
snap = true;
} else if (argc == 0) {
specialOption = args[argc].substring(1);
} else {
throw new IllegalArgumentException(
"illegal argument: " + args[argc]);
}
}
}
}
// prevent 'jstat <pid>' from being accepted as a valid argument
if (!(specialOption != null || list || snap || names != null)) {
throw new IllegalArgumentException("-<option> required");
}
switch (args.length - argc) {
case 3:
if (snap) {
throw new IllegalArgumentException("invalid argument count");
}
try {
count = Integer.parseInt(args[args.length-1]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("illegal count value: "
+ args[args.length-1]);
}
interval = toMillis(args[args.length-2]);
vmIdString = args[args.length-3];
break;
case 2:
if (snap) {
throw new IllegalArgumentException("invalid argument count");
}
interval = toMillis(args[args.length-1]);
vmIdString = args[args.length-2];
break;
case 1:
vmIdString = args[args.length-1];
break;
case 0:
if (!list) {
throw new IllegalArgumentException("invalid argument count");
}
break;
default:
throw new IllegalArgumentException("invalid argument count");
}
// set count and interval to their default values if not set above.
if (count == -1 && interval == -1) {
// default is for a single sample
count = 1;
interval = 0;
}
// validate arguments
if (comparator == null) {
comparator = new AscendingMonitorComparator();
}
// allow ',' characters to separate names, convert to '|' chars
names = (names == null) ? ALL_NAMES : names.replace(',', '|');
// verify that the given pattern parses without errors
try {
Pattern pattern = Pattern.compile(names);
} catch (PatternSyntaxException e) {
throw new IllegalArgumentException("Bad name pattern: "
+ e.getMessage());
}
// verify that the special option is valid and get it's formatter
if (specialOption != null) {
OptionFinder finder = new OptionFinder(optionsSources());
optionFormat = finder.getOptionFormat(specialOption, timestamp);
if (optionFormat == null) {
throw new IllegalArgumentException("Unknown option: -"
+ specialOption);
}
}
// verify that the vm identifier is valied
try {
vmId = new VmIdentifier(vmIdString);
} catch (URISyntaxException e) {
IllegalArgumentException iae = new IllegalArgumentException(
"Malformed VM Identifier: " + vmIdString);
iae.initCause(e);
throw iae;
}
}
public Comparator<Monitor> comparator() {
return comparator;
}
public boolean isHelp() {
return help;
}
public boolean isList() {
return list;
}
public boolean isSnap() {
return snap;
}
public boolean isOptions() {
return options;
}
public boolean isVerbose() {
return verbose;
}
public boolean printConstants() {
return constants;
}
public boolean isConstantsOnly() {
return constantsOnly;
}
public boolean printStrings() {
return strings;
}
public boolean showUnsupported() {
return showUnsupported;
}
public int headerRate() {
return headerRate;
}
public String counterNames() {
return names;
}
public VmIdentifier vmId() {
return vmId;
}
public String vmIdString() {
return vmIdString;
}
public int sampleInterval() {
return interval;
}
public int sampleCount() {
return count;
}
public boolean isTimestamp() {
return timestamp;
}
public boolean isSpecialOption() {
return specialOption != null;
}
public String specialOption() {
return specialOption;
}
public OptionFormat optionFormat() {
return optionFormat;
}
public List<URL> optionsSources() {
List<URL> sources = new ArrayList<URL>();
int i = 0;
String filename = OPTIONS_FILENAME;
try {
String userHome = System.getProperty("user.home");
String userDir = userHome + "/" + JVMSTAT_USERDIR;
File home = new File(userDir + "/" + filename);
sources.add(home.toURI().toURL());
} catch (Exception e) {
if (debug) {
System.err.println(e.getMessage());
e.printStackTrace();
}
throw new IllegalArgumentException("Internal Error: Bad URL: "
+ e.getMessage());
}
URL u = this.getClass().getResource("resources/" + filename);
assert u != null;
sources.add(u);
if (showUnsupported) {
u = this.getClass().getResource("resources/" + UNSUPPORTED_OPTIONS_FILENAME);
assert u != null;
sources.add(u);
}
return sources;
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* Class to compare two Monitor objects by name in ascending order.
*
* @author Brian Doherty
* @since 1.5
*/
class AscendingMonitorComparator implements Comparator<Monitor> {
public int compare(Monitor o1, Monitor o2) {
String name1 = o1.getName();
String name2 = o2.getName();
return name1.compareTo(name2);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.List;
import sun.jvmstat.monitor.MonitorException;
/**
* An interface for visitor object on a binary tree.
*
* @author Brian Doherty
* @since 1.5
*/
interface Closure {
void visit(Object o, boolean hasNext) throws MonitorException;
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
/**
* A class to represent the format for a column of data.
*
* @author Brian Doherty
* @since 1.5
*/
public class ColumnFormat extends OptionFormat {
private int number;
private int width;
private Alignment align = Alignment.CENTER;
private Scale scale = Scale.RAW;
private String format;
private String header;
private Expression expression;
private Object previousValue;
public ColumnFormat(int number) {
super("Column" + number);
this.number = number;
}
/*
* method to apply various validation rules to the ColumnFormat object.
*/
public void validate() throws ParserException {
// if we allow column spanning, then this method must change. it
// should allow null data statments
if (expression == null) {
// current policy is that a data statement must be specified
throw new ParserException("Missing data statement in column " + number);
}
if (header == null) {
// current policy is that if a header is not specified, then we
// will use the last component of the name as the header and
// insert the default anchor characters for center alignment..
throw new ParserException("Missing header statement in column " + number);
}
if (format == null) {
// if no formating is specified, then the format is set to output
// the raw data.
format="0";
}
}
public void setWidth(int width) {
this.width = width;
}
public void setAlignment(Alignment align) {
this.align = align;
}
public void setScale(Scale scale) {
this.scale = scale;
}
public void setFormat(String format) {
this.format = format;
}
public void setHeader(String header) {
this.header = header;
}
public String getHeader() {
return header;
}
public String getFormat() {
return format;
}
public int getWidth() {
return width;
}
public Alignment getAlignment() {
return align;
}
public Scale getScale() {
return scale;
}
public Expression getExpression() {
return expression;
}
public void setExpression(Expression e) {
this.expression = e;
}
public void setPreviousValue(Object o) {
this.previousValue = o;
}
public Object getPreviousValue() {
return previousValue;
}
public void printFormat(int indentLevel) {
String indentAmount = " ";
StringBuilder indent = new StringBuilder("");
for (int j = 0; j < indentLevel; j++) {
indent.append(indentAmount);
}
System.out.println(indent + name + " {");
System.out.println(indent + indentAmount + "name=" + name
+ ";data=" + expression.toString() + ";header=" + header
+ ";format=" + format + ";width=" + width
+ ";scale=" + scale.toString() + ";align=" + align.toString());
for (Iterator i = children.iterator(); i.hasNext(); /* empty */) {
OptionFormat of = (OptionFormat)i.next();
of.printFormat(indentLevel+1);
}
System.out.println(indent + "}");
}
public String getValue() {
return null;
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* Class to compare two Monitor objects by name in descending order.
*
* @author Brian Doherty
* @since 1.5
*/
class DescendingMonitorComparator implements Comparator<Monitor> {
public int compare(Monitor o1, Monitor o2) {
String name1 = o1.getName();
String name2 = o2.getName();
return name2.compareTo(name1);
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
/**
* A class that represents a mathematical expression as a tree structure
* containing operators as interior nodes and operands as leaves. The
* operands can be literals or lazily bound variables.
*
* @author Brian Doherty
* @since 1.5
*/
public class Expression {
private static int nextOrdinal;
private boolean debug = Boolean.getBoolean("Expression.debug");
private Expression left;
private Expression right;
private Operator operator;
private int ordinal = nextOrdinal++;
Expression() {
if (debug) {
System.out.println("Expression " + ordinal + " created");
}
}
void setLeft(Expression left) {
if (debug) {
System.out.println("Setting left on " + ordinal + " to " + left);
}
this.left = left;
}
Expression getLeft() {
return left;
}
void setRight(Expression right) {
if (debug) {
System.out.println("Setting right on " + ordinal + " to " + right);
}
this.right = right;
}
Expression getRight() {
return right;
}
void setOperator(Operator o) {
if (debug) {
System.out.println("Setting operator on " + ordinal + " to " + o);
}
this.operator = o;
}
Operator getOperator() {
return operator;
}
public String toString() {
StringBuilder b = new StringBuilder();
b.append('(');
if (left != null) {
b.append(left.toString());
}
if (operator != null) {
b.append(operator.toString());
if (right != null) {
b.append(right.toString());
}
}
b.append(')');
return b.toString();
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import sun.jvmstat.monitor.MonitorException;
/**
* An interface to allow an object to visit an Expression object and
* evaluate based on some context.
*
* @author Brian Doherty
* @since 1.5
*/
interface ExpressionEvaluator {
Object evaluate(Expression e) throws MonitorException;
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* A class implementing the ExpressionEvaluator to evaluate an expression
* in the context of the available monitoring data.
*
* @author Brian Doherty
* @since 1.5
*/
public class ExpressionExecuter implements ExpressionEvaluator {
private static final boolean debug =
Boolean.getBoolean("ExpressionEvaluator.debug");
private MonitoredVm vm;
private HashMap<String, Object> map = new HashMap<String, Object>();
ExpressionExecuter(MonitoredVm vm) {
this.vm = vm;
}
/*
* evaluate the given expression.
*/
public Object evaluate(Expression e) {
if (e == null) {
return null;
}
if (debug) {
System.out.println("Evaluating expression: " + e);
}
if (e instanceof Literal) {
return ((Literal)e).getValue();
}
if (e instanceof Identifier) {
Identifier id = (Identifier)e;
if (map.containsKey(id.getName())) {
return map.get(id.getName());
} else {
// cache the data values for coherency of the values over
// the life of this expression executer.
Monitor m = (Monitor)id.getValue();
Object v = m.getValue();
map.put(id.getName(), v);
return v;
}
}
Expression l = e.getLeft();
Expression r = e.getRight();
Operator op = e.getOperator();
if (op == null) {
return evaluate(l);
} else {
Double lval = new Double(((Number)evaluate(l)).doubleValue());
Double rval = new Double(((Number)evaluate(r)).doubleValue());
double result = op.eval(lval.doubleValue(), rval.doubleValue());
if (debug) {
System.out.println("Performed Operation: " + lval + op + rval
+ " = " + result);
}
return new Double(result);
}
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import sun.jvmstat.monitor.*;
/**
* A class implementing the ExpressionEvaluator to resolve unresolved
* symbols in an Expression in the context of the available monitoring data.
* This class also performs some minimal optimizations of the expressions,
* such as simplification of constant subexpressions.
*
* @author Brian Doherty
* @since 1.5
*/
public class ExpressionResolver implements ExpressionEvaluator {
private static boolean debug = Boolean.getBoolean("ExpressionResolver.debug");
private MonitoredVm vm;
ExpressionResolver(MonitoredVm vm) {
this.vm = vm;
}
/*
* evaluate the given expression. evaluation in this case means
* to resolve the counter names in the expression
*/
public Object evaluate(Expression e) throws MonitorException {
if (e == null) {
return null;
}
if (debug) {
System.out.println("Resolving Expression:" + e);
}
if (e instanceof Identifier) {
Identifier id = (Identifier)e;
// check if it's already resolved
if (id.isResolved()) {
return id;
}
// look it up
Monitor m = vm.findByName(id.getName());
if (m == null) {
System.err.println("Warning: Unresolved Symbol: "
+ id.getName() + " substituted NaN");
return new Literal(new Double(Double.NaN));
}
if (m.getVariability() == Variability.CONSTANT) {
if (debug) {
System.out.println("Converting constant " + id.getName()
+ " to literal with value "
+ m.getValue());
}
return new Literal(m.getValue());
}
id.setValue(m);
return id;
}
if (e instanceof Literal) {
return e;
}
Expression l = null;
Expression r = null;
if (e.getLeft() != null) {
l = (Expression)evaluate(e.getLeft());
}
if (e.getRight() != null) {
r = (Expression)evaluate(e.getRight());
}
if (l != null && r != null) {
if ((l instanceof Literal) && (r instanceof Literal)) {
Literal ll = (Literal)l;
Literal rl = (Literal)r;
boolean warn = false;
Double nan = new Double(Double.NaN);
if (ll.getValue() instanceof String) {
warn = true; ll.setValue(nan);
}
if (rl.getValue() instanceof String) {
warn = true; rl.setValue(nan);
}
if (debug && warn) {
System.out.println("Warning: String literal in "
+ "numerical expression: "
+ "substitutied NaN");
}
// perform the operation
Number ln = (Number)ll.getValue();
Number rn = (Number)rl.getValue();
double result = e.getOperator().eval(ln.doubleValue(),
rn.doubleValue());
if (debug) {
System.out.println("Converting expression " + e
+ " (left = " + ln.doubleValue() + ")"
+ " (right = " + rn.doubleValue() + ")"
+ " to literal value " + result);
}
return new Literal(new Double(result));
}
}
if (l != null && r == null) {
return l;
}
e.setLeft(l);
e.setRight(r);
return e;
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import sun.jvmstat.monitor.MonitorException;
/**
* A class implementing the Closure interface that visits the nodes of
* the nodes of a ColumFormat object and computes the header string for
* the columns of data.
*
* @author Brian Doherty
* @since 1.5
*/
public class HeaderClosure implements Closure {
private static final char ALIGN_CHAR = '^';
private StringBuilder header = new StringBuilder();
/*
* visit an object to perform some operation. In this case, the
* object is a ColumnFormat we are building the header string.
*/
public void visit(Object o, boolean hasNext) throws MonitorException {
if (! (o instanceof ColumnFormat)) {
return;
}
ColumnFormat c = (ColumnFormat)o;
String h = c.getHeader();
// check for special alignment character
if (h.indexOf(ALIGN_CHAR) >= 0) {
int len = h.length();
if ((h.charAt(0) == ALIGN_CHAR)
&& (h.charAt(len-1) == ALIGN_CHAR)) {
// ^<header>^ case - center alignment
c.setWidth(Math.max(c.getWidth(),
Math.max(c.getFormat().length(), len-2)));
h = h.substring(1, len-1);
h = Alignment.CENTER.align(h, c.getWidth());
} else if (h.charAt(0) == ALIGN_CHAR) {
// ^<header> case - left alignment
c.setWidth(Math.max(c.getWidth(),
Math.max(c.getFormat().length(), len-1)));
h = h.substring(1, len);
h = Alignment.LEFT.align(h, c.getWidth());
} else if (h.charAt(len-1) == ALIGN_CHAR) {
// <header>^ case - right alignment
c.setWidth(Math.max(c.getWidth(),
Math.max(c.getFormat().length(), len-1)));
h = h.substring(0, len-1);
h = Alignment.RIGHT.align(h, c.getWidth());
} else {
// an internal alignment character - ignore
}
} else {
// User has provided their own padding for alignment purposes
}
header.append(h);
if (hasNext) {
header.append(" ");
}
}
/*
* get the header string.
*/
public String getHeader() {
return header.toString();
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
/**
* An Expression subclass that describes the variable operands of an
* expression. Objects of this type are always leaves of an expression tree.
*
* @author Brian Doherty
* @since 1.5
*/
public class Identifier extends Expression {
private String name;
private Object value;
public Identifier(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public boolean isResolved() {
return value != null;
}
public String toString() {
return name;
}
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import java.io.*;
import sun.jvmstat.monitor.*;
import sun.jvmstat.monitor.event.*;
import java.util.regex.PatternSyntaxException;
/**
* Class to sample and output various jvmstat statistics for a target Java
* a target Java Virtual Machine.
*
* @author Brian Doherty
* @since 1.5
*/
public class JStatLogger {
private MonitoredVm monitoredVm;
private volatile boolean active = true;
public JStatLogger(MonitoredVm monitoredVm) {
this.monitoredVm = monitoredVm;
}
/**
* print the monitors that match the given monitor name pattern string.
*/
public void printNames(String names, Comparator<Monitor> comparator,
boolean showUnsupported, PrintStream out)
throws MonitorException, PatternSyntaxException {
// get the set of all monitors
List<Monitor> items = monitoredVm.findByPattern(names);
Collections.sort(items, comparator);
for (Monitor m: items) {
if (!(m.isSupported() || showUnsupported)) {
continue;
}
out.println(m.getName());
}
}
/**
* print name=value pairs for the given list of monitors.
*/
public void printSnapShot(String names, Comparator<Monitor> comparator,
boolean verbose, boolean showUnsupported,
PrintStream out)
throws MonitorException, PatternSyntaxException {
// get the set of all monitors
List<Monitor> items = monitoredVm.findByPattern(names);
Collections.sort(items, comparator);
printList(items, verbose, showUnsupported, out);
}
/**
* print name=value pairs for the given list of monitors.
*/
public void printList(List<Monitor> list, boolean verbose, boolean showUnsupported,
PrintStream out)
throws MonitorException {
// print out the name of each available counter
for (Monitor m: list ) {
if (!(m.isSupported() || showUnsupported)) {
continue;
}
StringBuilder buffer = new StringBuilder();
buffer.append(m.getName()).append("=");
if (m instanceof StringMonitor) {
buffer.append("\"").append(m.getValue()).append("\"");
} else {
buffer.append(m.getValue());
}
if (verbose) {
buffer.append(" ").append(m.getUnits());
buffer.append(" ").append(m.getVariability());
buffer.append(" ").append(m.isSupported() ? "Supported"
: "Unsupported");
}
out.println(buffer);
}
}
/**
* method to for asynchronous termination of sampling loops
*/
public void stopLogging() {
active = false;
}
/**
* print samples according to the given format.
*/
public void logSamples(OutputFormatter formatter, int headerRate,
int sampleInterval, int sampleCount, PrintStream out)
throws MonitorException {
long iterationCount = 0;
int printHeaderCount = 0;
// if printHeader == 0, then only an initial column header is desired.
int printHeader = headerRate;
if (printHeader == 0) {
// print the column header once, disable future printing
out.println(formatter.getHeader());
printHeader = -1;
}
while (active) {
// check if it's time to print another column header
if (printHeader > 0 && --printHeaderCount <= 0) {
printHeaderCount = printHeader;
out.println(formatter.getHeader());
}
out.println(formatter.getRow());
// check if we've hit the specified sample count
if (sampleCount > 0 && ++iterationCount >= sampleCount) {
break;
}
try { Thread.sleep(sampleInterval); } catch (Exception e) { };
}
}
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
import sun.jvmstat.monitor.event.*;
/**
* Application to output jvmstat statistics exported by a target Java
* Virtual Machine. The jstat tool gets its inspiration from the suite
* of 'stat' tools, such as vmstat, iostat, mpstat, etc., available in
* various UNIX platforms.
*
* @author Brian Doherty
* @since 1.5
*/
public class Jstat {
private static Arguments arguments;
public static void main(String[] args) {
try {
arguments = new Arguments(args);
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
Arguments.printUsage(System.err);
System.exit(1);
}
if (arguments.isHelp()) {
Arguments.printUsage(System.out);
System.exit(0);
}
if (arguments.isOptions()) {
OptionLister ol = new OptionLister(arguments.optionsSources());
ol.print(System.out);
System.exit(0);
}
try {
if (arguments.isList()) {
logNames();
} else if (arguments.isSnap()) {
logSnapShot();
} else {
logSamples();
}
} catch (MonitorException e) {
if (e.getMessage() != null) {
System.err.println(e.getMessage());
} else {
Throwable cause = e.getCause();
if ((cause != null) && (cause.getMessage() != null)) {
System.err.println(cause.getMessage());
} else {
e.printStackTrace();
}
}
System.exit(1);
}
System.exit(0);
}
static void logNames() throws MonitorException {
VmIdentifier vmId = arguments.vmId();
int interval = arguments.sampleInterval();
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
JStatLogger logger = new JStatLogger(monitoredVm);
logger.printNames(arguments.counterNames(), arguments.comparator(),
arguments.showUnsupported(), System.out);
monitoredHost.detach(monitoredVm);
}
static void logSnapShot() throws MonitorException {
VmIdentifier vmId = arguments.vmId();
int interval = arguments.sampleInterval();
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
JStatLogger logger = new JStatLogger(monitoredVm);
logger.printSnapShot(arguments.counterNames(), arguments.comparator(),
arguments.isVerbose(), arguments.showUnsupported(),
System.out);
monitoredHost.detach(monitoredVm);
}
static void logSamples() throws MonitorException {
final VmIdentifier vmId = arguments.vmId();
int interval = arguments.sampleInterval();
final MonitoredHost monitoredHost =
MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
final JStatLogger logger = new JStatLogger(monitoredVm);
OutputFormatter formatter = null;
if (arguments.isSpecialOption()) {
OptionFormat format = arguments.optionFormat();
formatter = new OptionOutputFormatter(monitoredVm, format);
} else {
List<Monitor> logged = monitoredVm.findByPattern(arguments.counterNames());
Collections.sort(logged, arguments.comparator());
List<Monitor> constants = new ArrayList<Monitor>();
for (Iterator i = logged.iterator(); i.hasNext(); /* empty */) {
Monitor m = (Monitor)i.next();
if (!(m.isSupported() || arguments.showUnsupported())) {
i.remove();
continue;
}
if (m.getVariability() == Variability.CONSTANT) {
i.remove();
if (arguments.printConstants()) constants.add(m);
} else if ((m.getUnits() == Units.STRING)
&& !arguments.printStrings()) {
i.remove();
}
}
if (!constants.isEmpty()) {
logger.printList(constants, arguments.isVerbose(),
arguments.showUnsupported(), System.out);
if (!logged.isEmpty()) {
System.out.println();
}
}
if (logged.isEmpty()) {
monitoredHost.detach(monitoredVm);
return;
}
formatter = new RawOutputFormatter(logged,
arguments.printStrings());
}
// handle user termination requests by stopping sampling loops
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
logger.stopLogging();
}
});
// handle target termination events for targets other than ourself
HostListener terminator = new HostListener() {
public void vmStatusChanged(VmStatusChangeEvent ev) {
Integer lvmid = new Integer(vmId.getLocalVmId());
if (ev.getTerminated().contains(lvmid)) {
logger.stopLogging();
} else if (!ev.getActive().contains(lvmid)) {
logger.stopLogging();
}
}
public void disconnected(HostEvent ev) {
if (monitoredHost == ev.getMonitoredHost()) {
logger.stopLogging();
}
}
};
if (vmId.getLocalVmId() != 0) {
monitoredHost.addHostListener(terminator);
}
logger.logSamples(formatter, arguments.headerRate(),
arguments.sampleInterval(), arguments.sampleCount(),
System.out);
// detach from host events and from the monitored target jvm
if (terminator != null) {
monitoredHost.removeHostListener(terminator);
}
monitoredHost.detach(monitoredVm);
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
/**
* An Expression subclass that describes the constant operands of an
* expression. Objects of this type are always leaves of an expression tree.
*
* @author Brian Doherty
* @since 1.5
*/
public class Literal extends Expression {
private Object value;
public Literal(Object value) {
super();
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String toString() {
return value.toString();
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
/**
* A typesafe enumeration for describing mathematical operators.
*
* @author Brian Doherty
* @since 1.5
*/
public abstract class Operator {
private static int nextOrdinal = 0;
private static HashMap<String, Operator> map = new HashMap<String, Operator>();
private final String name;
private final int ordinal = nextOrdinal++;
private Operator(String name) {
this.name = name;
map.put(name, this);
}
protected abstract double eval(double x, double y);
/* Operator '+' */
public static final Operator PLUS = new Operator("+") {
protected double eval(double x, double y) {
return x + y;
}
};
/* Operator '-' */
public static final Operator MINUS = new Operator("-") {
protected double eval(double x, double y) {
return x - y;
}
};
/* Operator '/' */
public static final Operator DIVIDE = new Operator("/") {
protected double eval(double x, double y) {
if (y == 0) {
return Double.NaN;
}
return x / y;
}
};
/* Operator '*' */
public static final Operator MULTIPLY = new Operator("*") {
protected double eval(double x, double y) {
return x * y;
}
};
/**
* Returns the string representation of this Operator object.
*
* @return the string representation of this Operator object
*/
public String toString() {
return name;
}
/**
* Maps a string to its corresponding Operator object.
*
* @param s an string to match against Operator objects.
* @return The Operator object matching the given string.
*/
public static Operator toOperator(String s) {
return map.get(s);
}
/**
* Returns an enumeration of the keys for this enumerated type
*
* @param s an string to match against Operator objects.
* @return The Operator object matching the given string.
*/
protected static Set keySet() {
return map.keySet();
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import java.net.*;
import java.io.*;
/**
* A class for finding a specific special option in the jstat_options file.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionFinder {
private static final boolean debug = false;
List<URL> optionsSources;
public OptionFinder(List<URL> optionsSources) {
this.optionsSources = optionsSources;
}
public OptionFormat getOptionFormat(String option, boolean useTimestamp) {
OptionFormat of = getOptionFormat(option, optionsSources);
OptionFormat tof = null;
if ((of != null) && (useTimestamp)) {
// prepend the timestamp column as first column
tof = getOptionFormat("timestamp", optionsSources);
if (tof != null) {
ColumnFormat cf = (ColumnFormat)tof.getSubFormat(0);
of.insertSubFormat(0, cf);
}
}
return of;
}
protected OptionFormat getOptionFormat(String option, List<URL> sources) {
OptionFormat of = null;
for (URL u : sources) {
try {
Reader r = new BufferedReader(
new InputStreamReader(u.openStream()));
of = new Parser(r).parse(option);
if (of != null)
break;
} catch (IOException e) {
if (debug) {
System.err.println("Error processing " + u
+ " : " + e.getMessage());
e.printStackTrace();
}
} catch (ParserException e) {
// Exception in parsing the options file.
System.err.println(u + ": " + e.getMessage());
System.err.println("Parsing of " + u + " aborted");
}
}
return of;
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.MonitorException;
/**
* A class for describing the output format specified by a command
* line option that was parsed from an option description file.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionFormat {
protected String name;
protected List<OptionFormat> children;
public OptionFormat(String name) {
this.name = name;
this.children = new ArrayList<OptionFormat>();
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof OptionFormat)) {
return false;
}
OptionFormat of = (OptionFormat)o;
return (this.name.compareTo(of.name) == 0);
}
public int hashCode() {
return name.hashCode();
}
public void addSubFormat(OptionFormat f) {
children.add(f);
}
public OptionFormat getSubFormat(int index) {
return children.get(index);
}
public void insertSubFormat(int index, OptionFormat f) {
children.add(index, f);
}
public String getName() {
return name;
}
public void apply(Closure c) throws MonitorException {
for (Iterator i = children.iterator(); i.hasNext(); /* empty */) {
OptionFormat o = (OptionFormat)i.next();
c.visit(o, i.hasNext());
}
for (Iterator i = children.iterator(); i.hasNext(); /* empty */) {
OptionFormat o = (OptionFormat)i.next();
o.apply(c);
}
}
public void printFormat() {
printFormat(0);
}
public void printFormat(int indentLevel) {
String indentAmount = " ";
StringBuilder indent = new StringBuilder("");
for (int j = 0; j < indentLevel; j++) {
indent.append(indentAmount);
}
System.out.println(indent + name + " {");
// iterate over all children and call their printFormat() methods
for (OptionFormat of : children) {
of.printFormat(indentLevel+1);
}
System.out.println(indent + "}");
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import java.net.*;
import java.io.*;
/**
* A class for listing the available options in the jstat_options file.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionLister {
private static final boolean debug = false;
private List<URL> sources;
public OptionLister(List<URL> sources) {
this.sources = sources;
}
public void print(PrintStream ps) {
Comparator<OptionFormat> c = new Comparator<OptionFormat>() {
public int compare(OptionFormat o1, OptionFormat o2) {
OptionFormat of1 = o1;
OptionFormat of2 = o2;
return (of1.getName().compareTo(of2.getName()));
}
};
Set<OptionFormat> options = new TreeSet<OptionFormat>(c);
for (URL u : sources) {
try {
Reader r = new BufferedReader(
new InputStreamReader(u.openStream()));
Set<OptionFormat> s = new Parser(r).parseOptions();
options.addAll(s);
} catch (IOException e) {
if (debug) {
System.err.println(e.getMessage());
e.printStackTrace();
}
} catch (ParserException e) {
// Exception in parsing the options file.
System.err.println(u + ": " + e.getMessage());
System.err.println("Parsing of " + u + " aborted");
}
}
for ( OptionFormat of : options) {
if (of.getName().compareTo("timestamp") == 0) {
// ignore the special timestamp OptionFormat.
continue;
}
ps.println("-" + of.getName());
}
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import sun.jvmstat.monitor.*;
/**
* A class for applying an OptionFormat to a particular context, the context
* of the available Instrumentation for a monitorable Java Virtual Machine.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionOutputFormatter implements OutputFormatter {
private OptionFormat format;
private String header;
private MonitoredVm vm;
public OptionOutputFormatter(MonitoredVm vm, OptionFormat format)
throws MonitorException {
this.vm = vm;
this.format = format;
resolve();
}
private void resolve() throws MonitorException {
ExpressionEvaluator ee = new ExpressionResolver(vm);
SymbolResolutionClosure ec = new SymbolResolutionClosure(ee);
format.apply(ec);
}
public String getHeader() throws MonitorException {
if (header == null) {
HeaderClosure hc = new HeaderClosure();
format.apply(hc);
header = hc.getHeader();
}
return header;
}
public String getRow() throws MonitorException {
RowClosure rc = new RowClosure(vm);
format.apply(rc);
return rc.getRow();
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import sun.jvmstat.monitor.MonitorException;
/**
* An interface for the JStatLogger formatting.
*
* @author Brian Doherty
* @since 1.5
*/
public interface OutputFormatter {
/**
* get the header row that describes the data in the columns
*/
String getHeader() throws MonitorException;
/**
* get the data row.
*/
String getRow() throws MonitorException;
}

View File

@@ -0,0 +1,585 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.io.*;
import java.util.*;
/**
* A class implementing a simple predictive parser for output format
* specification language for the jstat command.
*
* @author Brian Doherty
* @since 1.5
*/
public class Parser {
private static boolean pdebug = Boolean.getBoolean("jstat.parser.debug");
private static boolean ldebug = Boolean.getBoolean("jstat.lex.debug");
private static final char OPENBLOCK = '{';
private static final char CLOSEBLOCK = '}';
private static final char DOUBLEQUOTE = '"';
private static final char PERCENT_CHAR = '%';
private static final char OPENPAREN = '(';
private static final char CLOSEPAREN = ')';
private static final char OPERATOR_PLUS = '+';
private static final char OPERATOR_MINUS = '-';
private static final char OPERATOR_MULTIPLY = '*';
private static final char OPERATOR_DIVIDE = '/';
private static final String OPTION = "option";
private static final String COLUMN = "column";
private static final String DATA = "data";
private static final String HEADER = "header";
private static final String WIDTH = "width";
private static final String FORMAT = "format";
private static final String ALIGN = "align";
private static final String SCALE = "scale";
private static final String START = OPTION;
private static final Set scaleKeyWords = Scale.keySet();
private static final Set alignKeyWords = Alignment.keySet();
private static String[] otherKeyWords = {
OPTION, COLUMN, DATA, HEADER, WIDTH, FORMAT, ALIGN, SCALE
};
private static char[] infixOps = {
OPERATOR_PLUS, OPERATOR_MINUS, OPERATOR_MULTIPLY, OPERATOR_DIVIDE
};
private static char[] delimiters = {
OPENBLOCK, CLOSEBLOCK, PERCENT_CHAR, OPENPAREN, CLOSEPAREN
};
private static Set<String> reservedWords;
private StreamTokenizer st;
private String filename;
private Token lookahead;
private Token previous;
private int columnCount;
private OptionFormat optionFormat;
public Parser(String filename) throws FileNotFoundException {
this.filename = filename;
Reader r = new BufferedReader(new FileReader(filename));
}
public Parser(Reader r) {
st = new StreamTokenizer(r);
// allow both c++ style comments
st.ordinaryChar('/');
st.wordChars('_','_');
st.slashSlashComments(true);
st.slashStarComments(true);
reservedWords = new HashSet<String>();
for (int i = 0; i < otherKeyWords.length; i++) {
reservedWords.add(otherKeyWords[i]);
}
for (int i = 0; i < delimiters.length; i++ ) {
st.ordinaryChar(delimiters[i]);
}
for (int i = 0; i < infixOps.length; i++ ) {
st.ordinaryChar(infixOps[i]);
}
}
/**
* push back the lookahead token and restore the lookahead token
* to the previous token.
*/
private void pushBack() {
lookahead = previous;
st.pushBack();
}
/**
* retrieve the next token, placing the token value in the lookahead
* member variable, storing its previous value in the previous member
* variable.
*/
private void nextToken() throws ParserException, IOException {
int t = st.nextToken();
previous = lookahead;
lookahead = new Token(st.ttype, st.sval, st.nval);
log(ldebug, "lookahead = " + lookahead);
}
/**
* match one of the token values in the given set of key words
* token is assumed to be of type TT_WORD, and the set is assumed
* to contain String objects.
*/
private Token matchOne(Set keyWords) throws ParserException, IOException {
if ((lookahead.ttype == StreamTokenizer.TT_WORD)
&& keyWords.contains(lookahead.sval)) {
Token t = lookahead;
nextToken();
return t;
}
throw new SyntaxException(st.lineno(), keyWords, lookahead);
}
/**
* match a token with TT_TYPE=type, and the token value is a given sequence
* of characters.
*/
private void match(int ttype, String token)
throws ParserException, IOException {
if (lookahead.ttype == ttype && lookahead.sval.compareTo(token) == 0) {
nextToken();
} else {
throw new SyntaxException(st.lineno(), new Token(ttype, token),
lookahead);
}
}
/**
* match a token with TT_TYPE=type
*/
private void match(int ttype) throws ParserException, IOException {
if (lookahead.ttype == ttype) {
nextToken();
} else {
throw new SyntaxException(st.lineno(), new Token(ttype), lookahead);
}
}
/**
* match a token with TT_TYPE=char, where the token value is the given char.
*/
private void match(char ttype) throws ParserException, IOException {
if (lookahead.ttype == (int)ttype) {
nextToken();
}
else {
throw new SyntaxException(st.lineno(), new Token((int)ttype),
lookahead);
}
}
/**
* match a token with TT_TYPE='"', where the token value is a sequence
* of characters between matching quote characters.
*/
private void matchQuotedString() throws ParserException, IOException {
match(DOUBLEQUOTE);
}
/**
* match a TT_NUMBER token that matches a parsed number value
*/
private void matchNumber() throws ParserException, IOException {
match(StreamTokenizer.TT_NUMBER);
}
/**
* match a TT_WORD token that matches an arbitrary, not quoted token.
*/
private void matchID() throws ParserException, IOException {
match(StreamTokenizer.TT_WORD);
}
/**
* match a TT_WORD token that matches the given string
*/
private void match(String token) throws ParserException, IOException {
match(StreamTokenizer.TT_WORD, token);
}
/**
* determine if the given word is a reserved key word
*/
private boolean isReservedWord(String word) {
return reservedWords.contains(word);
}
/**
* determine if the give work is a reserved key word
*/
private boolean isInfixOperator(char op) {
for (int i = 0; i < infixOps.length; i++) {
if (op == infixOps[i]) {
return true;
}
}
return false;
}
/**
* scalestmt -> 'scale' scalespec
* scalespec -> <see above scaleTerminals array>
*/
private void scaleStmt(ColumnFormat cf)
throws ParserException, IOException {
match(SCALE);
Token t = matchOne(scaleKeyWords);
cf.setScale(Scale.toScale(t.sval));
String scaleString = t.sval;
log(pdebug, "Parsed: scale -> " + scaleString);
}
/**
* alignstmt -> 'align' alignspec
* alignspec -> <see above alignTerminals array>
*/
private void alignStmt(ColumnFormat cf)
throws ParserException, IOException {
match(ALIGN);
Token t = matchOne(alignKeyWords);
cf.setAlignment(Alignment.toAlignment(t.sval));
String alignString = t.sval;
log(pdebug, "Parsed: align -> " + alignString);
}
/**
* headerstmt -> 'header' quotedstring
*/
private void headerStmt(ColumnFormat cf)
throws ParserException, IOException {
match(HEADER);
String headerString = lookahead.sval;
matchQuotedString();
cf.setHeader(headerString);
log(pdebug, "Parsed: header -> " + headerString);
}
/**
* widthstmt -> 'width' integer
*/
private void widthStmt(ColumnFormat cf)
throws ParserException, IOException {
match(WIDTH);
double width = lookahead.nval;
matchNumber();
cf.setWidth((int)width);
log(pdebug, "Parsed: width -> " + width );
}
/**
* formatstmt -> 'format' quotedstring
*/
private void formatStmt(ColumnFormat cf)
throws ParserException, IOException {
match(FORMAT);
String formatString = lookahead.sval;
matchQuotedString();
cf.setFormat(formatString);
log(pdebug, "Parsed: format -> " + formatString);
}
/**
* Primary -> Literal | Identifier | '(' Expression ')'
*/
private Expression primary() throws ParserException, IOException {
Expression e = null;
switch (lookahead.ttype) {
case OPENPAREN:
match(OPENPAREN);
e = expression();
match(CLOSEPAREN);
break;
case StreamTokenizer.TT_WORD:
String s = lookahead.sval;
if (isReservedWord(s)) {
throw new SyntaxException(st.lineno(), "IDENTIFIER",
"Reserved Word: " + lookahead.sval);
}
matchID();
e = new Identifier(s);
log(pdebug, "Parsed: ID -> " + s);
break;
case StreamTokenizer.TT_NUMBER:
double literal = lookahead.nval;
matchNumber();
e = new Literal(new Double(literal));
log(pdebug, "Parsed: number -> " + literal);
break;
default:
throw new SyntaxException(st.lineno(), "IDENTIFIER", lookahead);
}
log(pdebug, "Parsed: primary -> " + e);
return e;
}
/**
* Unary -> ('+'|'-') Unary | Primary
*/
private Expression unary() throws ParserException, IOException {
Expression e = null;
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_PLUS:
match(OPERATOR_PLUS);
op = Operator.PLUS;
break;
case OPERATOR_MINUS:
match(OPERATOR_MINUS);
op = Operator.MINUS;
break;
default:
e = primary();
log(pdebug, "Parsed: unary -> " + e);
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setRight(e);
log(pdebug, "Parsed: unary -> " + e1);
e1.setLeft(new Literal(new Double(0)));
e = e1;
}
}
/**
* MultExpression -> Unary (('*' | '/') Unary)*
*/
private Expression multExpression() throws ParserException, IOException {
Expression e = unary();
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_MULTIPLY:
match(OPERATOR_MULTIPLY);
op = Operator.MULTIPLY;
break;
case OPERATOR_DIVIDE:
match(OPERATOR_DIVIDE);
op = Operator.DIVIDE;
break;
default:
log(pdebug, "Parsed: multExpression -> " + e);
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setLeft(e);
e1.setRight(unary());
e = e1;
log(pdebug, "Parsed: multExpression -> " + e);
}
}
/**
* AddExpression -> MultExpression (('+' | '-') MultExpression)*
*/
private Expression addExpression() throws ParserException, IOException {
Expression e = multExpression();
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_PLUS:
match(OPERATOR_PLUS);
op = Operator.PLUS;
break;
case OPERATOR_MINUS:
match(OPERATOR_MINUS);
op = Operator.MINUS;
break;
default:
log(pdebug, "Parsed: addExpression -> " + e);
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setLeft(e);
e1.setRight(multExpression());
e = e1;
log(pdebug, "Parsed: addExpression -> " + e);
}
}
/**
* Expression -> AddExpression
*/
private Expression expression() throws ParserException, IOException {
Expression e = addExpression();
log(pdebug, "Parsed: expression -> " + e);
return e;
}
/**
* datastmt -> 'data' expression
*/
private void dataStmt(ColumnFormat cf) throws ParserException, IOException {
match(DATA);
Expression e = expression();
cf.setExpression(e);
log(pdebug, "Parsed: data -> " + e);
}
/**
* statementlist -> optionalstmt statementlist
* optionalstmt -> 'data' expression
* 'header' quotedstring
* 'width' integer
* 'format' formatstring
* 'align' alignspec
* 'scale' scalespec
*/
private void statementList(ColumnFormat cf)
throws ParserException, IOException {
while (true) {
if (lookahead.ttype != StreamTokenizer.TT_WORD) {
return;
}
if (lookahead.sval.compareTo(DATA) == 0) {
dataStmt(cf);
} else if (lookahead.sval.compareTo(HEADER) == 0) {
headerStmt(cf);
} else if (lookahead.sval.compareTo(WIDTH) == 0) {
widthStmt(cf);
} else if (lookahead.sval.compareTo(FORMAT) == 0) {
formatStmt(cf);
} else if (lookahead.sval.compareTo(ALIGN) == 0) {
alignStmt(cf);
} else if (lookahead.sval.compareTo(SCALE) == 0) {
scaleStmt(cf);
} else {
return;
}
}
}
/**
* optionlist -> columspec optionlist
* null
* columspec -> 'column' '{' statementlist '}'
*/
private void optionList(OptionFormat of)
throws ParserException, IOException {
while (true) {
if (lookahead.ttype != StreamTokenizer.TT_WORD) {
return;
}
match(COLUMN);
match(OPENBLOCK);
ColumnFormat cf = new ColumnFormat(columnCount++);
statementList(cf);
match(CLOSEBLOCK);
cf.validate();
of.addSubFormat(cf);
}
}
/**
* optionstmt -> 'option' ID '{' optionlist '}'
*/
private OptionFormat optionStmt() throws ParserException, IOException {
match(OPTION);
String optionName=lookahead.sval;
matchID();
match(OPENBLOCK);
OptionFormat of = new OptionFormat(optionName);
optionList(of);
match(CLOSEBLOCK);
return of;
}
/**
* parse the specification for the given option identifier
*/
public OptionFormat parse(String option)
throws ParserException, IOException {
nextToken();
/*
* this search stops on the first occurance of an option
* statement with a name matching the given option. Any
* duplicate options are ignored.
*/
while (lookahead.ttype != StreamTokenizer.TT_EOF) {
// look for the start symbol
if ((lookahead.ttype != StreamTokenizer.TT_WORD)
|| (lookahead.sval.compareTo(START) != 0)) {
// skip tokens until a start symbol is found
nextToken();
continue;
}
// check if the option name is the one we are interested in
match(START);
if ((lookahead.ttype == StreamTokenizer.TT_WORD)
&& (lookahead.sval.compareTo(option) == 0)) {
// this is the one we are looking for, parse it
pushBack();
return optionStmt();
} else {
// not what we are looking for, start skipping tokens
nextToken();
}
}
return null;
}
public Set<OptionFormat> parseOptions() throws ParserException, IOException {
Set<OptionFormat> options = new HashSet<OptionFormat>();
nextToken();
while (lookahead.ttype != StreamTokenizer.TT_EOF) {
// look for the start symbol
if ((lookahead.ttype != StreamTokenizer.TT_WORD)
|| (lookahead.sval.compareTo(START) != 0)) {
// skip tokens until a start symbol is found
nextToken();
continue;
}
// note: if a duplicate option statement exists, then
// first one encountered is the chosen definition.
OptionFormat of = optionStmt();
options.add(of);
}
return options;
}
OptionFormat getOptionFormat() {
return optionFormat;
}
private void log(boolean logging, String s) {
if (logging) {
System.out.println(s);
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
/**
* A class for describing exceptions generated by the Parser class.
*
* @author Brian Doherty
* @since 1.5
*/
public class ParserException extends Exception {
public ParserException() {
super();
}
public ParserException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* A class for formatting raw counter output.
*
* @author Brian Doherty
* @since 1.5
*/
public class RawOutputFormatter implements OutputFormatter {
private List logged;
private String header;
private boolean printStrings;
public RawOutputFormatter(List logged, boolean printStrings) {
this.logged = logged;
this.printStrings = printStrings;
}
public String getHeader() throws MonitorException {
if (header == null) {
// build the header string and prune out any unwanted monitors
StringBuilder headerBuilder = new StringBuilder();
for (Iterator i = logged.iterator(); i.hasNext(); /* empty */ ) {
Monitor m = (Monitor)i.next();
headerBuilder.append(m.getName() + " ");
}
header = headerBuilder.toString();
}
return header;
}
public String getRow() throws MonitorException {
StringBuilder row = new StringBuilder();
int count = 0;
for (Iterator i = logged.iterator(); i.hasNext(); /* empty */ ) {
Monitor m = (Monitor)i.next();
if (count++ > 0) {
row.append(" ");
}
if (printStrings && m instanceof StringMonitor) {
row.append("\"").append(m.getValue()).append("\"");
} else {
row.append(m.getValue());
}
}
return row.toString();
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.text.*;
import sun.jvmstat.monitor.*;
/**
* A class implementing the Closure interface for iterating over the
* specified columns of data and generating the columnized string of
* data representing a row of output for the form.
*
* @author Brian Doherty
* @since 1.5
*/
public class RowClosure implements Closure {
private MonitoredVm vm;
private StringBuilder row = new StringBuilder();
public RowClosure(MonitoredVm vm) {
this.vm = vm;
}
public void visit(Object o, boolean hasNext) throws MonitorException {
if (! (o instanceof ColumnFormat)) {
return;
}
ColumnFormat c = (ColumnFormat)o;
String s = null;
Expression e = c.getExpression();
ExpressionEvaluator ee = new ExpressionExecuter(vm);
Object value = ee.evaluate(e);
if (value instanceof String) {
s = (String)value;
} else if (value instanceof Number) {
double d = ((Number)value).doubleValue();
double scaledValue = c.getScale().scale(d);
DecimalFormat df = new DecimalFormat(c.getFormat());
DecimalFormatSymbols syms = df.getDecimalFormatSymbols();
syms.setNaN("-");
df.setDecimalFormatSymbols(syms);
s = df.format(scaledValue);
}
c.setPreviousValue(value);
s = c.getAlignment().align(s, c.getWidth());
row.append(s);
if (hasNext) {
row.append(" ");
}
}
public String getRow() {
return row.toString();
}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.util.*;
/**
* A typesafe enumeration for describing data scaling semantics
*
* @author Brian Doherty
* @since 1.5
*/
public class Scale {
private static int nextOrdinal = 0;
private static HashMap<String, Scale> map = new HashMap<String, Scale>();
private final String name;
private final int ordinal = nextOrdinal++;
private final double factor;
private Scale(String name, double factor) {
this.name = name;
this.factor = factor;
assert !map.containsKey(name);
map.put(name, this);
}
/**
* Scale representing a no scaling
*/
public static final Scale RAW = new Scale("raw", 1);
/**
* Scale representing a percent scaling
*/
public static final Scale PERCENT = new Scale("percent", 1/100);
/**
* Scale representing a kilo scaling
*/
public static final Scale KILO = new Scale("K", 1024);
/**
* Scale representing a mega scaling
*/
public static final Scale MEGA = new Scale("M", 1024*1024);
/**
* Scale representing a giga scaling
*/
public static final Scale GIGA = new Scale("G", 1024*1024*1024);
/**
* Scale representing a tera scaling
*/
public static final Scale TERA = new Scale("T", 1024*1024*1024*1024);
/**
* Scale representing a tera scaling
*/
public static final Scale PETA = new Scale("P", 1024*1024*1024*1024*1024);
/**
* Scale representing a pico scaling
*/
public static final Scale PICO = new Scale("p", 10.0E-12);
/**
* Scale representing a nano scaling
*/
public static final Scale NANO = new Scale("n", 10.0E-9);
/**
* Scale representing a micro scaling
*/
public static final Scale MICRO = new Scale("u", 10.0E-6);
/**
* Scale representing a milli scaling
*/
public static final Scale MILLI = new Scale("m", 10.0E-3);
/**
* Scale representing a picosecond scaling
*/
public static final Scale PSEC = new Scale("ps", 10.0E-12);
/**
* Scale representing a nanosecond scaling
*/
public static final Scale NSEC = new Scale("ns", 10.0E-9);
/**
* Scale representing a microsecond scaling
*/
public static final Scale USEC = new Scale("us", 10.0E-6);
/**
* Scale representing a millisecond scaling
*/
public static final Scale MSEC = new Scale("ms", 10.0E-3);
/**
* Scale representing a second scaling
*/
public static final Scale SEC = new Scale("s", 1);
public static final Scale SEC2 = new Scale("sec", 1);
/**
* Scale representing a minutes scaling
*/
public static final Scale MINUTES = new Scale("min", 1/60.0);
/**
* Scale representing a hours scaling
*/
public static final Scale HOUR = new Scale("h", 1/(60.0*60.0));
public static final Scale HOUR2 = new Scale("hour", 1/(60.0*60.0));
/**
* Returns the scaling factor of this Scale object
*
* @return the scaling factor of this Scale object
*/
public double getFactor() {
return factor;
}
/**
* Returns the string representation of this Scale object.
* The string representation is the name of the Scale object.
*
* @return the string representation of this Scale object
*/
public String toString() {
return name;
}
/**
* Maps a string to its corresponding Scale object.
*
* @param s a string to match against Scale objects.
* @return The Scale object matching the given string.
*/
public static Scale toScale(String s) {
return map.get(s);
}
/**
* Returns an enumeration of the keys for this enumerated type
*
* @param s an string to match against Scale objects.
* @return The Scale object matching the given string.
*/
protected static Set keySet() {
return map.keySet();
}
protected double scale(double value) {
return value/factor;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.text.*;
import sun.jvmstat.monitor.MonitorException;
/**
* A class implementing the Closure interface which is used to resolve
* all the symbols in the expressions contained in ColumnFormat objects.
*
* @author Brian Doherty
* @since 1.5
*/
public class SymbolResolutionClosure implements Closure {
private static final boolean debug =
Boolean.getBoolean("SymbolResolutionClosure.debug");
private ExpressionEvaluator ee;
public SymbolResolutionClosure(ExpressionEvaluator ee) {
this.ee = ee;
}
public void visit(Object o, boolean hasNext) throws MonitorException {
if (! (o instanceof ColumnFormat)) {
return;
}
ColumnFormat c = (ColumnFormat)o;
Expression e = c.getExpression();
String previous = e.toString();
e = (Expression)ee.evaluate(e);
if (debug) {
System.out.print("Expression: " + previous + " resolved to "
+ e.toString());
}
c.setExpression(e);
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.io.StreamTokenizer;
import java.util.Set;
import java.util.Iterator;
/**
* An exception class for syntax exceptions detected by the options file
* parser.
*
* @author Brian Doherty
* @since 1.5
*/
public class SyntaxException extends ParserException {
private String message;
public SyntaxException(String message) {
this.message = message;
}
public SyntaxException(int lineno, String expected, String found) {
message = "Syntax error at line " + lineno
+ ": Expected " + expected
+ ", Found " + found;
}
public SyntaxException(int lineno, String expected, Token found) {
message = "Syntax error at line " + lineno
+ ": Expected " + expected
+ ", Found " + found.toMessage();
}
public SyntaxException(int lineno, Token expected, Token found) {
message = "Syntax error at line " + lineno
+ ": Expected " + expected.toMessage()
+ ", Found " + found.toMessage();
}
public SyntaxException(int lineno, Set expected, Token found) {
StringBuilder msg = new StringBuilder();
msg.append("Syntax error at line " + lineno + ": Expected one of \'");
boolean first = true;
for (Iterator i = expected.iterator(); i.hasNext(); /* empty */) {
String keyWord = (String)i.next();
if (first) {
msg.append(keyWord);
first = false;
} else {
msg.append("|" + keyWord);
}
}
msg.append("\', Found " + found.toMessage());
message = msg.toString();
}
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.jstat;
import java.io.StreamTokenizer;
/**
* A class for encapsulating tokens returned from StreamTokenizer primarily
* for output formatting purposes.
*
* @author Brian Doherty
* @since 1.5
*/
public class Token {
public String sval;
public double nval;
public int ttype;
public Token(int ttype, String sval, double nval) {
this.ttype = ttype;
this.sval = sval;
this.nval = nval;
}
public Token(int ttype, String sval) {
this(ttype, sval, 0);
}
public Token(int ttype) {
this(ttype, null, 0);
}
public String toMessage() {
switch(ttype) {
case StreamTokenizer.TT_EOL:
return "\"EOL\"";
case StreamTokenizer.TT_EOF:
return "\"EOF\"";
case StreamTokenizer.TT_NUMBER:
return "NUMBER";
case StreamTokenizer.TT_WORD:
if (sval == null) {
return "IDENTIFIER";
} else {
return "IDENTIFIER " + sval;
}
default:
if (ttype == (int)'"') {
String msg = "QUOTED STRING";
if (sval != null)
msg = msg + " \"" + sval + "\"";
return msg;
} else {
return "CHARACTER \'" + (char)ttype + "\'";
}
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
switch(ttype) {
case StreamTokenizer.TT_EOL:
sb.append("ttype=TT_EOL");
break;
case StreamTokenizer.TT_EOF:
sb.append("ttype=TT_EOF");
break;
case StreamTokenizer.TT_NUMBER:
sb.append("ttype=TT_NUM,").append("nval="+nval);
break;
case StreamTokenizer.TT_WORD:
if (sval == null) {
sb.append("ttype=TT_WORD:IDENTIFIER");
} else {
sb.append("ttype=TT_WORD:").append("sval="+sval);
}
break;
default:
if (ttype == (int)'"') {
sb.append("ttype=TT_STRING:").append("sval="+sval);
} else {
sb.append("ttype=TT_CHAR:").append((char)ttype);
}
break;
}
return sb.toString();
}
}