CodeDomSerializerBase.cs :  » 2.6.4-mono-.net-core » System.ComponentModel » System » ComponentModel » Design » Serialization » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.ComponentModel 
System.ComponentModel » System » ComponentModel » Design » Serialization » CodeDomSerializerBase.cs
//
// System.ComponentModel.Design.Serialization.CodeDomSerializerBase
//
// Authors:   
//    Ivan N. Zlatev (contact i-nZ.net)
//
// (C) 2007 Ivan N. Zlatev

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#if NET_2_0

using System;
using System.Collections;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.Design;

using System.CodeDom;

namespace System.ComponentModel.Design.Serialization{
  [EditorBrowsable (EditorBrowsableState.Never)]
  public abstract class CodeDomSerializerBase
  {

    // MSDN says that if the deserialization fails a CodeExpression is returned
    //
    private sealed class DeserializationErrorMarker : CodeExpression
    {
      public override bool Equals (object o)
      {
        return false;
      }

      public override int GetHashCode ()
      {
        return base.GetHashCode ();
      }
    }

    private static readonly DeserializationErrorMarker _errorMarker = new DeserializationErrorMarker ();

    internal CodeDomSerializerBase ()
    {
    }

    private class ExpressionTable : Hashtable // just so that we have a specific type to append to the context stack
    {
    }

    protected CodeExpression SerializeToExpression (IDesignerSerializationManager manager, object instance)
    {
      if (manager == null)
        throw new ArgumentNullException ("manager");

      CodeExpression expression = null;
      if (instance != null)
        expression = this.GetExpression (manager, instance); // 1 - IDesignerSerializationManager.GetExpression
      if (expression == null) {
        CodeDomSerializer serializer = this.GetSerializer (manager, instance); // 2 - manager.GetSerializer().Serialize()
        if (serializer != null) {
          object serialized = serializer.Serialize (manager, instance);
          expression = serialized as CodeExpression; // 3 - CodeStatement or CodeStatementCollection
          if (expression == null) {
            CodeStatement statement = serialized as CodeStatement;
            CodeStatementCollection statements = serialized as CodeStatementCollection;

            if (statement != null || statements != null) {
              CodeStatementCollection contextStatements = null;

              StatementContext context = manager.Context[typeof (StatementContext)] as StatementContext;
              if (context != null && instance != null)
                contextStatements = context.StatementCollection[instance];

              if (contextStatements == null)
                contextStatements = manager.Context[typeof (CodeStatementCollection)] as CodeStatementCollection;

              if (contextStatements != null) {
                if (statements != null)
                  contextStatements.AddRange (statements);
                else
                  contextStatements.Add (statement);
              }
            }
          }
          if (expression == null && instance != null)
            expression = this.GetExpression (manager, instance); // 4
        } else {
          ReportError (manager, "No serializer found for type '" + instance.GetType ().Name + "'");
        }
      }
      return expression;
    }

    protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, object instance)
    {
      DesignerSerializerAttribute attrInstance, attrType;
      attrType = attrInstance = null;

      CodeDomSerializer serializer = null;
      if (instance == null)
        serializer = this.GetSerializer (manager, null);
      else {    
        AttributeCollection attributes = TypeDescriptor.GetAttributes (instance);
        foreach (Attribute a in attributes) {
          DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute;
          if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) {
            attrInstance = designerAttr;
            break;
          }
        }
  
        attributes = TypeDescriptor.GetAttributes (instance.GetType ());
        foreach (Attribute a in attributes) {
          DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute;
          if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) {
            attrType = designerAttr;
            break;
          }
        }
  
        // if there is metadata modification in the instance then create the specified serializer instead of the one
        // in the Type.
        if (attrType != null && attrInstance != null && attrType.SerializerTypeName != attrInstance.SerializerTypeName)
          serializer = Activator.CreateInstance (manager.GetType (attrInstance.SerializerTypeName)) as CodeDomSerializer;
        else
          serializer = this.GetSerializer (manager, instance.GetType ());
      }

      return serializer;
    }

    protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, Type instanceType)
    {
      return manager.GetSerializer (instanceType, typeof (CodeDomSerializer)) as CodeDomSerializer;
    }

    protected CodeExpression GetExpression (IDesignerSerializationManager manager, object instance)
    {
      if (manager == null)
        throw new ArgumentNullException ("manager");
      if (instance == null)
        throw new ArgumentNullException ("instance");

      CodeExpression expression = null;

      ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable;
      if (expressions != null) // 1st try: ExpressionTable
        expression = expressions [instance] as CodeExpression;

      if (expression == null) { // 2nd try: RootContext
        RootContext context = manager.Context[typeof (RootContext)] as RootContext;
        if (context != null && context.Value == instance)
          expression = context.Expression;
      }

      if (expression == null) { // 3rd try: IReferenceService (instance.property.property.property
        string name = manager.GetName (instance);
        if (name == null || name.IndexOf (".") == -1) {
          IReferenceService service = manager.GetService (typeof (IReferenceService)) as IReferenceService;
          if (service != null) {
            name = service.GetName (instance);
            if (name != null && name.IndexOf (".") != -1) {
              string[] parts = name.Split (new char[] { ',' });
              instance = manager.GetInstance (parts[0]);
              if (instance != null) {
                expression = SerializeToExpression (manager, instance);
                if (expression != null) {
                  for (int i=1; i < parts.Length; i++)
                    expression = new CodePropertyReferenceExpression (expression, parts[i]);
                }
              }
            }
          }
        }
      }
      return expression;
    }

    protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression)
    {
      SetExpression (manager, instance, expression, false);
    }

    // XXX: isPreset - what does this do when set?
    //
    protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression, bool isPreset)
    {
      if (manager == null)
        throw new ArgumentNullException ("manager");
      if (instance == null)
        throw new ArgumentNullException ("instance");
      if (expression == null)
        throw new ArgumentNullException ("expression");

      ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable;
      if (expressions == null) {
        expressions = new ExpressionTable ();
        manager.Context.Append (expressions);
      }

      expressions[instance] = expression;
    }

    protected bool IsSerialized (IDesignerSerializationManager manager, object value) 
    {
      return this.IsSerialized (manager, value, false);
    }

    // XXX: What should honorPreset do?
    protected bool IsSerialized (IDesignerSerializationManager manager, object instance, bool honorPreset) 
    {
      if (instance == null)
        throw new ArgumentNullException ("instance");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      if (this.GetExpression (manager, instance) != null)
        return true;
      else
        return false;
    }

    protected CodeExpression SerializeCreationExpression (IDesignerSerializationManager manager, object value, out bool isComplete) 
    {
      if (value == null)
        throw new ArgumentNullException ("value");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      CodeExpression expression = null;

      TypeConverter converter = TypeDescriptor.GetConverter (value);
      if (converter != null && converter.CanConvertTo (typeof (InstanceDescriptor))) {
        InstanceDescriptor descriptor = converter.ConvertTo (value, typeof (InstanceDescriptor)) as InstanceDescriptor;
        isComplete = descriptor.IsComplete;
        if (descriptor != null || descriptor.MemberInfo != null)
          expression = this.SerializeInstanceDescriptor (manager, descriptor);
        else
          ReportError (manager, "Unable to serialize to InstanceDescriptor", 
                 "Value Type: " + value.GetType ().Name + System.Environment.NewLine + 
                 "Value (ToString): " + value.ToString ());
      } else {
        if (value.GetType().GetConstructor (Type.EmptyTypes) != null)
          expression = new CodeObjectCreateExpression (value.GetType ().FullName, new CodeExpression[0]);
        isComplete = false;
      }
      return expression;
    }

    private CodeExpression SerializeInstanceDescriptor (IDesignerSerializationManager manager, InstanceDescriptor descriptor)
    {
      CodeExpression expression = null;
      MemberInfo member = descriptor.MemberInfo;
      CodeExpression target = new CodeTypeReferenceExpression (member.DeclaringType);

      if (member is PropertyInfo) {
        expression = new CodePropertyReferenceExpression (target, member.Name);
      } else if (member is FieldInfo) {
        expression = new CodeFieldReferenceExpression (target, member.Name);
      } else if (member is MethodInfo) {
        CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression (target, member.Name);
        if (descriptor.Arguments != null && descriptor.Arguments.Count > 0)
          methodInvoke.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments));
        expression = methodInvoke;
      } else if (member is ConstructorInfo) {
        CodeObjectCreateExpression createExpr = new CodeObjectCreateExpression (member.DeclaringType);
        if (descriptor.Arguments != null && descriptor.Arguments.Count > 0)
          createExpr.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments));
        expression = createExpr;
      }

      return expression;
    }

    private CodeExpression[] SerializeParameters (IDesignerSerializationManager manager, ICollection parameters)
    {
      CodeExpression[] expressions = null;

      if (parameters != null && parameters.Count > 0) {
        expressions = new CodeExpression[parameters.Count];
        int i = 0;
        foreach (object parameter in parameters) {
          expressions[i] = this.SerializeToExpression (manager, parameter);
          i++;
        }
      }

      return expressions;
    }

    protected void SerializeEvent (IDesignerSerializationManager manager, CodeStatementCollection statements, 
                 object value, EventDescriptor descriptor) 
    {
      if (descriptor == null)
        throw new ArgumentNullException ("descriptor");
      if (value == null)
        throw new ArgumentNullException ("value");
      if (statements == null)
        throw new ArgumentNullException ("statements");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      MemberCodeDomSerializer serializer = manager.GetSerializer (descriptor.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer;
      if (serializer != null && serializer.ShouldSerialize (manager, value, descriptor))
        serializer.Serialize (manager, value, descriptor, statements);
    }

    protected void SerializeEvents (IDesignerSerializationManager manager, CodeStatementCollection statements, 
            object value, params Attribute[] filter)
    {
      if (filter == null)
        throw new ArgumentNullException ("filter");
      if (value == null)
        throw new ArgumentNullException ("value");
      if (statements == null)
        throw new ArgumentNullException ("statements");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      EventDescriptorCollection events = TypeDescriptor.GetEvents (value, filter);
      foreach (EventDescriptor e in events) 
        this.SerializeEvent (manager, statements, value, e);
    }

    protected void SerializeProperty (IDesignerSerializationManager manager, CodeStatementCollection statements, 
              object value, PropertyDescriptor propertyToSerialize)
    {
      if (propertyToSerialize == null)
        throw new ArgumentNullException ("propertyToSerialize");
      if (value == null)
        throw new ArgumentNullException ("value");
      if (statements == null)
        throw new ArgumentNullException ("statements");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      MemberCodeDomSerializer serializer = manager.GetSerializer (propertyToSerialize.GetType (), 
                        typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer;
      if (serializer != null && serializer.ShouldSerialize (manager, value, propertyToSerialize))
        serializer.Serialize (manager, value, propertyToSerialize, statements);
    }
    
    protected void SerializeProperties (IDesignerSerializationManager manager, CodeStatementCollection statements, 
                      object value, Attribute[] filter) 
    {
      if (filter == null)
        throw new ArgumentNullException ("filter");
      if (value == null)
        throw new ArgumentNullException ("value");
      if (statements == null)
        throw new ArgumentNullException ("statements");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (value, filter);
      foreach (PropertyDescriptor property in properties) {
        if (!property.Attributes.Contains (DesignerSerializationVisibilityAttribute.Hidden))
          this.SerializeProperty (manager, statements, value, property);
      }
    }

    protected virtual object DeserializeInstance (IDesignerSerializationManager manager, Type type, 
                    object[] parameters, string name, bool addToContainer)
    {
      if (type == null)
        throw new ArgumentNullException ("type");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      return manager.CreateInstance (type, parameters, name, addToContainer);
    }

    protected string GetUniqueName (IDesignerSerializationManager manager, object instance)
    {
      if (instance == null)
        throw new ArgumentNullException ("instance");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      string name = manager.GetName (instance);
      if (name == null) {
        INameCreationService service = manager.GetService (typeof (INameCreationService)) as INameCreationService;
        name = service.CreateName (null, instance.GetType ());
        if (name == null)
          name = instance.GetType ().Name.ToLower ();
        manager.SetName (instance, name);
      }
      return name;
    }

    protected object DeserializeExpression (IDesignerSerializationManager manager, string name, CodeExpression expression) 
    {
      if (expression == null)
        throw new ArgumentNullException ("expression");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      bool errorOccurred = false;
      object deserialized = null;

      // CodeThisReferenceExpression
      //
      CodeThisReferenceExpression thisExpr = expression as CodeThisReferenceExpression;
      if (thisExpr != null) {
        RootContext context = manager.Context[typeof (RootContext)] as RootContext;
        if (context != null) {
          deserialized = context.Value;
        } else {
          IDesignerHost host = manager.GetService (typeof (IDesignerHost)) as IDesignerHost;
          if (host != null)
            deserialized = host.RootComponent;
        }
      }
      
      // CodeVariableReferenceExpression
      //
      CodeVariableReferenceExpression varRef = expression as CodeVariableReferenceExpression;
      if (deserialized == null && varRef != null) {
        deserialized = manager.GetInstance (varRef.VariableName);
        if (deserialized == null) {
          ReportError (manager, "Variable '" + varRef.VariableName + "' not initialized prior to reference");
          errorOccurred = true;
        }
      }

      // CodeFieldReferenceExpression (used for Enum references as well)
      //
      CodeFieldReferenceExpression fieldRef = expression as CodeFieldReferenceExpression;
      if (deserialized == null && fieldRef != null) {
        deserialized = manager.GetInstance (fieldRef.FieldName);
        if (deserialized == null) {
          object fieldHolder = DeserializeExpression (manager, null, fieldRef.TargetObject);
          FieldInfo field = null;
          if (fieldHolder is Type) // static field
            field = ((Type)fieldHolder).GetField (fieldRef.FieldName, 
                          BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
          else // instance field
            field = fieldHolder.GetType().GetField (fieldRef.FieldName, 
                      BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
          if (field != null)
            deserialized = field.GetValue (fieldHolder);
        }
        if (deserialized == null)
          ReportError (manager, "Field '" + fieldRef.FieldName + "' not initialized prior to reference");
      }
        

      // CodePrimitiveExpression
      //
      CodePrimitiveExpression primitiveExp = expression as CodePrimitiveExpression;
      if (deserialized == null && primitiveExp != null)
        deserialized = primitiveExp.Value;

      // CodePropertyReferenceExpression
      //
      CodePropertyReferenceExpression propRef = expression as CodePropertyReferenceExpression;
      if (deserialized == null && propRef != null) {
        object target = DeserializeExpression (manager, null, propRef.TargetObject);
        if (target != null && target != _errorMarker) {
          bool found = false;
          if (target is Type) {
            PropertyInfo property = ((Type)target).GetProperty (propRef.PropertyName,
                            BindingFlags.GetProperty | 
                            BindingFlags.Public | BindingFlags.Static);
            if (property != null) {
              deserialized = property.GetValue (null, null);
              found = true;
            }

            // NRefactory seems to produce PropertyReferences to reference some fields and enums
            //
            FieldInfo field = ((Type)target).GetField (propRef.PropertyName,
                         BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
            if (field != null) {
              deserialized = field.GetValue (null);
              found = true;
            }
          } else {
            PropertyDescriptor property = TypeDescriptor.GetProperties (target)[propRef.PropertyName];
            if (property != null) {
              deserialized = property.GetValue (target);
              found = true;
            }

            FieldInfo field = target.GetType().GetField (propRef.PropertyName,
                           BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
            if (field != null) {
              deserialized = field.GetValue (null);
              found = true;
            }
          }
          
          if (!found) {
            ReportError (manager, "Missing field '" + propRef.PropertyName + " 'in type " + 
                   (target is Type ? ((Type)target).Name : target.GetType ().Name) + "'");
            errorOccurred = true;
          }
        }
      }

      // CodeObjectCreateExpression
      //
      CodeObjectCreateExpression createExpr = expression as CodeObjectCreateExpression;
      if (deserialized == null && createExpr != null) {
        Type type = manager.GetType (createExpr.CreateType.BaseType);
        if (type == null) {
          ReportError (manager, "Type '" + createExpr.CreateType.BaseType + "' not found." + 
                 "Are you missing a reference?");
          errorOccurred = true;
        } else {
          object[] arguments = new object[createExpr.Parameters.Count];
          for (int i=0; i < createExpr.Parameters.Count; i++) {
            arguments[i] = this.DeserializeExpression (manager, null, createExpr.Parameters[i]);
            if (arguments[i] == _errorMarker) {
              errorOccurred = true;
              break;
            }
          }
          if (!errorOccurred) {
            bool addToContainer = false;
            if (typeof(IComponent).IsAssignableFrom (type))
              addToContainer = true;
            deserialized = this.DeserializeInstance (manager, type, arguments, name, addToContainer);
            if (deserialized == _errorMarker || deserialized == null) {
              string info = "Type to create: " + createExpr.CreateType.BaseType + System.Environment.NewLine +
                "Name: " + name + System.Environment.NewLine +
                "addToContainer: " + addToContainer.ToString () + System.Environment.NewLine +
                "Parameters Count: " + createExpr.Parameters.Count + System.Environment.NewLine;
  
              for (int i=0; i < arguments.Length; i++) {
                info += "Parameter Number: " + i.ToString () + System.Environment.NewLine +
                  "Parameter Type: " + (arguments[i] == null ? "null" : arguments[i].GetType ().Name) +
                  System.Environment.NewLine +
                  "Parameter '" + i.ToString () + "' Value: " + arguments[i].ToString () + System.Environment.NewLine;
              }
              ReportError (manager, 
                     "Unable to create an instance of type '" + createExpr.CreateType.BaseType + "'",
                     info);
              errorOccurred = true;
            }
          }
        }
      }

      // CodeArrayCreateExpression
      //
      CodeArrayCreateExpression arrayCreateExpr = expression as CodeArrayCreateExpression;
      if (deserialized == null && arrayCreateExpr != null) {
        Type arrayType = manager.GetType (arrayCreateExpr.CreateType.BaseType);
        if (arrayType == null) {
          ReportError (manager, "Type '" + arrayCreateExpr.CreateType.BaseType + "' not found." + 
                 "Are you missing a reference?");
          errorOccurred = true;
        } else {
          ArrayList initializers = new ArrayList ();
          Type elementType = arrayType.GetElementType ();
          deserialized = Array.CreateInstance (arrayType, arrayCreateExpr.Initializers.Count);
          for (int i = 0; i < arrayCreateExpr.Initializers.Count; i++) {
            object element = this.DeserializeExpression (manager, null, arrayCreateExpr.Initializers[i]);
            errorOccurred = (element == _errorMarker);
            if (!errorOccurred) {
              if (arrayType.IsInstanceOfType (element)) {
                initializers.Add (element);
              } else {
                ReportError (manager, 
                       "Array initializer element type incompatible with array type.",
                       "Array Type: " + arrayType.Name + System.Environment.NewLine +
                       "Array Element Type: " + elementType + System.Environment.NewLine +
                       "Initializer Type: " + (element == null ? "null" : element.GetType ().Name));
                errorOccurred = true;
              }
            }
          }
          if (!errorOccurred)
            initializers.CopyTo ((Array)deserialized, 0);
        }
      }

      // CodeMethodInvokeExpression
      //
      CodeMethodInvokeExpression methodExpr = expression as CodeMethodInvokeExpression;
      if (deserialized == null && methodExpr != null) {
        object target = this.DeserializeExpression (manager, null, methodExpr.Method.TargetObject);
        object[] parameters = null;
        if (target == _errorMarker || target == null) {
          errorOccurred = true;
        } else {
          parameters = new object[methodExpr.Parameters.Count];
          for (int i=0; i < methodExpr.Parameters.Count; i++) {
            parameters[i] = this.DeserializeExpression (manager, null, methodExpr.Parameters[i]);
            if (parameters[i] == _errorMarker) {
              errorOccurred = true;
              break;
            }
          }
        }

        if (!errorOccurred) {
          MethodInfo method = null;
          if (target is Type) {
            method = GetExactMethod ((Type)target, methodExpr.Method.MethodName, 
                         BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                         parameters);
          } else {
            method = GetExactMethod (target.GetType(), methodExpr.Method.MethodName, 
                         BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                         parameters);
          }
  
          if (method != null) {
            deserialized = method.Invoke (target, parameters);
          } else {
            string info = 
              "Method Name: " + methodExpr.Method.MethodName + System.Environment.NewLine +
              "Method is: " + (target is Type ? "static" : "instance") + System.Environment.NewLine +
              "Method Holder Type: " + (target is Type ? ((Type)target).Name : target.GetType ().Name) + System.Environment.NewLine +
              "Parameters Count: " + methodExpr.Parameters.Count + System.Environment.NewLine +
              System.Environment.NewLine;

            for (int i = 0; i < parameters.Length; i++) {
              info += "Parameter Number: " + i.ToString () + System.Environment.NewLine +
                "Parameter Type: " + (parameters[i] == null ? "null" : parameters[i].GetType ().Name) +
                System.Environment.NewLine +
                "Parameter " + i.ToString () + " Value: " + parameters[i].ToString () + System.Environment.NewLine;
            }
            ReportError (manager, 
                   "Method '" + methodExpr.Method.MethodName + "' missing in type '" + 
                   (target is Type ? ((Type)target).Name : target.GetType ().Name + "'"),
                   info);
            errorOccurred = true;
          }
        }
      }

      // CodeTypeReferenceExpression
      //
      CodeTypeReferenceExpression typeRef = expression as CodeTypeReferenceExpression;
      if (deserialized == null && typeRef != null) {
        deserialized = manager.GetType (typeRef.Type.BaseType);
        if (deserialized == null) {
          ReportError (manager, "Type '" + typeRef.Type.BaseType + "' not found." + 
                 "Are you missing a reference?");
          errorOccurred = true;
        }
      }

      // CodeCastExpression
      // 
      CodeCastExpression castExpr = expression as CodeCastExpression;
      if (deserialized == null && castExpr != null) {
        Type targetType = manager.GetType (castExpr.TargetType.BaseType);
        object instance = DeserializeExpression (manager, null, castExpr.Expression);
        if (instance != null && instance != _errorMarker && targetType != null) {
          IConvertible convertible = instance as IConvertible;
          if (convertible != null) {
            try {
              instance = convertible.ToType (targetType, null);
            } catch {
              errorOccurred = true;
            }
          } else {
            errorOccurred = true;
          }
          if (errorOccurred) {
            ReportError (manager, "Unable to convert type '" + instance.GetType ().Name + 
                   "' to type '" + castExpr.TargetType.BaseType + "'",
                   "Target Type: " + castExpr.TargetType.BaseType + System.Environment.NewLine +
                   "Instance Type: " + (instance == null ? "null" : instance.GetType ().Name) + System.Environment.NewLine +
                   "Instance Value: " + (instance == null ? "null" : instance.ToString()) + System.Environment.NewLine +
                   "Instance is IConvertible: " + (instance is IConvertible).ToString());
          }

          deserialized = instance;
        }
      }


      // CodeBinaryOperatorExpression
      //
      CodeBinaryOperatorExpression binOperator = expression as CodeBinaryOperatorExpression;
      if (deserialized == null && binOperator != null) {
        string errorText = null;
        IConvertible left = null;
        IConvertible right = null;
        switch (binOperator.Operator) {
          case CodeBinaryOperatorType.BitwiseOr:
            left = DeserializeExpression (manager, null, binOperator.Left) as IConvertible;
            right = DeserializeExpression (manager, null, binOperator.Right) as IConvertible;
            if (left is Enum && right is Enum) {
              deserialized = Enum.ToObject (left.GetType (), Convert.ToInt64 (left) | Convert.ToInt64 (right));
            } else {
              errorText = "CodeBinaryOperatorType.BitwiseOr allowed only on Enum types";
              errorOccurred = true;
            }
            break;
          default:
            errorText = "Unsupported CodeBinaryOperatorType: " + binOperator.Operator.ToString ();
            errorOccurred = true;
            break;
        }

        if (errorOccurred) {
          string info = "BinaryOperator Type: " + binOperator.Operator.ToString() + System.Environment.NewLine +
            "Left Type: " + (left == null ? "null" : left.GetType().Name) + System.Environment.NewLine +
            "Left Value: " + (left == null ? "null" : left.ToString ()) + System.Environment.NewLine +
            "Left Expression Type: " + binOperator.Left.GetType ().Name + System.Environment.NewLine +
            "Right Type: " + (right == null ? "null" : right.GetType().Name) + System.Environment.NewLine +
            "Right Value: " + (right == null ? "null" : right.ToString ()) + System.Environment.NewLine +
            "Right Expression Type: " + binOperator.Right.GetType ().Name;
          ReportError (manager, errorText, info);
        }
      }


      if (!errorOccurred) {
        if (deserialized == null && !(expression is CodePrimitiveExpression) && !(expression is CodeMethodInvokeExpression)) {
          ReportError (manager, "Unsupported Expression Type: " + expression.GetType ().Name);
          errorOccurred = true;
        }
      }

      if (errorOccurred)
        deserialized = _errorMarker;
      return deserialized;
    }

    // Searches for a method on type that matches argument types
    //
    private MethodInfo GetExactMethod (Type type, string methodName, BindingFlags flags, ICollection argsCollection)
    {
      object[] arguments = null;
      Type[] types = Type.EmptyTypes;

      if (argsCollection != null) {
        arguments = new object[argsCollection.Count];
        types = new Type[argsCollection.Count];
        argsCollection.CopyTo (arguments, 0);

        for (int i=0; i < arguments.Length; i++) {
          if (arguments[i] == null)
            types[i] = null;
          else
            types[i] = arguments[i].GetType ();
        }
      }

      return type.GetMethod (methodName, flags, null, types, null);
    }

    protected void DeserializeStatement (IDesignerSerializationManager manager, CodeStatement statement)
    {
      if (statement == null)
        throw new ArgumentNullException ("statement");
      if (manager == null)
        throw new ArgumentNullException ("manager");

      // CodeAssignStatement
      //
      CodeAssignStatement assignment = statement as CodeAssignStatement;
      if (assignment != null)
        DeserializeAssignmentStatement (manager, assignment);

      // CodeExpressionStatement
      //
      CodeExpressionStatement expression = statement as CodeExpressionStatement;
      if (expression != null)
        this.DeserializeExpression (manager, null, expression.Expression);

      // CodeAttachEventStatement
      //
      CodeAttachEventStatement attachStatement = statement as CodeAttachEventStatement;
      if (attachStatement != null) {
        string methodName = null;

        CodeObjectCreateExpression createExpr = attachStatement.Listener as CodeObjectCreateExpression;
        if (createExpr != null && createExpr.Parameters.Count == 1 ) { // += new EventType (method)
          CodeMethodReferenceExpression handlerRef = createExpr.Parameters[0] as CodeMethodReferenceExpression;
          if (handlerRef != null)
            methodName = handlerRef.MethodName;
        }

        CodeDelegateCreateExpression delegateCreateExpr = attachStatement.Listener as CodeDelegateCreateExpression;
        if (delegateCreateExpr != null)// += new EventType (method)
          methodName = delegateCreateExpr.MethodName;

        CodeMethodReferenceExpression methodRef = attachStatement.Listener as CodeMethodReferenceExpression;
        if (methodRef != null) // += method
          methodName = methodRef.MethodName;

        object component = DeserializeExpression (manager, null, attachStatement.Event.TargetObject);
        if (component != null && component != _errorMarker && methodName != null) {
          string error = null;
          EventDescriptor eventDescriptor = TypeDescriptor.GetEvents (component)[attachStatement.Event.EventName];
          if (eventDescriptor != null) {
            IEventBindingService service = manager.GetService (typeof (IEventBindingService)) as IEventBindingService;
            if (service != null)
              service.GetEventProperty (eventDescriptor).SetValue (component, methodName);
            else
              error = "IEventBindingService missing";
          } else {
            error = "No event '" + attachStatement.Event.EventName + 
              "' found in type '" + component.GetType ().Name + "'";
          }

          if (error != null) {
            ReportError (manager, error, "Method Name: " + methodName + System.Environment.NewLine +
              "Event Name: " + attachStatement.Event.EventName + System.Environment.NewLine +
              "Listener Expression Type: " + methodRef.GetType ().Name + System.Environment.NewLine +
              "Event Holder Type: " + component.GetType ().Name + System.Environment.NewLine +
              "Event Holder Expression Type: " + attachStatement.Event.TargetObject.GetType ().Name);
          }
        }
      }
    }

    private void DeserializeAssignmentStatement (IDesignerSerializationManager manager, CodeAssignStatement statement)
    {
      CodeExpression leftExpr = statement.Left;
      
      // Assign to a Property
      //
      CodePropertyReferenceExpression propRef = leftExpr as CodePropertyReferenceExpression;
      if (propRef != null) {
        object propertyHolder = DeserializeExpression (manager, null, propRef.TargetObject);
        object value = null;
        if (propertyHolder != null && propertyHolder != _errorMarker)
          value = DeserializeExpression (manager, null, statement.Right);

        if (value != null && value != _errorMarker && propertyHolder != null) {
          PropertyDescriptor property = TypeDescriptor.GetProperties (propertyHolder)[propRef.PropertyName];
          if (property != null) {
            property.SetValue (propertyHolder, value);
          } else {
            ReportError (manager, 
                   "Missing property '" + propRef.PropertyName + 
                   "' in type '" + propertyHolder.GetType ().Name + "'");
          }
        }
      }
      
      // Assign to a Field
      // 
      CodeFieldReferenceExpression fieldRef = leftExpr as CodeFieldReferenceExpression;
      if (fieldRef != null && fieldRef.FieldName != null) {
        // Note that if the Right expression is a CodeCreationExpression the component will be created in this call
        //
        object fieldHolder = DeserializeExpression (manager, null, fieldRef.TargetObject);
        object value = null;
        if (fieldHolder != null && fieldHolder != _errorMarker)
          value = DeserializeExpression (manager, fieldRef.FieldName, statement.Right);
        FieldInfo field = null;

        RootContext context = manager.Context[typeof (RootContext)] as RootContext;
        if (fieldHolder != null && fieldHolder != _errorMarker && value != _errorMarker) {
          if (fieldRef.TargetObject is CodeThisReferenceExpression && context != null && context.Value == fieldHolder) {
            // Do not deserialize the fields of the root component, because the root component type 
            // is actually an instance of the its parent type, e.g: CustomControl : _UserControl_
            // and thus it doesn't contain the fields. The trick is that once DeserializeExpression 
            // is called on a CodeObjectCreateExpression the component is created and is added to the name-instance
            // table.
            // 
          } else {
            if (fieldHolder is Type) // static field
              field = ((Type)fieldHolder).GetField (fieldRef.FieldName, 
                            BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
            else // instance field
              field = fieldHolder.GetType().GetField (fieldRef.FieldName, 
                        BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
            if (field != null)
              field.SetValue (fieldHolder, value);
            else {
              ReportError (manager, "Field '" + fieldRef.FieldName + "' missing in type '" +
                     fieldHolder.GetType ().Name + "'",
                     "Field Name: " + fieldRef.FieldName + System.Environment.NewLine +
                     "Field is: " + (fieldHolder is Type ? "static" : "instance") + System.Environment.NewLine +
                     "Field Value: " + (value == null ? "null" : value.ToString()) + System.Environment.NewLine +
                     "Field Holder Type: " + fieldHolder.GetType ().Name + System.Environment.NewLine +
                     "Field Holder Expression Type: " + fieldRef.TargetObject.GetType ().Name);
            }
          }
        }
      }

      // Assign to a Variable
      // 
      CodeVariableReferenceExpression varRef = leftExpr as CodeVariableReferenceExpression;
      if (varRef != null && varRef.VariableName != null) {
        object value = DeserializeExpression (manager, varRef.VariableName, statement.Right);
        // If .Right is not CodeObjectCreateExpression the instance won't be assigned a name, 
        // so do it ourselves
        if (value != _errorMarker && manager.GetName (value) == null)
          manager.SetName (value, varRef.VariableName);
      }
    }

    internal void ReportError (IDesignerSerializationManager manager, string message)
    {
      this.ReportError (manager, message, String.Empty);
    }

    internal void ReportError (IDesignerSerializationManager manager, string message, string details)
    {
      try {
        throw new Exception (message);
      } catch (Exception e) {
        e.Data["Details"] = message + Environment.NewLine + Environment.NewLine + details;
        manager.ReportError (e);
      }
    }

#region Resource Serialization - TODO
    protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value) 
    {
      throw new NotImplementedException ();
    }
    
    protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value, 
                  bool ensureInvariant) 
    {
      throw new NotImplementedException ();
    }
     
    protected void SerializePropertiesToResources (IDesignerSerializationManager manager, CodeStatementCollection statements, 
                     object value, Attribute[] filter) 
    {
      throw new NotImplementedException ();
    }

    protected void SerializeResource (IDesignerSerializationManager manager, string resourceName, object value)
    {
      throw new NotImplementedException ();
    }

    protected void SerializeResourceInvariant (IDesignerSerializationManager manager, string resourceName, object value) 
    {
      throw new NotImplementedException ();
    }

    protected void DeserializePropertiesFromResources (IDesignerSerializationManager manager, object value, Attribute[] filter)
    {
      throw new NotImplementedException ();
    }
#endregion
  }
}
#endif
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.