You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2011/09/23 19:47:40 UTC

svn commit: r1174916 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ tapestry-core/src/test/java/org/apache/tapestry5/internal/serv...

Author: hlship
Date: Fri Sep 23 17:47:40 2011
New Revision: 1174916

URL: http://svn.apache.org/viewvc?rev=1174916&view=rev
Log:
TAP5-1369: ExceptionUtils.findCause() does not use the same approach as ExceptionAnalyzer

Added:
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionWrapper.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidationSupportImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldValidationSupportImplTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/ExceptionUtils.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionUtilsTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java?rev=1174916&r1=1174915&r2=1174916&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java Fri Sep 23 17:47:40 2011
@@ -31,6 +31,7 @@ import org.apache.tapestry5.ioc.annotati
 import org.apache.tapestry5.ioc.annotations.Symbol;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.ioc.services.PropertyAccess;
 import org.apache.tapestry5.ioc.util.ExceptionUtils;
 import org.apache.tapestry5.ioc.util.IdAllocator;
 import org.apache.tapestry5.json.JSONArray;
@@ -244,6 +245,9 @@ public class Form implements ClientEleme
     @Inject
     private ClientDataEncoder clientDataEncoder;
 
+    @Inject
+    private PropertyAccess propertyAccess;
+
     private String clientId;
 
     // Set during rendering or submit processing to be the
@@ -603,7 +607,7 @@ public class Form implements ClientEleme
             resources.triggerContextEvent(eventName, context, callback);
         } catch (RuntimeException ex)
         {
-            ValidationException ve = ExceptionUtils.findCause(ex, ValidationException.class);
+            ValidationException ve = ExceptionUtils.findCause(ex, ValidationException.class, propertyAccess);
 
             if (ve != null)
             {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidationSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidationSupportImpl.java?rev=1174916&r1=1174915&r2=1174916&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidationSupportImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/FieldValidationSupportImpl.java Fri Sep 23 17:47:40 2011
@@ -14,17 +14,11 @@
 
 package org.apache.tapestry5.internal.services;
 
-import org.apache.tapestry5.ComponentEventCallback;
-import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.FieldTranslator;
-import org.apache.tapestry5.FieldValidationSupport;
-import org.apache.tapestry5.FieldValidator;
-import org.apache.tapestry5.NullFieldStrategy;
-import org.apache.tapestry5.ValidationException;
+import org.apache.tapestry5.*;
 import org.apache.tapestry5.corelib.internal.InternalMessages;
 import org.apache.tapestry5.internal.util.Holder;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.services.PropertyAccess;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.ioc.util.ExceptionUtils;
 
@@ -33,13 +27,16 @@ public class FieldValidationSupportImpl 
 {
     private final TypeCoercer typeCoercer;
 
-    public FieldValidationSupportImpl(TypeCoercer typeCoercer)
+    private final PropertyAccess propertyAccess;
+
+    public FieldValidationSupportImpl(TypeCoercer typeCoercer, PropertyAccess propertyAccess)
     {
         this.typeCoercer = typeCoercer;
+        this.propertyAccess = propertyAccess;
     }
 
     public String toClient(Object value, ComponentResources componentResources, FieldTranslator<Object> translator,
-            NullFieldStrategy nullFieldStrategy)
+                           NullFieldStrategy nullFieldStrategy)
     {
         assert componentResources != null;
         assert translator != null;
@@ -63,7 +60,7 @@ public class FieldValidationSupportImpl 
         };
 
         componentResources.triggerEvent(EventConstants.TO_CLIENT, new Object[]
-        { value }, callback);
+                {value}, callback);
 
         if (resultHolder.hasValue())
             return resultHolder.get();
@@ -89,7 +86,7 @@ public class FieldValidationSupportImpl 
     }
 
     public Object parseClient(String clientValue, ComponentResources componentResources,
-            FieldTranslator<Object> translator, NullFieldStrategy nullFieldStrategy) throws ValidationException
+                              FieldTranslator<Object> translator, NullFieldStrategy nullFieldStrategy) throws ValidationException
     {
         assert componentResources != null;
         assert translator != null;
@@ -118,9 +115,8 @@ public class FieldValidationSupportImpl 
         try
         {
             componentResources.triggerEvent(EventConstants.PARSE_CLIENT, new Object[]
-            { effectiveValue }, callback);
-        }
-        catch (RuntimeException ex)
+                    {effectiveValue}, callback);
+        } catch (RuntimeException ex)
         {
             rethrowValidationException(ex);
         }
@@ -134,15 +130,13 @@ public class FieldValidationSupportImpl 
     /**
      * Checks for a {@link org.apache.tapestry5.ValidationException} inside the outer exception and throws that,
      * otherwise rethrows the runtime exception.
-     * 
-     * @param outerException
-     *            initially caught exception
-     * @throws ValidationException
-     *             if found
+     *
+     * @param outerException initially caught exception
+     * @throws ValidationException if found
      */
     private void rethrowValidationException(RuntimeException outerException) throws ValidationException
     {
-        ValidationException ve = ExceptionUtils.findCause(outerException, ValidationException.class);
+        ValidationException ve = ExceptionUtils.findCause(outerException, ValidationException.class, propertyAccess);
 
         if (ve != null)
             throw ve;
@@ -151,7 +145,7 @@ public class FieldValidationSupportImpl 
     }
 
     @SuppressWarnings(
-    { "unchecked" })
+            {"unchecked"})
     public void validate(Object value, ComponentResources componentResources, FieldValidator validator)
             throws ValidationException
     {
@@ -162,9 +156,8 @@ public class FieldValidationSupportImpl 
         try
         {
             componentResources.triggerEvent(EventConstants.VALIDATE, new Object[]
-            { value }, null);
-        }
-        catch (RuntimeException ex)
+                    {value}, null);
+        } catch (RuntimeException ex)
         {
             rethrowValidationException(ex);
         }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldValidationSupportImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldValidationSupportImplTest.java?rev=1174916&r1=1174915&r2=1174916&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldValidationSupportImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldValidationSupportImplTest.java Fri Sep 23 17:47:40 2011
@@ -14,32 +14,29 @@
 
 package org.apache.tapestry5.internal.services;
 
-import static org.easymock.EasyMock.eq;
-
-import org.apache.tapestry5.ComponentEventCallback;
-import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.FieldTranslator;
-import org.apache.tapestry5.FieldValidationSupport;
-import org.apache.tapestry5.FieldValidator;
-import org.apache.tapestry5.NullFieldStrategy;
-import org.apache.tapestry5.ValidationException;
+import org.apache.tapestry5.*;
 import org.apache.tapestry5.corelib.internal.InternalMessages;
 import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.ioc.services.PropertyAccess;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import static org.easymock.EasyMock.eq;
+
 public class FieldValidationSupportImplTest extends InternalBaseTestCase
 {
     private TypeCoercer typeCoercer;
 
+    private PropertyAccess propertyAccess;
+
     @BeforeClass
     public void setup()
     {
         typeCoercer = getService(TypeCoercer.class);
+        propertyAccess = getService(PropertyAccess.class);
     }
 
 
@@ -69,14 +66,14 @@ public class FieldValidationSupportImplT
         };
 
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(EventConstants.PARSE_CLIENT),
-                                               EasyMock.isA(Object[].class),
-                                               EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
+                EasyMock.isA(Object[].class),
+                EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
 
 
         replay();
 
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         Object actual = support.parseClient(clientValue, resources, translator, nullFieldStrategy);
 
@@ -102,7 +99,7 @@ public class FieldValidationSupportImplT
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         Object actual = support.parseClient(clientValue, resources, translator, nullFieldStrategy);
 
@@ -114,8 +111,8 @@ public class FieldValidationSupportImplT
     private void ignoreEvent(ComponentResources resources, String event, Object... context)
     {
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(event),
-                                               EasyMock.aryEq(context),
-                                               EasyMock.isA(ComponentEventCallback.class))).andReturn(false);
+                EasyMock.aryEq(context),
+                EasyMock.isA(ComponentEventCallback.class))).andReturn(false);
     }
 
     protected final void train_replaceFromClient(NullFieldStrategy nullFieldStrategy, String value)
@@ -135,22 +132,21 @@ public class FieldValidationSupportImplT
         String clientValue = "abracadabra";
 
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(EventConstants.PARSE_CLIENT),
-                                               EasyMock.isA(Object[].class),
-                                               EasyMock.isA(ComponentEventCallback.class))).andThrow(
+                EasyMock.isA(Object[].class),
+                EasyMock.isA(ComponentEventCallback.class))).andThrow(
                 new RuntimeException(ve));
 
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         try
         {
             support.parseClient(clientValue, resources, translator, nullFieldStrategy);
 
             unreachable();
-        }
-        catch (ValidationException ex)
+        } catch (ValidationException ex)
         {
             assertSame(ex, ve);
         }
@@ -172,21 +168,20 @@ public class FieldValidationSupportImplT
 
 
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(EventConstants.PARSE_CLIENT),
-                                               EasyMock.isA(Object[].class),
-                                               EasyMock.isA(ComponentEventCallback.class))).andThrow(re);
+                EasyMock.isA(Object[].class),
+                EasyMock.isA(ComponentEventCallback.class))).andThrow(re);
 
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         try
         {
             support.parseClient(clientValue, resources, translator, nullFieldStrategy);
 
             unreachable();
-        }
-        catch (RuntimeException ex)
+        } catch (RuntimeException ex)
         {
             assertSame(ex, re);
         }
@@ -210,7 +205,7 @@ public class FieldValidationSupportImplT
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         Object actual = support.parseClient(clientValue, resources, translator, nullFieldStrategy);
 
@@ -233,14 +228,14 @@ public class FieldValidationSupportImplT
         String clientValue = "abracadabra";
 
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(EventConstants.TO_CLIENT),
-                                               EasyMock.aryEq(new Object[] {value}),
-                                               EasyMock.isA(ComponentEventCallback.class))).andReturn(false);
+                EasyMock.aryEq(new Object[]{value}),
+                EasyMock.isA(ComponentEventCallback.class))).andReturn(false);
 
         expect(translator.toClient(value)).andReturn(clientValue);
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         String actual = support.toClient(value, resources, translator, nullFieldStrategy);
 
@@ -273,13 +268,13 @@ public class FieldValidationSupportImplT
         };
 
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(EventConstants.TO_CLIENT),
-                                               EasyMock.aryEq(new Object[] {value}),
-                                               EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
+                EasyMock.aryEq(new Object[]{value}),
+                EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
 
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(null);
+        FieldValidationSupport support = new FieldValidationSupportImpl(null, propertyAccess);
 
         String actual = support.toClient(value, resources, translator, nullFieldStrategy);
 
@@ -310,13 +305,13 @@ public class FieldValidationSupportImplT
         };
 
         EasyMock.expect(resources.triggerEvent(EasyMock.eq(EventConstants.TO_CLIENT),
-                                               EasyMock.aryEq(new Object[] {value}),
-                                               EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
+                EasyMock.aryEq(new Object[]{value}),
+                EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
 
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(null);
+        FieldValidationSupport support = new FieldValidationSupportImpl(null, propertyAccess);
 
         try
         {
@@ -324,8 +319,7 @@ public class FieldValidationSupportImplT
             support.toClient(value, resources, translator, null);
 
             unreachable();
-        }
-        catch (RuntimeException ex)
+        } catch (RuntimeException ex)
         {
             assertEquals(ex.getMessage(), InternalMessages.toClientShouldReturnString());
         }
@@ -349,12 +343,12 @@ public class FieldValidationSupportImplT
         ComponentEventCallback handler = null;
 
         expect(resources.triggerEvent(EasyMock.eq(EventConstants.VALIDATE),
-                                      EasyMock.aryEq(new Object[] {value}), EasyMock.eq(handler))).andReturn(true);
+                EasyMock.aryEq(new Object[]{value}), EasyMock.eq(handler))).andReturn(true);
 
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
         support.validate(value, resources, fv);
 
@@ -378,20 +372,19 @@ public class FieldValidationSupportImplT
         fv.validate(value);
 
         expect(resources.triggerEvent(eq(EventConstants.VALIDATE),
-                                      EasyMock.aryEq(new Object[] {value}), eq(handler))).andThrow(re);
+                EasyMock.aryEq(new Object[]{value}), eq(handler))).andThrow(re);
 
 
         replay();
 
-        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer);
+        FieldValidationSupport support = new FieldValidationSupportImpl(typeCoercer, propertyAccess);
 
 
         try
         {
             support.validate(value, resources, fv);
             unreachable();
-        }
-        catch (ValidationException ex)
+        } catch (ValidationException ex)
         {
             assertSame(ex, ve);
         }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/ExceptionUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/ExceptionUtils.java?rev=1174916&r1=1174915&r2=1174916&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/ExceptionUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/ExceptionUtils.java Fri Sep 23 17:47:40 2011
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2011 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,6 +14,9 @@
 
 package org.apache.tapestry5.ioc.util;
 
+import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry5.ioc.services.PropertyAccess;
+
 /**
  * Contains static methods useful for manipulating exceptions.
  */
@@ -33,7 +36,10 @@ public class ExceptionUtils
 
         while (current != null)
         {
-            if (type.isInstance(current)) return type.cast(current);
+            if (type.isInstance(current))
+            {
+                return type.cast(current);
+            }
 
             // Not a match, work down.
 
@@ -42,4 +48,48 @@ public class ExceptionUtils
 
         return null;
     }
+
+    /**
+     * Locates a particular type of exception, working its way down via any property that returns some type of Exception.
+     * This is more expensive, but more accurate, than {@link #findCause(Throwable, Class)} as it works with older exceptions
+     * that do not properly implement the (relatively new) {@linkplain Throwable#getCause() cause property}.
+     *
+     * @param t      the outermost exception
+     * @param type   the type of exception to search for
+     * @param access used to access properties
+     * @return the first exception of the given type, if found, or null
+     */
+    public static <T extends Throwable> T findCause(Throwable t, Class<T> type, PropertyAccess access)
+    {
+        Throwable current = t;
+
+        while (current != null)
+        {
+            if (type.isInstance(current))
+            {
+                return type.cast(current);
+            }
+
+            Throwable next = null;
+
+            ClassPropertyAdapter adapter = access.getAdapter(current);
+
+            for (String name : adapter.getPropertyNames())
+            {
+
+                Object value = adapter.getPropertyAdapter(name).get(current);
+
+                if (value != null && value != current && value instanceof Throwable)
+                {
+                    next = (Throwable) value;
+                    break;
+                }
+            }
+
+            current = next;
+        }
+
+
+        return null;
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionUtilsTest.java?rev=1174916&r1=1174915&r2=1174916&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionUtilsTest.java Fri Sep 23 17:47:40 2011
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2011 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,12 +14,16 @@
 
 package org.apache.tapestry5.ioc.util;
 
+import org.apache.tapestry5.ioc.internal.services.PropertyAccessImpl;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.ioc.services.PropertyAccess;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 public class ExceptionUtilsTest extends Assert
 {
+    private final PropertyAccess access = new PropertyAccessImpl();
+
     @Test
     public void find_cause_with_match()
     {
@@ -28,6 +32,8 @@ public class ExceptionUtilsTest extends 
         RuntimeException outer = new RuntimeException(inner);
 
         assertSame(ExceptionUtils.findCause(outer, TapestryException.class), inner);
+        assertSame(ExceptionUtils.findCause(outer, TapestryException.class, access), inner);
+
     }
 
     @Test
@@ -36,5 +42,20 @@ public class ExceptionUtilsTest extends 
         RuntimeException re = new RuntimeException("No cause for you!");
 
         assertNull(ExceptionUtils.findCause(re, TapestryException.class));
+        assertNull(ExceptionUtils.findCause(re, TapestryException.class, access));
     }
+
+    @Test
+    public void find_hidden_exception()
+    {
+        RuntimeException inner = new RuntimeException();
+        Exception outer = new ExceptionWrapper(inner);
+
+        // TAP5-1639: The old code can't find inner
+        assertNull(ExceptionUtils.findCause(outer, RuntimeException.class));
+
+        // The new reflection-based code can:
+        assertSame(ExceptionUtils.findCause(outer, RuntimeException.class, access), inner);
+    }
+
 }

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionWrapper.java?rev=1174916&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionWrapper.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/ExceptionWrapper.java Fri Sep 23 17:47:40 2011
@@ -0,0 +1,31 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.util;
+
+
+public class ExceptionWrapper extends Exception
+{
+    private final Exception inner;
+
+    public ExceptionWrapper(Exception inner)
+    {
+        this.inner = inner;
+    }
+
+    public Exception getInner()
+    {
+        return inner;
+    }
+}