From ed1c1216ccf2297cf1ca97710e73fe4f7512c450 Mon Sep 17 00:00:00 2001 From: eeichinger Date: Sat, 18 Oct 2008 22:29:16 +0000 Subject: [PATCH] sprnet-924 --- .../AutoProxy/AbstractAutoProxyCreator.cs | 2 +- .../AutoProxy/ObjectNameAutoProxyCreator.cs | 206 ++++++++++-------- .../PointcutFilteringAutoProxyCreator.cs | 77 +++++++ src/Spring/Spring.Aop/Spring.Aop.2008.csproj | 3 +- .../PointcutFilteringAutoProxyCreatorTests.cs | 93 ++++++++ .../Spring.Aop.Tests.2008.csproj | 3 +- 6 files changed, 285 insertions(+), 99 deletions(-) create mode 100644 src/Spring/Spring.Aop/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreator.cs create mode 100644 test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreatorTests.cs diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs index 2751b8d1..ed1be482 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs @@ -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. /// /// the type of the object /// the name of the object diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs index 18e00496..5d63b4b9 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs @@ -1,5 +1,5 @@ -#region License - +#region License + /* * Copyright © 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 -{ - /// - /// Object Auto Proxy Creator - /// - /// - /// - /// Auto proxy creator that identifies objects to proxy via a list of names. - /// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches. - /// - /// 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 "&" e.g. "&MyFactoryObject". - /// - /// - /// - /// Juergen Hoeller - /// Adhari C Mahendra (.NET) - public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator - { - private IList objectNames; - - /// - /// 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". - /// - public IList ObjectNames - { - set { objectNames = value; } - } - - /// - /// Identify as object to proxy if the object name is in the configured list of names. - /// - 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; - - } - - /// - /// Return if the given object name matches the mapped name. - /// - /// - ///

- /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, - /// as well as direct equality. Can be overridden in subclasses. - ///

- ///
- /// the object name to check - /// the name in the configured list of names - /// if the names match - 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 +{ + /// + /// Object Auto Proxy Creator + /// + /// + /// + /// Auto proxy creator that identifies objects to proxy via a list of names. + /// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches. + /// + /// 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 "&" e.g. "&MyFactoryObject". + /// + /// + /// + /// Juergen Hoeller + /// Adhari C Mahendra (.NET) + public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator + { + private IList objectNames; + + /// + /// 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". + /// + public IList ObjectNames + { + set { objectNames = value; } + get { return objectNames; } + } + + /// + /// Determines, whether the given object shall be proxied. + /// + /// + /// if the object shall be proxied.
+ /// otherwise. + ///
+ protected override object[] GetAdvicesAndAdvisorsForObject( Type objType, string name, ITargetSource customTargetSource ) + { + if (ShallProxy( objType, name, customTargetSource )) + { + return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS; + } + return DO_NOT_PROXY; + } + + /// + /// Identify as object to proxy if the object name is in the configured list of names. + /// + 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; + } + + /// + /// Return if the given object name matches the mapped name. + /// + /// + ///

+ /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, + /// as well as direct equality. Can be overridden in subclasses. + ///

+ ///
+ /// the object name to check + /// the name in the configured list of names + /// if the names match + protected virtual bool IsMatch( string objectName, string mappedName ) + { + return PatternMatchUtils.SimpleMatch( mappedName, objectName ); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreator.cs new file mode 100644 index 00000000..18b09d7a --- /dev/null +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreator.cs @@ -0,0 +1,77 @@ +#region License + +/* + * Copyright © 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 +{ + /// + /// This AutoProxyCreator only proxies objects matching the specified . Additionally, proxy creation may + /// be further restricted by specifying object name patterns like with . + /// + /// Erich Eichinger + public class PointcutFilteringAutoProxyCreator : ObjectNameAutoProxyCreator + { + private IPointcut _pointcut; + + /// + /// Set the pointcut used to filter objects that should automatically get wrapped with proxies. + /// + public IPointcut Pointcut + { + set { _pointcut = value; } + } + + /// + /// Determines, whether the given object shall be proxied. + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Spring.Aop.2008.csproj b/src/Spring/Spring.Aop/Spring.Aop.2008.csproj index 224a1ce9..57c87c8c 100644 --- a/src/Spring/Spring.Aop/Spring.Aop.2008.csproj +++ b/src/Spring/Spring.Aop/Spring.Aop.2008.csproj @@ -1,7 +1,7 @@  Local - 9.0.21022 + 9.0.30729 2.0 {3A3A4E65-45A6-4B20-B460-0BEDC302C02C} Debug @@ -137,6 +137,7 @@ + diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreatorTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreatorTests.cs new file mode 100644 index 00000000..549d3ec8 --- /dev/null +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/PointcutFilteringAutoProxyCreatorTests.cs @@ -0,0 +1,93 @@ +#region License + +/* + * Copyright © 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 +{ + /// + /// + /// + /// Erich Eichinger + [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)); + } + } +} \ No newline at end of file diff --git a/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2008.csproj b/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2008.csproj index 939054a5..10e9d433 100644 --- a/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2008.csproj +++ b/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2008.csproj @@ -1,7 +1,7 @@  Local - 9.0.21022 + 9.0.30729 2.0 {2111596A-0327-4C9D-8919-294FBD988A23} Debug @@ -131,6 +131,7 @@ +