Пример #1
0
        /// <returns>The root element of the tree</returns>
        public static ObjectElement RecreateObjectTree(SerializableNode[] nodes)
        {
            // Recreate all objects
            ObjectElement root     = null;
            var           elements = new Dictionary <int, ObjectElement>();

            foreach (var obj in nodes)
            {
                ObjectElement element;
                switch (obj.Type)
                {
                case ObjectElement.Types.Root:
                    element = ObjectElement.CreateRoot();
                    if (root != null)
                    {
                        throw new ApplicationException("There is more than 1 root element in the XML document.");
                    }
                    root = element;
                    break;

                case ObjectElement.Types.Exception: {
                    string str;
                    if (obj.ValueTranslatable != null)
                    {
                        element = ObjectElement.CreateException(obj.ValueTranslatable.CreateTranslatableElement(), obj.Class, obj.StackTrace);
                    }
                    else if ((str = obj.ValuePrimitive.Value as string) != null)
                    {
                        element = ObjectElement.CreateException(str, obj.Class, obj.StackTrace);
                    }
                    else
                    {
                        System.Diagnostics.Debug.Fail("Unsupported element type '" + obj.ValuePrimitive.Value.GetType().FullName + "'");
                        continue;
                    }
                    break;
                }

                case ObjectElement.Types.Object:
                    if (obj.NameTranslatable != null)
                    {
                        element = ObjectElement.CreateObject(obj.NameTranslatable.CreateTranslatableElement(), obj.Class);
                    }
                    else
                    {
                        element = ObjectElement.CreateObject(obj.NameString, obj.Class);
                    }
                    break;

                case ObjectElement.Types.Field:
                    if (obj.NameTranslatable != null)
                    {
                        element = ObjectElement.CreateField(obj.NameTranslatable.CreateTranslatableElement(), obj.Class, obj.ValuePrimitive != null ? obj.ValuePrimitive.Value : obj.ValueTranslatable);
                    }
                    else
                    {
                        element = ObjectElement.CreateField(obj.NameString, obj.Class, obj.ValuePrimitive != null ? obj.ValuePrimitive.Value : obj.ValueTranslatable);
                    }
                    break;

                default:
                    throw new NotImplementedException("The object type '" + obj.Type.ToString() + "' is not supported");
                }
                elements.Add(obj.ID, element);
            }
            if (root == null)
            {
                throw new ApplicationException("There is no root element in the XML document.");
            }

            // Recreate parent/child links between objects
            foreach (var obj in nodes)
            {
                var parentElement = elements[obj.ID];
                if (obj.Children != null)
                {
                    foreach (var childObj in obj.Children)
                    {
                        parentElement.Children.Add(elements[childObj]);
                    }
                }
            }

            return(root);
        }
Пример #2
0
        private ObjectElement Explore(string fieldName, string fieldType, object currentObject, int currentDepth)
        {
            try
            {
                System.Diagnostics.Debug.Assert(fieldName != null);
                System.Diagnostics.Debug.Assert(fieldType != null);
                System.Diagnostics.Debug.Assert(currentDepth <= MaximumDepth);
                System.Diagnostics.Debug.Assert(VisitedObjects != null);

                if (currentObject == null)
                {
                    return(ObjectElement.CreateField(fieldName, fieldType, NullValue));
                }

                // Check that this object has not been visited yet
                ObjectElement visited;
                VisitedObjects.TryGetValue(currentObject, out visited);
                if (visited != null)
                {
                    return(ObjectElement.CloneElement(fieldName, fieldType, visited));
                }

                // Create the ObjectElement for this object and register it as visited
                ObjectElement currentElement;
                Type          currentType          = currentObject.GetType();
                BaseException currentBaseException = null;
                Exception     currentException     = null;
                IDictionary   currentDictionary    = null;
                IEnumerable   currentEnumerable    = null;
                var           fieldsToSkip         = new Dictionary <string, object>();
                string[]      stackTrace           = null;
                bool          exploreChildren;
                if (IsDirectlyInterpretable(currentType))
                {
                    exploreChildren = false;
                    currentElement  = ObjectElement.CreateField(fieldName, currentType.FullName, currentObject);
                }
                else
                {
                    exploreChildren = true;

                    if ((currentBaseException = currentObject as BaseException) != null)
                    {
                        currentException = currentBaseException;
                        if (currentBaseException.TranslatableMessage == null)
                        {
                            // Treat as regular exception
                            currentBaseException = null;
                        }

                        fieldsToSkip.Add("InnerException", null);
                        fieldsToSkip.Add("Message", null);
                        fieldsToSkip.Add("TranslatableMessage", null);
                        fieldsToSkip.Add("StackTrace", null);
                        stackTrace = currentException.StackTrace.Split(new char[] { '\n' });
                        for (int i = 0; i < stackTrace.Length; ++i)
                        {
                            stackTrace[i] = stackTrace[i].Trim();
                        }
                    }
                    else if ((currentException = currentObject as Exception) != null)
                    {
                        fieldsToSkip.Add("InnerException", null);
                        fieldsToSkip.Add("Message", null);
                        fieldsToSkip.Add("StackTrace", null);
                        stackTrace = currentException.StackTrace.Split(new char[] { '\n' });
                        for (int i = 0; i < stackTrace.Length; ++i)
                        {
                            stackTrace[i] = stackTrace[i].Trim();
                        }
                    }
                    if ((currentDictionary = currentObject as IDictionary) != null)
                    {
                        fieldsToSkip.Add("Keys", null);
                        fieldsToSkip.Add("Values", null);
                        fieldsToSkip.Add("Item", null);
                        //exploreChildren = false;
                    }
                    else if ((currentEnumerable = currentObject as IEnumerable) != null)
                    {
                        //exploreChildren = false;
                    }

                    if (currentBaseException != null)
                    {
                        currentElement = ObjectElement.CreateException(currentBaseException.TranslatableMessage, currentBaseException.GetType().FullName, stackTrace);
                    }
                    else if (currentException != null)
                    {
                        currentElement = ObjectElement.CreateException(currentException.Message, currentException.GetType().FullName, stackTrace);
                    }
                    else
                    {
                        currentElement = ObjectElement.CreateObject(fieldName, currentObject.GetType().FullName);
                    }
                }
                if (currentDepth >= MaximumDepth)
                {
                    // Stop exploring
                    exploreChildren = false;
                }
                VisitedObjects.Add(currentObject, currentElement);

                var childDepth = currentDepth + 1;
                if ((currentException == null) && (currentEnumerable == null) && (currentDictionary == null) && currentType.FullName.StartsWith("System."))
                {
                    // Don't explore childs of objects of type 'System.*' (except exceptions, enumerables and dictionaries)
                    childDepth = MaximumDepth;
                }
                if (exploreChildren)
                {
                    // Explore children
                    foreach (var childMember in currentObject.GetType().GetMembers())
                    {
                        if (fieldsToSkip.ContainsKey(childMember.Name))
                        {
                            continue;
                        }

                        // Get the child type/value
                        string childType;
                        object childObject;
                        switch (childMember.MemberType)
                        {
                        case MemberTypes.Field: {
                            var field = (FieldInfo)childMember;
                            childType   = field.FieldType.FullName;
                            childObject = field.GetValue(currentObject);
                            break;
                        }

                        case MemberTypes.Property: {
                            var property     = (PropertyInfo)childMember;
                            var propertyType = property.PropertyType;
                            childType = propertyType.FullName;
                            try
                            {
                                childObject = property.GetGetMethod().Invoke(currentObject, new object[] {});
                            }
                            catch (System.Exception ex)
                            {
                                // Error calling the getter => Replace by an error string and continue
                                string errorString   = string.Format(GetterError, ex.GetType().FullName, ex.Message);
                                var    childElement2 = ObjectElement.CreateField(childMember.Name, childType, errorString);
                                currentElement.Children.Add(childElement2);
                                continue;
                            }
                            break;
                        }

                        default:
                            // Nothing to explore
                            continue;
                        }

                        // Recursive call
                        var childElement = Explore(childMember.Name, childType, childObject, childDepth);
                        currentElement.Children.Add(childElement);
                    }

                    if (currentDictionary != null)
                    {
                        // Add dictionary entries
                        foreach (DictionaryEntry entry in currentDictionary)
                        {
                            string name;
                            try
                            {
                                object key = entry.Key;
                                if (key == null)
                                {
                                    name = "<NULL>";
                                }
                                else
                                {
                                    name = key.ToString();
                                    if (name.Length > MaxDictKeyLen)
                                    {
                                        name = name.Substring(0, MaxDictKeyLen);
                                    }
                                    name = "[" + name + "]";
                                }
                            }
                            catch (System.Exception ex)
                            {
                                // Error converting the Key to string => Replace by an error string and continue
                                name = string.Format(GetterError, ex.GetType().FullName, ex.Message);
                            }
                            // Recursive call
                            var childElement = Explore(name, typeof(object).ToString(), entry.Value, childDepth);
                            currentElement.Children.Add(childElement);
                        }
                    }
                    else if (currentEnumerable != null)
                    {
                        // Add enumerable entries
                        int i = 0;
                        foreach (object entry in currentEnumerable)
                        {
                            // Recursive call
                            string name         = string.Format("[{0}]", i++);
                            var    childElement = Explore(name, typeof(object).ToString(), entry, childDepth);
                            currentElement.Children.Add(childElement);
                        }
                    }
                }

                return(currentElement);
            }
            catch (System.Exception ex)
            {
                // Error exploring => Replace by an error field
                System.Diagnostics.Debug.Fail("Explore error");
                var element = ObjectElement.CreateField(fieldName, fieldType, string.Format(ExploreError, ex.GetType(), ex.Message));
                return(element);
            }
        }