1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.util; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.PrintStream; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.PrintWriter; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Exception which carries around structured context. 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic class ExceptionWithContext 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson extends RuntimeException { 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} human-oriented context of the exception */ 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private StringBuffer context; 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Augments the given exception with the given context, and return the 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * result. The result is either the given exception if it was an 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@link ExceptionWithContext}, or a newly-constructed exception if it 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * was not. 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param ex {@code non-null;} the exception to augment 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param str {@code non-null;} context to add 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriate instance 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static ExceptionWithContext withContext(Throwable ex, String str) { 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ExceptionWithContext ewc; 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (ex instanceof ExceptionWithContext) { 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ewc = (ExceptionWithContext) ex; 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ewc = new ExceptionWithContext(ex); 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ewc.addContext(str); 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ewc; 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param message human-oriented message 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ExceptionWithContext(String message) { 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this(message, null); 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param cause {@code null-ok;} exception that caused this one 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ExceptionWithContext(Throwable cause) { 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this(null, cause); 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param message human-oriented message 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param cause {@code null-ok;} exception that caused this one 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ExceptionWithContext(String message, Throwable cause) { 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super((message != null) ? message : 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (cause != null) ? cause.getMessage() : null, 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cause); 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (cause instanceof ExceptionWithContext) { 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String ctx = ((ExceptionWithContext) cause).context.toString(); 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson context = new StringBuffer(ctx.length() + 200); 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson context.append(ctx); 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson context = new StringBuffer(200); 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void printStackTrace(PrintStream out) { 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super.printStackTrace(out); 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(context); 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void printStackTrace(PrintWriter out) { 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super.printStackTrace(out); 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(context); 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Adds a line of context to this instance. 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param str {@code non-null;} new context 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void addContext(String str) { 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (str == null) { 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("str == null"); 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson context.append(str); 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!str.endsWith("\n")) { 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson context.append('\n'); 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the context. 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the context 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getContext() { 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return context.toString(); 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Prints the message and context. 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} where to print to 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void printContext(PrintStream out) { 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(getMessage()); 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.print(context); 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Prints the message and context. 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} where to print to 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void printContext(PrintWriter out) { 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.println(getMessage()); 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.print(context); 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 150