| /* |
| * 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"); |
| } |
| } |