SPRNET-904 - RollbackRuleAttribute throws AopConfiguration exception instead of ArgumentException
This commit is contained in:
@@ -1,201 +1,208 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Spring.Aop.Framework;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Transaction.Interceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Rule determining whether or not a given exception (and any subclasses) should
|
||||
/// cause a rollback.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Multiple such rules can be applied to determine whether a transaction should commit
|
||||
/// or rollback after an exception has been thrown.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Griffin Caprio (.NET)</author>
|
||||
[Serializable]
|
||||
public class RollbackRuleAttribute : Attribute
|
||||
{
|
||||
private string _exceptionName;
|
||||
|
||||
/// <summary>
|
||||
/// Canonical instance representing default behavior for rolling back on
|
||||
/// all <see cref="System.SystemException"/>s.
|
||||
/// </summary>
|
||||
public static RollbackRuleAttribute RollbackOnSystemExceptions
|
||||
= new RollbackRuleAttribute(typeof (Exception).Name);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/> class
|
||||
/// for the named <paramref name="exceptionName"/>.
|
||||
/// </summary>
|
||||
/// <param name="exceptionName">The exception name.</param>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// As always, the <paramref name="exceptionName"/> should be the full
|
||||
/// assembly qualified version.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public RollbackRuleAttribute( string exceptionName )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(exceptionName, "exceptionName");
|
||||
_exceptionName = exceptionName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/> class
|
||||
/// for the suplied <paramref name="exceptionType"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The exception class must be <see cref="System.Exception"/> or a subclass.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This is the preferred way to construct a
|
||||
/// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/>,
|
||||
/// matching the exception class and subclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="exceptionType">
|
||||
/// The <see cref="System.Exception"/> class that will trigger a rollback.
|
||||
/// </param>
|
||||
public RollbackRuleAttribute( Type exceptionType )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(exceptionType, "exceptionType");
|
||||
if ( ! typeof(Exception).IsAssignableFrom( exceptionType ) )
|
||||
{
|
||||
throw new AopConfigException("Cannot construct rollback rule from " + exceptionType + "; " + "It's not an Exception");
|
||||
}
|
||||
_exceptionName = exceptionType.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name of the exception.
|
||||
/// </summary>
|
||||
public string ExceptionName
|
||||
{
|
||||
get { return _exceptionName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the depth to the matching superclass execption <see cref="System.Type"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A return value of 0 means that the <paramref name="exceptionType"/> matches.
|
||||
/// </remarks>
|
||||
/// <param name="exceptionType">
|
||||
/// The <see cref="System.Type"/> of exception to find.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins.
|
||||
/// </returns>
|
||||
public int GetDepth( Type exceptionType )
|
||||
{
|
||||
return getDepth( exceptionType, 0 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the depth to the matching superclass execption <see cref="System.Type"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A return value of 0 means that the <paramref name="exception"/>s
|
||||
/// <see cref="System.Type"/> matches.
|
||||
/// </remarks>
|
||||
/// <param name="exception">
|
||||
/// The exception object to find.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins.
|
||||
/// </returns>
|
||||
public int GetDepth( object exception )
|
||||
{
|
||||
return GetDepth( exception.GetType() );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> representation of this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> containing the exception covered by this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "RollbackRule with pattern '" + ExceptionName + "'";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override of <see cref="System.Object.GetHashCode"/>.
|
||||
/// </summary>
|
||||
/// <returns>The hashcode of the exception name covered by this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ExceptionName.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override of <see cref="System.Object.Equals(object)"/>.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare.</param>
|
||||
/// <returns><b>True</b> if the input object is equal to this instance.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
RollbackRuleAttribute rollbackRuleAttribute = obj as RollbackRuleAttribute;
|
||||
if ( rollbackRuleAttribute == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Equals( rollbackRuleAttribute );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strongly typed <c>Equals()</c> implementation.
|
||||
/// </summary>
|
||||
/// <param name="rollbackRuleAttribute">
|
||||
/// The <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/> to compare.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <b>True</b> if the input object is equal to the supplied <paramref name="rollbackRuleAttribute"/>.
|
||||
/// </returns>
|
||||
public bool Equals( RollbackRuleAttribute rollbackRuleAttribute )
|
||||
{
|
||||
return ExceptionName.Equals(rollbackRuleAttribute.ExceptionName);
|
||||
}
|
||||
|
||||
private int getDepth( Type exceptionType, int depth )
|
||||
{
|
||||
if ( ( exceptionType.Name.IndexOf( ExceptionName ) != -1 ) || ( exceptionType.FullName.IndexOf( ExceptionName ) != -1 ) )
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
if ( exceptionType == typeof(Exception))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return getDepth( exceptionType.BaseType, depth + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Spring.Aop.Framework;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Transaction.Interceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Rule determining whether or not a given exception (and any subclasses) should
|
||||
/// cause a rollback.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Multiple such rules can be applied to determine whether a transaction should commit
|
||||
/// or rollback after an exception has been thrown.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Griffin Caprio (.NET)</author>
|
||||
[Serializable]
|
||||
public class RollbackRuleAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Could hold exception, resolving class name but would always require FQN.
|
||||
/// This way does multiple string comparisons, but how often do we decide
|
||||
/// whether to roll back a transaction following an exception?
|
||||
/// </summary>
|
||||
private string _exceptionName;
|
||||
|
||||
/// <summary>
|
||||
/// Canonical instance representing default behavior for rolling back on
|
||||
/// all <see cref="System.Exception"/>s.
|
||||
/// </summary>
|
||||
public static RollbackRuleAttribute RollbackOnSystemExceptions
|
||||
= new RollbackRuleAttribute(typeof (Exception).Name);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/> class
|
||||
/// for the named <paramref name="exceptionName"/>.
|
||||
/// </summary>
|
||||
/// <param name="exceptionName">The exception name.</param>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// As always, the <paramref name="exceptionName"/> should be the full
|
||||
/// assembly qualified version.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public RollbackRuleAttribute( string exceptionName )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(exceptionName, "exceptionName");
|
||||
_exceptionName = exceptionName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/> class
|
||||
/// for the suplied <paramref name="exceptionType"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The exception class must be <see cref="System.Exception"/> or a subclass.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This is the preferred way to construct a
|
||||
/// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/>,
|
||||
/// matching the exception class and subclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="exceptionType">
|
||||
/// The <see cref="System.Exception"/> class that will trigger a rollback.
|
||||
/// </param>
|
||||
public RollbackRuleAttribute( Type exceptionType )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(exceptionType, "exceptionType");
|
||||
if ( ! typeof(Exception).IsAssignableFrom( exceptionType ) )
|
||||
{
|
||||
throw new ArgumentException("Cannot construct rollback rule from " + exceptionType + "; " + "It's not an Exception");
|
||||
}
|
||||
_exceptionName = exceptionType.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name of the exception.
|
||||
/// </summary>
|
||||
public string ExceptionName
|
||||
{
|
||||
get { return _exceptionName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the depth to the matching superclass execption <see cref="System.Type"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A return value of 0 means that the <paramref name="exceptionType"/> matches.
|
||||
/// </remarks>
|
||||
/// <param name="exceptionType">
|
||||
/// The <see cref="System.Type"/> of exception to find.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins.
|
||||
/// </returns>
|
||||
public int GetDepth( Type exceptionType )
|
||||
{
|
||||
return getDepth( exceptionType, 0 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the depth to the matching superclass execption <see cref="System.Type"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A return value of 0 means that the <paramref name="exception"/>s
|
||||
/// <see cref="System.Type"/> matches.
|
||||
/// </remarks>
|
||||
/// <param name="exception">
|
||||
/// The exception object to find.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins.
|
||||
/// </returns>
|
||||
public int GetDepth( object exception )
|
||||
{
|
||||
return GetDepth( exception.GetType() );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> representation of this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> containing the exception covered by this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "RollbackRule with pattern '" + ExceptionName + "'";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override of <see cref="System.Object.GetHashCode"/>.
|
||||
/// </summary>
|
||||
/// <returns>The hashcode of the exception name covered by this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override of <see cref="System.Object.Equals(object)"/>.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare.</param>
|
||||
/// <returns><b>True</b> if the input object is equal to this instance.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
RollbackRuleAttribute rollbackRuleAttribute = obj as RollbackRuleAttribute;
|
||||
if ( rollbackRuleAttribute == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Equals( rollbackRuleAttribute );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strongly typed <c>Equals()</c> implementation.
|
||||
/// </summary>
|
||||
/// <param name="rollbackRuleAttribute">
|
||||
/// The <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/> to compare.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <b>True</b> if the input object is equal to the supplied <paramref name="rollbackRuleAttribute"/>.
|
||||
/// </returns>
|
||||
public bool Equals( RollbackRuleAttribute rollbackRuleAttribute )
|
||||
{
|
||||
return base.Equals(rollbackRuleAttribute);
|
||||
}
|
||||
|
||||
private int getDepth( Type exceptionType, int depth )
|
||||
{
|
||||
if ( ( exceptionType.Name.IndexOf( ExceptionName ) != -1 ) || ( exceptionType.FullName.IndexOf( ExceptionName ) != -1 ) )
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
if ( exceptionType == typeof(Exception))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return getDepth( exceptionType.BaseType, depth + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Spring.Transaction.Interceptor
|
||||
Assert.IsTrue(rr.GetDepth(typeof(TransactionSystemException)) > 0);
|
||||
}
|
||||
[Test]
|
||||
[ExpectedException(typeof(AopConfigException))]
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
public void ConstructorArgMustBeAExceptionClass()
|
||||
{
|
||||
new NoRollbackRuleAttribute( typeof( StringBuilder ) );
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Spring.Transaction.Interceptor
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof (AopConfigException))]
|
||||
[ExpectedException(typeof (ArgumentException))]
|
||||
public void ConstructorArgMustBeAExceptionClass()
|
||||
{
|
||||
new RollbackRuleAttribute(typeof (StringBuilder));
|
||||
|
||||
Reference in New Issue
Block a user