[runtime] Fix corlib out of date error with disabled COM
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / Microsoft.Tools.Common / Microsoft / Activities / Presentation / Xaml / ActivityTemplateFactoryBuilderReader.cs
1 // <copyright>
2 //   Copyright (c) Microsoft Corporation.  All rights reserved.
3 // </copyright>
4
5 namespace Microsoft.Activities.Presentation.Xaml
6 {
7     using System;
8     using System.Activities.Presentation.Toolbox;
9     using System.Xaml;
10
11     // ActivityTemplateFactoryBuilderReader is a XamlReader that support <ActivityTemplateFactory x:Class ... 
12     //
13     // Think of this class (and any other XamlReader) as a XAML node stream editor
14     // XAML node are *not* objects, they are represented as this. For example, when the reader encounter a StartObject node, its NodeType will become StartObject, and its Type will become the type of the starting object.
15     // The writer will then edit the stream and send the nodes to the underlying stream (by calling the methods on the underlying writer)
16     // 
17     // The editing algorithm goes as follow:
18     // 
19     // Initially, the first node is read from the underlying reader, if the first node is <ActivityTemplateFactory, then we start buffering nodes, otherwise we simply switch to the Bypass state
20     // We transform and buffer the transformed nodes until we reach the StartMember of Implementation Node, then we yield the control and switch to the ReadingFromBuffer state.
21     //
22     // All the external calls are then delegated to the reader provided by the buffer.
23     //
24     // Eventually, the buffer will used up, and we will switch to the Bypass state.
25     internal sealed class ActivityTemplateFactoryBuilderReader : XamlReader, IXamlLineInfo
26     {
27         private XamlSchemaContext schemaContext;
28         private XamlReader underlyingReader;
29         private XamlNodeQueue queuedNodes;
30         private XamlType activityTemplateFactoryBuilderType;
31         private XamlMember activityTemplateFactoryBuilderImplementationMember;
32         private XamlMember activityTemplateFactoryBuilderNameMember;
33         private XamlMember activityTemplateFactoryBuilderTargetTypeMember;
34
35         private bool hasLineInfo;
36         private ActivityTemplateFactoryBuilderReaderStates currentState = ActivityTemplateFactoryBuilderReaderStates.InitialState;
37
38         public ActivityTemplateFactoryBuilderReader(XamlReader underlyingReader, XamlSchemaContext schemaContext)
39         {
40             this.underlyingReader = underlyingReader;
41             this.schemaContext = schemaContext;
42             this.hasLineInfo = this.underlyingReader is IXamlLineInfo;
43         }
44
45         private enum ActivityTemplateFactoryBuilderReaderStates
46         {
47             InitialState,
48             ReadingFromBufferState,
49             BypassState,
50         }
51
52         public override bool IsEof
53         {
54             get
55             {
56                 if (this.currentState == ActivityTemplateFactoryBuilderReaderStates.ReadingFromBufferState)
57                 {
58                     return false;
59                 }
60                 else
61                 {
62                     return this.underlyingReader.IsEof;
63                 }
64             }
65         }
66
67         public override XamlMember Member
68         {
69             get { return this.CurrentReader.Member; }
70         }
71
72         public override NamespaceDeclaration Namespace
73         {
74             get { return this.CurrentReader.Namespace; }
75         }
76
77         public override XamlNodeType NodeType
78         {
79             get { return this.CurrentReader.NodeType; }
80         }
81
82         public override XamlSchemaContext SchemaContext
83         {
84             get { return this.schemaContext; }
85         }
86
87         public override XamlType Type
88         {
89             get { return this.CurrentReader.Type; }
90         }
91
92         public override object Value
93         {
94             get { return this.CurrentReader.Value; }
95         }
96
97         public bool HasLineInfo
98         {
99             get { return this.hasLineInfo; }
100         }
101
102         public int LineNumber
103         {
104             get
105             {
106                 if (this.HasLineInfo)
107                 {
108                     return this.CurrentLineInfo.LineNumber;
109                 }
110                 else
111                 {
112                     return 0;
113                 }
114             }
115         }
116
117         public int LinePosition
118         {
119             get
120             {
121                 if (this.HasLineInfo)
122                 {
123                     return this.CurrentLineInfo.LinePosition;
124                 }
125                 else
126                 {
127                     return 0;
128                 }
129             }
130         }
131
132         private XamlReader CurrentReader
133         {
134             get
135             {
136                 switch (this.currentState)
137                 {
138                     case ActivityTemplateFactoryBuilderReaderStates.InitialState:
139                     case ActivityTemplateFactoryBuilderReaderStates.BypassState:
140                         return this.underlyingReader;
141
142                     default:
143                         SharedFx.Assert(this.currentState == ActivityTemplateFactoryBuilderReaderStates.ReadingFromBufferState, "This is the only remaining ActivityTemplateFactoryBuilderReaderStates.");
144                         return this.queuedNodes.Reader;
145                 }
146             }
147         }
148
149         private IXamlLineInfo CurrentLineInfo
150         {
151             get { return (IXamlLineInfo)this.CurrentReader; }
152         }
153
154         private XamlType ActivityTemplateFactoryBuilderType
155         {
156             get
157             {
158                 if (this.activityTemplateFactoryBuilderType == null)
159                 {
160                     this.activityTemplateFactoryBuilderType = new XamlType(typeof(ActivityTemplateFactoryBuilder), this.schemaContext);
161                 }
162
163                 return this.activityTemplateFactoryBuilderType;
164             }
165         }
166
167         private XamlMember ActivityTemplateFactoryBuilderImplementationMember
168         {
169             get
170             {
171                 if (this.activityTemplateFactoryBuilderImplementationMember == null)
172                 {
173                     this.activityTemplateFactoryBuilderImplementationMember = ActivityTemplateFactoryBuilderXamlMembers.ActivityTemplateFactoryBuilderImplementationMember(this.schemaContext);
174                 }
175
176                 return this.activityTemplateFactoryBuilderImplementationMember;
177             }
178         }
179
180         private XamlMember ActivityTemplateFactoryBuilderNameMember
181         {
182             get
183             {
184                 if (this.activityTemplateFactoryBuilderNameMember == null)
185                 {
186                     this.activityTemplateFactoryBuilderNameMember = ActivityTemplateFactoryBuilderXamlMembers.ActivityTemplateFactoryBuilderNameMember(this.schemaContext);
187                 }
188
189                 return this.activityTemplateFactoryBuilderNameMember;
190             }
191         }
192
193         private XamlMember ActivityTemplateFactoryBuilderTargetTypeMember
194         {
195             get
196             {
197                 if (this.activityTemplateFactoryBuilderTargetTypeMember == null)
198                 {
199                     this.activityTemplateFactoryBuilderTargetTypeMember = ActivityTemplateFactoryBuilderXamlMembers.ActivityTemplateFactoryBuilderTargetTypeMember(this.schemaContext);
200                 }
201
202                 return this.activityTemplateFactoryBuilderTargetTypeMember;
203             }
204         }
205
206         public override bool Read()
207         {
208             switch (this.currentState)
209             {
210                 case ActivityTemplateFactoryBuilderReaderStates.InitialState:
211                     bool hasMoreNodes = this.underlyingReader.Read();
212                     if (this.underlyingReader.NodeType == XamlNodeType.StartObject && IsActivityTemplateFactoryType(this.underlyingReader.Type))
213                     {
214                         Type underlyingType = this.underlyingReader.Type.UnderlyingType;
215                         Type targetType = underlyingType.IsGenericType ? underlyingType.GetGenericArguments()[0] : null;
216
217                         this.currentState = ActivityTemplateFactoryBuilderReaderStates.ReadingFromBufferState;
218                         this.queuedNodes = new XamlNodeQueue(this.schemaContext);
219                         this.queuedNodes.Writer.WriteStartObject(this.ActivityTemplateFactoryBuilderType, (IXamlLineInfo)this.underlyingReader);
220
221                         string className;
222
223                         while (this.underlyingReader.Read())
224                         {
225                             if (this.underlyingReader.NodeType == XamlNodeType.StartMember && this.underlyingReader.Member == XamlLanguage.Class)
226                             {
227                                 this.underlyingReader.Read();
228                                 className = (string)this.underlyingReader.Value;
229                                 this.underlyingReader.Read();
230                                 this.queuedNodes.Writer.WriteStartMember(this.ActivityTemplateFactoryBuilderNameMember, (IXamlLineInfo)this.underlyingReader);
231                                 this.queuedNodes.Writer.WriteValue(className, (IXamlLineInfo)this.underlyingReader);
232                                 this.queuedNodes.Writer.WriteEndMember((IXamlLineInfo)this.underlyingReader);
233                                 if (targetType != null)
234                                 {
235                                     this.queuedNodes.Writer.WriteStartMember(this.ActivityTemplateFactoryBuilderTargetTypeMember, (IXamlLineInfo)this.underlyingReader);
236                                     object targetTypeString = targetType;
237                                     this.queuedNodes.Writer.WriteValue(targetTypeString);
238                                     this.queuedNodes.Writer.WriteEndMember();
239                                 }
240                             }
241                             else if (this.underlyingReader.NodeType == XamlNodeType.StartMember && this.IsActivityTemplateFactoryImplementationMember(this.underlyingReader.Member))
242                             {
243                                 this.queuedNodes.Writer.WriteStartMember(this.ActivityTemplateFactoryBuilderImplementationMember, (IXamlLineInfo)this.underlyingReader);
244                                 return true;
245                             }
246                         }
247                     }
248
249                     return hasMoreNodes;
250
251                 case ActivityTemplateFactoryBuilderReaderStates.ReadingFromBufferState:
252                     if (this.queuedNodes.Reader.Read())
253                     {
254                         return true;
255                     }
256                     else
257                     {
258                         this.currentState = ActivityTemplateFactoryBuilderReaderStates.BypassState;
259                         this.queuedNodes = null;
260                         return this.underlyingReader.Read();
261                     }
262
263                 default:
264                     SharedFx.Assert(this.currentState == ActivityTemplateFactoryBuilderReaderStates.BypassState, "This is the only remaining ActivityTemplateFactoryBuilderReaderStates.");
265                     return this.underlyingReader.Read();
266             }
267         }
268
269         private static bool IsActivityTemplateFactoryType(XamlType xamlType)
270         {
271             if (xamlType.UnderlyingType == null)
272             {
273                 return false;
274             }
275
276             return xamlType.UnderlyingType == typeof(ActivityTemplateFactory) || (xamlType.UnderlyingType.IsGenericType && xamlType.UnderlyingType.GetGenericTypeDefinition() == typeof(ActivityTemplateFactory<>));
277         }
278
279         private bool IsActivityTemplateFactoryImplementationMember(XamlMember xamlMember)
280         {
281             return IsActivityTemplateFactoryType(xamlMember.DeclaringType) && xamlMember == ActivityTemplateFactoryBuilderXamlMembers.ActivityTemplateFactoryImplementationMemberForReader(xamlMember.DeclaringType.UnderlyingType, this.schemaContext);
282         }
283     }
284 }