0
|
1 /*
|
|
2 * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
5 * This code is free software; you can redistribute it and/or modify it
|
|
6 * under the terms of the GNU General Public License version 2 only, as
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.utilities;
|
|
26
|
|
27 import java.io.*;
|
|
28 import java.util.*;
|
|
29
|
|
30 /** Reads all of the data from the given InputStream, and allows the
|
|
31 caller to wait for a given string to come in or watch for many
|
|
32 possible strings. */
|
|
33
|
|
34 public class StreamMonitor implements Runnable {
|
|
35 private BufferedReader input;
|
|
36 private boolean printStreamContents;
|
|
37
|
|
38 private String waitString;
|
|
39 private boolean waitStringSeen;
|
|
40 private List triggers = new LinkedList();
|
|
41 private List triggersSeen = new LinkedList();
|
|
42
|
|
43 private String prefixString;
|
|
44 private boolean printContents;
|
|
45
|
|
46 private StringBuffer captureBuffer;
|
|
47
|
|
48 class Trigger {
|
|
49 private String[] triggerStrings;
|
|
50 private int triggerVal;
|
|
51
|
|
52 Trigger(String str, int val) {
|
|
53 triggerStrings = new String[] { str };
|
|
54 triggerVal = val;
|
|
55 }
|
|
56
|
|
57 // Hack because we don't have a regexp library yet.
|
|
58 // This requires all strings to be matched.
|
|
59 Trigger(String[] strs, int val) {
|
|
60 triggerStrings = strs;
|
|
61 triggerVal = val;
|
|
62 }
|
|
63
|
|
64 boolean matches(String str) {
|
|
65 for (int i = 0; i < triggerStrings.length; i++) {
|
|
66 if (str.indexOf(triggerStrings[i]) == -1) {
|
|
67 return false;
|
|
68 }
|
|
69 }
|
|
70 return true;
|
|
71 }
|
|
72
|
|
73 boolean equals(String[] strs) {
|
|
74 if (strs.length != triggerStrings.length) {
|
|
75 return false;
|
|
76 }
|
|
77
|
|
78 for (int i = 0; i < strs.length; i++) {
|
|
79 if (!strs[i].equals(triggerStrings[i])) {
|
|
80 return false;
|
|
81 }
|
|
82 }
|
|
83
|
|
84 return true;
|
|
85 }
|
|
86 }
|
|
87
|
|
88 /** Equivalent to StreamMonitor(istr, null, false) */
|
|
89 public StreamMonitor(InputStream istr) {
|
|
90 this(istr, null, false);
|
|
91 }
|
|
92
|
|
93 public StreamMonitor(InputStream istr, String prefixString, boolean printContents) {
|
|
94 input = new BufferedReader(new InputStreamReader(istr));
|
|
95 this.prefixString = prefixString;
|
|
96 this.printContents = printContents;
|
|
97 Thread thr = new Thread(this);
|
|
98 thr.setDaemon(true);
|
|
99 thr.start();
|
|
100 }
|
|
101
|
|
102 /** Adds a "trigger", which the stream watches for and, if seen,
|
|
103 reports the trigger value of via the getTriggers() method.
|
|
104 Returns true if the addition was successful, false if the string
|
|
105 was already present as a trigger. */
|
|
106 public boolean addTrigger(String str, int value) {
|
|
107 return addTrigger(new String[] { str }, value);
|
|
108 }
|
|
109
|
|
110 /** Adds a "trigger", which the stream watches for and, if seen,
|
|
111 reports the trigger value of via the getTriggers() method.
|
|
112 Returns true if the addition was successful, false if the string
|
|
113 was already present as a trigger. */
|
|
114 public boolean addTrigger(String[] strs, int value) {
|
|
115 for (Iterator iter = triggers.iterator(); iter.hasNext(); ) {
|
|
116 Trigger trigger = (Trigger) iter.next();
|
|
117 if (trigger.equals(strs)) {
|
|
118 return false;
|
|
119 }
|
|
120 }
|
|
121 Trigger trigger = new Trigger(strs, value);
|
|
122 return triggers.add(trigger);
|
|
123 }
|
|
124
|
|
125 /** Removes a previously added trigger. Returns true if it was
|
|
126 present, false if not. */
|
|
127 public boolean removeTrigger(String str) {
|
|
128 return removeTrigger(new String[] { str });
|
|
129 }
|
|
130
|
|
131 /** Removes a previously added trigger. Returns true if it was
|
|
132 present, false if not. */
|
|
133 public boolean removeTrigger(String[] strs) {
|
|
134 for (ListIterator iter = triggers.listIterator(); iter.hasNext(); ) {
|
|
135 Trigger trigger = (Trigger) iter.next();
|
|
136 if (trigger.equals(strs)) {
|
|
137 iter.remove();
|
|
138 return true;
|
|
139 }
|
|
140 }
|
|
141 return false;
|
|
142 }
|
|
143
|
|
144 /** Returns an List of java.lang.Integer objects indicating the
|
|
145 values of the triggers seen since the last call to
|
|
146 getTriggersSeen. If there were no triggers seen, returns an
|
|
147 empty list; does not return null. */
|
|
148 public synchronized List getTriggersSeen() {
|
|
149 List tmpList = triggersSeen;
|
|
150 triggersSeen = new LinkedList();
|
|
151 return tmpList;
|
|
152 }
|
|
153
|
|
154 /** Waits for the specified string to come in for the given period
|
|
155 of time (measured in milliseconds). */
|
|
156 public synchronized boolean waitFor(String str, long millis) {
|
|
157 waitString = str;
|
|
158 waitStringSeen = false;
|
|
159 try {
|
|
160 wait(millis);
|
|
161 }
|
|
162 catch (InterruptedException e) {
|
|
163 }
|
|
164
|
|
165 waitString = null;
|
|
166 return waitStringSeen;
|
|
167 }
|
|
168
|
|
169 public synchronized void startCapture() {
|
|
170 captureBuffer = new StringBuffer();
|
|
171 }
|
|
172
|
|
173 public synchronized String stopCapture() {
|
|
174 String ret = captureBuffer.toString();
|
|
175 captureBuffer = null;
|
|
176 return ret;
|
|
177 }
|
|
178
|
|
179 public void run() {
|
|
180 byte[] buf = new byte[10240];
|
|
181 boolean shouldContinue = true;
|
|
182
|
|
183 try {
|
|
184 do {
|
|
185 String str = input.readLine();
|
|
186 if (str == null) {
|
|
187 shouldContinue = false;
|
|
188 } else {
|
|
189 if (printContents) {
|
|
190 System.err.println(prefixString + ": " + str);
|
|
191 }
|
|
192 synchronized (this) {
|
|
193
|
|
194 if (captureBuffer != null) {
|
|
195 captureBuffer.append(str);
|
|
196 captureBuffer.append("\n");
|
|
197 }
|
|
198
|
|
199 // Check wait string
|
|
200 if ((waitString != null) &&
|
|
201 (str.indexOf(waitString) != -1)) {
|
|
202 waitStringSeen = true;
|
|
203 notifyAll();
|
|
204 }
|
|
205
|
|
206 // Check all triggers
|
|
207 for (Iterator iter = triggers.iterator(); iter.hasNext(); ) {
|
|
208 Trigger trigger = (Trigger) iter.next();
|
|
209 if (trigger.matches(str)) {
|
|
210 triggersSeen.add(new Integer(trigger.triggerVal));
|
|
211 }
|
|
212 }
|
|
213 }
|
|
214 }
|
|
215 } while (shouldContinue);
|
|
216 }
|
|
217 catch (IOException e) {
|
|
218 }
|
|
219
|
|
220 System.err.print("StreamMonitor ");
|
|
221 if (prefixString != null) {
|
|
222 System.err.print("\"" + prefixString + "\" ");
|
|
223 }
|
|
224 System.err.println("exiting");
|
|
225 }
|
|
226 }
|