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 */ withContext(Throwable ex, String str)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 */ ExceptionWithContext(String message)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 */ ExceptionWithContext(Throwable cause)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 */ ExceptionWithContext(String message, Throwable cause)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 printStackTrace(PrintStream out)92 public void printStackTrace(PrintStream out) { 93 super.printStackTrace(out); 94 out.println(context); 95 } 96 97 /** {@inheritDoc} */ 98 @Override printStackTrace(PrintWriter out)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 */ addContext(String str)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 */ getContext()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 */ printContext(PrintStream out)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 */ printContext(PrintWriter out)144 public void printContext(PrintWriter out) { 145 out.println(getMessage()); 146 out.print(context); 147 } 148 } 149