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 25package org.jf.dexlib.Util; 26 27import java.io.PrintStream; 28import java.io.PrintWriter; 29 30/** 31 * Exception which carries around structured context. 32 */ 33public 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) { 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(str); 58 return ewc; 59 } 60 61 /** 62 * Constructs an instance. 63 * 64 * @param message human-oriented message 65 */ 66 public ExceptionWithContext(String message) { 67 this(message, null); 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(null, cause); 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(String message, Throwable cause) { 86 super((message != null) ? message : 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 /** {@inheritDoc} */ 100 @Override 101 public void printStackTrace(PrintStream out) { 102 super.printStackTrace(out); 103 out.println(context); 104 } 105 106 /** {@inheritDoc} */ 107 @Override 108 public void printStackTrace(PrintWriter out) { 109 super.printStackTrace(out); 110 out.println(context); 111 } 112 113 /** 114 * Adds a line of context to this instance. 115 * 116 * @param str non-null; new context 117 */ 118 public void addContext(String str) { 119 if (str == null) { 120 throw new NullPointerException("str == null"); 121 } 122 123 context.append(str); 124 if (!str.endsWith("\n")) { 125 context.append('\n'); 126 } 127 } 128 129 /** 130 * Gets the context. 131 * 132 * @return non-null; the context 133 */ 134 public String getContext() { 135 return context.toString(); 136 } 137 138 /** 139 * Prints the message and context. 140 * 141 * @param out non-null; where to print to 142 */ 143 public void printContext(PrintStream out) { 144 out.println(getMessage()); 145 out.print(context); 146 } 147 148 /** 149 * Prints the message and context. 150 * 151 * @param out non-null; where to print to 152 */ 153 public void printContext(PrintWriter out) { 154 out.println(getMessage()); 155 out.print(context); 156 } 157}