KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > NestedThrowable


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software 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 GNU
15   * 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 software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.util;
23
24 import java.io.PrintWriter JavaDoc;
25 import java.io.PrintStream JavaDoc;
26 import java.io.Serializable JavaDoc;
27
28 import org.jboss.logging.Logger;
29
30 import org.jboss.util.platform.Java;
31
32
33 /**
34  * Interface which is implemented by all the nested throwable flavors.
35  *
36  * @version <tt>$Revision: 1958 $</tt>
37  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
38  */

39 public interface NestedThrowable
40    extends Serializable JavaDoc
41 {
42    /**
43     * A system wide flag to enable or disable printing of the
44     * parent throwable traces.
45     *
46     * <p>
47     * This value is set from the system property
48     * <tt>org.jboss.util.NestedThrowable.parentTraceEnabled</tt>
49     * or if that is not set defaults to <tt>true</tt>.
50     */

51    boolean PARENT_TRACE_ENABLED = Util.getBoolean("parentTraceEnabled", true);
52
53    /**
54     * A system wide flag to enable or disable printing of the
55     * nested detail throwable traces.
56     *
57     * <p>
58     * This value is set from the system property
59     * <tt>org.jboss.util.NestedThrowable.nestedTraceEnabled</tt>
60     * or if that is not set defaults to <tt>true</tt> unless
61     * using JDK 1.4 with {@link #PARENT_TRACE_ENABLED} set to false,
62     * then <tt>false</tt> since there is a native mechansim for this there.
63     *
64     * <p>
65     * Note then when running under 1.4 is is not possible to disable
66     * the nested trace output, since that is handled by java.lang.Throwable
67     * which we delegate the parent printing to.
68     */

69    boolean NESTED_TRACE_ENABLED = Util.getBoolean("nestedTraceEnabled",
70                                                   (Java.isCompatible(Java.VERSION_1_4) &&
71                                                    !PARENT_TRACE_ENABLED) ||
72                                                   !Java.isCompatible(Java.VERSION_1_4));
73
74    /**
75     * A system wide flag to enable or disable checking of parent and child
76     * types to detect uneeded nesting
77     *
78     * <p>
79     * This value is set from the system property
80     * <tt>org.jboss.util.NestedThrowable.detectDuplicateNesting</tt>
81     * or if that is not set defaults to <tt>true</tt>.
82     */

83    boolean DETECT_DUPLICATE_NESTING = Util.getBoolean("detectDuplicateNesting", true);
84    
85    /**
86     * Return the nested throwable.
87     *
88     * @return Nested throwable.
89     */

90    Throwable JavaDoc getNested();
91
92    /**
93     * Return the nested <tt>Throwable</tt>.
94     *
95     * <p>For JDK 1.4 compatibility.
96     *
97     * @return Nested <tt>Throwable</tt>.
98     */

99    Throwable JavaDoc getCause();
100
101
102    /////////////////////////////////////////////////////////////////////////
103
// Nested Throwable Utilities //
104
/////////////////////////////////////////////////////////////////////////
105

106    /**
107     * Utilitiy methods for the various flavors of
108     * <code>NestedThrowable</code>.
109     */

110    final class Util
111    {
112       // Can not be final due to init bug, see getLogger() for details
113
private static Logger log = Logger.getLogger(NestedThrowable.class);
114
115       /**
116        * Something is very broken with class nesting, which can sometimes
117        * leave log uninitialized durring one of the following method calls.
118        *
119        * <p>
120        * This is a HACK to keep those methods from NPE until this problem
121        * can be resolved.
122        */

123       private static Logger getLogger()
124       {
125          if (log == null)
126             log = Logger.getLogger(NestedThrowable.class);
127
128          return log;
129       }
130       
131       /** A helper to get a boolean property. */
132       protected static boolean getBoolean(String JavaDoc name, boolean defaultValue)
133       {
134          name = NestedThrowable.class.getName() + "." + name;
135          String JavaDoc value = System.getProperty(name, String.valueOf(defaultValue));
136
137          // HACK see getLogger() for details
138
log = getLogger();
139          
140          log.debug(name + "=" + value);
141
142          return new Boolean JavaDoc(value).booleanValue();
143       }
144
145       /**
146        * Check and possibly warn if the nested exception type is the same
147        * as the parent type (duplicate nesting).
148        */

149       public static void checkNested(final NestedThrowable parent,
150                                      final Throwable JavaDoc child)
151       {
152          if (!DETECT_DUPLICATE_NESTING || parent == null || child == null) return;
153
154          Class JavaDoc parentType = parent.getClass();
155          Class JavaDoc childType = child.getClass();
156
157          //
158
// This might be backwards... I always get this confused
159
//
160

161          if (parentType.isAssignableFrom(childType)) {
162             // HACK see getLogger() for details
163
log = getLogger();
164
165             log.warn("Duplicate throwable nesting of same base type: " +
166                      parentType + " is assignable from: " + childType);
167          }
168       }
169       
170       /**
171        * Returns a formated message for the given detail message
172        * and nested <code>Throwable</code>.
173        *
174        * @param msg Detail message.
175        * @param nested Nested <code>Throwable</code>.
176        * @return Formatted message.
177        */

178       public static String JavaDoc getMessage(final String JavaDoc msg,
179                                       final Throwable JavaDoc nested)
180       {
181          StringBuffer JavaDoc buff = new StringBuffer JavaDoc(msg == null ? "" : msg);
182
183          if (nested != null) {
184             buff.append(msg == null ? "- " : "; - ")
185                .append("nested throwable: (")
186                .append(nested)
187                .append(")");
188          }
189  
190          return buff.toString();
191       }
192
193       /**
194        * Prints the nested <code>Throwable</code> to the given stream.
195        *
196        * @param nested Nested <code>Throwable</code>.
197        * @param stream Stream to print to.
198        */

199       public static void print(final Throwable JavaDoc nested,
200                                final PrintStream JavaDoc stream)
201       {
202          if (stream == null)
203             throw new NullArgumentException("stream");
204
205          if (NestedThrowable.NESTED_TRACE_ENABLED && nested != null) {
206             synchronized (stream) {
207                if (NestedThrowable.PARENT_TRACE_ENABLED) {
208                   stream.print(" + nested throwable: ");
209                }
210                else {
211                   stream.print("[ parent trace omitted ]: ");
212                }
213                
214                nested.printStackTrace(stream);
215             }
216          }
217       }
218
219       /**
220        * Prints the nested <code>Throwable</code> to the given writer.
221        *
222        * @param nested Nested <code>Throwable</code>.
223        * @param writer Writer to print to.
224        */

225       public static void print(final Throwable JavaDoc nested,
226                                final PrintWriter JavaDoc writer)
227       {
228          if (writer == null)
229             throw new NullArgumentException("writer");
230
231          if (NestedThrowable.NESTED_TRACE_ENABLED && nested != null) {
232             synchronized (writer) {
233                if (NestedThrowable.PARENT_TRACE_ENABLED) {
234                   writer.print(" + nested throwable: ");
235                }
236                else {
237                   writer.print("[ parent trace omitted ]: ");
238                }
239                
240                nested.printStackTrace(writer);
241             }
242          }
243       }
244    }
245 }
246
Popular Tags