001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.collections; 018 019 import java.io.PrintStream; 020 import java.io.PrintWriter; 021 022 /** 023 * Runtime exception thrown from functors. 024 * If required, a root cause error can be wrapped within this one. 025 * 026 * @since Commons Collections 3.0 027 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $ 028 * 029 * @author Stephen Colebourne 030 */ 031 public class FunctorException extends RuntimeException { 032 033 /** 034 * Does JDK support nested exceptions 035 */ 036 private static final boolean JDK_SUPPORTS_NESTED; 037 038 static { 039 boolean flag = false; 040 try { 041 Throwable.class.getDeclaredMethod("getCause", new Class[0]); 042 flag = true; 043 } catch (NoSuchMethodException ex) { 044 flag = false; 045 } 046 JDK_SUPPORTS_NESTED = flag; 047 } 048 049 /** 050 * Root cause of the exception 051 */ 052 private final Throwable rootCause; 053 054 /** 055 * Constructs a new <code>FunctorException</code> without specified 056 * detail message. 057 */ 058 public FunctorException() { 059 super(); 060 this.rootCause = null; 061 } 062 063 /** 064 * Constructs a new <code>FunctorException</code> with specified 065 * detail message. 066 * 067 * @param msg the error message. 068 */ 069 public FunctorException(String msg) { 070 super(msg); 071 this.rootCause = null; 072 } 073 074 /** 075 * Constructs a new <code>FunctorException</code> with specified 076 * nested <code>Throwable</code> root cause. 077 * 078 * @param rootCause the exception or error that caused this exception 079 * to be thrown. 080 */ 081 public FunctorException(Throwable rootCause) { 082 super((rootCause == null ? null : rootCause.getMessage())); 083 this.rootCause = rootCause; 084 } 085 086 /** 087 * Constructs a new <code>FunctorException</code> with specified 088 * detail message and nested <code>Throwable</code> root cause. 089 * 090 * @param msg the error message. 091 * @param rootCause the exception or error that caused this exception 092 * to be thrown. 093 */ 094 public FunctorException(String msg, Throwable rootCause) { 095 super(msg); 096 this.rootCause = rootCause; 097 } 098 099 /** 100 * Gets the cause of this throwable. 101 * 102 * @return the cause of this throwable, or <code>null</code> 103 */ 104 public Throwable getCause() { 105 return rootCause; 106 } 107 108 /** 109 * Prints the stack trace of this exception to the standard error stream. 110 */ 111 public void printStackTrace() { 112 printStackTrace(System.err); 113 } 114 115 /** 116 * Prints the stack trace of this exception to the specified stream. 117 * 118 * @param out the <code>PrintStream</code> to use for output 119 */ 120 public void printStackTrace(PrintStream out) { 121 synchronized (out) { 122 PrintWriter pw = new PrintWriter(out, false); 123 printStackTrace(pw); 124 // Flush the PrintWriter before it's GC'ed. 125 pw.flush(); 126 } 127 } 128 129 /** 130 * Prints the stack trace of this exception to the specified writer. 131 * 132 * @param out the <code>PrintWriter</code> to use for output 133 */ 134 public void printStackTrace(PrintWriter out) { 135 synchronized (out) { 136 super.printStackTrace(out); 137 if (rootCause != null && JDK_SUPPORTS_NESTED == false) { 138 out.print("Caused by: "); 139 rootCause.printStackTrace(out); 140 } 141 } 142 } 143 144 }