Author: ggregory
Date: Thu Jan  5 09:35:43 2006
New Revision: 366225

URL: http://svn.apache.org/viewcvs?rev=366225&view=rev
Log:
http://issues.apache.org/bugzilla/show_bug.cgi?id=37574
[lang] [PATCH] new ExceptionUtils.setCause() method

Modified:
    
jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
    
jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java

Modified: 
jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java?rev=366225&r1=366224&r2=366225&view=diff
==============================================================================
--- 
jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
 (original)
+++ 
jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
 Thu Jan  5 09:35:43 2006
@@ -31,10 +31,11 @@
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang.NullArgumentException;
 
 /**
  * <p>Provides utilities for manipulating and examining 
- * <code>Throwable</code> objects.</p>
+<code>Throwable</code> objects.</p>
  *
  * @author <a href="mailto:dlr@finemaltcoding.com";>Daniel Rall</a>
  * @author Dmitri Plotnikov
@@ -73,22 +74,40 @@
     };
 
     /**
-     * <p>The Method object for JDK1.4 getCause.</p>
+     * <p>
+     * The Method object for Java 1.4 getCause.
+     * </p>
      */
     private static final Method THROWABLE_CAUSE_METHOD;
+
+    /**
+     * <p>
+     * The Method object for Java 1.4 initCause.
+     * </p>
+     */
+    private static final Method THROWABLE_INITCAUSE_METHOD;
+    
     static {
-        Method getCauseMethod;
+        Method causeMethod;
         try {
-            getCauseMethod = Throwable.class.getMethod("getCause", null);
+            causeMethod = Throwable.class.getMethod("getCause", null);
         } catch (Exception e) {
-            getCauseMethod = null;
+            causeMethod = null;
         }
-        THROWABLE_CAUSE_METHOD = getCauseMethod;
+        THROWABLE_CAUSE_METHOD = causeMethod;
+        try {
+            causeMethod = Throwable.class.getMethod("initCause", new 
Class[]{Throwable.class});
+        } catch (Exception e) {
+            causeMethod = null;
+        }
+        THROWABLE_INITCAUSE_METHOD = causeMethod;
     }
     
     /**
-     * <p>Public constructor allows an instance of <code>ExceptionUtils</code>
-     * to be created, although that is not normally necessary.</p>
+     * <p>
+     * Public constructor allows an instance of <code>ExceptionUtils</code> to 
be created, although that is not
+     * normally necessary.
+     * </p>
      */
     public ExceptionUtils() {
         super();
@@ -130,6 +149,72 @@
     }
 
     /**
+     * <p>
+     * Sets the cause of a <code>Throwable</code> using introspection, 
allowing source code compatibility between
+     * pre-1.4 and post-1.4 Java releases.
+     * </p>
+     * 
+     * <p>
+     * The typical use of this method is inside a constructor as in the 
following example:
+     * </p>
+     * 
+     * <p>
+     * <pre>
+     * import org.apache.commons.lang.exception.ExceptionUtils;
+     *  
+     * public class MyException extends Exception {
+     *  
+     *    public MyException(String msg) {
+     *       super(msg);
+     *    }
+     *   
+     *    public MyException(String msg, Throwable cause) {
+     *       super(msg);
+     *       ExceptionUtils.setCause(this, cause);
+     *    }
+     * 
+     * }           
+     * </pre>
+     * </p>
+     * 
+     * @param target
+     *            the target <code>Throwable</code>
+     * @param cause
+     *            the <code>Throwable</code> to set in the target
+     * @return a <code>true</code> if the target has been modified
+     * @since 2.2
+     */
+    public static boolean setCause(Throwable target, Throwable cause) {
+        if (target == null) {
+            throw new NullArgumentException("target");
+        }
+        Object[] causeArgs = new Object[]{cause};
+        boolean modifiedTarget = false;
+        if (THROWABLE_INITCAUSE_METHOD != null) {
+            try {
+                THROWABLE_INITCAUSE_METHOD.invoke(target, causeArgs);
+                modifiedTarget = true;
+            } catch (IllegalAccessException ignored) {
+                // Exception ignored.
+            } catch (InvocationTargetException ignored) {
+                // Exception ignored.
+            }
+        }
+        try {
+            Method setCauseMethod = target.getClass().getMethod("setCause", 
new Class[]{Throwable.class});
+            setCauseMethod.invoke(target, causeArgs);
+            modifiedTarget = true;
+        } catch (NoSuchMethodException ignored) {
+            // Exception ignored.
+        } catch (IllegalAccessException ignored) {
+            // Exception ignored.
+        } catch (InvocationTargetException ignored) {
+            // Exception ignored.
+        }
+        return modifiedTarget;
+    }
+
+    /**
      * Returns the given list as a <code>String[]</code>.
      * @param list a list to transform.
      * @return the given list as a <code>String[]</code>.
@@ -768,14 +853,20 @@
     }
 
     /**
-     * <p>Returns an array where each element is a line from the argument.</p>
-     * <p>The end of line is determined by the value of [EMAIL PROTECTED] 
SystemUtils#LINE_SEPARATOR}.</p>
-     *  
-     * <p>Functionality shared between the
-     * <code>getStackFrames(Throwable)</code> methods of this and the
-     * [EMAIL PROTECTED] org.apache.commons.lang.exception.NestableDelegate}
-     * classes.</p>
-     * @param stackTrace A stack trace String.
+     * <p>
+     * Returns an array where each element is a line from the argument.
+     * </p>
+     * <p>
+     * The end of line is determined by the value of [EMAIL PROTECTED] 
SystemUtils#LINE_SEPARATOR}.
+     * </p>
+     * 
+     * <p>
+     * Functionality shared between the <code>getStackFrames(Throwable)</code> 
methods of this and the
+     * [EMAIL PROTECTED] org.apache.commons.lang.exception.NestableDelegate} 
classes.
+     * </p>
+     * 
+     * @param stackTrace
+     *            A stack trace String.
      * @return an array where each element is a line from the argument.
      */
     static String[] getStackFrames(String stackTrace) {

Modified: 
jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java?rev=366225&r1=366224&r2=366225&view=diff
==============================================================================
--- 
jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java
 (original)
+++ 
jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java
 Thu Jan  5 09:35:43 2006
@@ -16,6 +16,7 @@
 package org.apache.commons.lang.exception;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -25,6 +26,7 @@
 import junit.framework.Assert;
 import junit.framework.Test;
 import junit.framework.TestSuite;
+
 import org.apache.commons.lang.SystemUtils;
 
 /**
@@ -139,6 +141,25 @@
         assertSame(withoutCause, ExceptionUtils.getRootCause(withCause));
     }
 
+    public void testSetCause() {
+        Exception cause = new ExceptionWithoutCause();
+        assertEquals(true, ExceptionUtils.setCause(new 
ExceptionWithCause(null), cause));
+        if (SystemUtils.isJavaVersionAtLeast(140)) {
+            assertEquals(true, ExceptionUtils.setCause(new 
ExceptionWithoutCause(), cause));
+        }
+    }
+
+    /**
+     * Tests overriding a cause to <code>null</code>.
+     */
+    public void testSetCauseToNull() {
+        Exception ex = new ExceptionWithCause(new IOException());
+        assertEquals(true, ExceptionUtils.setCause(ex, new 
IllegalStateException()));
+        assertNotNull(ExceptionUtils.getCause(ex));
+        assertEquals(true, ExceptionUtils.setCause(ex, null));
+        assertNull(ExceptionUtils.getCause(ex));
+    }
+
     //-----------------------------------------------------------------------
     public void testIsThrowableNested() {
         if (SystemUtils.isJavaVersionAtLeast(140)) {
@@ -387,11 +408,15 @@
         private Throwable cause;
 
         public ExceptionWithCause(Throwable cause) {
-            this.cause = cause;
+            setCause(cause);
         }
 
         public Throwable getCause() {
             return cause;
+        }
+
+        public void setCause(Throwable cause) {
+            this.cause = cause;
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to