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

Quick Search    Search Deep

Source code: org/apache/derby/iapi/services/sanity/SanityManager.java


1   /*
2   
3      Derby - Class org.apache.derby.iapi.services.sanity.SanityManager
4   
5      Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6   
7      Licensed under the Apache License, Version 2.0 (the "License");
8      you may not use this file except in compliance with the License.
9      You may obtain a copy of the License at
10  
11        http://www.apache.org/licenses/LICENSE-2.0
12  
13     Unless required by applicable law or agreed to in writing, software
14     distributed under the License is distributed on an "AS IS" BASIS,
15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16     See the License for the specific language governing permissions and
17     limitations under the License.
18  
19   */
20  
21  package org.apache.derby.iapi.services.sanity;
22  
23  
24  import org.apache.derby.iapi.services.sanity.AssertFailure;
25  
26  import java.util.Hashtable;
27  import java.util.Enumeration;
28  
29  /**
30   * The SanityService provides assertion checking and debug
31   * control.
32   * <p>
33   * Assertions and debug checks
34   * can only be used for testing conditions that might occur
35   * in development code but not in production code.  
36   * <b>They are compiled out of production code.</b>
37   * <p>
38   * Uses of assertions should not add AssertFailure catches or
39   * throws clauses; AssertFailure is under RuntimeException
40   * in the java exception hierarchy. Our outermost system block
41   * will bring the system down when it detects an assertion
42   * failure.
43   * <p>
44   * In addition to ASSERTs in code, classes can choose to implement
45   * an isConsistent method that would be used by ASSERTs, UnitTests,
46   * and any other code wanting to check the consistency of an object.
47   * <p>
48   * Assertions are meant to be used to verify the state of the system
49   * and bring the system down if the state is not correct. Debug checks
50   * are meant to display internal information about a running system.
51   * <p>
52   * @see org.apache.derby.iapi.services.sanity.AssertFailure
53   */
54  public class SanityManager {
55    /**
56     * The build tool may be configured to alter
57     * this source file to reset the static final variables
58     * so that assertion and debug checks can be compiled out
59     * of the code.
60     */
61  
62    public static final boolean ASSERT = SanityState.ASSERT; // code should use DEBUG
63    public static final boolean DEBUG = SanityState.DEBUG;
64    
65    public static final String DEBUGDEBUG = "DumpSanityDebug";
66    
67    /**
68     * debugStream holds a pointer to the debug stream for writing out
69     * debug messages.  It is cached at the first debug write request.
70     */
71    static private java.io.PrintWriter debugStream = new java.io.PrintWriter(System.err);
72    /**
73     * DebugFlags holds the values of all debug flags in
74     * the configuration file.
75     */
76    static private Hashtable DebugFlags = new Hashtable();
77    /**
78     * AllDebugOn and AllDebugOff override individual flags
79     */
80    static private boolean AllDebugOn = false;
81    static private boolean AllDebugOff = false;
82  
83    //
84    // class interface
85    //
86  
87    /**
88     * ASSERT checks the condition, and if it is
89     * false, throws AssertFailure.
90     * A message about the assertion failing is
91     * printed.
92     * <p>
93     * @see org.apache.derby.iapi.services.sanity.AssertFailure
94     */
95    public static final void ASSERT(boolean mustBeTrue) {
96      if (DEBUG)
97        if (! mustBeTrue) {
98          if (DEBUG) {
99            AssertFailure af = new AssertFailure("ASSERT FAILED");
100           if (DEBUG_ON("AssertFailureTrace")) {
101             showTrace(af);
102           }
103           throw af;
104         }
105         else
106           throw new AssertFailure("ASSERT FAILED");
107       }
108   }
109 
110   /**
111    * ASSERT checks the condition, and if it is
112    * false, throws AssertFailure. The message will
113    * be printed and included in the assertion.
114    * <p>
115    * @see org.apache.derby.iapi.services.sanity.AssertFailure
116    */
117   public static final void ASSERT(boolean mustBeTrue, String msgIfFail) {
118     if (DEBUG)
119       if (! mustBeTrue) {
120         if (DEBUG) {
121           AssertFailure af = new AssertFailure("ASSERT FAILED " + msgIfFail);
122           if (DEBUG_ON("AssertFailureTrace")) {
123             showTrace(af);
124           }
125           throw af;
126         }
127         else
128           throw new AssertFailure("ASSERT FAILED " + msgIfFail);
129       }
130   }
131 
132   /**
133    * THROWASSERT throws AssertFailure. This is used in cases where
134    * the caller has already detected the assertion failure (such as
135    * in the default case of a switch). This method should be used,
136    * rather than throwing AssertFailure directly, to allow us to 
137    * centralize all sanity checking.  The message argument will
138    * be printed and included in the assertion.
139      * <p>
140    * @param msgIfFail message to print with the assertion
141    *
142    * @see org.apache.derby.iapi.services.sanity.AssertFailure
143    */
144   public static final void THROWASSERT(String msgIfFail) {
145     // XXX (nat) Hmm, should we check ASSERT here?  The caller is
146     // not expecting this function to return, whether assertions
147     // are compiled in or not.
148 
149     if (DEBUG) {
150       AssertFailure af = new AssertFailure("ASSERT FAILED " + msgIfFail);
151       if (DEBUG_ON("AssertFailureTrace")) {
152         showTrace(af);
153       }
154       throw af;
155     }
156     else
157       throw new AssertFailure("ASSERT FAILED " + msgIfFail);
158   }
159 
160   /**
161    * THROWASSERT throws AssertFailure.
162    * This flavor will print the stack associated with the exception.
163    * The message argument will
164    * be printed and included in the assertion.
165      * <p>
166    * @param msg message to print with the assertion
167    * @param t exception to print with the assertion
168    *
169    * @see org.apache.derby.iapi.services.sanity.AssertFailure
170    */
171   public static final void THROWASSERT(String msg, Throwable t) {
172 
173     if (DEBUG) {
174       AssertFailure af = new AssertFailure("ASSERT FAILED " + t.toString(), t);
175       if (DEBUG_ON("AssertFailureTrace")) {
176         showTrace(af);
177       }
178       showTrace(t);
179       throw af;
180     }
181     else {
182       showTrace(t);
183       throw new AssertFailure("ASSERT FAILED " + t.toString(), t);
184     }
185   }
186 
187   /**
188    * THROWASSERT throws AssertFailure.
189    * This flavor will print the stack associated with the exception.
190      * <p>
191    * @param t exception to print with the assertion
192    *
193    * @see org.apache.derby.iapi.services.sanity.AssertFailure
194    */
195   public static final void THROWASSERT(Throwable t) {
196 
197     if (DEBUG) {
198       AssertFailure af = new AssertFailure("ASSERT FAILED " + t.toString(), t);
199       if (DEBUG_ON("AssertFailureTrace")) {
200         showTrace(af);
201       }
202       showTrace(t);
203       throw af;
204     }
205     else {
206       showTrace(t);
207       throw new AssertFailure("ASSERT FAILED " + t.toString(), t);
208     }
209   }
210 
211   /**
212      * The DEBUG calls provide the ability to print information or
213      * perform actions based on whether a debug flag is set or not.
214      * debug flags are set in configurations and picked up by the
215      * sanity manager when the monitor finds them (see CONFIG below).
216    * <p>
217    * The message is output to the trace stream, so it ends up in
218    * db2j.LOG. It will include a header line of
219    *   DEBUG <flagname> OUTPUT:
220    * before the message.
221    * <p>
222    * If the debugStream stream cannot be found, the message is printed to
223    * System.out.
224      */
225   public static final void DEBUG(String flag, String message) {
226     if (DEBUG) {
227       if (DEBUG_ON(flag)) {
228         DEBUG_PRINT(flag, message);
229       }
230     }
231   }
232 
233   /**
234    * This can be called directly if you want to control
235      * what is done once the debug flag has been verified --
236    * for example, if you are calling a routine that prints to
237    * the trace stream directly rather than returning a string to
238    * be printed, or if you want to perform more (or fewer!)
239    *
240    * <p>
241      * Calls to this method should be surrounded with
242    *     if (SanityManager.DEBUG) {
243    *     }
244    * so that they can be compiled out completely.
245    *
246    * @return true if the flag has been set to "true"; false
247    * if the flag is not set, or is set to something other than "true".
248    */
249   public static final boolean DEBUG_ON(String flag) {
250     if (DEBUG) {
251       if (AllDebugOn) return true;
252       else if (AllDebugOff) return false;
253       else {
254           Boolean flagValue = (Boolean) DebugFlags.get(flag);
255           if (! DEBUGDEBUG.equals(flag)) {
256             if (DEBUG_ON(DEBUGDEBUG)) {
257               DEBUG_PRINT(DEBUGDEBUG, "DEBUG_ON: Debug flag "+flag+" = "+flagValue);
258             }
259           }
260           if (flagValue == null) return false;
261           else return flagValue.booleanValue();
262       }
263     }
264     else return false;
265   }
266 
267   /**
268    * Set the named debug flag to true.
269    *
270    * <p>
271      * Calls to this method should be surrounded with
272    *     if (SanityManager.DEBUG) {
273    *     }
274    * so that they can be compiled out completely.
275    *
276    * @param flag  The name of the debug flag to set to true
277    *
278    * @return  Nothing
279    */
280   public static final void DEBUG_SET(String flag) {
281     if (DEBUG) {
282       if (! DEBUGDEBUG.equals(flag)) {
283         if (DEBUG_ON(DEBUGDEBUG))
284           DEBUG_PRINT(DEBUGDEBUG, "DEBUG_SET: Debug flag " + flag);
285       }
286 
287       DebugFlags.put(flag, Boolean.TRUE);
288     }
289   }
290 
291   /**
292    * Set the named debug flag to false.
293    *
294    * <p>
295      * Calls to this method should be surrounded with
296    *     if (SanityManager.DEBUG) {
297    *     }
298    * so that they can be compiled out completely.
299    *
300    * @param flag  The name of the debug flag to set to false
301    *
302    * @return  Nothing
303    */
304   public static final void DEBUG_CLEAR(String flag) {
305     if (DEBUG) {
306       if (! DEBUGDEBUG.equals(flag)) {
307         if (DEBUG_ON(DEBUGDEBUG))
308           DEBUG_PRINT(DEBUGDEBUG, "DEBUG_CLEAR: Debug flag " + flag);
309       }
310 
311       DebugFlags.put(flag, Boolean.FALSE);
312     }
313   }
314 
315   /**
316    * This can be used to have the SanityManager return TRUE
317    * for any DEBUG_ON check. DEBUG_CLEAR of an individual
318    * flag will appear to have no effect.
319    */
320   public static final void DEBUG_ALL_ON() {
321     if (DEBUG) {
322       AllDebugOn = true;
323       AllDebugOff = false;
324     }
325   }
326 
327   /**
328    * This can be used to have the SanityManager return FALSE
329    * for any DEBUG_ON check. DEBUG_SET of an individual
330    * flag will appear to have no effect.
331    */
332   public static final void DEBUG_ALL_OFF() {
333     if (DEBUG) {
334       AllDebugOff = true;
335       AllDebugOn = false;
336     }
337   }
338 
339   //
340   // class implementation
341   //
342 
343   static public void SET_DEBUG_STREAM(java.io.PrintWriter pw) {
344     debugStream = pw;
345   }
346 
347   static public java.io.PrintWriter GET_DEBUG_STREAM() {
348     return debugStream;
349   }
350 
351   static private void showTrace(AssertFailure af) {
352     af.printStackTrace();
353     java.io.PrintWriter assertStream = GET_DEBUG_STREAM();
354 
355     assertStream.println("Assertion trace:");
356     af.printStackTrace(assertStream);
357     assertStream.flush();
358   }
359 
360   static public void showTrace(Throwable t) {
361     java.io.PrintWriter assertStream = GET_DEBUG_STREAM();
362 
363     assertStream.println("Exception trace: ");
364     t.printStackTrace(assertStream);
365   }
366 
367   /**
368    * The DEBUG_PRINT calls provides a convenient way to print debug
369    * information to the db2j.LOG file,  The message includes a header
370    *<p>
371    *  DEBUG <flag> OUTPUT: 
372    * before the message
373    *<p>
374    * If the debugStream stream cannot be found, the message is printed to
375    * System.out.
376    *
377    */
378   static public void DEBUG_PRINT(String flag, String message) {
379     java.io.PrintWriter debugStream = GET_DEBUG_STREAM();
380 
381     debugStream.println("DEBUG "+flag+" OUTPUT: " + message);
382     debugStream.flush();
383   }
384 
385   public static void NOTREACHED() {
386     THROWASSERT("code should not be reached");
387   }
388 }
389