diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InfrastructureAdvisorAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InfrastructureAdvisorAutoProxyCreator.cs new file mode 100644 index 00000000..4cd266fc --- /dev/null +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InfrastructureAdvisorAutoProxyCreator.cs @@ -0,0 +1,45 @@ +#region License + +/* + * Copyright 2002-2009 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.Objects.Factory.Config; + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// + /// Erich Eichinger + internal class InfrastructureAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator + { + private IConfigurableListableObjectFactory _objectFactory; + + protected override void InitObjectFactory(IConfigurableListableObjectFactory objectFactory) + { + base.InitObjectFactory(objectFactory); + _objectFactory = objectFactory; + } + + protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName) + { + return _objectFactory.ContainsObjectDefinition(advisorName) + && _objectFactory.GetObjectDefinition(advisorName).Role == ObjectRole.ROLE_INFRASTRUCTURE; + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectFactoryAdvisorRetrievalHelper.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectFactoryAdvisorRetrievalHelper.cs new file mode 100644 index 00000000..ea81b381 --- /dev/null +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectFactoryAdvisorRetrievalHelper.cs @@ -0,0 +1,162 @@ +#region License + +/* + * Copyright 2002-2009 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 System.Collections; +using Common.Logging; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Util; + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// Helper for retrieving standard Spring advisors from an for + /// use with auto-proxying. + /// + /// Erich Eichinger + public class ObjectFactoryAdvisorRetrievalHelper + { + private readonly ILog _log; + private readonly IConfigurableListableObjectFactory _owningFactory; + private string[] _cachedObjectNames; + + /// + /// Create a new helper for the specified . + /// + public ObjectFactoryAdvisorRetrievalHelper(IConfigurableListableObjectFactory owningFactory ) + { + AssertUtils.ArgumentNotNull(owningFactory, "owningFactory"); + _log = LogManager.GetLogger(this.GetType()); + _owningFactory = owningFactory; + } + + /// + /// Find all all eligible advisor objects in the current object factory. + /// + /// the type of the object to be advised + /// the name of the object to be advised + /// A list of eligible instances + public virtual IList FindAdvisorObjects(Type targetType, string targetName) + { + string[] advisorNames = GetAdvisorCandidateNames(targetType, targetName); + + ArrayList advisors = new ArrayList(); + + if (advisorNames.Length == 0) + { + return advisors; + } + + for (int i = 0; i < advisorNames.Length; i++) + { + string name = advisorNames[i]; + if (IsEligibleObject(name, targetType, targetName) && !_owningFactory.IsCurrentlyInCreation(name)) + { + try + { + AddAdvisorCandidate(advisors, name); + } + catch (ObjectCreationException ex) + { + Exception rootEx = ex.GetBaseException(); + if (rootEx is ObjectCurrentlyInCreationException) + { + ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException)rootEx; + if (_owningFactory.IsCurrentlyInCreation(oce.ObjectName)) + { + if (_log.IsDebugEnabled) + { + _log.Debug(string.Format("Ignoring currently created advisor '{0}': exception message = {1}", + name, ex.Message)); + } + continue; + } + } + throw; + } + } + } + + return advisors; + } + + /// + /// Add the named advisor instance to the list of advisors. + /// + /// the advisor list + /// the object name of the advisor to add + private void AddAdvisorCandidate(ArrayList advisors, string advisorName) + { + object advisorCandidate = _owningFactory.GetObject(advisorName); + if (advisorCandidate is IAdvisor) + { + advisors.Add(advisorCandidate); + } + else if (advisorCandidate is IAdvisors) + { + advisors.AddRange(((IAdvisors)advisorCandidate).Advisors); + } + else + { + throw new InvalidOperationException("expected type IAdvisor or IAdvisors but was " + + advisorCandidate.GetType().FullName); + } + } + + /// + /// Gets the names of advisor candidates + /// + /// the type of the object to be advised + /// the name of the object to be advised + /// a non-null string array of advisor candidate names + protected virtual string[] GetAdvisorCandidateNames(Type targetType, string targetName) + { + if (_cachedObjectNames == null) + { + lock(this) + { + if (_cachedObjectNames == null) + { + ArrayList candidateNameList = new ArrayList(); + string[] advisorCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( _owningFactory, typeof(IAdvisor), true, false); + candidateNameList.AddRange(advisorCandidateNames); + string[] advisorsCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_owningFactory, typeof(IAdvisors), true, false); + candidateNameList.AddRange(advisorsCandidateNames); + _cachedObjectNames = (string[]) candidateNameList.ToArray(typeof(string)); + } + } + } + return _cachedObjectNames; + } + + /// + /// Determine, whether the specified aspect object is eligible. + /// The default implementation always returns true. + /// + /// the name of the candidate advisor + /// the type of the object to be advised + /// the name of the object to be advised + protected virtual bool IsEligibleObject(string advisorName, Type objectType, string objectName ) + { + return true; + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectRole.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectRole.cs new file mode 100644 index 00000000..80066877 --- /dev/null +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectRole.cs @@ -0,0 +1,54 @@ +#region License + +/* + * Copyright 2002-2009 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; + +namespace Spring.Objects.Factory.Config +{ + /// + /// + /// Erich Eichinger + public enum ObjectRole + { + // TODO (EE): ComponentDefinitions are part of Spring/J 2.5 + + /// + /// Role hint indicating that a is a major part of the application. Typically corresponds to a user-defined bean. + /// + ROLE_APPLICATION = 0, + + /// + /// Role hint indicating that a is a supporting + /// part of some larger configuration, typically an outer ComponentDefinition + /// SUPPORT objects are considered important enough to be aware + /// of when looking more closely at a particular ComponentDefinition, + /// but not when looking at the overall configuration of an application. + /// + ROLE_SUPPORT = 1, + + /// + /// Role hint indicating that a is providing an + /// entirely background role and has no relevance to the end-user. This hint is + /// used when registering objects that are completely part of the internal workings + /// of a ComponentDefinition. + /// + ROLE_INFRASTRUCTURE = 2 + } +} \ No newline at end of file