Mercurial > hg > truffle
comparison graal/com.oracle.max.criutils/src/com/oracle/max/criutils/TTY.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | bc8527f3071c |
comparison
equal
deleted
inserted
replaced
3732:3e2e8b8abdaf | 3733:e233f5660da4 |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.max.criutils; | |
24 | |
25 import java.io.*; | |
26 import java.lang.reflect.*; | |
27 import java.util.*; | |
28 import java.util.regex.*; | |
29 | |
30 /** | |
31 * A collection of static methods for printing debug and informational output to a global {@link LogStream}. | |
32 * The output can be (temporarily) suppressed per thread through use of a {@linkplain Filter filter}. | |
33 */ | |
34 public class TTY { | |
35 | |
36 /** | |
37 * Support for thread-local suppression of {@link TTY}. | |
38 */ | |
39 public static class Filter { | |
40 private LogStream previous; | |
41 private final Thread thread = Thread.currentThread(); | |
42 | |
43 /** | |
44 * Creates an object that will suppress {@link TTY} for the current thread if the given filter does not | |
45 * {@linkplain #matches(String, Object) match} the given object. To revert the suppression state to how it was | |
46 * before this call, the {@link #remove()} method must be called on the suppression object. | |
47 * | |
48 * @param filter the pattern for matching. If {@code null}, then the match is successful. If it starts with "~", | |
49 * then a regular expression {@linkplain Pattern#matches(String, CharSequence) match} is performed | |
50 * where the regular expression is specified by {@code filter} without the "~" prefix. Otherwise, a | |
51 * simple {@linkplain String#contains(CharSequence) substring} match is performed where {@code | |
52 * filter} is the substring used. | |
53 * @param object an object whose {@linkplain Object#toString() string} value is matched against {@code filter} | |
54 */ | |
55 public Filter(String filter, Object object) { | |
56 boolean suppressed = false; | |
57 if (filter != null) { | |
58 String input = object.toString(); | |
59 if (filter.startsWith("~")) { | |
60 suppressed = !Pattern.matches(filter.substring(1), input); | |
61 } else { | |
62 suppressed = !input.contains(filter); | |
63 } | |
64 if (suppressed) { | |
65 previous = out(); | |
66 out.set(LogStream.SINK); | |
67 } | |
68 } | |
69 } | |
70 | |
71 /** | |
72 * Creates an object that will suppress {@link TTY} for the current thread. | |
73 * To revert the suppression state to how it was before this call, the | |
74 * {@link #remove()} method must be called on this filter object. | |
75 */ | |
76 public Filter() { | |
77 previous = out(); | |
78 out.set(LogStream.SINK); | |
79 } | |
80 | |
81 /** | |
82 * Reverts the suppression state of {@link TTY} to how it was before this object was constructed. | |
83 */ | |
84 public void remove() { | |
85 assert thread == Thread.currentThread(); | |
86 if (previous != null) { | |
87 out.set(previous); | |
88 } | |
89 } | |
90 } | |
91 | |
92 public static final String MAX_TTY_LOG_FILE_PROPERTY = "max.tty.file"; | |
93 | |
94 public static PrintStream cachedOut; | |
95 | |
96 public static void initialize() { | |
97 cachedOut = System.out; | |
98 } | |
99 | |
100 private static LogStream createLog() { | |
101 if (cachedOut == null) { | |
102 // In case initialize() was not called. | |
103 cachedOut = System.out; | |
104 } | |
105 PrintStream out = cachedOut; | |
106 String value = System.getProperty(MAX_TTY_LOG_FILE_PROPERTY); | |
107 if (value != null) { | |
108 try { | |
109 out = new PrintStream(new FileOutputStream(value)); | |
110 } catch (FileNotFoundException e) { | |
111 System.err.println("Could not open log file " + value + ": " + e); | |
112 } | |
113 } | |
114 return new LogStream(out); | |
115 } | |
116 | |
117 private static final ThreadLocal<LogStream> out = new ThreadLocal<LogStream>() { | |
118 @Override | |
119 protected LogStream initialValue() { | |
120 return createLog(); | |
121 } | |
122 }; | |
123 | |
124 public static boolean isSuppressed() { | |
125 return out.get() == LogStream.SINK; | |
126 } | |
127 | |
128 /** | |
129 * Gets the thread-local log stream to which the static methods of this class send their output. | |
130 * This will either be a global log stream or the global {@linkplain LogStream#SINK sink} depending | |
131 * on whether any suppression {@linkplain Filter filters} are in effect for the current thread. | |
132 */ | |
133 public static LogStream out() { | |
134 return out.get(); | |
135 } | |
136 | |
137 /** | |
138 * @see LogStream#print(String) | |
139 */ | |
140 public static void print(String s) { | |
141 out().print(s); | |
142 } | |
143 | |
144 /** | |
145 * @see LogStream#print(int) | |
146 */ | |
147 public static void print(int i) { | |
148 out().print(i); | |
149 } | |
150 | |
151 /** | |
152 * @see LogStream#print(long) | |
153 */ | |
154 public static void print(long i) { | |
155 out().print(i); | |
156 } | |
157 | |
158 /** | |
159 * @see LogStream#print(char) | |
160 */ | |
161 public static void print(char c) { | |
162 out().print(c); | |
163 } | |
164 | |
165 /** | |
166 * @see LogStream#print(boolean) | |
167 */ | |
168 public static void print(boolean b) { | |
169 out().print(b); | |
170 } | |
171 | |
172 /** | |
173 * @see LogStream#print(double) | |
174 */ | |
175 public static void print(double d) { | |
176 out().print(d); | |
177 } | |
178 | |
179 /** | |
180 * @see LogStream#print(float) | |
181 */ | |
182 public static void print(float f) { | |
183 out().print(f); | |
184 } | |
185 | |
186 /** | |
187 * @see LogStream#println(String) | |
188 */ | |
189 public static void println(String s) { | |
190 out().println(s); | |
191 } | |
192 | |
193 /** | |
194 * @see LogStream#println() | |
195 */ | |
196 public static void println() { | |
197 out().println(); | |
198 } | |
199 | |
200 /** | |
201 * @see LogStream#println(int) | |
202 */ | |
203 public static void println(int i) { | |
204 out().println(i); | |
205 } | |
206 | |
207 /** | |
208 * @see LogStream#println(long) | |
209 */ | |
210 public static void println(long l) { | |
211 out().println(l); | |
212 } | |
213 | |
214 /** | |
215 * @see LogStream#println(char) | |
216 */ | |
217 public static void println(char c) { | |
218 out().println(c); | |
219 } | |
220 | |
221 /** | |
222 * @see LogStream#println(boolean) | |
223 */ | |
224 public static void println(boolean b) { | |
225 out().println(b); | |
226 } | |
227 | |
228 /** | |
229 * @see LogStream#println(double) | |
230 */ | |
231 public static void println(double d) { | |
232 out().println(d); | |
233 } | |
234 | |
235 /** | |
236 * @see LogStream#println(float) | |
237 */ | |
238 public static void println(float f) { | |
239 out().println(f); | |
240 } | |
241 | |
242 public static void print(String format, Object... args) { | |
243 out().printf(format, args); | |
244 } | |
245 | |
246 public static void println(String format, Object... args) { | |
247 out().printf(format + "%n", args); | |
248 } | |
249 | |
250 public static void fillTo(int i) { | |
251 out().fillTo(i, ' '); | |
252 } | |
253 | |
254 public static void printFields(Class<?> javaClass) { | |
255 final String className = javaClass.getSimpleName(); | |
256 TTY.println(className + " {"); | |
257 for (final Field field : javaClass.getFields()) { | |
258 printField(field, false); | |
259 } | |
260 TTY.println("}"); | |
261 } | |
262 | |
263 public static void printField(final Field field, boolean tabbed) { | |
264 final String fieldName = String.format("%35s", field.getName()); | |
265 try { | |
266 String prefix = tabbed ? "" : " " + fieldName + " = "; | |
267 String postfix = tabbed ? "\t" : "\n"; | |
268 if (field.getType() == int.class) { | |
269 TTY.print(prefix + field.getInt(null) + postfix); | |
270 } else if (field.getType() == boolean.class) { | |
271 TTY.print(prefix + field.getBoolean(null) + postfix); | |
272 } else if (field.getType() == float.class) { | |
273 TTY.print(prefix + field.getFloat(null) + postfix); | |
274 } else if (field.getType() == String.class) { | |
275 TTY.print(prefix + field.get(null) + postfix); | |
276 } else if (field.getType() == Map.class) { | |
277 Map<?, ?> m = (Map<?, ?>) field.get(null); | |
278 TTY.print(prefix + printMap(m) + postfix); | |
279 } else { | |
280 TTY.print(prefix + field.get(null) + postfix); | |
281 } | |
282 } catch (IllegalAccessException e) { | |
283 // do nothing. | |
284 } | |
285 } | |
286 | |
287 private static String printMap(Map<?, ?> m) { | |
288 StringBuilder sb = new StringBuilder(); | |
289 | |
290 List<String> keys = new ArrayList<String>(); | |
291 for (Object key : m.keySet()) { | |
292 keys.add((String) key); | |
293 } | |
294 Collections.sort(keys); | |
295 | |
296 for (String key : keys) { | |
297 sb.append(key); | |
298 sb.append("\t"); | |
299 sb.append(m.get(key)); | |
300 sb.append("\n"); | |
301 } | |
302 | |
303 return sb.toString(); | |
304 } | |
305 | |
306 private static void printField(String fieldName, long value) { | |
307 TTY.print(" " + fieldName + " = " + value + "\n"); | |
308 } | |
309 | |
310 private static void printField(String fieldName, double value) { | |
311 TTY.print(" " + fieldName + " = " + value + "\n"); | |
312 } | |
313 | |
314 public static void flush() { | |
315 out().flush(); | |
316 } | |
317 } |