Example #1
0
 /// <summary> Determines an attribute string for the given instance reference. </summary>
 private string ReferenceToString(object tempValue, out bool reference)
 {
     reference = true;
     if (tempValue == null)
     {
         return(String.Empty);
     }
     else
     {
         Type type = tempValue.GetType();
         PublishNameAttribute attribute = ((PublishNameAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishNameAttribute)));
         if (attribute != null)
         {
             return((string)ReflectionUtility.GetMemberValue(ReflectionUtility.FindSimpleMember(type, attribute.MemberName), tempValue));
         }
         else
         {
             var converter = Persistence.GetTypeConverter(type);
             if (converter != null)
             {
                 reference = false;
                 return(converter.ConvertToString(tempValue));
             }
         }
         return(String.Empty);
     }
 }
Example #2
0
        /// <summary> Determines if the specified property should be serialized. </summary>
        private bool ShouldPersist(MemberInfo member, object tempValue, object instance)
        {
            DefaultValueAttribute defaultValues = (DefaultValueAttribute)ReflectionUtility.GetAttribute(member, typeof(DefaultValueAttribute));

            if (defaultValues != null)
            {
                return(!Object.Equals(tempValue, defaultValues.Value));
            }

            DefaultValueMemberAttribute defaultMember = (DefaultValueMemberAttribute)ReflectionUtility.GetAttribute(member, typeof(DefaultValueMemberAttribute));

            if (defaultMember != null)
            {
                return
                    (!Object.Equals
                     (
                         tempValue,
                         ReflectionUtility.GetMemberValue
                         (
                             ReflectionUtility.FindSimpleMember(instance.GetType(), defaultMember.MemberName),
                             instance
                         )
                     ));
            }

            return(true);
        }
        /// <summary> Finds the instance for a specific member. </summary>
        /// <remarks>
        ///		Names with dot qualifiers are resolved to their unqualified names by finding
        ///		a by-reference member for each qualifier for each instance.
        ///	</remarks>
        ///	<param name="LNamePath"> Pass the fully qualified name and get the simple name back. </param>
        ///	<returns> The instance containing the member named the simple (unqualified) name. </returns>
        private static object FindMemberInstance(object LInstance, ref string LNamePath)
        {
            int dotPos;

            while ((dotPos = LNamePath.IndexOf('.')) >= 0)
            {
                LInstance = ReflectionUtility.GetMemberValue(ReflectionUtility.FindSimpleMember(LInstance.GetType(), LNamePath.Substring(0, dotPos)), LInstance);
                LNamePath = LNamePath.Substring(dotPos + 1);
            }
            ;
            return(LInstance);
        }
        /// <summary> Gets the MemberInfo for the name member of the specified type. </summary>
        private MemberInfo GetNameMemberInfo(Type type)
        {
            PublishNameAttribute publishName = (PublishNameAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishNameAttribute));

            if (publishName == null)
            {
                return(null);
            }
            else
            {
                return(ReflectionUtility.FindSimpleMember(type, publishName.MemberName));
            }
        }
        /// <summary> Deserializes an instance from a node. </summary>
        /// <param name="node"> The XML node.  This node will not be affected by this method. </param>
        /// <param name="instance"> An optional instance to deserialize "into". </param>
        /// <returns> The instance that was passed by AInstance or was constructed if null was passed. </returns>
        private object ReadObject(XElement node, object instance)
        {
            string elementName = node.Name.LocalName.Substring(node.Name.LocalName.LastIndexOf('.') + 1).ToLower();             // simple type name

            Type type;

            if (instance != null)               // instance provided
            {
                type = instance.GetType();
                string typeName = GetElementName(type);                 // result is lower case
                if (elementName != typeName)
                {
                    Errors.Add(new BOPException(BOPException.Codes.TypeNameMismatch, elementName, typeName));
                }
            }
            else                // construct instance
            {
                type = GetClassType(elementName, node.Name.NamespaceName);

                try
                {
                    if (!IsValueType(type))
                    {
                        PublishDefaultConstructorAttribute constructorAttribute = (PublishDefaultConstructorAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishDefaultConstructorAttribute));
                        if ((constructorAttribute == null) || (constructorAttribute.ConstructorSignature == String.Empty))
                        {
                            instance = Activator.CreateInstance(type, new object[] { });
                        }
                        else
                        {
                            // create a copy of the node to work with
                            // so that the original is not corrupted by disappearing attributes
                            node     = new XElement(node);
                            instance = ConstructInstance(constructorAttribute.ConstructorSignature, type, node);
                        }
                    }
                    else
                    {
                        return(ReflectionUtility.StringToValue(node.Attribute("value").Value, type));
                    }
                }
                catch (Exception E)
                {
                    throw new BOPException(BOPException.Codes.UnableToConstruct, E, type.FullName);
                }
            }

            MemberInfo member;
            object     memberInstance;
            string     memberName;
            Type       memberType;

            // Have Type and Instance, now read the properties
            try
            {
                // Read attributes
                foreach (XAttribute attribute in node.Attributes())
                {
                    try
                    {
                        memberName = attribute.Name.LocalName.ToLower();
                        if
                        (
                            (!attribute.IsNamespaceDeclaration)
                            &&
                            !(
                                IsBOPNode(attribute.Name) &&
                                (memberName.StartsWith(BOPType) || memberName.StartsWith(BOPDefault))
                                )
                        )
                        {
                            if (IsBOPNode(attribute.Name))
                            {
                                memberInstance = instance;
                                if (Persistence.XNamesEqual(attribute.Name, XmlBOPName))
                                {
                                    member = GetNameMemberInfo(type);
                                    if (member == null)
                                    {
                                        throw new BOPException(BOPException.Codes.InvalidElementName, type.Name);
                                    }
                                }
                                else
                                {
                                    throw new BOPException(BOPException.Codes.InvalidAttribute, attribute.Name);
                                }
                            }
                            else
                            {
                                memberInstance = FindMemberInstance(instance, ref memberName);
                                member         = ReflectionUtility.FindSimpleMember(memberInstance.GetType(), memberName);
                            }
                            memberType = GetMemberType(node, member);

                            ReflectionUtility.SetMemberValue
                            (
                                member,
                                memberInstance,
                                (
                                    AttributeToValue
                                    (
                                        attribute.Value,
                                        memberType,
                                        memberInstance,
                                        member
                                    )
                                )
                            );
                        }
                    }
                    catch (Exception exception)
                    {
                        Errors.Add(exception);
                    }
                }

                // Add this instance to the list of read instances if it has a name
                member = GetNameMemberInfo(instance.GetType());
                if (member != null)
                {
                    memberName = (string)ReflectionUtility.GetMemberValue(member, instance);
                    if (memberName != String.Empty)
                    {
                        InstancesByName.Add(memberName, instance);
                    }
                }

                // read child nodes
                IList list;
                foreach (XElement localNode in node.Elements())
                {
                    try
                    {
                        memberName     = localNode.Name.LocalName.ToLower();
                        memberInstance = FindMemberInstance(instance, ref memberName);

                        // First see if the member instance has a default list attribute and use it if it does
                        string defaultListName = GetDefaultListMemberName(memberInstance.GetType());
                        if (defaultListName == String.Empty)
                        {
                            list = memberInstance as IList;
                        }
                        else                         // if no default list, assume the member instance IS the list
                        {
                            list = ReflectionUtility.GetMemberValue
                                   (
                                ReflectionUtility.FindSimpleMember(memberInstance.GetType(), defaultListName),
                                memberInstance
                                   ) as IList;
                        }
                        if (list == null)
                        {
                            throw new BOPException(BOPException.Codes.DefaultListNotFound, memberInstance.GetType().Name);
                        }
                        list.Add(ReadObject(localNode, null));
                    }
                    catch (Exception exception)
                    {
                        Errors.Add(exception);
                    }
                }

                // call AfterDeserialize
                if (instance is IBOPSerializationEvents)
                {
                    ((IBOPSerializationEvents)instance).AfterDeserialize(this);
                }

                if (AfterDeserialized != null)
                {
                    AfterDeserialized(instance);
                }
            }
            catch
            {
                if ((instance != null) && (instance is IDisposable))
                {
                    ((IDisposable)instance).Dispose();
                }
                throw;
            }

            return(instance);
        }
        /// <summary> Constructs a new instance given a specified type and signature. </summary>
        /// <remarks>
        ///		Any constructor arguments are loaded from the specified XML node.
        ///		The specified node may be altered by this method.  (clone it first if you do not want it affected)
        ///	</remarks>
        private object ConstructInstance(string signature, Type type, XElement node)
        {
            // Determine the constructor signature
            string[] signatureNames = signature.Split(new char[] { ';' });
            Type[]   localSignature = new Type[signatureNames.Length];
            for (int i = localSignature.Length - 1; i >= 0; i--)
            {
                localSignature[i] = ReflectionUtility.GetType(signatureNames[i], type.Assembly);
            }

            // Find the matching constructor
            ConstructorInfo constructor = type.GetConstructor(localSignature);

            if (constructor == null)
            {
                throw new BOPException(BOPException.Codes.DefaultConstructorNotFound, signature);
            }

            string nameMemberName = GetNameMemberName(type);

            // Build the constructor's parameter list
            ParameterInfo[]        parameters      = constructor.GetParameters();
            object[]               parameterValues = new object[parameters.Length];
            PublishSourceAttribute source;

            for (int i = parameters.Length - 1; i >= 0; i--)                    // order doesn't matter so step down to avoid re-eval of length - 1
            {
                source = (PublishSourceAttribute)ReflectionUtility.GetAttribute(parameters[i], typeof(PublishSourceAttribute));
                if (source == null)
                {
                    throw new BOPException(BOPException.Codes.ConstructorArgumentRefNotSpecified, parameters[i].Name, type.FullName);
                }

                var        memberName = source.MemberName.ToLower();
                XAttribute attribute  = node.Attribute(memberName);
                if (attribute != null)
                {
                    parameterValues[i] = AttributeToValue
                                         (
                        attribute.Value,
                        GetMemberType(node, ReflectionUtility.FindSimpleMember(type, memberName)),
                        null,
                        null
                                         );

                    attribute.Remove(); // remove so we don't read the attribute later
                }
                else                    // didn't find a regular attribute, so look for a default tag in the xml
                {
                    attribute = node.Attribute(XmlBOPDefault + source.MemberName.ToLower());
                    if (attribute != null)
                    {
                        parameterValues[i] = ReadAttributeDefault(ReflectionUtility.FindSimpleMember(type, memberName), null);
                        attribute.Remove();
                    }
                    else
                    {
                        // see if the property on the object has a DefaultValueAttribute set
                        DefaultValueAttribute defaultValue = (DefaultValueAttribute)ReflectionUtility.GetAttribute(ReflectionUtility.FindSimpleMember(type, source.MemberName), typeof(DefaultValueAttribute));
                        if (defaultValue != null)
                        {
                            parameterValues[i] = defaultValue.Value;
                        }
                        else
                        {
                            throw new BOPException(BOPException.Codes.ConstructorArgumentRefNotFound, source.MemberName, type.FullName);
                        }
                    }
                }
            }
            return(constructor.Invoke(parameterValues));
        }