Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/port80/util/Debug.java


1   /** Debug mode configuration.
2    */
3   
4   //
5   // Copyright(c) 2002, Chris Leung
6   //
7   
8   package com.port80.util;
9   
10  import java.util.*;
11  
12  /** Debug mode and related utilities to selectively enable specific debug modes.
13      Debug.set('*') enables all debug modes. Modes 'debug','trace','test','verbose','check'
14      exists by default (but disabled except 'test' is default enabled) on startup 
15      and after Debug.clear().
16  
17      Builtin modes:
18    debug    Turns on debug messages.
19    trace    Turns on trace messages.
20    test    Turns on test messages, which are temporary and would normally remove 
21                    from source code after the testing.
22    verbose    Turns on verbose messages during normal execution.
23    check    Turns on check mode code, which provide additional sanity checkings that 
24                    normal execution should skip.
25  
26      USAGE:
27  
28      . Note that all data and methods are static.
29  
30      . For class that have custom debug mode, it should add the mode in a static initialization block:
31  
32    static { Debug.add("package.classname"); }
33  
34        The added mode by default is disabled. However, if the mode already exist add() would not change
35        its enable/disable state.
36  
37      . The main program is responsible for enabling the specific debug modes by the enable() method.
38        Since the static initialization are executed when the class is loaded,  it may be initialized 
39        after the main program command line processing.  The command line processing can enable specific 
40        modes, in that case, the static initialization would be change the enable/disable state.  
41        The command line processing call enable() with a wildcard ('*') pattern.  In that case, the
42        modes that match the pattern would be enabled when it is added.
43  
44          enable("specific-mode");  // Enable a single mode.
45    enable("wildcard*pattern");  // Enable all existing and future added modes that match the pattern.
46  
47      . There is also disable() methods, however, they should be used sparsely when really neccessary.
48        If there are contradicting enable and disable wildcard patterns, the result is undetermined.
49  
50      . It is the main program's main method repsonsible for enable/disable debugging of a particular module
51        (after checking command line options).
52  
53      . Each module check (static) whether it is required to run in debug mode:
54      
55    public static boolean DEBUG=Debug.isEnabled(<packagename>)||Debug.isEnabled(<packgename.classname>);
56  
57  */
58  
59  public class Debug {
60  
61      static private final Boolean  ENABLE    =new Boolean(true);
62      static private final Boolean  DISABLE    =new Boolean(false);
63  
64      static private Map    theModes  =null;
65      static private Map    theDefaults  =null;
66  
67      static {init();}
68  
69      static public void clear() {init();}
70  
71      /** Enable a list of debug modes.
72       *
73       * @param s    The debug mode is added if not already exist.
74       *      The mode string can also be use wildcard '*' to enable
75       *                  multiple modes. In that case, all existing and future modes
76       *                  that match the pattern would be enabled.
77       *
78       * Due to the way Java initialized static variables, which initialized dynamically
79       * when the class is loaded.  The static initialization that add debug modes may
80       * not be executed even during command line processing of the main class.  So we
81       * have to keep the wild card pattern from command line options and apply them 
82       * when new modes are added.
83       */
84      static public void enable(List modes) {
85    if(theModes==null) init();
86    if(modes==null) return;
87    for(int i=0; i<modes.size(); i++) {
88        String mode=(String)modes.get(i);
89        if(mode.indexOf('*')==-1) {
90      theModes.put(mode,ENABLE);
91      msg.debug("Debug.enable(): mode="+mode);
92      continue;
93        }
94        // Wild card.
95        mode=msg.subst("s/\\*/.*/g",mode);
96        // Enable future added modes that match.
97        theDefaults.put(mode,ENABLE);
98        // Enable existing modes that match.
99        TreeSet keys=new TreeSet(theModes.keySet());
100       for(Iterator it=keys.iterator(); it.hasNext();) {
101     String key=(String)it.next();
102     if(msg.match("/"+mode+"/",key)) {
103         theModes.put(key,ENABLE);
104         msg.debug("Debug.enable(): matched: pattern="+mode+", key="+key);
105     }
106       }
107   }
108     }
109     
110     static public void enable(String modes) {
111   if(theModes==null) init();
112   if(modes==null) return;
113   enable(msg.split("/,/",modes));
114     }
115 
116     /** Disable a list of debug mode.
117      *
118      *  @param modes  List of modes to be disabled. If not yet exist, the modes would be added.
119      *                  Wildcard pattern can be used and in that case all existing and future modes
120      *                  added that match the pattern would be disabled.
121      */
122     static public void disable(List modes) {
123   if(theModes==null) init();
124   if(modes==null) return;
125   for(int i=0; i<modes.size(); i++) {
126       String mode=(String)modes.get(i);
127       if(mode.indexOf('*')==-1) {
128     theModes.put(mode,DISABLE );
129     msg.debug("Debug.disable(): mode="+mode);
130     continue;
131       }
132       // Wild card.
133       mode=msg.subst("s/\\*/.*/g",mode);
134       // Enable future added modes that match.
135       theDefaults.put(mode,DISABLE); 
136       // Enable existing modes that match.
137       TreeSet keys=new TreeSet(theModes.keySet());
138       for(Iterator it=keys.iterator(); it.hasNext();) {
139     String key=(String)it.next();
140     if(msg.match("/"+mode+"/",key)) {
141         msg.debug("Debug.disable(): matched: pattern="+mode+", key="+key);
142         theModes.put(key,DISABLE);
143     }
144       }
145   }
146     }
147 
148     static public void disable(String modes) {
149   if(theModes==null) init();
150   if(modes==null) return;
151   disable(msg.split("/,/",modes));
152     }
153 
154     /** Add a mode, by default disabled. If the mode already exist, its enable/disable state 
155      *  would not be changed.  If the mode match any wildcard patterns (specified in previous
156      *  enable() or disable() calls), it would be enable/disabled accordingly.
157      *
158      *   @param mode  The mode to be added. No wildcard allowed here.
159      */
160     static public void add (String mode) {
161   if(theModes==null) init();
162   Object modeObject=theModes.get(mode);
163   if (modeObject!=null) return;
164   // New added, disable by default.
165   theModes.put(mode,DISABLE);
166   // Check pattern table.
167   TreeSet keys=new TreeSet(theDefaults.keySet());
168   for(Iterator it=keys.iterator(); it.hasNext(); ) {
169       String key=(String)it.next();
170       Boolean value=(Boolean)theDefaults.get(key);
171       if(msg.match("/^"+key+"$/",mode)) {
172     theModes.put(mode,value);
173       }
174   }
175   msg.debug("Debug.add(): mode="+mode+", value="+theModes.get(mode).toString());
176     }
177 
178     /** Add a mode and optionally enable it.
179      *
180      *  @param on  true = enable the added mode.
181      */
182     static public void add (String s, boolean on) {
183   if(theModes==null) init();
184   theModes.put(s, (on? ENABLE: DISABLE));
185     }
186 
187     ////////////////////
188 
189     /** Return the name of all declared debug modes.
190      */
191     static public List getModes() {
192   List keys = new Vector(new TreeSet(theModes.keySet()));
193   return keys;
194     }
195 
196     /** Return the name of all debug modes that are enabled.
197      */
198     static public List getEnables() {
199   List ret=msg.newListInstance();
200   TreeSet keys = new TreeSet(theModes.keySet());
201   for(Iterator it=keys.iterator(); it.hasNext();) {
202       Object key=it.next();
203       Boolean value=(Boolean)theModes.get(key);
204       if(value.booleanValue()) ret.add(key);
205   }
206   return ret;
207     }
208 
209     /** Return the name of all debug modes that are disabled.
210      */
211     static public List getDisables() {
212   List ret=msg.newListInstance();
213   TreeSet keys = new TreeSet(theModes.keySet());
214   for(Iterator it=keys.iterator(); it.hasNext();) {
215       Object key=it.next();
216       Boolean value=(Boolean)theModes.get(key);
217       if(!value.booleanValue()) ret.add(key);
218   }
219   return ret;
220     }
221 
222     static public boolean isEnabled (String s) {
223   if(!isDebug()) return false;
224   Object o = theModes.get(s);
225   return ( o != null && ((Boolean)o).booleanValue() );
226     }
227 
228     //////////////////// Some predefined mode and shortcut.
229 
230     static public boolean isOn() {
231   return ((Boolean)theModes.get("debug")).booleanValue();
232     }
233     static public boolean isDebug() {
234   return ((Boolean)theModes.get("debug")).booleanValue();
235     }
236     static public boolean isTrace() {
237   return ((Boolean)theModes.get("trace")).booleanValue();
238     }
239     static public boolean isTest() {
240   return ((Boolean)theModes.get("test")).booleanValue();
241     }
242     static public boolean isVerbose() {
243   return ((Boolean)theModes.get("verbose")).booleanValue();
244     }
245     static public boolean isCheck() {
246   return ((Boolean)theModes.get("check")).booleanValue();
247     }
248 
249     /** Same as enable(),disable(),isEnabled(),isDebug()...etc. */
250     static public void set (String s) {enable(s);}
251     static public void reset (String s) {disable(s);}
252     static public boolean get (String s) {return isEnabled(s);}
253     static public boolean on() { return isDebug(); }
254     static public boolean debug() { return isDebug(); }
255     static public boolean trace() { return isTrace(); }
256     static public boolean test() { return isTest(); }
257     static public boolean verbose() { return isVerbose(); }
258     static public boolean check() { return isCheck(); }
259 
260     //////////////////// Private ////////////////////
261 
262     static private void init() {
263   theModes=msg.newMapInstance();
264   theDefaults=msg.newMapInstance();
265   theModes.put("debug", DISABLE);
266   theModes.put("trace", DISABLE);
267   theModes.put("test", DISABLE);
268   theModes.put("verbose", DISABLE);
269   theModes.put("check", DISABLE);
270     }
271 
272 }