1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  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. package org.apache.commons.collections;
  17. import java.io.PrintStream;
  18. import java.io.PrintWriter;
  19. /**
  20. * Runtime exception thrown from functors.
  21. * If required, a root cause error can be wrapped within this one.
  22. *
  23. * @since Commons Collections 3.0
  24. * @version $Revision: 1.6 $ $Date: 2004/02/18 01:15:42 $
  25. *
  26. * @author Stephen Colebourne
  27. */
  28. public class FunctorException extends RuntimeException {
  29. /**
  30. * Does JDK support nested exceptions
  31. */
  32. private static final boolean JDK_SUPPORTS_NESTED;
  33. static {
  34. boolean flag = false;
  35. try {
  36. Throwable.class.getDeclaredMethod("getCause", new Class[0]);
  37. flag = true;
  38. } catch (NoSuchMethodException ex) {
  39. flag = false;
  40. }
  41. JDK_SUPPORTS_NESTED = flag;
  42. }
  43. /**
  44. * Root cause of the exception
  45. */
  46. private final Throwable rootCause;
  47. /**
  48. * Constructs a new <code>FunctorException</code> without specified
  49. * detail message.
  50. */
  51. public FunctorException() {
  52. super();
  53. this.rootCause = null;
  54. }
  55. /**
  56. * Constructs a new <code>FunctorException</code> with specified
  57. * detail message.
  58. *
  59. * @param msg the error message.
  60. */
  61. public FunctorException(String msg) {
  62. super(msg);
  63. this.rootCause = null;
  64. }
  65. /**
  66. * Constructs a new <code>FunctorException</code> with specified
  67. * nested <code>Throwable</code> root cause.
  68. *
  69. * @param rootCause the exception or error that caused this exception
  70. * to be thrown.
  71. */
  72. public FunctorException(Throwable rootCause) {
  73. super((rootCause == null ? null : rootCause.getMessage()));
  74. this.rootCause = rootCause;
  75. }
  76. /**
  77. * Constructs a new <code>FunctorException</code> with specified
  78. * detail message and nested <code>Throwable</code> root cause.
  79. *
  80. * @param msg the error message.
  81. * @param rootCause the exception or error that caused this exception
  82. * to be thrown.
  83. */
  84. public FunctorException(String msg, Throwable rootCause) {
  85. super(msg);
  86. this.rootCause = rootCause;
  87. }
  88. /**
  89. * Gets the cause of this throwable.
  90. *
  91. * @return the cause of this throwable, or <code>null</code>
  92. */
  93. public Throwable getCause() {
  94. return rootCause;
  95. }
  96. /**
  97. * Prints the stack trace of this exception to the standard error stream.
  98. */
  99. public void printStackTrace() {
  100. printStackTrace(System.err);
  101. }
  102. /**
  103. * Prints the stack trace of this exception to the specified stream.
  104. *
  105. * @param out the <code>PrintStream</code> to use for output
  106. */
  107. public void printStackTrace(PrintStream out) {
  108. synchronized (out) {
  109. PrintWriter pw = new PrintWriter(out, false);
  110. printStackTrace(pw);
  111. // Flush the PrintWriter before it's GC'ed.
  112. pw.flush();
  113. }
  114. }
  115. /**
  116. * Prints the stack trace of this exception to the specified writer.
  117. *
  118. * @param out the <code>PrintWriter</code> to use for output
  119. */
  120. public void printStackTrace(PrintWriter out) {
  121. synchronized (out) {
  122. super.printStackTrace(out);
  123. if (rootCause != null && JDK_SUPPORTS_NESTED == false) {
  124. out.print("Caused by: ");
  125. rootCause.printStackTrace(out);
  126. }
  127. }
  128. }
  129. }