/// <summary>
 /// Resolve the target type of the passed <see cref="TypedStringValue"/>.
 /// </summary>
 /// <param name="value">The <see cref="TypedStringValue"/> who's target type is to be resolved</param>
 /// <returns>The resolved target type, if any. <see lang="null" /> otherwise.</returns>
 protected virtual Type ResolveTargetType(TypedStringValue value)
 {
     if (value.HasTargetType)
     {
         return(value.TargetType);
     }
     return(value.ResolveTargetType());
 }
 /// <summary>
 /// Resolve the target type of the passed <see cref="TypedStringValue"/>.
 /// </summary>
 /// <param name="value">The <see cref="TypedStringValue"/> who's target type is to be resolved</param>
 /// <returns>The resolved target type, if any. <see lang="null" /> otherwise.</returns>
 protected virtual Type ResolveTargetType(TypedStringValue value)
 {
     if (value.HasTargetType)
     {
         return(value.TargetType);
     }
     else
     {
         return(null);
     }
 }
        /// <summary>The build typed string value.</summary>
        /// <param name="value">The value.</param>
        /// <param name="targetTypeName">The target type name.</param>
        /// <returns>The Spring.Objects.Factory.Config.TypedStringValue.</returns>
        protected TypedStringValue buildTypedStringValue(string value, string targetTypeName)
        {
            TypedStringValue typedValue;

            if (!StringUtils.HasText(targetTypeName))
            {
                typedValue = new TypedStringValue(value);
            }
            else
            {
                var targetType = Type.GetType(targetTypeName);

                if (targetType != null)
                {
                    typedValue = new TypedStringValue(value, targetType);
                }
                else
                {
                    typedValue = new TypedStringValue(value, targetTypeName);
                }
            }

            return(typedValue);
        }
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="name">
        /// The name of the object that is having the value of one of its properties resolved.
        /// </param>
        /// <param name="definition">
        /// The definition of the named object.
        /// </param>
        /// <param name="argumentName">
        /// The name of the property the value of which is being resolved.
        /// </param>
        /// <param name="argumentValue">
        /// The value of the property that is being resolved.
        /// </param>
        private object ResolvePropertyValue(string name, IObjectDefinition definition, string argumentName, object argumentValue)
        {
            object resolvedValue = null;

            // we must check the argument value to see whether it requires a runtime
            // reference to another object to be resolved.
            // if it does, we'll attempt to instantiate the object and set the reference.
            if (RemotingServices.IsTransparentProxy(argumentValue))
            {
                resolvedValue = argumentValue;
            }
            else if (argumentValue is ICustomValueReferenceHolder)
            {
                resolvedValue = ((ICustomValueReferenceHolder)argumentValue).Resolve(objectFactory, name, definition, argumentName, argumentValue);
            }
            else if (argumentValue is ObjectDefinitionHolder)
            {
                // contains an IObjectDefinition with name and aliases...
                ObjectDefinitionHolder holder = (ObjectDefinitionHolder)argumentValue;
                resolvedValue = ResolveInnerObjectDefinition(name, holder.ObjectName, argumentName, holder.ObjectDefinition, definition.IsSingleton);
            }
            else if (argumentValue is IObjectDefinition)
            {
                // resolve plain IObjectDefinition, without contained name: use dummy name...
                IObjectDefinition def = (IObjectDefinition)argumentValue;
                resolvedValue = ResolveInnerObjectDefinition(name, "(inner object)", argumentName, def, definition.IsSingleton);
            }
            else if (argumentValue is RuntimeObjectReference)
            {
                RuntimeObjectReference roref = (RuntimeObjectReference)argumentValue;
                resolvedValue = ResolveReference(definition, name, argumentName, roref);
            }
            else if (argumentValue is ExpressionHolder)
            {
                ExpressionHolder             expHolder = (ExpressionHolder)argumentValue;
                object                       context   = null;
                IDictionary <string, object> variables = null;

                if (expHolder.Properties != null)
                {
                    PropertyValue contextProperty = expHolder.Properties.GetPropertyValue("Context");
                    context = contextProperty == null
                                  ? null
                                  : ResolveValueIfNecessary(name, definition, "Context",
                                                            contextProperty.Value);
                    PropertyValue variablesProperty = expHolder.Properties.GetPropertyValue("Variables");
                    object        vars = (variablesProperty == null
                                       ? null
                                       : ResolveValueIfNecessary(name, definition, "Variables",
                                                                 variablesProperty.Value));
                    if (vars is IDictionary <string, object> )
                    {
                        variables = (IDictionary <string, object>)vars;
                    }
                    if (vars is IDictionary)
                    {
                        IDictionary temp = (IDictionary)vars;
                        variables = new Dictionary <string, object>(temp.Count);
                        foreach (DictionaryEntry entry in temp)
                        {
                            variables.Add((string)entry.Key, entry.Value);
                        }
                    }
                    else
                    {
                        if (vars != null)
                        {
                            throw new ArgumentException("'Variables' must resolve to an IDictionary");
                        }
                    }
                }

                if (variables == null)
                {
                    variables = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
                }
                // add 'this' objectfactory reference to variables
                variables.Add(Expression.ReservedVariableNames.CurrentObjectFactory, objectFactory);

                resolvedValue = expHolder.Expression.GetValue(context, variables);
            }
            else if (argumentValue is IManagedCollection)
            {
                resolvedValue =
                    ((IManagedCollection)argumentValue).Resolve(name, definition, argumentName, ResolveValueIfNecessary);
            }
            else if (argumentValue is TypedStringValue)
            {
                TypedStringValue tsv = (TypedStringValue)argumentValue;
                try
                {
                    Type resolvedTargetType = ResolveTargetType(tsv);
                    if (resolvedTargetType != null)
                    {
                        resolvedValue = TypeConversionUtils.ConvertValueIfNecessary(tsv.TargetType, tsv.Value, null);
                    }
                    else
                    {
                        resolvedValue = tsv.Value;
                    }
                }
                catch (Exception ex)
                {
                    throw new ObjectCreationException(definition.ResourceDescription, name,
                                                      "Error converted typed String value for " + argumentName, ex);
                }
            }
            else
            {
                // no need to resolve value...
                resolvedValue = argumentValue;
            }
            return(resolvedValue);
        }
        private AbstractObjectDefinition ParseAttributeSource(XmlElement element, ParserContext parserContext)
        {
            XmlNodeList       methods = element.SelectNodes("*[local-name()='method' and namespace-uri()='" + element.NamespaceURI + "']");
            ManagedDictionary transactionAttributeMap = new ManagedDictionary();

            foreach (XmlElement methodElement in methods)
            {
                string           name       = GetAttributeValue(methodElement, "name");
                TypedStringValue nameHolder = new TypedStringValue(name);

                RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute();
                string propagation = GetAttributeValue(methodElement, PROPAGATION);
                string isolation   = GetAttributeValue(methodElement, ISOLATION);
                string timeout     = GetAttributeValue(methodElement, TIMEOUT);
                string readOnly    = GetAttributeValue(methodElement, READ_ONLY);
                if (StringUtils.HasText(propagation))
                {
                    attribute.PropagationBehavior = (TransactionPropagation)Enum.Parse(typeof(TransactionPropagation), propagation, true);
                }
                if (StringUtils.HasText(isolation))
                {
                    attribute.TransactionIsolationLevel =
                        (IsolationLevel)Enum.Parse(typeof(IsolationLevel), isolation, true);
                }
                if (StringUtils.HasText(timeout))
                {
                    try
                    {
                        attribute.TransactionTimeout = Int32.Parse(timeout);
                    }
                    catch (FormatException ex)
                    {
                        parserContext.ReaderContext.ReportException(methodElement, "tx advice", "timeout must be an integer value: [" + timeout + "]", ex);
                    }
                }
                if (StringUtils.HasText(readOnly))
                {
                    attribute.ReadOnly = Boolean.Parse(GetAttributeValue(methodElement, READ_ONLY));
                }

                var rollbackRules = new List <RollbackRuleAttribute>();
                if (methodElement.HasAttribute(ROLLBACK_FOR))
                {
                    string rollbackForValue = GetAttributeValue(methodElement, ROLLBACK_FOR);
                    AddRollbackRuleAttributesTo(rollbackRules, rollbackForValue);
                }
                if (methodElement.HasAttribute(NO_ROLLBACK_FOR))
                {
                    string noRollbackForValue = GetAttributeValue(methodElement, NO_ROLLBACK_FOR);
                    AddNoRollbackRuleAttributesTo(rollbackRules, noRollbackForValue);
                }
                attribute.RollbackRules = rollbackRules;

                transactionAttributeMap[nameHolder] = attribute;
            }

            ObjectDefinitionBuilder builder = parserContext
                                              .ParserHelper
                                              .CreateRootObjectDefinitionBuilder(typeof(NameMatchTransactionAttributeSource));

            builder.AddPropertyValue(NAME_MAP, transactionAttributeMap);
            return(builder.ObjectDefinition);
        }
        private object parsePropertySubElement(XmlElement ele, IObjectDefinition bd, string defaultValueType)
        {
            if (!isDefaultNamespace(ele))
            {
                return(this.parseNestedCustomElement(ele, bd));
            }
            else if (this.NodeNameEquals(ele, OBJECT_ELEMENT))
            {
                ObjectDefinitionHolder nestedBd = this.parserContext.ParserHelper.ParseObjectDefinitionElement(ele, bd);

                // if (nestedBd != null)
                // {
                // nestedBd = decorateObjectDefinitionIfRequired(ele, nestedBd, bd);
                // }
                return(nestedBd);
            }
            else if (this.NodeNameEquals(ele, REF_ELEMENT))
            {
                // A generic reference to any name of any object.
                string refName  = ele.GetAttribute(OBJECT_REF_ATTRIBUTE);
                bool   toParent = false;
                if (!StringUtils.HasLength(refName))
                {
                    // A reference to the id of another object in the same XML file.
                    refName = ele.GetAttribute(LOCAL_REF_ATTRIBUTE);
                    if (!StringUtils.HasLength(refName))
                    {
                        // A reference to the id of another object in a parent context.
                        refName  = ele.GetAttribute(PARENT_REF_ATTRIBUTE);
                        toParent = true;
                        if (!StringUtils.HasLength(refName))
                        {
                            this.Error("'object', 'local' or 'parent' is required for <ref> element", ele);
                            return(null);
                        }
                    }
                }

                if (!StringUtils.HasText(refName))
                {
                    this.Error("<ref> element contains empty target attribute", ele);
                    return(null);
                }

                var reference = new RuntimeObjectReference(refName, toParent);
                return(reference);
            }


            // else if (NodeNameEquals(ele, IDREF_ELEMENT)) {
            // return parseIdRefElement(ele);
            // }
            else if (this.NodeNameEquals(ele, VALUE_ELEMENT))
            {
                return(this.parseValueElement(ele, defaultValueType));
            }
            else if (this.NodeNameEquals(ele, NULL_ELEMENT))
            {
                // It's a distinguished null value. Let's wrap it in a TypedStringValue
                // object in order to preserve the source location.
                var nullHolder = new TypedStringValue(null);
                return(nullHolder);
            }
            else if (this.NodeNameEquals(ele, ARRAY_ELEMENT))
            {
                return(this.parseArrayElement(ele, bd));
            }
            else if (this.NodeNameEquals(ele, LIST_ELEMENT))
            {
                return(this.parseListElement(ele, bd));
            }
            else if (this.NodeNameEquals(ele, SET_ELEMENT))
            {
                return(this.parseSetElement(ele, bd));
            }
            else if (this.NodeNameEquals(ele, MAP_ELEMENT))
            {
                return(this.ParseMapElement(ele, bd));
            }



            // else if (NodeNameEquals(ele, PROPS_ELEMENT))
            // {
            // return parsePropsElement(ele);
            // }
            else
            {
                this.Error("Unknown property sub-element: [" + ele.Name + "]", ele);
                return(null);
            }
        }
        /// <summary>The build typed string value for map.</summary>
        /// <param name="value">The value.</param>
        /// <param name="defaultTypeName">The default type name.</param>
        /// <returns>The System.Object.</returns>
        protected object buildTypedStringValueForMap(string value, string defaultTypeName)
        {
            TypedStringValue typedValue = this.buildTypedStringValue(value, defaultTypeName);

            return(typedValue);
        }