resolved SPRNET-924

fixed bug in AttributeTypeFilter wrt attribute lookup
This commit is contained in:
eeichinger
2008-11-04 16:27:42 +00:00
parent 0b3d2bbd67
commit c79c47f4ea
14 changed files with 1365 additions and 729 deletions

View File

@@ -0,0 +1,81 @@
#region License
/*
* Copyright <20> 2002-2008 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
#region Imports
using System;
using System.Collections;
using Spring.Objects.Factory;
using Spring.Util;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// The base class for AutoProxyCreator implementations that mark objects
/// eligible for proxying based on arbitrary criteria.
/// </summary>
/// <author>Erich Eichinger</author>
public abstract class AbstractFilteringAutoProxyCreator : AbstractAutoProxyCreator
{
/// <summary>
///Overridden to call <see cref="IsEligibleForProxying"/>.
/// </summary>
/// <param name="objectType">the type of the object</param>
/// <param name="objectName">the name of the object</param>
/// <returns>if remarkable to skip</returns>
protected override bool ShouldSkip( Type objectType, string objectName )
{
bool shouldSkip = !IsEligibleForProxying( objectType, objectName );
return shouldSkip;
}
/// <summary>
/// Override to always return <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>.
/// </summary>
/// <remarks>
/// Whether an object shall be proxied or not is determined by the result of <see cref="IsEligibleForProxying"/>.
/// </remarks>
/// <param name="objType">ingored</param>
/// <param name="name">ignored</param>
/// <param name="customTargetSource">ignored</param>
/// <returns>
/// Always <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/> to indicate, that the object shall be proxied.
/// </returns>
/// <seealso cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>
protected override object[] GetAdvicesAndAdvisorsForObject( Type objType, string name, ITargetSource customTargetSource )
{
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
/// <summary>
/// Decide, whether the given object is eligible for proxying.
/// </summary>
/// <remarks>
/// Override this method to allow or reject proxying for the given object.
/// </remarks>
/// <param name="objType">the object's type</param>
/// <param name="name">the name of the object</param>
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
/// <returns>whether the given object shall be proxied.</returns>
protected abstract bool IsEligibleForProxying( Type objType, string name );
}
}

View File

@@ -0,0 +1,115 @@
#region License
/*
* Copyright <20> 2002-2008 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
#region Imports
using System;
using System.Collections;
using Spring.Aop.Support;
using Spring.Util;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// An AutoProxyCreator, that identifies objects to be proxied by checking <see cref="Attribute"/>s defined on their type.
/// </summary>
/// <author>Erich Eichinger</author>
public class AttributeAutoProxyCreator : AbstractFilteringAutoProxyCreator
{
private bool _checkInherited = false;
private Type[] _attributeTypes = null;
/// <summary>
/// Indicates, whether to consider base types for filtering when checking declared attributes. Defaults to <c>false</c>.
/// </summary>
public bool CheckInherited
{
get { return _checkInherited; }
set { _checkInherited = value; }
}
/// <summary>
/// The list of attribute types marking object types as eligible for auto-proxying by this AutoProxyCreator. Must not be <c>null</c>.
/// </summary>
public Type[] AttributeTypes
{
get { return _attributeTypes; }
set
{
AssertUtils.ArgumentNotNull( value, "AttributeTypes" );
_attributeTypes = value;
}
}
/// <summary>
/// Determines, whether the given object shall be proxied by matching <paramref name="objType"/> against <see cref="AttributeTypes"/>.
/// </summary>
/// <param name="objType">the object's type</param>
/// <param name="name">the name of the object</param>
protected override bool IsEligibleForProxying( Type objType, string name )
{
AssertUtils.ArgumentNotNull(this.AttributeTypes, "AttributeTypes");
bool shallProxy = IsAnnotatedWithAnyOfAttribute( objType, this.AttributeTypes, this.CheckInherited );
return shallProxy;
}
/// <summary>
/// Checks if <paramref name="objectType"/> is annotated with any of the attributes within the given list of <paramref name="attributeTypes"/>.
/// </summary>
/// <param name="objectType">the object's type</param>
/// <param name="attributeTypes">the list of <see cref="Attribute"/> types to match agains.</param>
/// <param name="checkInherited">whether to check base classes and intefaces for any of the given attributes.</param>
/// <returns><see langword="true"/> if any of the attributes is found</returns>
protected virtual bool IsAnnotatedWithAnyOfAttribute( Type objectType, Type[] attributeTypes, bool checkInherited )
{
foreach(Type attributeType in attributeTypes)
{
if (IsAnnotatedWithAttribute(objectType, attributeType, checkInherited))
{
return true;
}
}
return false;
}
/// <summary>
/// Checks if <paramref name="objectType"/> is annotated with the specified <paramref name="attributeType"/>.
/// </summary>
/// <param name="objectType">the object's type</param>
/// <param name="attributeType">the <see cref="Attribute"/> type to match agains.</param>
/// <param name="checkInherited">whether to check base classes and intefaces for the specified attribute.</param>
/// <returns><see langword="true"/> if the attributes is found</returns>
protected virtual bool IsAnnotatedWithAttribute( Type objectType, Type attributeType, bool checkInherited )
{
if (checkInherited)
{
return AttributeUtils.FindAttribute( objectType, attributeType ) != null;
}
else
{
object[] atts = objectType.GetCustomAttributes( attributeType, false );
return ArrayUtils.HasLength( atts );
}
}
}
}

View File

@@ -30,7 +30,7 @@ using Spring.Util;
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// Object Auto Proxy Creator
/// AutoProxyCreator that identifies objects to proxy via a list of names.
/// </summary>
/// <remarks>
/// <para>
@@ -46,10 +46,16 @@ namespace Spring.Aop.Framework.AutoProxy
/// <seealso cref="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator.IsMatch"/>
/// <author>Juergen Hoeller</author>
/// <author>Adhari C Mahendra (.NET)</author>
public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator
public class ObjectNameAutoProxyCreator : AbstractFilteringAutoProxyCreator
{
private IList objectNames;
/// <summary>
/// Initializes a new instance of <see cref="ObjectNameAutoProxyCreator"/>.
/// </summary>
public ObjectNameAutoProxyCreator()
{}
/// <summary>
/// Set the names of the objects in IList fashioned way that should automatically
/// get wrapped with proxies.
@@ -62,47 +68,15 @@ namespace Spring.Aop.Framework.AutoProxy
get { return objectNames; }
}
/// <summary>
/// Determines, whether the given object shall be proxied.
/// </summary>
/// <returns>
/// <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/> if the object shall be proxied.<br/>
/// <see cref="AbstractAutoProxyCreator.DO_NOT_PROXY"/> otherwise.
/// </returns>
protected override object[] GetAdvicesAndAdvisorsForObject( Type objType, string name, ITargetSource customTargetSource )
{
if (ShallProxy( objType, name, customTargetSource ))
{
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
return DO_NOT_PROXY;
}
/// <summary>
/// Identify as object to proxy if the object name is in the configured list of names.
/// </summary>
protected virtual bool ShallProxy( Type objType, string name, ITargetSource customTargetSource )
protected override bool IsEligibleForProxying( Type objType, string name )
{
if (objectNames != null)
{
for (int i = 0; i < objectNames.Count; i++)
{
string mappedName = String.Copy( (string)objectNames[i] );
if (typeof( IFactoryObject ).IsAssignableFrom( objType ))
{
if (!name.StartsWith( ObjectFactoryUtils.FactoryObjectPrefix ))
{
continue;
}
mappedName = mappedName.Substring( ObjectFactoryUtils.FactoryObjectPrefix.Length );
}
if (IsMatch( name, mappedName ))
{
return true;
}
}
}
return false;
AssertUtils.ArgumentNotNull(this.ObjectNames, "ObjectNames");
bool shallProxy = PatternMatchUtils.IsObjectNameMatch(objType, name, this.ObjectNames, new PatternMatchUtils.ObjectNameMatchPredicate(IsMatch), ObjectFactoryUtils.FactoryObjectPrefix);
return shallProxy;
}
/// <summary>

View File

@@ -34,7 +34,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// be further restricted by specifying object name patterns like with <see cref="ObjectNameAutoProxyCreator"/>.
/// </summary>
/// <author>Erich Eichinger</author>
public class PointcutFilteringAutoProxyCreator : ObjectNameAutoProxyCreator
public class PointcutFilteringAutoProxyCreator : AbstractFilteringAutoProxyCreator
{
private IPointcut _pointcut;
@@ -44,34 +44,18 @@ namespace Spring.Aop.Framework.AutoProxy
public IPointcut Pointcut
{
set { _pointcut = value; }
get { return _pointcut; }
}
/// <summary>
/// Determines, whether the given object shall be proxied.
/// </summary>
protected override bool ShallProxy( Type objType, string name, ITargetSource customTargetSource )
protected override bool IsEligibleForProxying( Type objType, string name )
{
if (CollectionUtils.IsEmpty( ObjectNames ) && _pointcut == null)
{
throw new ArgumentException("At least one of ObjectNames and Pointcut criteria are required");
}
AssertUtils.ArgumentNotNull(_pointcut, "Pointcut");
bool isObjectNameMatch = base.ShallProxy( objType, name, customTargetSource );
// we have a name match, but empty pointcut -> ok
if (isObjectNameMatch && _pointcut==null)
{
return true;
}
// positive name match or no names specified -> get the pointcut match
if ( (isObjectNameMatch || CollectionUtils.IsEmpty(ObjectNames) )
&& _pointcut != null)
{
return AopUtils.CanApply( _pointcut, objType, null );
}
return false;
bool shallProxy = AopUtils.CanApply( _pointcut, objType, null );
return shallProxy;
}
}
}

View File

@@ -0,0 +1,70 @@
#region License
/*
* Copyright <20> 2002-2008 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
#region Imports
using System;
using Spring.Aop.Support;
using Spring.Util;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// AutoProxyCreator, that identifies objects to proxy by matching their <see cref="Type.FullName"/> against a list of patterns.
/// </summary>
/// <author>Erich Eichinger</author>
public class TypeNameAutoProxyCreator : AbstractFilteringAutoProxyCreator
{
private TypeNameTypeFilter _typeNameFilter = null;
///<summary>
/// The list of patterns to match <see cref="Type.FullName"/> against. For pattern syntax, see <see cref="TypeNameTypeFilter"/>
///</summary>
public string[] TypeNames
{
get { return _typeNameFilter.TypeNamePatterns; }
set
{
AssertUtils.ArgumentNotNull(value, "TypeNames");
_typeNameFilter = new TypeNameTypeFilter(value);
}
}
/// <summary>
/// Decide, whether the given object is eligible for proxying.
/// </summary>
/// <remarks>
/// Override this method to allow or reject proxying for the given object.
/// </remarks>
/// <param name="objType">the object's type</param>
/// <param name="name">the name of the object</param>
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
/// <returns>whether the given object shall be proxied.</returns>
protected override bool IsEligibleForProxying(Type objType, string name)
{
AssertUtils.ArgumentNotNull(_typeNameFilter, "TypeNames");
bool shallProxy = _typeNameFilter.Matches(objType);
return shallProxy;
}
}
}

View File

@@ -31,9 +31,24 @@ namespace Spring.Aop.Support
public class AttributeTypeFilter : ITypeFilter
{
private readonly Type attributeType;
private readonly bool checkInherited;
/// <summary>
/// The attribute <see cref="Type"/> for this filter.
/// </summary>
public Type AttributeType
{
get { return attributeType; }
}
/// <summary>
/// Indicates, whether this filter considers base types for filtering.
/// </summary>
public bool CheckInherited
{
get { return checkInherited; }
}
/// <summary>
/// Initializes a new instance of the <see cref="AttributeTypeFilter"/> class for the
/// given attribute type.
@@ -80,9 +95,11 @@ namespace Spring.Aop.Support
if (checkInherited)
{
return AttributeUtils.FindAttribute(type, attributeType) != null;
} else
}
else
{
return Attribute.GetCustomAttributes(type, attributeType, false) != null;
object[] atts = type.GetCustomAttributes(attributeType, false);
return ArrayUtils.HasLength(atts);
}
}

View File

@@ -0,0 +1,75 @@
#region License
/*
* Copyright <20> 2002-2008 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
#region Imports
using System;
using Spring.Util;
#endregion
namespace Spring.Aop.Support
{
/// <summary>
/// Simple <see cref="Spring.Aop.ITypeFilter"/> implementation that matches
/// a given <see cref="Type"/>'s <see cref="Type.FullName"/> against <see cref="TypeNamePatterns"/>.
/// For a list of supported pattern syntax see <see cref="PatternMatchUtils.SimpleMatch(string[],string)"/>.
/// </summary>
/// <author>Erich Eichinger</author>
/// <seealso cref="PatternMatchUtils.SimpleMatch(string[],string)"/>
public class TypeNameTypeFilter : ITypeFilter
{
private string[] _typeNamePatterns;
///<summary>
/// Returns the list of type name patterns for this filter.
///</summary>
/// <seealso cref="PatternMatchUtils.SimpleMatch(string[],string)"/>
public string[] TypeNamePatterns
{
get { return _typeNamePatterns; }
}
///<summary>
///Creates a new instance of <see cref="TypeNameTypeFilter"/> using a list of given <paramref name="patterns"/>.
///</summary>
///<param name="patterns">the list patterns to match typenames against. Must not be <c>null</c>.</param>
/// <seealso cref="PatternMatchUtils.SimpleMatch(string[],string)"/>
public TypeNameTypeFilter(string[] patterns)
{
AssertUtils.ArgumentNotNull(patterns, "patterns");
_typeNamePatterns = patterns;
}
/// <summary>
/// Does the supplied type's <see cref="Type.FullName"/> match any of the <see cref="TypeNamePatterns"/>?
/// </summary>
/// <param name="type">
/// The candidate <see cref="System.Type"/>.
/// </param>
/// <returns>
/// <see langword="true"/> if the <paramref name="type"/> matches any of the <see cref="TypeNamePatterns"/>.
/// </returns>
public bool Matches(Type type)
{
return PatternMatchUtils.SimpleMatch(_typeNamePatterns, type.FullName);
}
}
}

View File

@@ -136,8 +136,11 @@
<Compile Include="Aop\Config\AopNamespaceUtils.cs" />
<Compile Include="Aop\Config\ConfigObjectDefinitionParser.cs" />
<Compile Include="Aop\Framework\AopUtils.cs" />
<Compile Include="Aop\Framework\AutoProxy\AbstractFilteringAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\AutoProxy\AttributeAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\AutoProxy\InheritanceBasedAopConfigurer.cs" />
<Compile Include="Aop\Framework\AutoProxy\PointcutFilteringAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\AutoProxy\TypeNameAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\DynamicMethodInvocation.cs" />
<Compile Include="Aop\Framework\DynamicProxy\CachedAopProxyFactory.cs" />
<Compile Include="Aop\Framework\DynamicProxy\DefaultAopProxyFactory.cs" />
@@ -359,6 +362,7 @@
<Compile Include="Aop\Support\TypeFilters.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Aop\Support\TypeNameTypeFilter.cs" />
<Compile Include="Aop\Support\UnionPointcut.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -21,8 +21,10 @@
#region Imports
using System;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using Spring.Objects.Factory;
#endregion
@@ -94,5 +96,56 @@ namespace Spring.Util
}
return false;
}
/// <summary>
/// Signature of callbacks that may be used for matching object names.
/// </summary>
/// <param name="objectName">the object name to check.</param>
/// <param name="namePattern">the pattern to match <paramref name="objectName"/> against.</param>
/// <returns>true, if the <paramref name="objectName"/> matches <paramref name="namePattern"/></returns>
/// <see cref="IsObjectNameMatch"/>
public delegate bool ObjectNameMatchPredicate(string objectName, string namePattern);
/// <summary>
/// Convenience method that may be used by derived classes. Iterates over the list of <paramref name="objectNamePatterns"/> to match <paramref name="objectName"/> against.
/// </summary>
/// <param name="objType">the object's type. Must not be <c>null</c>.</param>
/// <param name="objectName">the name of the object Must not be <c>null</c>.</param>
/// <param name="objectNamePatterns">the list of patterns, that <paramref name="objectName"/> shall be matched against. Must not be <c>null</c>.</param>
/// <param name="isMatchPredicate">
/// the <see cref="ObjectNameMatchPredicate"/> used for
/// matching <paramref name="objectName"/> against each pattern in <paramref name="objectNamePatterns"/>. Must not be <c>null</c>.
/// </param>
/// <param name="factoryObjectPrefix">the prefix to be used for dereferencing factory object names.</param>
/// <returns>
/// If <paramref name="objectNamePatterns"/> is <c>null</c>, will always return <c>true</c>, otherwise
/// if <paramref name="objectName"/> matches any of the patterns specified in <paramref name="objectNamePatterns"/>.
/// </returns>
public static bool IsObjectNameMatch(Type objType, string objectName, IList objectNamePatterns, ObjectNameMatchPredicate isMatchPredicate, string factoryObjectPrefix)
{
AssertUtils.ArgumentNotNull(objType, "objType");
AssertUtils.ArgumentNotNull(objectName, "objectName");
AssertUtils.ArgumentNotNull(objectNamePatterns, "objectNamePatterns");
AssertUtils.ArgumentNotNull(isMatchPredicate, "isMatchPredicate");
AssertUtils.ArgumentNotNull(factoryObjectPrefix, "factoryObjectPrefix");
for (int i = 0; i < objectNamePatterns.Count; i++)
{
string mappedName = (string)objectNamePatterns[i];
if (typeof( IFactoryObject ).IsAssignableFrom( objType ))
{
if (!objectName.StartsWith( factoryObjectPrefix ))
{
continue;
}
mappedName = mappedName.Substring( factoryObjectPrefix.Length );
}
if (isMatchPredicate( objectName, mappedName ))
{
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,150 @@
#region License
/*
* Copyright <20> 2002-2008 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
#region Imports
using System;
using NUnit.Framework;
using Spring.Objects;
using Spring.Stereotype;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
///
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class AttributeAutoProxyCreatorTests
{
public interface IEmptyInterface
{}
[AttributeUsage( AttributeTargets.Class|AttributeTargets.Method, Inherited=false )]
private class ApcTestAttribute : Attribute {}
private class ApcTestObject: IEmptyInterface {}
[ApcTest]
private class AttributedApcTestObject : ApcTestObject
{}
private class DerivedAttributedApcTestObject : AttributedApcTestObject
{
[ApcTest]
public void SomeMethod() {}
}
[Test]
[ExpectedException( typeof( ArgumentNullException ) )]
public void ThrowsOnMissingAttributeTypeList()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.PostProcessAfterInitialization( new ApcTestObject(), "testObject" );
}
[Test]
[ExpectedException( typeof( ArgumentNullException ) )]
public void ThrowsOnAssigningNullAttributeList()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = null;
}
[Test]
public void AllowsEmptyAttributeList()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[0];
apc.PostProcessAfterInitialization( new ApcTestObject(), "testObject" );
}
[Test]
public void DefaultsToNotCheckInherited()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
Assert.IsFalse(apc.CheckInherited);
}
[Test]
public void CreatesProxyOnAttributeMatch()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[] { typeof(ApcTestAttribute) };
object result = apc.PostProcessAfterInitialization( new AttributedApcTestObject(), "testObject" );
Assert.IsTrue( AopUtils.IsAopProxy( result ) );
}
[Test]
public void CreatesProxyOnInheritedAttributeMatchWhenCheckInherited()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[] { typeof(ApcTestAttribute) };
apc.CheckInherited = true;
object result = apc.PostProcessAfterInitialization( new DerivedAttributedApcTestObject(), "testObject" );
Assert.IsTrue( AopUtils.IsAopProxy( result ) );
}
[Test]
public void DoesNotCreateProxyOnInheritedAttributeMatchWhenNotCheckInherited()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[] { typeof(ApcTestAttribute) };
apc.CheckInherited = false;
object result = apc.PostProcessAfterInitialization( new DerivedAttributedApcTestObject(), "testObject" );
Assert.IsFalse( AopUtils.IsAopProxy( result ) );
}
[Test]
public void DoesNotCreateProxyIfNoAttributeMatch()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[] { typeof(ApcTestAttribute) };
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsFalse( AopUtils.IsAopProxy( result ) );
}
[Test]
public void DoesNotCheckMethodLevelAttributes()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[] { typeof(ApcTestAttribute) };
apc.CheckInherited = false; // (!)
// does not check method level attributes!
object result = apc.PostProcessAfterInitialization( new DerivedAttributedApcTestObject(), "testObject" );
Assert.IsFalse( AopUtils.IsAopProxy( result ) );
}
[Test]
public void DoesNotCreateProxyIfEmptyAtributeList()
{
AttributeAutoProxyCreator apc = new AttributeAutoProxyCreator();
apc.AttributeTypes = new Type[0];
object result = apc.PostProcessAfterInitialization( new ApcTestObject(), "testObject" );
Assert.IsFalse( AopUtils.IsAopProxy( result ) );
}
}
}

View File

@@ -36,58 +36,30 @@ namespace Spring.Aop.Framework.AutoProxy
[TestFixture]
public class PointcutFilteringAutoProxyCreatorTests
{
[Test]
public void CreatesProxyOnlyIfPointcutAndObjectNameMatch()
{
// is match
PointcutFilteringAutoProxyCreator apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = new string[] { "test*" } ;;
apc.Pointcut = new SdkRegularExpressionMethodPointcut(".*\\.GetHashCode");
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsTrue(AopUtils.IsAopProxy(result));
apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = new string[] { "test*" } ;;
apc.Pointcut = new SdkRegularExpressionMethodPointcut(".*\\.GetHashCODE");
result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsFalse(AopUtils.IsAopProxy(result));
apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = new string[] { "tesT*" } ;;
apc.Pointcut = new SdkRegularExpressionMethodPointcut(".*\\.GetHashCode");
result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsFalse(AopUtils.IsAopProxy(result));
}
[Test]
public void CreatesProxyOnPointcutMatch()
{
PointcutFilteringAutoProxyCreator apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = null;
apc.Pointcut = new SdkRegularExpressionMethodPointcut(".*\\.GetHashCode");
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsTrue(AopUtils.IsAopProxy(result));
}
[Test]
public void CreatesProxyOnNameMatch()
public void DoesNotCreateProxyIfNoPointcutMatch()
{
PointcutFilteringAutoProxyCreator apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = new string[] { "test*" } ;
apc.Pointcut = null;
apc.Pointcut = new SdkRegularExpressionMethodPointcut(".*\\.DOEsNOTExist");
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsTrue(AopUtils.IsAopProxy(result));
Assert.IsFalse(AopUtils.IsAopProxy(result));
}
[Test]
[ExpectedException(typeof(ArgumentException))]
[ExpectedException(typeof(ArgumentNullException))]
public void ThrowsArgumentExceptionIfNoCriteriaSpecified()
{
PointcutFilteringAutoProxyCreator apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = new string[] {} ;
apc.Pointcut = null;
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsTrue(AopUtils.IsAopProxy(result));
apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
}
}
}

View File

@@ -0,0 +1,98 @@
#region License
/*
* Copyright <20> 2002-2008 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
#region Imports
using System;
using NUnit.Framework;
using Spring.Objects;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
///
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class TypeNameAutoProxyCreatorTests
{
private class MyLocalTestObject: TestObject
{}
[Test]
[ExpectedException( typeof( ArgumentNullException ) )]
public void ThrowsOnMissingTypeNames()
{
TypeNameAutoProxyCreator apc = new TypeNameAutoProxyCreator();
apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
}
[Test]
[ExpectedException( typeof( ArgumentNullException ) )]
public void ThrowsOnAssigningNullTypeNames()
{
TypeNameAutoProxyCreator apc = new TypeNameAutoProxyCreator();
apc.TypeNames = null;
}
[Test]
public void AllowsEmptyTypeNameList()
{
TypeNameAutoProxyCreator apc = new TypeNameAutoProxyCreator();
apc.TypeNames = new string[] {};
apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
}
[Test]
public void CreatesProxyOnTypeNameMatch()
{
TypeNameAutoProxyCreator apc = new TypeNameAutoProxyCreator();
apc.TypeNames = new string[] { "Spring.Objects.Test*", "*MyLocal*" };
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsTrue( AopUtils.IsAopProxy( result ) );
result = apc.PostProcessAfterInitialization( new MyLocalTestObject(), "myLocalTestObject" );
Assert.IsTrue( AopUtils.IsAopProxy( result ) );
}
[Test]
public void DoesNotCreateProxyIfNoTypeNameMatch()
{
TypeNameAutoProxyCreator apc = new TypeNameAutoProxyCreator();
apc.TypeNames = new string[] { "Foo*" };
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsFalse( AopUtils.IsAopProxy( result ) );
}
[Test]
public void DoesNotCreateProxyIfEmptyTypeNameList()
{
TypeNameAutoProxyCreator apc = new TypeNameAutoProxyCreator();
apc.TypeNames = new string[] {};
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsFalse( AopUtils.IsAopProxy( result ) );
}
}
}

View File

@@ -125,6 +125,7 @@
</Compile>
<Compile Include="Aop\Framework\AutoProxy\AdvisorAutoProxyCreatorCircularReferencesTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\AdvisorAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\AttributeAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\LogicalThreadContextAdvice.cs" />
<Compile Include="Aop\Framework\AutoProxy\NoSetterProperties.cs" />
<Compile Include="Aop\Framework\AutoProxy\ObjectNameAutoProxyCreatorTests.cs" />
@@ -132,6 +133,7 @@
<Compile Include="Aop\Framework\AbstractMethodInvocationTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\CreatesTestObject.cs" />
<Compile Include="Aop\Framework\AutoProxy\PointcutFilteringAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\TypeNameAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\DynamicMethodInvocationTests.cs" />
<Compile Include="Aop\Framework\CountingAfterReturningAdvice.cs" />
<Compile Include="Aop\Framework\CountingBeforeAdvice.cs">