Source code: org/dinopolis/util/Debug.java
1 /***********************************************************************
2 * @(#)$RCSfile: Debug.java,v $ $Revision: 1.2 $ $Date: 2003/02/18 08:10:20 $
3 *
4 * Copyright (c) 2000 IICM, Graz University of Technology
5 * Inffeldgasse 16c, A-8010 Graz, Austria.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License (LGPL)
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 ***********************************************************************/
22
23
24 package org.dinopolis.util;
25
26 import java.io.Writer;
27
28 //---------------------------------------------------------------------
29 //---------------------------------------------------------------------
30 /**
31 * Debug helps the programmer to print various debug messages. This
32 * class is a frontend to the {@link org.dinopolis.util.debug.Debug
33 * org.dinopolis.util.debug.Debug} class. Its only purpose is to ease
34 * the use of the mentioned class. All methods in this class are
35 * static so the usage simply is
36 * <code>Debug.methodName(arguments)</code>. No instance must be
37 * handed from one class to the other.
38 * <p>
39 *
40 * <h3>Debug Levels</h3>
41 * <a name="sd:DebugDebugLevels">
42 *
43 * The Debug class provides the possibility to print debug messages
44 * depending on the debug level. There is a status for a given debug
45 * level that indicates if messages for this level should be put out or
46 * not. This status can be requested from the debug class. A shortcut
47 * in the method that prints the debug message will be provided.
48 *
49 * <h3>Change Settings</h3>
50 * <a name="sd:DebugChangeSettings">
51 *
52 * The settings of the debug class (e.g. enable/disable debug messages
53 * for a debug-level, ...) can be set using different ways:
54 *
55 * <ul>
56 *
57 * <li> Hardcoded in the application that should be debugged: The debug
58 * methods that change the settings can be invoked within the code of the
59 * application.
60 *
61 * <li> In the configuration file of the debug class: All settings can
62 * be written into a configuration file. This file is read by the debug
63 * class when the application uses a debug method for the first time. If
64 * wanted, the debug class rereads this file periodically, so any changes
65 * made in this file are applied directly.
66 *
67 * <li> The debug class provides a way to set debug settings first and
68 * then directly start a given application, so the settings stay valid
69 * for the application.
70 *
71 * </ul>
72 *
73 *
74 * <h3>Redirect Output</h3>
75 * <a name="sd:DebugRedirectOutput">
76 *
77 * The debug class is able to write the debug messages to any stream. By
78 * default this stream is set to <code>System.err</code>, but can easily be
79 * set to a file or to a network stream.
80 *
81 * <h3>Format of Debug Message</h3>
82 * <a name="sd:DebugFormatOfDebugMessage">
83 *
84 * The format of the debug message is freely configurable. The debug
85 * message format definition is parsed for keywords (Keywords are
86 * delimitered by a special character.). A factory creates objects by
87 * using the keyword as a part of the classname. On request, these
88 * objects return a String-value which replaces the keyword in the debug
89 * message format definition. E.g. for the keyword <code>%date%</code>,
90 * an object of the class {@link
91 * org.dinopolis.util.debug.DebugMessageDATE} is created.
92 * <p>
93 * For performance reasons these objects are crated only when the format
94 * definiation changes and are then reused for every debug message. This
95 * implies that these objects are stateless.
96 *
97 * <h3>Timer</h3>
98 * <a name="sd:DebugTimer">
99 *
100 * A simple timer functionality is provided. The timer objects are named
101 * and the name is then used to retrieve the time or to stop the
102 * timer. The timer object is never handed to the user; it is only
103 * possible to obtain a string representation that holds the current time
104 * and the time spent since the timer was started.
105 * <p>
106 * The timer does not subtract the time spent inside the debug class. So
107 * timings may vary depending on the debug levels enabled/disabled.
108 *
109 * <h3>StackTrace</h3>
110 * <a name="sd:DebugStacktrace">
111 *
112 * The debug class provides methods to obtain a string representation of
113 * the stack trace, so any calling hierarchies can be made visible
114 * easily. Alternatively only one line of the stack trace can be
115 * requested. This line indicates the class and linenumber (if available)
116 * of the caller.
117 * <p>
118 * As Java offers only stacktraces of Exceptions/Throwables, a new
119 * Throwable is created and its stacktrace is used. Any traces from the
120 * Debug class itself are removed.
121 *
122 * <h3>Print Various Objects Types</h3>
123 * <a name="sd:DebugPrintVariousObjectsTypes">
124 *
125 * A static method is provided that returns the string representation of
126 * arrays of objects as well as of objects. In the case of objects, the
127 * <code>toString()<code> method is called. In the case of arrays, for each
128 * element in the array the static method is recursivly called. Using
129 * this way, string representations of arrays that hold arrays can be
130 * returned as well.
131 *
132 * <h3>Remove Debug Code</h3>
133 * <a name="sd:DebugRemoveDebugCode">
134 *
135 * The Debug class holds a <code>static final boolean</code> variable. If this
136 * variable is used in a conditional statement, the Java compiler is able
137 * to decide that the code is written into the class file or not during
138 * compilation. For better understanding, an example is given:
139 * <pre>
140 * if (Debug.DEBUG)
141 * {
142 * // this code will only be in the class file,
143 * // if Debug.DEBUG is set to true!
144 * }
145 * </pre>
146 *
147 * <h3>Static and non-static class</h3>
148 * <a name="sd:DebugStaticAndNon-StaticClass">
149 *
150 * There are two different ways to use the Debug class. This class
151 * with static methods is for comfortable use by applications. This is
152 * the class normal users will use. Some situations may ask for
153 * independent Debug objects, so an instance of {@link
154 * org.dinopolis.util.debug.Debug org.dinopolis.util.debug.Debug} may
155 * be used for these purposes. The {@linkplain
156 * org.dinopolis.util.Debug 'static' Debug class} uses one instance of
157 * the 'instance' Debug class.
158 *
159 * <h3>Message Format Objects</h3>
160 *
161 * Message Format Objects are created by {@link
162 * org.dinopolis.util.debug.DebugMessageFormatFactory} and are used for
163 * formatting the debug message depending on the debug message format
164 * definition. All Format Objects must implement the interface {@link
165 * org.dinopolis.util.debug.DebugMessageFormatObject}
166 *
167 * <h3>Usage</h3>
168 *
169 * The static methods of Debug makes them easy to use.
170 * <p>
171 * The easiest way to to print a messages:
172 * <pre>
173 * Debug.println("this is a debug message");
174 * </pre>
175 *
176 * Generally this does not really make sense, as no differentiation can
177 * be made. The only exception is when debug messages should not be
178 * printed on the console but to a file or a network connection. All
179 * debug messages can be printed to any {@link java.io.Writer} (see
180 * method {@link #setWriter(java.io.Writer)}). For simplicity, a special
181 * method is provided that faciliates the output to files:
182 * <pre>
183 * Debug.setWriterToFile("/log/debug.log")
184 * Debug.println("this is a debug message sent to file '/log/debug.log'");
185 * </pre>
186 *
187 * Different debug levels let the user decide what type of debug messages
188 * should be printed, and which shouldn't:
189 * <pre>
190 * Debug.println("test-level",
191 * "this is a debug message for debug level 'test-level'");
192 * </pre>
193 *
194 * In this example the debug message is only printed when the given debug
195 * level was enabled before:
196 * <pre>
197 * Debug.addLevelsToPrint("test-level");
198 * </pre>
199 *
200 * Of course it is possible to enable more than one level at a
201 * time. Debug levels can be separated by space, comma, newlines or tabs.
202 * <pre>
203 * Debug.addLevelsToPrint("test-level, another-level a_third_level");
204 * </pre>
205 *
206 * One way to use these levels in the println method was shown
207 * above. Another is to use it in a conditional statement. This is very
208 * handy in the case when more than one debug message should be printed.
209 * <pre>
210 * if (Debug.isEnabled("test-level"))
211 * {
212 * Debug.println("this a debug message, printed only when "
213 * +"the debug level 'test-level' is enabled.");
214 * // do something else
215 * Debug.println("this another debug message, printed only when "
216 * +"the debug level 'test-level' is enabled.");
217 * }
218 * </pre>
219 *
220 * This method is slightly more to type, but peforms better, if the debug
221 * message has to be created first:
222 * <pre>
223 * Object object = new Integer(2);
224 * Debug.println("test-level","variable object="+object.toString());
225 * </pre>
226 * In the statement above the debug message has to be created from the
227 * given string and from the result of <code>object.toString()</code>. If
228 * the debug-level 'test-level' is not enabled, the creation was done for
229 * nothing and performance is wasted.
230 * <p>
231 * Another way to increase performance is the following: Debug has a
232 * final static variable named {@link org.dinopolis.util.Debug#DEBUG}. If set to false, any
233 * conditional statements using this are evaluated to false already at
234 * compile time! When creating a version of an application that should
235 * not have any debug information, simply set {@link org.dinopolis.util.Debug#DEBUG}
236 * to false (in the classfile) and recompile Debug and the whole
237 * application. For best usage always use the Debug methods like this:
238 * <pre>
239 * if (Debug.DEBUG)
240 * {
241 * Debug.println("test-level",
242 * "this part of source code will not make it into "
243 * +"the class file when Debug.DEBUG is set to false!");
244 * }
245 * </pre>
246 *
247 * There are other helpful methods in the Debug class. How often is it
248 * necessary to print the content of an array for debugging reasons. The
249 * java method <code>toString()</code> does not work in this
250 * case. {@link org.dinopolis.util.Debug#objectToString(Object)} handles nearly all
251 * objects and returns a human readable output:
252 * <pre>
253 * Object[] obj_array = new Object[]{"one", new Integer(2), "three"};
254 * if (Debug.DEBUG && Debug.isEnabled("test-level"))
255 * {
256 * Debug.println("content of string_array = "
257 * +Debug.objectToString(obj_array));
258 * }
259 * </pre>
260 *
261 *
262 * Sometimes it is interesting to measure how long a method takes to
263 * execute. Debug offers a simple way to measure time:
264 * <pre>
265 * Debug.startTimer("timer_name");
266 * // ----------------
267 * // execute method 1
268 * // ----------------
269 * Debug.println("test-level",Debug.getTimer("timer_name"));
270 * // ----------------
271 * // execute method 2
272 * // ----------------
273 * Debug.println("test-level",Debug.stopTimer("timer_name"));
274 * </pre>
275 *
276 * {@link #getTimer(String)} returns a String but does not stop (and
277 * remove) the timer, whereas {@link #stopTimer(String)} returns the
278 * String and removes the timer from memory.
279 * <p>
280 * Sometimes it is usefull to know exactly where a debug output is
281 * created. The StackTrace-methods of Debug help here:
282 * {@link #getStackTrace()} returns a complete StackTrace, so the
283 * calling hierarchy is visible, whereas {@link #getStackTraceLine()}
284 * returns only the line, from which the command was invoked:
285 * <pre>
286 * if (Debug.isEnabled("test_level"))
287 * {
288 * Debug.println("complete stacktrace: "
289 * +Debug.getStackTrace());
290 * Debug.println("only a line of the stacktrace: "
291 * +Debug.getStackTraceLine());
292 * }
293 * </pre>
294 *
295 * The format of the debug message is widely configurable. A message
296 * format string consists of strings and keywords. The command below sets
297 * the format of all debug messages to the given format. All keywords
298 * (words between '<code>%</code>') are replaced by their value, the rest is
299 * left unchanged:
300 * <pre>
301 * Debug.setMessageFormat("DEBUG: %date% \"%message%\" (Thread: %thread%)");
302 * Debug.println("this message is in a different format now.");
303 * </pre>
304 *
305 * Available keywords are:
306 * <ul>
307 * <li> <code>%date%</code>: actual date
308 * <li> <code>%milliseconds%</code>: the actual milliseconds
309 * <li> <code>%diffmilliseconds%</code>: the time difference since the
310 * last debug message was printed (in milliseconds)
311 * <li> <code>%level%</code>: the levelname of the debugmessage
312 * <li> <code>%stacktrace%</code>: a stacktrace to ever msg
313 * <li> <code>%stacktraceline%</code>: last line in stacktrace (caller)
314 * <li> <code>%thread%</code>: the string rep of the thread of the caller
315 * <li> <code>%threadname%</code>: the name of the thread of the caller
316 * <li> <code>%threadgroup%</code>: the name of the threadgroup of the caller
317 * <li> <code>%message%</code>: the debug message itself
318 * </ul>
319 *
320 * You can also insert '<code>\n</code>' (and others) e.g. to force a new line
321 * or '<code>\t</code>' to divide the output in columns. The key words are
322 * replaced by their value, the rest is left unchanged.
323 *
324 * <h3>debug.properties file</h3>
325 * All settings of the Debug-class can be set through method calls from
326 * the application or by editing the config-file named 'debug.properties'
327 * in the directory returned by a call to
328 * <code>System.getProperties().get("user.home")</code>. Using java in a
329 * Unix environment this is normally the home directory of the user
330 * (under Windows, I don't know, sorry!).
331 * <p>
332 * The second way to set debug options has the
333 * advantage that the settings can be changed without restarting the
334 * application. This makes it possible to change e.g. the debug-level or
335 * the debug-message-format when necessary.
336 *
337 * An example of such a properties file is given here (everything behind
338 * a '<code>#</code>' is taken as a comment):
339 * <pre>
340 * # ---------- debug.properties start --------------
341 * # enable debug messages
342 * Debug.enabled=true
343 *
344 * # debug levels to print
345 * Debug.printLevels=debug_test, debug_start_application
346 *
347 * # set to true, if you want to see all level output
348 * #Debug.printAllLevels=true
349 *
350 * # set this, if you want the output logged in a file:
351 * #Debug.fileName=/home/cdaller/tmp/debug.log
352 *
353 * # reload this file every xxx milliseconds
354 * # (if xxx == 0, no thread is started.)
355 * Debug.refreshPropertyTime=5000
356 *
357 * # Set the format of the debug messages.
358 * Debug.messageFormat=DEBUG: "%message%" (L:%level%)
359 * # ---------- debug.properties end --------------
360 * </pre>
361 *
362 * Especially the 'Debug.refreshPropertyTime' is worth taking a closer
363 * look. It determines that Debug rereads the property file every 5
364 * seconds, so any changes in the file become applied at least 5
365 * seconds after saving it. Therefore the user may change the debug
366 * levels to be printed without the need to restart the application!
367 * <p>
368 * Another comfortable way to set debug options without hardcoding the
369 * calls to debug methods into the application is the following: The
370 * {@link org.dinopolis.util.Debug#main(String[])} method can be used to set
371 * Debug options and then start a given application.
372 * <p>
373 * To let an applicaton be started by Debug, {@link
374 * org.dinopolis.util.Debug#main(String[])} accepts some debug-specific
375 * options and the classname (and its arguments) of the application.
376 * <p>
377 * Debug specific options are:
378 * <ul>
379 *
380 * <li> <code>--debuglevels <level(s)></code>: adds one or more
381 * debug levels (if there are any levels set in the property file, they
382 * are added).
383 *
384 * <li> <code>--debugmessage <messageformat></code>: sets the format of the
385 * debug messages. Please see method
386 * {@link #setMessageFormat(String)} for details.
387 *
388 * <li> <code>--debugfilename <filename></code>: sets the name of the file the
389 * debug messages are written to.
390 *
391 * <li> <code>--debugrefresh <milliseconds></code>: sets the refresh time for
392 * the thread that rereads the properties-file.
393 *
394 * <li> <code>--debugpropertiesfile <filename></code>: sets the name of the
395 * properties-file.
396 *
397 * </ul>
398 *
399 * An example that sets two debug levels and the messageformat and then
400 * starts the class <code>test.TestApplication</code>:
401 * <pre>
402 * java org.dinopolis.util.Debug --debuglevels "level1, level2" \
403 * --debugmessage "DEBUG: %message% (Thread: %thread%)" \
404 * "test.Application argument1 argument2 --option value"
405 * </pre>
406 *
407 * <bold>Note:<bold> The class that should be started and its arguments are
408 * put inside double quotes, otherwise its arguments are taken as
409 * arguments for <code>Debug<code>. The backslash at the end of the
410 * lines indicates that the line is continued in the next one.
411 *
412 * Another example shows how to redirect the debug messages to a file and
413 * how to set the properties-file:
414 * <pre>
415 * java org.dinopolis.util.Debug --debugfile my_debug_output.txt \
416 * --debugproperiesfile "my_debug.properties" \
417 * "test.Application argument1 argument2 --option value"
418 * </pre>
419 * *
420 * @author Christof Dallermassl <cdaller@iicm.edu>
421 * @version $Id: Debug.java,v 1.2 2003/02/18 08:10:20 cdaller Exp $
422 * @see org.dinopolis.util.debug.Debug
423 *
424 */
425 public class Debug
426 {
427
428 static final public boolean DEBUG = org.dinopolis.util.debug.Debug.DEBUG;
429
430 static private org.dinopolis.util.debug.Debug debug_instance_ =
431 org.dinopolis.util.debug.Debug.getInstance();
432
433
434 //----------------------------------------------------------------------
435 /**
436 * Set the format of the debug messages.
437 * Key words are delimited by '%' and are replaced at run-time.
438 * Valid key words are:
439 * %date% - prints actual date
440 * //%count% - prints the debug message counter
441 * %milliseconds% - prints the actual milliseconds
442 * %diffmilliseconds% - prints the time difference since the last
443 * debug message was printed (in milliseconds)
444 * %level% - prints the levelname of the debugmessage
445 * %stacktrace% - prints a stacktrace to ever msg
446 * %stacktraceline% - prints last line in stacktrace (caller)
447 * %thread% - prints the string rep of the thread of the caller
448 * %threadgroup% - prints the name of the threadgroup of the caller
449 * %threadname% - prints the name of the thread of the caller
450 * %message% - prints the debug message itself
451 *
452 * You can also insert '\n' (and others) e.g. to force a new line or '\t' to
453 * divide the output in columns.
454 * The key words are replaced by their value, the rest is left unchanged.
455 *
456 * Example: <BR>
457 * "DEBUG L=%level%: %message%" prints "DEBUG L=defaultlevel: debug message"
458 * @param format_string the format string of the debug-messages.
459 */
460 public static void setMessageFormat(String format_string)
461 {
462 debug_instance_.setMessageFormat(format_string);
463 }
464
465 //----------------------------------------------------------------------
466 /**
467 * Should all debug messages be printed, ignoring the level?
468 * @param print_all if <code>true</code> all debug messages are
469 * printed (debug levels are not checked anymore), if
470 * <code>false</code> the debug levels are checked and depending on
471 * this check, the messages are printed or not.
472 */
473 public static void printAllLevels(boolean print_all)
474 {
475 debug_instance_.printAllLevels(print_all);
476 }
477
478
479 //----------------------------------------------------------------------
480 /**
481 * adds one or more levels, for which messages should be printed
482 * (levels can be separated by space, tab, newline or comma).
483 * @param levels the debug-levels to be added
484 */
485 public static void addLevelsToPrint(String levels)
486 {
487 debug_instance_.addLevelsToPrint(levels);
488 }
489
490 //----------------------------------------------------------------------
491 /**
492 * removes one or more levels, for which messages should be printed
493 * (levels can be separated by space, tab, newline or comma).
494 * @param levels the debug-levels to be removed
495 */
496 public static void removeLevelsToPrint(String levels)
497 {
498 debug_instance_.removeLevelsToPrint(levels);
499 }
500
501 //----------------------------------------------------------------------
502 /**
503 * removes all levels, for which messages should be printed
504 */
505 public static void removeAllLevelsToPrint()
506 {
507 debug_instance_.removeAllLevelsToPrint();
508 }
509
510
511 //----------------------------------------------------------------------
512 /**
513 * Creates a new Timer and names it. The timer starts at zero.
514 * @param name name of the timer(case insensitive).
515 */
516 public static void startTimer(String name)
517 {
518 debug_instance_.startTimer(name);
519 }
520
521
522 //----------------------------------------------------------------------
523 /**
524 * Stops the named timer and returns the string representation of it.
525 * @param name name of the timer(case insensitive)
526 * @return the String representation of the timer.
527 */
528 public static String stopTimer(String name)
529 {
530 return(debug_instance_.stopTimer(name));
531 }
532
533 //----------------------------------------------------------------------
534 /**
535 * Returns the string representation of the named timer, but does not
536 * stop it.
537 * @param name name of the timer (case insensitive)
538 * @return the String representation of the timer.
539 */
540 public static String getTimer(String name)
541 {
542 return(debug_instance_.getTimer(name));
543 }
544
545
546 //----------------------------------------------------------------------
547 /**
548 * Denable/disable debug output.
549 * @param flag <code>true</code> enables, <code>false</code> disables
550 * debug output.
551 */
552 public static void enable(boolean flag)
553 {
554 debug_instance_.enable(flag);
555 }
556
557
558 //----------------------------------------------------------------------
559 /**
560 * Returns <code>true</code>, if debug output is enabled.
561 * @return <code>true</code>, if debug output is enabled.
562 */
563 public static boolean isEnabled()
564 {
565 return(debug_instance_.isEnabled());
566 }
567
568 //----------------------------------------------------------------------
569 /**
570 * Return <code>true</code>, if debug output is enabled for the given
571 * level. If debug output is disabled in general, this method returns
572 * <code>false</code>.
573 * @param level name of the level
574 * @return <code>true</code>, if debug output is enabled for the given
575 * level. If debug output is disabled in general, this method returns
576 * <code>false</code>.
577 */
578 public static boolean isEnabled(String level)
579 {
580 return(debug_instance_.isEnabled(level));
581 }
582
583
584 //----------------------------------------------------------------------
585 /**
586 * Prints an object (its string-representation).
587 * There is no newline added to the debug message.
588 * @param obj the object to be printed.
589 */
590 public static void print(Object obj)
591 {
592 debug_instance_.print(obj);
593 }
594
595
596 //----------------------------------------------------------------------
597 /**
598 * Prints an object (its string-representation) using the given
599 * debug-level. There is no newline added to the debug message.
600 * @param level the debug-level for this object.
601 * @param obj the object to be printed.
602 */
603 public static void print(String level, Object obj)
604 {
605 debug_instance_.print(level,obj);
606 }
607
608
609
610 //----------------------------------------------------------------------
611 /**
612 * Prints an object (its string-representation).
613 * There is a newline added to the debug message.
614 * @param obj the object to be printed.
615 */
616 public static void println(Object obj)
617 {
618 debug_instance_.println(obj);
619 }
620
621 //----------------------------------------------------------------------
622 /**
623 * Prints an object (its string-representation) using the given
624 * debug-level. There is a newline added to the debug message.
625 * @param level the debug-level for this object.
626 * @param obj the object to be printed.
627 */
628 public static void println(String level, Object obj)
629 {
630 debug_instance_.println(level,obj);
631 }
632
633
634 //----------------------------------------------------------------------
635 /**
636 * Returns a stacktrace. It returned does not include the
637 * trace inside the Debug class.
638 *
639 * @return the stacktrace.
640 */
641 public static String getStackTrace()
642 {
643 Throwable throwable = new Throwable();
644 return(debug_instance_.getStackTrace(throwable, 4, 10000));
645 }
646
647
648 //----------------------------------------------------------------------
649 /**
650 * Returns the stacktrace of throwable.
651 *
652 * @param throwable the throwable to be printed.
653 * @return the stacktrace of throwable.
654 */
655 public static String getStackTrace(Throwable throwable)
656 {
657 return(debug_instance_.getStackTrace(throwable,0,10000));
658 }
659
660
661 //----------------------------------------------------------------------
662 /**
663 * Returns the line of the source code from which this method
664 * was called.
665 * @return the line of the source code from which this method
666 * was called.
667 */
668 public static String getStackTraceLine()
669 {
670 return(debug_instance_.getStackTrace(5,1));
671 }
672
673
674 //----------------------------------------------------------------------
675 /**
676 * Returns a String representation of the object, this method also
677 * handles primitive arrays and object arrays.
678 * @param obj a String representation of the object
679 * @return a String representation of an object
680 */
681 public static String objectToString (Object obj)
682 {
683 return(org.dinopolis.util.debug.Debug.objectToString(obj));
684 }
685
686 //----------------------------------------------------------------------
687 /**
688 * Stops the program and waits for a 'enter' on
689 * <code>System.in</code>. Actually, it waits for any character, but
690 * <code>System.in</code> is flushed only on 'enter', so any
691 * characters typed before might stay in the keyboard buffer.
692 */
693 public static void waitEnterPressed()
694 {
695 org.dinopolis.util.debug.Debug.waitEnterPressed();
696 }
697
698 //----------------------------------------------------------------------
699 /**
700 * The Debug Util class is able to reread its property-file from an *
701 * independent thread, so any changes in the file (e.g. additional *
702 * debug-levels set) are reflected in the behaviour of the Debug Util
703 * class.
704 * @param refresh_time the time given in milliseconds to reload the
705 * debug-property-file, if <code>0<code>, the file is never reloaded
706 * (and no thread is started
707 */
708 public static void startRefreshPropertiesThread(long refresh_time)
709 {
710 debug_instance_.startRefreshPropertiesThread(refresh_time);
711 }
712
713
714 //----------------------------------------------------------------------
715 /**
716 * The thread that rereads the debug property file is stopped, so any
717 * changes in the file are ignored.
718 */
719 public static void stopRefreshPropertiesThread()
720 {
721 debug_instance_.stopRefreshPropertiesThread();
722 }
723
724
725
726 //----------------------------------------------------------------------
727 /**
728 * Writes all messages to a file.
729 * @param filename the file to write to.
730 */
731 public static void setWriterToFile(String filename)
732 {
733 debug_instance_.setWriterToFile(filename);
734 }
735
736
737 //----------------------------------------------------------------------
738 /**
739 * Sets the writer the debug messages are written to. The default is
740 * System.err.
741 * @param out the java.io.Writer (e.g. System.out, System.err, or a
742 * network connection), where all the messages are written to
743 */
744 public static void setWriter(Writer out)
745 {
746 debug_instance_.setWriter(out);
747 }
748
749
750 //----------------------------------------------------------------------
751 /**
752 * Returns the Writer, where the debug messages are written to.
753 * @return the Writer, where the debug messages are written to.
754 */
755 public static Writer getWriter()
756 {
757 return(debug_instance_.getWriter());
758 }
759
760
761 //----------------------------------------------------------------------
762 /**
763 * The main method can be used to set Debug options and then start a
764 * given application. After execution of the application the thread
765 * that rereads the properties is stopped.
766 * <P>
767 * Valid options are:
768 * <UL>
769 * <li><code>--debuglevels level1,level2</code>: sets one or more
770 * debug levels.</li>
771 * <li><code>--debugmessage "messageformat"</code>: sets the format of
772 * the debug messages. Please see method <code>setMessageFormat</code>
773 * for details.</li>
774 * <li><code>--debugfilename debugfile.log</code>: sets the name of
775 * the file the debug messages are written to.</li>
776 * <li><code>--debugrefresh milliseconds</code>: sets the refresh time
777 * for the thread that rereads the properties-file.</li>
778 * <li><code>--debugpropertiesfile filename</code>: sets the name of
779 * the properties-file.</li>
780 * </UL>
781 * <P>
782 * One(!) argument must hold the classname to start and the arguments
783 * that should be handed to the main method of the class. To ensure
784 * that it is only one argument, put the whole command line in
785 * quotes.
786 * <P>
787 * E.g. <code>javac org.dinopolis.util.Debug --debuglevels test-level
788 * --debugrefresh 5000 --debugfilename debug.log
789 * "org.testpackage.testclass argument1 argument2 'argument with
790 * space in single quote' --option1"</code>
791 *
792 * @param args any debug arguments to set debug options and the
793 * commandline to start the application (in quotes).
794 */
795 public static void main(String[] args)
796 {
797 org.dinopolis.util.debug.Debug.main(args);
798 }
799
800 }
801
802
803
804