blob: d7f4ddc5bf8cc42f2e216b70da61e93be9dacf49 [file] [log] [blame]
/*
* Copyright (c) 2000, 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.
*
* 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.jvm.hotspot.utilities;
import java.io.*;
import java.util.*;
/** Reads all of the data from the given InputStream, and allows the
caller to wait for a given string to come in or watch for many
possible strings. */
public class StreamMonitor implements Runnable {
private BufferedReader input;
private boolean printStreamContents;
private String waitString;
private boolean waitStringSeen;
private List triggers = new LinkedList();
private List triggersSeen = new LinkedList();
private String prefixString;
private boolean printContents;
private StringBuffer captureBuffer;
class Trigger {
private String[] triggerStrings;
private int triggerVal;
Trigger(String str, int val) {
triggerStrings = new String[] { str };
triggerVal = val;
}
// Hack because we don't have a regexp library yet.
// This requires all strings to be matched.
Trigger(String[] strs, int val) {
triggerStrings = strs;
triggerVal = val;
}
boolean matches(String str) {
for (int i = 0; i < triggerStrings.length; i++) {
if (str.indexOf(triggerStrings[i]) == -1) {
return false;
}
}
return true;
}
boolean equals(String[] strs) {
if (strs.length != triggerStrings.length) {
return false;
}
for (int i = 0; i < strs.length; i++) {
if (!strs[i].equals(triggerStrings[i])) {
return false;
}
}
return true;
}
}
/** Equivalent to StreamMonitor(istr, null, false) */
public StreamMonitor(InputStream istr) {
this(istr, null, false);
}
public StreamMonitor(InputStream istr, String prefixString, boolean printContents) {
input = new BufferedReader(new InputStreamReader(istr));
this.prefixString = prefixString;
this.printContents = printContents;
Thread thr = new Thread(this);
thr.setDaemon(true);
thr.start();
}
/** Adds a "trigger", which the stream watches for and, if seen,
reports the trigger value of via the getTriggers() method.
Returns true if the addition was successful, false if the string
was already present as a trigger. */
public boolean addTrigger(String str, int value) {
return addTrigger(new String[] { str }, value);
}
/** Adds a "trigger", which the stream watches for and, if seen,
reports the trigger value of via the getTriggers() method.
Returns true if the addition was successful, false if the string
was already present as a trigger. */
public boolean addTrigger(String[] strs, int value) {
for (Iterator iter = triggers.iterator(); iter.hasNext(); ) {
Trigger trigger = (Trigger) iter.next();
if (trigger.equals(strs)) {
return false;
}
}
Trigger trigger = new Trigger(strs, value);
return triggers.add(trigger);
}
/** Removes a previously added trigger. Returns true if it was
present, false if not. */
public boolean removeTrigger(String str) {
return removeTrigger(new String[] { str });
}
/** Removes a previously added trigger. Returns true if it was
present, false if not. */
public boolean removeTrigger(String[] strs) {
for (ListIterator iter = triggers.listIterator(); iter.hasNext(); ) {
Trigger trigger = (Trigger) iter.next();
if (trigger.equals(strs)) {
iter.remove();
return true;
}
}
return false;
}
/** Returns an List of java.lang.Integer objects indicating the
values of the triggers seen since the last call to
getTriggersSeen. If there were no triggers seen, returns an
empty list; does not return null. */
public synchronized List getTriggersSeen() {
List tmpList = triggersSeen;
triggersSeen = new LinkedList();
return tmpList;
}
/** Waits for the specified string to come in for the given period
of time (measured in milliseconds). */
public synchronized boolean waitFor(String str, long millis) {
waitString = str;
waitStringSeen = false;
try {
wait(millis);
}
catch (InterruptedException e) {
}
waitString = null;
return waitStringSeen;
}
public synchronized void startCapture() {
captureBuffer = new StringBuffer();
}
public synchronized String stopCapture() {
String ret = captureBuffer.toString();
captureBuffer = null;
return ret;
}
public void run() {
byte[] buf = new byte[10240];
boolean shouldContinue = true;
try {
do {
String str = input.readLine();
if (str == null) {
shouldContinue = false;
} else {
if (printContents) {
System.err.println(prefixString + ": " + str);
}
synchronized (this) {
if (captureBuffer != null) {
captureBuffer.append(str);
captureBuffer.append("\n");
}
// Check wait string
if ((waitString != null) &&
(str.indexOf(waitString) != -1)) {
waitStringSeen = true;
notifyAll();
}
// Check all triggers
for (Iterator iter = triggers.iterator(); iter.hasNext(); ) {
Trigger trigger = (Trigger) iter.next();
if (trigger.matches(str)) {
triggersSeen.add(new Integer(trigger.triggerVal));
}
}
}
}
} while (shouldContinue);
}
catch (IOException e) {
}
System.err.print("StreamMonitor ");
if (prefixString != null) {
System.err.print("\"" + prefixString + "\" ");
}
System.err.println("exiting");
}
}