[reflection] Coop handles icalls in System.Reflection and System.RuntimeTypeHandle...
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / NamespaceSettingsHandler.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4
5 namespace System.Activities.Presentation
6 {
7     using System.Activities.Debugger;
8     using System.Activities.Expressions;
9     using System.Activities.Presentation.Model;
10     using System.Collections.Generic;
11     using System.Collections.ObjectModel;
12     using System.ComponentModel;
13     using System.Linq;
14     using System.Runtime;
15     using System.Runtime.Versioning;
16     using System.ServiceModel.Activities;
17     using Microsoft.Activities.Presentation;
18     using Microsoft.VisualBasic.Activities;
19
20     //the class does several things:
21     //1. make sure a special property "Imports" (implemented using VisualBasicSettings attached properties) is added to the root object before it's loaded into ModelTree
22     //2. make sure the "root workflow" of the root object always have the same VisualBasicSettings
23     static class NamespaceSettingsHandler
24     {
25         static Type WorkflowServiceType = typeof(WorkflowService);
26
27         static public void PreviewLoadRoot(object sender, WorkflowDesigner.PreviewLoadEventArgs args)
28         {
29             object root = args.Instance;
30
31             DesignerConfigurationService configService = args.Context.Services.GetService<DesignerConfigurationService>();
32
33             if (configService != null && configService.NamespaceConversionEnabled)
34             {
35                 ConvertNamespaces(root, args.Context);
36             }
37
38             if (root.GetType() == WorkflowServiceType)
39             {
40                 args.Context.Services.Subscribe<ModelTreeManager>(manager => manager.Root.PropertyChanged += new PropertyChangedEventHandler(OnRootPropertyChanged));
41             }
42
43             TypeDescriptor.AddProvider(new RootModelTypeDescriptionProvider(root), root);
44         }
45
46         private static void ConvertNamespaces(object root, EditingContext context)
47         {
48             VisualBasicSettings settings = VisualBasic.GetSettings(root);
49             IList<AssemblyReference> references;
50             IList<string> importedNamespaces = NamespaceHelper.GetTextExpressionNamespaces(root, out references);
51             FrameworkName targetFramework = WorkflowDesigner.GetTargetFramework(context);
52             if (targetFramework.IsLessThan45())
53             {
54                 if (settings == null)
55                 {
56                     if ((importedNamespaces != null) && (importedNamespaces.Count > 0))
57                     {
58                         NamespaceHelper.ConvertToVBSettings(
59                             importedNamespaces,
60                             references,
61                             context,
62                             out settings);
63                     }
64                     else
65                     {
66                         settings = new VisualBasicSettings();
67                     }
68
69                     NamespaceHelper.SetVisualBasicSettings(root, settings);
70                     NamespaceHelper.SetTextExpressionNamespaces(root, null, null);
71                 }
72
73                 IDebuggableWorkflowTree debuggableWorkflowTree = root as IDebuggableWorkflowTree;
74                 if (debuggableWorkflowTree != null)
75                 {
76                     Activity rootActivity = debuggableWorkflowTree.GetWorkflowRoot();
77                     if (rootActivity != null)
78                     {
79                         NamespaceHelper.SetVisualBasicSettings(rootActivity, settings);
80                         NamespaceHelper.SetTextExpressionNamespaces(rootActivity, null, null);
81                     }                 
82                 }
83             }
84             else
85             {
86                 if ((importedNamespaces == null) || (importedNamespaces.Count == 0))
87                 {
88                     if (settings != null)
89                     {
90                         NamespaceHelper.ConvertToTextExpressionImports(settings, out importedNamespaces, out references);
91                         NamespaceHelper.SetTextExpressionNamespaces(root, importedNamespaces, references);
92                         NamespaceHelper.SetVisualBasicSettings(root, null);
93                     }
94                     else
95                     {
96                         NamespaceHelper.SetTextExpressionNamespaces(root, new Collection<string>(), new Collection<AssemblyReference>());
97                     }
98                 }
99             }
100         }
101
102         static void OnRootPropertyChanged(object sender, PropertyChangedEventArgs e)
103         {
104             ModelItem rootModel = sender as ModelItem;
105             Fx.Assert(rootModel != null, "sender item could not be null");
106             ModelProperty changedProperty = rootModel.Properties[e.PropertyName];
107             if (changedProperty == null)
108             {
109                 return;
110             }
111
112             object changedPropertyValue = changedProperty.ComputedValue;
113             if (changedPropertyValue == null)
114             {
115                 return;
116             }
117
118             Fx.Assert(rootModel.GetCurrentValue().GetType() == WorkflowServiceType, "This handler should only be attached when the root is WorkflowService");
119             IDebuggableWorkflowTree root = rootModel.GetCurrentValue() as IDebuggableWorkflowTree;            
120             Activity rootActivity = root.GetWorkflowRoot();
121             if (rootActivity == changedPropertyValue)
122             {
123                 if (WorkflowDesigner.GetTargetFramework(rootModel.GetEditingContext()).IsLessThan45())
124                 {
125                     VisualBasicSettings settings = VisualBasic.GetSettings(root);
126                     NamespaceHelper.SetVisualBasicSettings(changedPropertyValue, settings);
127                 }
128                 else
129                 {
130                     IList<AssemblyReference> referencedAssemblies;
131                     IList<string> namespaces = NamespaceHelper.GetTextExpressionNamespaces(root, out referencedAssemblies);
132                     NamespaceHelper.SetTextExpressionNamespaces(rootActivity, namespaces, referencedAssemblies);
133                 }
134             }
135         }
136     }
137
138     class RootModelTypeDescriptionProvider : TypeDescriptionProvider
139     {
140         public RootModelTypeDescriptionProvider(object instance)
141             : base(TypeDescriptor.GetProvider(instance))
142         {
143         }
144
145         public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
146         {
147             ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
148             return new RootModelTypeDescriptor(defaultDescriptor, instance);
149         }
150     }
151
152     class RootModelTypeDescriptor : CustomTypeDescriptor
153     {
154         object root;
155         NamespaceListPropertyDescriptor importDescriptor;
156
157         public RootModelTypeDescriptor(ICustomTypeDescriptor parent, object root)
158             : base(parent)
159         {
160             this.root = root;
161         }
162
163         PropertyDescriptor ImportDescriptor
164         {
165             get
166             {
167                 if (this.importDescriptor == null)
168                 {
169                     this.importDescriptor = new NamespaceListPropertyDescriptor(this.root);
170                 }
171
172                 return this.importDescriptor;
173             }
174         }
175
176         public override PropertyDescriptorCollection GetProperties()
177         {
178             return GetProperties(null);
179         }
180
181         public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
182         {
183             return new PropertyDescriptorCollection(base.GetProperties(attributes).Cast<PropertyDescriptor>()
184                 .Union(new PropertyDescriptor[] { this.ImportDescriptor }).ToArray());
185         }
186     }        
187 }