Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * As per the Apache license requirements, this file has been modified
     19  * from its original state.
     20  *
     21  * Such modifications are Copyright (C) 2010 Ben Gruver, and are released
     22  * under the original license
     23  */
     24 
     25 package org.jf.util;
     26 
     27 import java.io.PrintStream;
     28 import java.io.PrintWriter;
     29 
     30 /**
     31  * Exception which carries around structured context.
     32  */
     33 public class ExceptionWithContext
     34         extends RuntimeException {
     35     /** non-null; human-oriented context of the exception */
     36     private StringBuffer context;
     37 
     38     /**
     39      * Augments the given exception with the given context, and return the
     40      * result. The result is either the given exception if it was an
     41      * {@link ExceptionWithContext}, or a newly-constructed exception if it
     42      * was not.
     43      *
     44      * @param ex non-null; the exception to augment
     45      * @param str non-null; context to add
     46      * @return non-null; an appropriate instance
     47      */
     48     public static ExceptionWithContext withContext(Throwable ex, String str, Object... formatArgs) {
     49         ExceptionWithContext ewc;
     50 
     51         if (ex instanceof ExceptionWithContext) {
     52             ewc = (ExceptionWithContext) ex;
     53         } else {
     54             ewc = new ExceptionWithContext(ex);
     55         }
     56 
     57         ewc.addContext(String.format(str, formatArgs));
     58         return ewc;
     59     }
     60 
     61     /**
     62      * Constructs an instance.
     63      *
     64      * @param message human-oriented message
     65      */
     66     public ExceptionWithContext(String message, Object... formatArgs) {
     67         this(null, message, formatArgs);
     68     }
     69 
     70     /**
     71      * Constructs an instance.
     72      *
     73      * @param cause null-ok; exception that caused this one
     74      */
     75     public ExceptionWithContext(Throwable cause) {
     76         this(cause, null);
     77     }
     78 
     79     /**
     80      * Constructs an instance.
     81      *
     82      * @param message human-oriented message
     83      * @param cause null-ok; exception that caused this one
     84      */
     85     public ExceptionWithContext(Throwable cause, String message, Object... formatArgs) {
     86         super((message != null) ? formatMessage(message, formatArgs) :
     87               (cause != null) ? cause.getMessage() : null,
     88               cause);
     89 
     90         if (cause instanceof ExceptionWithContext) {
     91             String ctx = ((ExceptionWithContext) cause).context.toString();
     92             context = new StringBuffer(ctx.length() + 200);
     93             context.append(ctx);
     94         } else {
     95             context = new StringBuffer(200);
     96         }
     97     }
     98 
     99     private static String formatMessage(String message, Object... formatArgs) {
    100         if (message == null) {
    101             return null;
    102         }
    103         return String.format(message, formatArgs);
    104     }
    105 
    106     /** {@inheritDoc} */
    107     @Override
    108     public void printStackTrace(PrintStream out) {
    109         super.printStackTrace(out);
    110         out.println(context);
    111     }
    112 
    113     /** {@inheritDoc} */
    114     @Override
    115     public void printStackTrace(PrintWriter out) {
    116         super.printStackTrace(out);
    117         out.println(context);
    118     }
    119 
    120     /**
    121      * Adds a line of context to this instance.
    122      *
    123      * @param str non-null; new context
    124      */
    125     public void addContext(String str) {
    126         if (str == null) {
    127             throw new NullPointerException("str == null");
    128         }
    129 
    130         context.append(str);
    131         if (!str.endsWith("\n")) {
    132             context.append('\n');
    133         }
    134     }
    135 
    136     /**
    137      * Gets the context.
    138      *
    139      * @return non-null; the context
    140      */
    141     public String getContext() {
    142         return context.toString();
    143     }
    144 
    145     /**
    146      * Prints the message and context.
    147      *
    148      * @param out non-null; where to print to
    149      */
    150     public void printContext(PrintStream out) {
    151         out.println(getMessage());
    152         out.print(context);
    153     }
    154 
    155     /**
    156      * Prints the message and context.
    157      *
    158      * @param out non-null; where to print to
    159      */
    160     public void printContext(PrintWriter out) {
    161         out.println(getMessage());
    162         out.print(context);
    163     }
    164 }