Ejemplo n.º 1
0
        /// <summary>
        /// Add an attribute for a transactional method.
        /// </summary>
        /// <remarks>
        /// Method names can end or start with "*" for matching multiple methods.
        /// </remarks>
        /// <param name="name">The class and method name, separated by a dot.</param>
        /// <param name="attribute">The attribute to be associated with the method.</param>
        public void AddTransactionalMethod(string name, ITransactionAttribute attribute)
        {
            AssertUtils.ArgumentNotNull(name, "name");
            int lastCommaIndex = name.LastIndexOf(",");

            if (lastCommaIndex == -1)
            {
                throw new ArgumentException("'" + name + "'" +
                                            " is not a valid method name, missing AssemblyName.  Format is FQN.MethodName, AssemblyName.");
            }
            string fqnWithMethod = name.Substring(0, lastCommaIndex);

            int lastDotIndex = fqnWithMethod.LastIndexOf(".");

            if (lastDotIndex == -1)
            {
                throw new TransactionUsageException("'" + fqnWithMethod + "' is not a valid method name: format is FQN.methodName");
            }
            string className    = fqnWithMethod.Substring(0, lastDotIndex);
            string assemblyName = name.Substring(lastCommaIndex + 1);
            string methodName   = fqnWithMethod.Substring(lastDotIndex + 1);
            string fqnClassName = className + ", " + assemblyName;

            try
            {
                Type type = TypeResolutionUtils.ResolveType(fqnClassName);
                AddTransactionalMethod(type, methodName, attribute);
            } catch (TypeLoadException exception)
            {
                throw new TransactionUsageException("Type '" + fqnClassName + "' not found.", exception);
            }
        }
        public void DefaultTransactionAttributeToString()
        {
            DefaultTransactionAttribute source = new DefaultTransactionAttribute( );

            source.PropagationBehavior       = TransactionPropagation.Supports;
            source.TransactionIsolationLevel = IsolationLevel.RepeatableRead;
            source.TransactionTimeout        = 10;
            source.ReadOnly = true;

            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText(source.ToString( ));
            ITransactionAttribute ta = editor.Value;

            Assert.AreEqual(source, ta);
            Assert.AreEqual(ta.PropagationBehavior, TransactionPropagation.Supports);
            Assert.AreEqual(ta.TransactionIsolationLevel, IsolationLevel.RepeatableRead);
            Assert.AreEqual(ta.TransactionTimeout, 10);
            Assert.IsTrue(ta.ReadOnly);
            Assert.IsTrue(ta.RollbackOn(new SystemException( )));
            //mlp 3/17 changed rollback to rollback on all exceptions.
            Assert.IsTrue(ta.RollbackOn(new ApplicationException( )));

            source.TransactionTimeout = 9;
            Assert.IsFalse(ta == source);
            source.TransactionTimeout = 10;
            Assert.AreEqual(ta, source);
        }
        /// <summary>
        /// Return the transaction attribute for this method invocation.
        /// </summary>
        /// <remarks>
        /// Defaults to the class's transaction attribute if no method
        /// attribute is found
        /// </remarks>
        /// <param name="method">method for the current invocation. Can't be null</param>
        /// <param name="targetType">target class for this invocation. May be null.</param>
        /// <returns><see cref="ITransactionAttribute"/> for this method, or null if the method is non-transactional</returns>
        public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType)
        {
            object cacheKey = getCacheKey(method, targetType);

            lock (_transactionAttibuteCache)
            {
                object cached = _transactionAttibuteCache[cacheKey];

                if (cached != null)
                {
                    if (NULL_TX_ATTIBUTE == cached)
                    {
                        return(null);
                    }
                    {
                        return((ITransactionAttribute)cached);
                    }
                }
                else
                {
                    ITransactionAttribute transactionAttribute = computeTransactionAttribute(method, targetType);
                    if (null == transactionAttribute)
                    {
                        _transactionAttibuteCache.Add(cacheKey, NULL_TX_ATTIBUTE);
                    }
                    else
                    {
                        _transactionAttibuteCache.Add(cacheKey, transactionAttribute);
                    }
                    return(transactionAttribute);
                }
            }
        }
        /// <summary>
        /// Return the transaction attribute, given this set of attributes
        /// attached to a method or class. Return null if it's not transactional.
        /// </summary>
        /// <remarks>
        /// Protected rather than private as subclasses may want to customize
        /// how this is done: for example, returning a
        /// <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/>
        /// affected by the values of other attributes.
        /// This implementation takes into account
        /// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/>s, if
        /// the TransactionAttribute is a RuleBasedTransactionAttribute.
        /// </remarks>
        /// <param name="attributes">
        /// Attributes attached to a method or class. May be null, in which case a null
        /// <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> will be returned.
        /// </param>
        /// <returns>
        /// The <see cref="ITransactionAttribute"/> configured transaction attribute, or null
        /// if none was found.
        /// </returns>
        protected virtual ITransactionAttribute FindTransactionAttribute(Attribute[] attributes)
        {
            if (null == attributes)
            {
                return(null);
            }
            ITransactionAttribute transactionAttribute = null;

            foreach (Attribute currentAttribute in attributes)
            {
                transactionAttribute = currentAttribute as ITransactionAttribute;
                if (null != transactionAttribute)
                {
                    break;
                }
            }

            RuleBasedTransactionAttribute ruleBasedTransactionAttribute = transactionAttribute as RuleBasedTransactionAttribute;

            if (null != ruleBasedTransactionAttribute)
            {
                IList rollbackRules = new LinkedList();
                foreach (Attribute currentAttribute in attributes)
                {
                    RollbackRuleAttribute rollbackRuleAttribute = currentAttribute as RollbackRuleAttribute;
                    if (null != rollbackRuleAttribute)
                    {
                        rollbackRules.Add(rollbackRuleAttribute);
                    }
                }
                ruleBasedTransactionAttribute.RollbackRules = rollbackRules;
                return(ruleBasedTransactionAttribute);
            }
            return(transactionAttribute);
        }
        public void RuleBasedTransactionAttributeToString()
        {
            RuleBasedTransactionAttribute source = new RuleBasedTransactionAttribute();

            source.PropagationBehavior       = TransactionPropagation.Supports;
            source.TransactionIsolationLevel = IsolationLevel.RepeatableRead;
            source.TransactionTimeout        = 10;
            source.ReadOnly = true;
            source.AddRollbackRule(new RollbackRuleAttribute("ArgumentException"));
            source.AddRollbackRule(new NoRollbackRuleAttribute("IllegalTransactionStateException"));

            TransactionAttributeEditor editor = new TransactionAttributeEditor();

            editor.SetAsText(source.ToString());
            ITransactionAttribute ta = editor.Value;

            Assert.AreEqual(source, ta);
            Assert.AreEqual(ta.PropagationBehavior, TransactionPropagation.Supports);
            Assert.AreEqual(ta.TransactionIsolationLevel, IsolationLevel.RepeatableRead);
            Assert.AreEqual(ta.TransactionTimeout, 10);
            Assert.IsTrue(ta.ReadOnly);
            Assert.IsTrue(ta.RollbackOn(new ArgumentException()));
            Assert.IsFalse(ta.RollbackOn(new IllegalTransactionStateException()));

            source.ClearRollbackRules();
            Assert.IsFalse(ta == source);
            source.AddRollbackRule(new RollbackRuleAttribute("ArgumentException"));
            source.AddRollbackRule(new NoRollbackRuleAttribute("IllegalTransactionStateException"));
            Assert.AreEqual(ta, source);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Create a transaction if necessary
        /// </summary>
        /// <param name="method">Method about to execute</param>
        /// <param name="targetType">Type that the method is on</param>
        /// <returns>
        /// A <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/> object,
        /// whether or not a transaction was created.
        /// <p>
        /// The
        /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo.HasTransaction"/>
        /// property on the
        /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/>
        /// class can be used to tell if there was a transaction created.
        /// </p>
        /// </returns>
        protected TransactionInfo CreateTransactionIfNecessary(MethodInfo method, Type targetType)
        {
            // If the transaction attribute is null, the method is non-transactional.
            ITransactionAttribute sourceAttr = _transactionAttributeSource.ReturnTransactionAttribute(method, targetType);

            return(CreateTransactionIfNecessary(sourceAttr, MethodIdentification(method)));
        }
        private void checkTransactionProperties(ITransactionAttributeSource tas, MethodInfo method, TransactionPropagation transactionPropagation)
        {
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(method, null);

            Assert.IsTrue(ta != null);
            Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted);
            Assert.IsTrue(ta.PropagationBehavior == transactionPropagation);
        }
        public void EmptyStringTest()
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText(String.Empty);
            ITransactionAttribute ta = editor.Value;

            Assert.IsNull(ta);
        }
        public void NullTest()
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText(null);
            ITransactionAttribute ta = editor.Value;

            Assert.IsNull(ta);
        }
        /// <summary>
        /// Add a mapping.
        /// </summary>
        public void Add(string methodPattern, string txAttributeText)
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor();

            editor.SetAsText(txAttributeText);
            ITransactionAttribute txAttribute = editor.Value;

            AddTransactionMethod(methodPattern, txAttribute);
        }
 /// <summary>
 /// Add an attribute for a transactional method.
 /// </summary>
 /// <remarks>
 /// <p>
 /// Method names can end with "*" for matching multiple methods.
 /// </p>
 /// </remarks>
 /// <param name="methodName">The transactional method name.</param>
 /// <param name="attribute">
 /// The attribute to be associated with the method.
 /// </param>
 public void AddTransactionMethod(string methodName, ITransactionAttribute attribute)
 {
     #region Instrumentation
     if (log.IsDebugEnabled)
     {
         log.Debug("Adding transactional method [" + methodName + "] with attribute [" + attribute + "]");
     }
     #endregion
     nameMap.Add(methodName, attribute);
 }
        public void NameMatchTransactionAttributeSourceWithEmptyMethodName()
        {
            NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
            NameValueCollection attributes          = new NameValueCollection();

            attributes.Add("", "PROPAGATION_MANDATORY");
            tas.NameProperties = attributes;
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null);

            Assert.IsNull(ta);
        }
        public void ValidPropagationCodeAndIsolationCode()
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText("PROPAGATION_REQUIRED, ISOLATION_READUNCOMMITTED");
            ITransactionAttribute ta = editor.Value;

            Assert.IsTrue(ta != null);
            Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Required);
            Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadUncommitted);
        }
        public void NameMatchTransactionAttributeSourceWithStarAtEndOfMethodName()
        {
            NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
            NameValueCollection attributes          = new NameValueCollection();

            attributes.Add("GetHashCod*", "PROPAGATION_REQUIRED");
            tas.NameProperties = attributes;
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null);

            Assert.IsNotNull(ta);
            Assert.AreEqual(TransactionPropagation.Required, ta.PropagationBehavior);
        }
        public void ValidPropagationCodeOnly()
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText("PROPAGATION_REQUIRED");
            ITransactionAttribute ta = editor.Value;

            Assert.IsTrue(ta != null);
            Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Required);
            Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted);
            Assert.IsFalse(ta.ReadOnly);
        }
        public void NameMatchTransactionAttributeSourceMostSpecificMethodNameIsDefinitelyMatched()
        {
            NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
            NameValueCollection attributes          = new NameValueCollection();

            attributes.Add("*", "PROPAGATION_REQUIRED");
            attributes.Add("GetHashCode", "PROPAGATION_MANDATORY");
            tas.NameProperties = attributes;
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null);

            Assert.IsNotNull(ta);
            Assert.AreEqual(TransactionPropagation.Mandatory, ta.PropagationBehavior);
        }
        public void GetTransactionAttribute()
        {
            MatchAlwaysTransactionAttributeSource tas = new MatchAlwaysTransactionAttributeSource();
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(Object).GetMethod("GetHashCode"), null);

            Assert.IsNotNull(ta);
            Assert.IsTrue(TransactionPropagation.Required == ta.PropagationBehavior);
            tas.TransactionAttribute = new DefaultTransactionAttribute(TransactionPropagation.Supports);
            ta =
                tas.ReturnTransactionAttribute(typeof(DataException).GetType().GetMethod("GetHashCode"),
                                               typeof(DataException));
            Assert.IsNotNull(ta);
            Assert.IsTrue(TransactionPropagation.Supports == ta.PropagationBehavior);
        }
        private ITransactionAttribute getTransactionAttribute(MethodInfo methodInfo)
        {
            ITransactionAttribute transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo));

            if (null != transactionAttribute)
            {
                return(transactionAttribute);
            }
            transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo.DeclaringType));
            if (null != transactionAttribute)
            {
                return(transactionAttribute);
            }
            return(null);
        }
Ejemplo n.º 19
0
        private ITransactionAttribute computeTransactionAttribute(MethodInfo method, Type targetType)
        {
            MethodInfo specificMethod;

            if (targetType == null)
            {
                specificMethod = method;
            }
            else
            {
                ParameterInfo[] parameters = method.GetParameters();

                ComposedCriteria searchCriteria = new ComposedCriteria();
                searchCriteria.Add(new MethodNameMatchCriteria(method.Name));
                searchCriteria.Add(new MethodParametersCountCriteria(parameters.Length));
#if NET_2_0
                searchCriteria.Add(new MethodGenericArgumentsCountCriteria(
                                       method.GetGenericArguments().Length));
#endif
                searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(parameters)));

                MemberInfo[] matchingMethods = targetType.FindMembers(
                    MemberTypes.Method,
                    BindingFlags.Instance | BindingFlags.Public,
                    new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria),
                    searchCriteria);

                if (matchingMethods != null && matchingMethods.Length == 1)
                {
                    specificMethod = matchingMethods[0] as MethodInfo;
                }
                else
                {
                    specificMethod = method;
                }
            }

            ITransactionAttribute transactionAttribute = getTransactionAttribute(specificMethod);
            if (null != transactionAttribute)
            {
                return(transactionAttribute);
            }
            else if (specificMethod != method)
            {
                transactionAttribute = getTransactionAttribute(method);
            }
            return(null);
        }
        public void NameMatchTransactionAttributeSource()
        {
            NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
            IDictionary methodMap = new Hashtable();

            methodMap.Add("GetHashCode", "PROPAGATION_REQUIRED");
            methodMap.Add("ToString", new DefaultTransactionAttribute(TransactionPropagation.Supports));
            tas.NameMap = methodMap;
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null);

            Assert.IsNotNull(ta);
            Assert.AreEqual(TransactionPropagation.Required, ta.PropagationBehavior);
            ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("ToString"), null);
            Assert.IsNotNull(ta);
            Assert.AreEqual(TransactionPropagation.Supports, ta.PropagationBehavior);
        }
Ejemplo n.º 21
0
        public void RollbackRules()
        {
            TransactionInterceptor txInterceptor = ctx.GetObject("txRollbackAdvice") as TransactionInterceptor;

            Assert.IsNotNull(txInterceptor);

            MethodInfo getDescriptionMethod          = typeof(ITestObject).GetMethod("GetDescription");
            MethodInfo exceptionalMethod             = typeof(ITestObject).GetMethod("Exceptional");
            ITransactionAttributeSource txAttrSource = txInterceptor.TransactionAttributeSource;
            ITransactionAttribute       txAttr       = txAttrSource.ReturnTransactionAttribute(getDescriptionMethod, typeof(ITestObject));

            Assert.IsTrue(txAttr.RollbackOn(new System.ApplicationException()));

            txAttr = txAttrSource.ReturnTransactionAttribute(exceptionalMethod, typeof(ITestObject));
            Assert.IsFalse(txAttr.RollbackOn(new System.ArithmeticException()));
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Add an attribute for a transactional method.
        /// </summary>
        /// <remarks>
        /// Method names can end or start with "*" for matching multiple methods.
        /// </remarks>
        /// <param name="type">The target interface or class.</param>
        /// <param name="mappedName">The mapped method name.</param>
        /// <param name="transactionAttribute">
        /// The attribute to be associated with the method.
        /// </param>
        public void AddTransactionalMethod(
            Type type, string mappedName, ITransactionAttribute transactionAttribute)
        {
            // TODO address method overloading? At present this will
            // simply match all methods that have the given name.
            string name = type.Name + "." + mappedName;

            MethodInfo[] methods         = type.GetMethods();
            IList        matchingMethods = new ArrayList();

            for (int i = 0; i < methods.Length; i++)
            {
                if (methods[i].Name.Equals(mappedName) || IsMatch(methods[i].Name, mappedName))
                {
                    matchingMethods.Add(methods[i]);
                }
            }
            if (matchingMethods.Count == 0)
            {
                throw new TransactionUsageException("Couldn't find method '" + mappedName + "' on Type [" + type.Name + "]");
            }
            // register all matching methods
            foreach (MethodInfo currentMethod in matchingMethods)
            {
                string regularMethodName = (string)_nameMap[currentMethod];
                if (regularMethodName == null || (!regularMethodName.Equals(name) && regularMethodName.Length <= name.Length))
                {
                    // No already registered method name, or more specific
                    // method name specification now -> (re-)register method.
                    if (LOG.IsDebugEnabled && regularMethodName != null)
                    {
                        LOG.Debug("Replacing attribute for transactional method [" + currentMethod + "]: current name '" +
                                  name + "' is more specific than '" + regularMethodName + "'");
                    }
                    _nameMap.Add(currentMethod, name);
                    AddTransactionalMethod(currentMethod, transactionAttribute);
                }
                else
                {
                    if (LOG.IsDebugEnabled && regularMethodName != null)
                    {
                        LOG.Debug("Keeping attribute for transactional method [" + currentMethod + "]: current name '" +
                                  name + "' is not more specific than '" + regularMethodName + "'");
                    }
                }
            }
        }
        public void ValidPropagationCodeAndIsolationCodeAndRollbackRules1()
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText("PROPAGATION_MANDATORY,ISOLATION_REPEATABLEREAD,timeout_10,-DataException,+RemotingException");
            ITransactionAttribute ta = editor.Value;

            Assert.IsNotNull(ta);
            Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Mandatory);
            Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.RepeatableRead);
            Assert.IsTrue(ta.TransactionTimeout == 10);
            Assert.IsFalse(ta.ReadOnly);
            Assert.IsTrue(ta.RollbackOn(new SystemException( )));
            // Check for our bizarre customized rollback rules
            Assert.IsTrue(ta.RollbackOn(new DataException( )));
            Assert.IsTrue(!ta.RollbackOn(new RemotingException( )));
        }
        public void ValidPropagationCodeAndIsolationCodeAndRollbackRules2()
        {
            TransactionAttributeEditor editor = new TransactionAttributeEditor( );

            editor.SetAsText("+DataException,readOnly,ISOLATION_READCOMMITTED,-RemotingException,PROPAGATION_SUPPORTS");
            ITransactionAttribute ta = editor.Value;

            Assert.IsNotNull(ta);
            Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Supports);
            Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted);
            Assert.IsTrue(ta.TransactionTimeout == -1);
            Assert.IsTrue(ta.ReadOnly);
            Assert.IsTrue(ta.RollbackOn(new SystemException( )));
            // Check for our bizarre customized rollback rules
            Assert.IsFalse(ta.RollbackOn(new DataException( )));
            Assert.IsTrue(ta.RollbackOn(new RemotingException( )));
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Creates the transaction if necessary.
        /// </summary>
        /// <param name="sourceAttr">The source transaction attribute.</param>
        /// <param name="joinpointIdentification">The joinpoint identification.</param>
        /// <returns>Transaction Info for declarative transaction management.</returns>
        protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification)
        {
            ITransactionAttribute txAttr = sourceAttr;

            // If no name specified, apply method identification as transaction name.
            if (txAttr != null && txAttr.Name == null)
            {
                txAttr = new DelegatingTransactionAttributeWithName(txAttr, joinpointIdentification);
            }

            TransactionInfo transactionInfo = new TransactionInfo(txAttr, joinpointIdentification);

            if (txAttr != null)
            {
                // We need a transaction for this method
                #region Instrumentation

                if (log.IsDebugEnabled)
                {
                    log.Debug("Getting transaction for " + transactionInfo.JoinpointIdentification);
                }

                #endregion
                // The transaction manager will flag an error if an incompatible tx already exists
                transactionInfo.TransactionStatus = _transactionManager.GetTransaction(txAttr);
            }
            else
            {
                // The TransactionInfo.HasTransaction property will return
                // false. We created it only to preserve the integrity of
                // the ThreadLocal stack maintained in this class.
                if (log.IsDebugEnabled)
                {
                    log.Debug("Skipping transactional joinpoint [" + joinpointIdentification +
                              "] because no transaction manager has been configured");
                }
            }

            // We always bind the TransactionInfo to the thread, even if we didn't create
            // a new transaction here. This guarantees that the TransactionInfo stack
            // will be managed correctly even if no transaction was created by this aspect.
            transactionInfo.BindToThread( );
            return(transactionInfo);
        }
        /// <summary>
        /// Parses the input properties <see cref="System.String"/> into a valid
        /// <see cref="Spring.Transaction.Interceptor.ITransactionAttributeSource"/>
        /// instance
        /// </summary>
        /// <param name="attributeSource">The properties string to be parsed.</param>
        public void SetAsText(string attributeSource)
        {
            MethodMapTransactionAttributeSource source = new MethodMapTransactionAttributeSource();

            if (attributeSource == null || attributeSource.Length == 0)
            {
                _attributeSource = null;
            }
            else
            {
                PropertiesEditor           editor = new PropertiesEditor(attributeSource);
                TransactionAttributeEditor tae    = new TransactionAttributeEditor();

                foreach (string name in editor.Keys)
                {
                    string value = editor[name];
                    tae.SetAsText(value);
                    ITransactionAttribute transactionAttribute = tae.Value;
                    source.AddTransactionalMethod(name, transactionAttribute);
                }
            }
            _attributeSource = source;
        }
        /// <summary>
        /// Return the <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> for this
        /// method.
        /// </summary>
        /// <param name="method">The method to check.</param>
        /// <param name="targetType">
        /// The target <see cref="System.Type"/>. May be null, in which case the declaring
        /// class of the supplied <paramref name="method"/> must be used.
        /// </param>
        /// <returns>
        /// A <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> or
        /// null if the method is non-transactional.
        /// </returns>
        public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType)
        {
            string methodName = method.Name;
            ITransactionAttribute attribute = (ITransactionAttribute)nameMap[methodName];

            if (attribute != null)
            {
                return(attribute);
            }
            else
            {
                string bestNameMatch = null;
                foreach (string mappedName in nameMap.Keys)
                {
                    if ((IsMatch(methodName, mappedName)) && (bestNameMatch == null || bestNameMatch.Length <= mappedName.Length))
                    {
                        attribute     = (ITransactionAttribute)nameMap[mappedName];
                        bestNameMatch = mappedName;
                    }
                }
            }
            return(attribute);
        }
        /// <summary>
        /// Add an attribute for a transactional method.
        /// </summary>
        /// <remarks>
        /// Method names can end or start with "*" for matching multiple methods.
        /// </remarks>
        /// <param name="type">The target interface or class.</param>
        /// <param name="mappedName">The mapped method name.</param>
        /// <param name="transactionAttribute">
        /// The attribute to be associated with the method.
        /// </param>
        public void AddTransactionalMethod(
			Type type, string mappedName, ITransactionAttribute transactionAttribute )
        {
            // TODO address method overloading? At present this will
            // simply match all methods that have the given name.
            string name = type.Name + "." + mappedName;
            MethodInfo[] methods = type.GetMethods();
            IList matchingMethods = new ArrayList();
            for ( int i = 0; i < methods.Length; i++ )
            {
                if ( methods[i].Name.Equals( mappedName ) || IsMatch(methods[i].Name, mappedName ))
                {
                    matchingMethods.Add( methods[i] );
                }
            }
            if ( matchingMethods.Count == 0 )
            {
                throw new TransactionUsageException("Couldn't find method '" + mappedName + "' on Type [" + type.Name + "]");
            }
            // register all matching methods
            foreach ( MethodInfo currentMethod in matchingMethods )
            {
                string regularMethodName = (string)_nameMap[currentMethod];
                if ( regularMethodName == null || ( !regularMethodName.Equals(name) && regularMethodName.Length <= name.Length))
                {
                    // No already registered method name, or more specific
                    // method name specification now -> (re-)register method.
                    if (LOG.IsDebugEnabled && regularMethodName != null)
                    {
                        LOG.Debug("Replacing attribute for transactional method [" + currentMethod + "]: current name '" +
                            name + "' is more specific than '" + regularMethodName + "'");
                    }
                    _nameMap.Add( currentMethod, name );
                    AddTransactionalMethod( currentMethod, transactionAttribute );
                }
                else
                {
                    if (LOG.IsDebugEnabled && regularMethodName != null)
                    {
                        LOG.Debug("Keeping attribute for transactional method [" + currentMethod + "]: current name '" +
                            name + "' is not more specific than '" + regularMethodName + "'");
                    }
                }
            }
        }
		/// <summary>
		/// Add an attribute for a transactional method.
		/// </summary>
		/// <remarks>
		/// <p>
		/// Method names can end with "*" for matching multiple methods.
		/// </p>
		/// </remarks>
		/// <param name="methodName">The transactional method name.</param>
		/// <param name="attribute">
		/// The attribute to be associated with the method.
		/// </param>
		public void AddTransactionMethod( string methodName, ITransactionAttribute attribute )
        {
            #region Instrumentation
            if (log.IsDebugEnabled)
            {
                log.Debug("Adding transactional method [" + methodName + "] with attribute [" + attribute + "]");
            }
            #endregion
            nameMap.Add( methodName, attribute );
		}	
 /// <summary>
 /// Add a mapping.
 /// </summary>
 public void Add(string methodPattern, ITransactionAttribute txAttribute)
 {
     AddTransactionMethod(methodPattern, txAttribute);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="DelegatingTransactionAttributeWithName"/> class.
 /// </summary>
 /// <param name="targetAttribute">The target attribute.</param>
 /// <param name="identification">The identification.</param>
 public DelegatingTransactionAttributeWithName(ITransactionAttribute targetAttribute, string identification)
 {
     this.targetAttribute = targetAttribute;
     joinpointIdentification = identification;
 }
        /// <summary>
        /// Add an attribute for a transactional method.
        /// </summary>
        /// <remarks>
        /// Method names can end or start with "*" for matching multiple methods.
        /// </remarks>
        /// <param name="name">The class and method name, separated by a dot.</param>
        /// <param name="attribute">The attribute to be associated with the method.</param>
        public void AddTransactionalMethod( string name, ITransactionAttribute attribute )
        {
            AssertUtils.ArgumentNotNull(name, "name");
            int lastCommaIndex = name.LastIndexOf( "," );
            if (lastCommaIndex == -1)
            {
                throw new ArgumentException("'" + name + "'" +
                                            " is not a valid method name, missing AssemblyName.  Format is FQN.MethodName, AssemblyName.");
            }
            string fqnWithMethod = name.Substring(0, lastCommaIndex);

            int lastDotIndex = fqnWithMethod.LastIndexOf( "." );
            if ( lastDotIndex == -1 )
            {
                throw new TransactionUsageException("'" + fqnWithMethod + "' is not a valid method name: format is FQN.methodName");
            }
            string className = fqnWithMethod.Substring(0, lastDotIndex );
            string assemblyName = name.Substring(lastCommaIndex + 1);
            string methodName = fqnWithMethod.Substring(lastDotIndex + 1 );
            string fqnClassName = className + ", " + assemblyName;
            try
            {
                Type type = TypeResolutionUtils.ResolveType(fqnClassName);
                AddTransactionalMethod( type, methodName, attribute );
            } catch ( TypeLoadException exception )
            {
                throw new TransactionUsageException( "Type '" + fqnClassName + "' not found.", exception );
            }
        }
 /// <summary>
 /// Creates a new instance of the
 /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/>
 /// class for the supplied <paramref name="transactionAttribute"/>.
 /// </summary>
 /// <param name="transactionAttribute">The transaction attributes to associate with any transaction.</param>
 /// <param name="joinpointIdentification">The info for diagnostic display of joinpoint</param>
 public TransactionInfo( ITransactionAttribute transactionAttribute, string joinpointIdentification)
 {
     _transactionAttribute = transactionAttribute;
     _joinpointIdentification = joinpointIdentification;
 }
        /// <summary>
        /// Creates the transaction if necessary.
        /// </summary>
        /// <param name="sourceAttr">The source transaction attribute.</param>
        /// <param name="joinpointIdentification">The joinpoint identification.</param>
        /// <returns>Transaction Info for declarative transaction management.</returns>
        protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification)
        {
            ITransactionAttribute txAttr = sourceAttr;

            // If no name specified, apply method identification as transaction name.
            if (txAttr != null && txAttr.Name == null)
            {
                txAttr = new DelegatingTransactionAttributeWithName(txAttr, joinpointIdentification);
            }

            TransactionInfo transactionInfo = new TransactionInfo(txAttr, joinpointIdentification);
            if ( txAttr != null )
            {
                // We need a transaction for this method
                #region Instrumentation

                if (log.IsDebugEnabled)
                {
                    log.Debug("Getting transaction for " + transactionInfo.JoinpointIdentification);
                }

                #endregion
                // The transaction manager will flag an error if an incompatible tx already exists
                transactionInfo.TransactionStatus = _transactionManager.GetTransaction(txAttr);
            }
            else
            {
                // The TransactionInfo.HasTransaction property will return
                // false. We created it only to preserve the integrity of
                // the ThreadLocal stack maintained in this class.
                if (log.IsDebugEnabled)
                {
                    log.Debug("Skipping transactional joinpoint [" + joinpointIdentification +
                              "] because no transaction manager has been configured");
                }
            }

            // We always bind the TransactionInfo to the thread, even if we didn't create
            // a new transaction here. This guarantees that the TransactionInfo stack
            // will be managed correctly even if no transaction was created by this aspect.
            transactionInfo.BindToThread( );
            return transactionInfo;
        }
 /// <summary>
 /// Creates a new instance of the
 /// <see cref="Spring.Transaction.Interceptor.MatchAlwaysTransactionAttributeSource"/>
 /// class.
 /// </summary>
 public MatchAlwaysTransactionAttributeSource()
 {
     _transactionAttribute = new DefaultTransactionAttribute();
 }
Ejemplo n.º 36
0
 public DefaultTransactionAttribute(ITransactionAttribute other)
     : base(other)
 {
 }
        private void checkTransactionProperties(ITransactionAttributeSource tas, MethodInfo method)
        {
            ITransactionAttribute ta = tas.ReturnTransactionAttribute(method, null);

            Assert.IsNull(ta);
        }
 /// <summary>
 /// Creates a new instance of the
 /// <see cref="Spring.Transaction.Interceptor.MatchAlwaysTransactionAttributeSource"/>
 /// class.
 /// </summary>
 public MatchAlwaysTransactionAttributeSource()
 {
     _transactionAttribute = new DefaultTransactionAttribute();
 }
 /// <summary>
 /// Add an attribute for a transactional method.
 /// </summary>
 /// <param name="method">The transactional method.</param>
 /// <param name="transactionAttribute">
 /// The attribute to be associated with the method.
 /// </param>
 public void AddTransactionalMethod( MethodInfo method, ITransactionAttribute transactionAttribute )
 {
     _methodMap.Add( method, transactionAttribute );
 }