ExceptionWithContext.java revision e8665c7a91f2af56de3124bd351b75dcc81fcf85
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2007 The Android Open Source Project 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * See the License for the specific language governing permissions and 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License. 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * As per the Apache license requirements, this file has been modified 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from its original state. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Such modifications are Copyright (C) 2010 Ben Gruver, and are released 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * under the original license 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.jf.util; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.io.PrintStream; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.PrintWriter; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Exception which carries around structured context. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class ExceptionWithContext 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extends RuntimeException { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** non-null; human-oriented context of the exception */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private StringBuffer context; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Augments the given exception with the given context, and return the 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result. The result is either the given exception if it was an 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * {@link ExceptionWithContext}, or a newly-constructed exception if it 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * was not. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param ex non-null; the exception to augment 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param str non-null; context to add 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return non-null; an appropriate instance 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public static ExceptionWithContext withContext(Throwable ex, String str, Object... formatArgs) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExceptionWithContext ewc; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ex instanceof ExceptionWithContext) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ewc = (ExceptionWithContext) ex; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ewc = new ExceptionWithContext(ex); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ewc.addContext(String.format(str, formatArgs)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ewc; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Constructs an instance. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param message human-oriented message 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public ExceptionWithContext(String message, Object... formatArgs) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this(null, message, formatArgs); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Constructs an instance. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param cause null-ok; exception that caused this one 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ExceptionWithContext(Throwable cause) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this(cause, null); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Constructs an instance. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param message human-oriented message 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param cause null-ok; exception that caused this one 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ExceptionWithContext(Throwable cause, String message, Object... formatArgs) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) super((message != null) ? formatMessage(message, formatArgs) : 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cause != null) ? cause.getMessage() : null, 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cause); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cause instanceof ExceptionWithContext) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String ctx = ((ExceptionWithContext) cause).context.toString(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context = new StringBuffer(ctx.length() + 200); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context.append(ctx); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) context = new StringBuffer(200); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static String formatMessage(String message, Object... formatArgs) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message == null) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return null; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return String.format(message, formatArgs); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** {@inheritDoc} */ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @Override 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void printStackTrace(PrintStream out) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) super.printStackTrace(out); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.println(context); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** {@inheritDoc} */ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @Override 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void printStackTrace(PrintWriter out) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) super.printStackTrace(out); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out.println(context); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adds a line of context to this instance. 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param str non-null; new context 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void addContext(String str) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == null) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new NullPointerException("str == null"); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context.append(str); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!str.endsWith("\n")) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context.append('\n'); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Gets the context. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return non-null; the context 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public String getContext() { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context.toString(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Prints the message and context. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param out non-null; where to print to 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void printContext(PrintStream out) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.println(getMessage()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.print(context); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Prints the message and context. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param out non-null; where to print to 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void printContext(PrintWriter out) { 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out.println(getMessage()); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out.print(context); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}