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 package com.android.dexgen.util;
     18 
     19 import java.io.PrintStream;
     20 import java.io.PrintWriter;
     21 
     22 /**
     23  * Exception which carries around structured context.
     24  */
     25 public class ExceptionWithContext
     26         extends RuntimeException {
     27     /** {@code non-null;} human-oriented context of the exception */
     28     private StringBuffer context;
     29 
     30     /**
     31      * Augments the given exception with the given context, and return the
     32      * result. The result is either the given exception if it was an
     33      * {@link ExceptionWithContext}, or a newly-constructed exception if it
     34      * was not.
     35      *
     36      * @param ex {@code non-null;} the exception to augment
     37      * @param str {@code non-null;} context to add
     38      * @return {@code non-null;} an appropriate instance
     39      */
     40     public static ExceptionWithContext withContext(Throwable ex, String str) {
     41         ExceptionWithContext ewc;
     42 
     43         if (ex instanceof ExceptionWithContext) {
     44             ewc = (ExceptionWithContext) ex;
     45         } else {
     46             ewc = new ExceptionWithContext(ex);
     47         }
     48 
     49         ewc.addContext(str);
     50         return ewc;
     51     }
     52 
     53     /**
     54      * Constructs an instance.
     55      *
     56      * @param message human-oriented message
     57      */
     58     public ExceptionWithContext(String message) {
     59         this(message, null);
     60     }
     61 
     62     /**
     63      * Constructs an instance.
     64      *
     65      * @param cause {@code null-ok;} exception that caused this one
     66      */
     67     public ExceptionWithContext(Throwable cause) {
     68         this(null, cause);
     69     }
     70 
     71     /**
     72      * Constructs an instance.
     73      *
     74      * @param message human-oriented message
     75      * @param cause {@code null-ok;} exception that caused this one
     76      */
     77     public ExceptionWithContext(String message, Throwable cause) {
     78         super((message != null) ? message :
     79               (cause != null) ? cause.getMessage() : null,
     80               cause);
     81 
     82         if (cause instanceof ExceptionWithContext) {
     83             String ctx = ((ExceptionWithContext) cause).context.toString();
     84             context = new StringBuffer(ctx.length() + 200);
     85             context.append(ctx);
     86         } else {
     87             context = new StringBuffer(200);
     88         }
     89     }
     90 
     91     /** {@inheritDoc} */
     92     @Override
     93     public void printStackTrace(PrintStream out) {
     94         super.printStackTrace(out);
     95         out.println(context);
     96     }
     97 
     98     /** {@inheritDoc} */
     99     @Override
    100     public void printStackTrace(PrintWriter out) {
    101         super.printStackTrace(out);
    102         out.println(context);
    103     }
    104 
    105     /**
    106      * Adds a line of context to this instance.
    107      *
    108      * @param str {@code non-null;} new context
    109      */
    110     public void addContext(String str) {
    111         if (str == null) {
    112             throw new NullPointerException("str == null");
    113         }
    114 
    115         context.append(str);
    116         if (!str.endsWith("\n")) {
    117             context.append('\n');
    118         }
    119     }
    120 
    121     /**
    122      * Gets the context.
    123      *
    124      * @return {@code non-null;} the context
    125      */
    126     public String getContext() {
    127         return context.toString();
    128     }
    129 
    130     /**
    131      * Prints the message and context.
    132      *
    133      * @param out {@code non-null;} where to print to
    134      */
    135     public void printContext(PrintStream out) {
    136         out.println(getMessage());
    137         out.print(context);
    138     }
    139 
    140     /**
    141      * Prints the message and context.
    142      *
    143      * @param out {@code non-null;} where to print to
    144      */
    145     public void printContext(PrintWriter out) {
    146         out.println(getMessage());
    147         out.print(context);
    148     }
    149 }
    150