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