sprnet-924

This commit is contained in:
eeichinger
2008-10-18 22:29:16 +00:00
parent ef64f08844
commit ed1c1216cc
6 changed files with 285 additions and 99 deletions

View File

@@ -340,7 +340,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// Subclasses should override this method to return true if this
/// object should not be considered for autoproxying by this post processor.
/// Sometimes we need to be able to avoid this happening if it will lead to
/// a circular reference. This implementation returns true.
/// a circular reference. This implementation returns false.
/// </summary>
/// <param name="objectType">the type of the object</param>
/// <param name="objectName">the name of the object</param>

View File

@@ -1,5 +1,5 @@
#region License
#region License
/*
* Copyright <20> 2002-2005 the original author or authors.
*
@@ -14,98 +14,112 @@
* 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>
/// Object Auto Proxy Creator
/// </summary>
/// <remarks>
/// <para>
/// Auto proxy creator that identifies objects to proxy via a list of names.
/// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches.
/// </para>
/// <para>In case of a IFactoryObject, only the objects created by the
/// FactoryBean will get proxied. If you intend to proxy a IFactoryObject instance itself
/// specify the object name of the IFactoryObject including
/// the factory-object prefix "&amp;" e.g. "&amp;MyFactoryObject".
/// </para>
/// </remarks>
/// <seealso cref="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator.IsMatch"/>
/// <author>Juergen Hoeller</author>
/// <author>Adhari C Mahendra (.NET)</author>
public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator
{
private IList objectNames;
/// <summary>
/// Set the names of the objects in IList fashioned way that should automatically
/// get wrapped with proxies.
/// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
/// will match the object named "myObject" and all objects whose name start with "tx".
/// </summary>
public IList ObjectNames
{
set { objectNames = value; }
}
/// <summary>
/// Identify as object to proxy if the object name is in the configured list of names.
/// </summary>
protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource)
{
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 PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
}
}
return DO_NOT_PROXY;
}
/// <summary>
/// Return if the given object name matches the mapped name.
/// </summary>
/// <remarks>
/// <p>
/// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
/// as well as direct equality. Can be overridden in subclasses.
/// </p>
/// </remarks>
/// <param name="objectName">the object name to check</param>
/// <param name="mappedName">the name in the configured list of names</param>
/// <returns>if the names match</returns>
protected virtual bool IsMatch(string objectName, string mappedName)
{
return PatternMatchUtils.SimpleMatch(mappedName, objectName);
}
}
*/
#endregion
#region Imports
using System;
using System.Collections;
using Spring.Objects.Factory;
using Spring.Util;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// Object Auto Proxy Creator
/// </summary>
/// <remarks>
/// <para>
/// Auto proxy creator that identifies objects to proxy via a list of names.
/// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches.
/// </para>
/// <para>In case of a IFactoryObject, only the objects created by the
/// FactoryBean will get proxied. If you intend to proxy a IFactoryObject instance itself
/// specify the object name of the IFactoryObject including
/// the factory-object prefix "&amp;" e.g. "&amp;MyFactoryObject".
/// </para>
/// </remarks>
/// <seealso cref="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator.IsMatch"/>
/// <author>Juergen Hoeller</author>
/// <author>Adhari C Mahendra (.NET)</author>
public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator
{
private IList objectNames;
/// <summary>
/// Set the names of the objects in IList fashioned way that should automatically
/// get wrapped with proxies.
/// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
/// will match the object named "myObject" and all objects whose name start with "tx".
/// </summary>
public IList ObjectNames
{
set { objectNames = value; }
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 )
{
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;
}
/// <summary>
/// Return if the given object name matches the mapped name.
/// </summary>
/// <remarks>
/// <p>
/// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
/// as well as direct equality. Can be overridden in subclasses.
/// </p>
/// </remarks>
/// <param name="objectName">the object name to check</param>
/// <param name="mappedName">the name in the configured list of names</param>
/// <returns>if the names match</returns>
protected virtual bool IsMatch( string objectName, string mappedName )
{
return PatternMatchUtils.SimpleMatch( mappedName, objectName );
}
}
}

View File

@@ -0,0 +1,77 @@
#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>
/// This AutoProxyCreator only proxies objects matching the specified <see cref="IPointcut"/>. Additionally, proxy creation may
/// be further restricted by specifying object name patterns like with <see cref="ObjectNameAutoProxyCreator"/>.
/// </summary>
/// <author>Erich Eichinger</author>
public class PointcutFilteringAutoProxyCreator : ObjectNameAutoProxyCreator
{
private IPointcut _pointcut;
/// <summary>
/// Set the pointcut used to filter objects that should automatically get wrapped with proxies.
/// </summary>
public IPointcut Pointcut
{
set { _pointcut = value; }
}
/// <summary>
/// Determines, whether the given object shall be proxied.
/// </summary>
protected override bool ShallProxy( Type objType, string name, ITargetSource customTargetSource )
{
if (CollectionUtils.IsEmpty( ObjectNames ) && _pointcut == null)
{
throw new ArgumentException("At least one of ObjectNames and Pointcut criteria are required");
}
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;
}
}
}

View File

@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -137,6 +137,7 @@
<Compile Include="Aop\Config\ConfigObjectDefinitionParser.cs" />
<Compile Include="Aop\Framework\AopUtils.cs" />
<Compile Include="Aop\Framework\AutoProxy\InheritanceBasedAopConfigurer.cs" />
<Compile Include="Aop\Framework\AutoProxy\PointcutFilteringAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\DynamicMethodInvocation.cs" />
<Compile Include="Aop\Framework\DynamicProxy\CachedAopProxyFactory.cs" />
<Compile Include="Aop\Framework\DynamicProxy\DefaultAopProxyFactory.cs" />

View File

@@ -0,0 +1,93 @@
#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.Aop.Support;
using Spring.Objects;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
///
/// </summary>
/// <author>Erich Eichinger</author>
[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()
{
PointcutFilteringAutoProxyCreator apc = new PointcutFilteringAutoProxyCreator();
apc.ObjectNames = new string[] { "test*" } ;
apc.Pointcut = null;
object result = apc.PostProcessAfterInitialization( new TestObject(), "testObject" );
Assert.IsTrue(AopUtils.IsAopProxy(result));
}
[Test]
[ExpectedException(typeof(ArgumentException))]
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));
}
}
}

View File

@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2111596A-0327-4C9D-8919-294FBD988A23}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -131,6 +131,7 @@
<Compile Include="Aop\Framework\AutoProxy\OrderedLogicalThreadContextCheckAdvisor.cs" />
<Compile Include="Aop\Framework\AbstractMethodInvocationTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\CreatesTestObject.cs" />
<Compile Include="Aop\Framework\AutoProxy\PointcutFilteringAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\DynamicMethodInvocationTests.cs" />
<Compile Include="Aop\Framework\CountingAfterReturningAdvice.cs" />
<Compile Include="Aop\Framework\CountingBeforeAdvice.cs">