2005-09-01 Iain McCoy <iain@mccoy.id.au>
[mono.git] / mcs / class / PresentationFramework / Mono.Windows.Serialization / ParserConsumerBase.cs
1 using System;
2 using System.Reflection;
3 using System.Windows;
4 using System.Windows.Serialization;
5 using System.Xml;
6 using System.Diagnostics;
7
8 namespace Mono.Windows.Serialization {
9         /* base class to help consume the event stream produced by the parser
10          *
11          * the crunch method will call the relevant methods according to what
12          * the parser returns. The easiest way to implement a class that builds
13          * something from a xaml file is probably to inherit from this class.
14          */
15         internal abstract class ParserConsumerBase {
16                 internal void crunch (XmlTextReader reader) {
17                         int justClosed = 0;
18                         XamlParser p = new XamlParser(reader);
19                         XamlNode n;
20                         while (true) {
21                                 n = p.GetNextNode();
22                                 if (n == null)
23                                         break;
24                                 Debug.WriteLine(this.GetType() + ": INCOMING " + n.GetType());
25                                 if (n is XamlDocumentStartNode) {
26                                         Debug.WriteLine(this.GetType() + ": document begins");
27                                         // do nothing
28                                 } else if (n is XamlElementStartNode && n.Depth == 0) {
29                                         Debug.WriteLine(this.GetType() + ": element begins as top-level");
30                                         CreateTopLevel(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name);
31                                 } else if (n is XamlElementStartNode && ((XamlElementStartNode)n).propertyObject) {
32                                         Debug.WriteLine(this.GetType() + ": element begins as property value");
33                                         string key = getKeyFromNode(n);
34                                         CreatePropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name, key);
35                                 } else if (n is XamlElementStartNode && ((XamlElementStartNode)n).depPropertyObject) {
36                                         Debug.WriteLine(this.GetType() + ": element begins as dependency property value");
37                                         string key = getKeyFromNode(n);
38                                         CreateDependencyPropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name, key);
39
40                                 } else if (n is XamlElementStartNode) {
41                                         Debug.WriteLine(this.GetType() + ": element begins");
42                                         string key = getKeyFromNode(n);
43                                         CreateObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name, key);
44                                 } else if (n is XamlPropertyNode && ((XamlPropertyNode)n).PropInfo != null) {
45                                         Debug.WriteLine(this.GetType() + ": normal property begins");
46                                         CreateProperty(((XamlPropertyNode)n).PropInfo);
47                                 } else if (n is XamlPropertyNode && ((XamlPropertyNode)n).DP != null) {
48                                         Debug.WriteLine(this.GetType() + ": dependency property begins");
49                                         DependencyProperty dp = ((XamlPropertyNode)n).DP;
50                                         Type typeAttachedTo = dp.OwnerType;
51                                         string propertyName = ((XamlPropertyNode)n).PropertyName;
52                                         
53                                         CreateDependencyProperty(typeAttachedTo, propertyName, dp.PropertyType);
54                                 } else if (n is XamlClrEventNode && !(((XamlClrEventNode)n).EventMember is EventInfo)) {
55                                         Debug.WriteLine(this.GetType() + ": delegate property");
56                                         CreatePropertyDelegate(((XamlClrEventNode)n).Value, ((PropertyInfo)((XamlClrEventNode)n).EventMember).PropertyType);
57                                         EndProperty();
58
59
60                                 } else if (n is XamlClrEventNode) {
61                                         Debug.WriteLine(this.GetType() + ": event");
62                                         CreateEvent((EventInfo)((XamlClrEventNode)n).EventMember);
63                                         CreateEventDelegate(((XamlClrEventNode)n).Value, ((EventInfo)((XamlClrEventNode)n).EventMember).EventHandlerType);
64                                         EndEvent();
65
66                                 } else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.Object){
67                                         Debug.WriteLine(this.GetType() + ": text for object");
68                                         CreateObjectText(((XamlTextNode)n).TextContent);
69                                 } else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.Property){
70                                         Debug.WriteLine(this.GetType() + ": text for property");
71                                         if (((XamlTextNode)n).keyText != null)
72                                                 CreatePropertyReference(((XamlTextNode)n).keyText);
73                                         else
74                                                 CreatePropertyText(((XamlTextNode)n).TextContent, ((XamlTextNode)n).finalType);
75                                         EndProperty();
76                                 } else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.DependencyProperty){
77                                         Debug.WriteLine(this.GetType() + ": text for dependency property");
78                                         if (((XamlTextNode)n).keyText != null)
79                                                 CreateDependencyPropertyReference(((XamlTextNode)n).keyText);
80                                         else
81                                                 CreateDependencyPropertyText(((XamlTextNode)n).TextContent, ((XamlTextNode)n).finalType);
82                                         EndDependencyProperty();
83                                 } else if (n is XamlPropertyComplexEndNode) {
84                                         Debug.WriteLine(this.GetType() + ": end complex property");
85                                         if (justClosed == 2) {
86                                                 EndProperty();
87                                         } else if (justClosed == 1) {
88                                                 EndDependencyProperty();
89                                         } else {
90                                                 throw new NotImplementedException("justClosed of " + justClosed);
91                                         }
92                                         justClosed = 0;
93                                 } else if (n is XamlLiteralContentNode) {
94                                         Debug.WriteLine(this.GetType() + ": literal content");
95                                         CreateCode(((XamlLiteralContentNode)n).Content);
96                                 } else if (n is XamlElementEndNode) {
97                                         Debug.WriteLine(this.GetType() + ": end element");
98                                         Type ft = ((XamlElementEndNode)n).finalType;
99                                         if (((XamlElementEndNode)n).propertyObject) {
100                                                 EndPropertyObject(ft);
101                                                 justClosed = 2;
102                                         } else if (((XamlElementEndNode)n).depPropertyObject) {
103                                                 EndDependencyPropertyObject(ft);
104                                                 justClosed = 1;
105                                         } else {
106                                                 EndObject();
107                                         }
108                                 } else if (n is XamlDocumentEndNode) {
109                                         Debug.WriteLine(this.GetType() + ": end document");
110                                         Finish();
111                                 } else {
112                                         throw new Exception("Unknown node " + n.GetType());
113                                 }
114                         }
115
116                 }
117
118                 private string getKeyFromNode(XamlNode n)
119                 {
120                         // we know that n is a XamlElementStartNode, but don't need that knowledge
121                         if (n is XamlKeyElementStartNode)
122                                 return ((XamlKeyElementStartNode)n).key;
123                         else
124                                 return null;
125                 }
126
127                 
128                 public abstract void CreateTopLevel(Type parent, string className);
129                 public abstract void CreateObject(Type type, string varName, string key);
130                 public abstract void CreateProperty(PropertyInfo property);
131                 public abstract void CreateEvent(EventInfo evt);
132                 public abstract void CreateDependencyProperty(Type attachedTo, string propertyName, Type propertyType);
133                 public abstract void EndDependencyProperty();
134                 public abstract void CreateObjectText(string text);
135                 public abstract void CreateEventDelegate(string functionName, Type eventDelegateType);
136                 public abstract void CreatePropertyDelegate(string functionName, Type propertyType);
137                 public abstract void CreatePropertyText(string text, Type propertyType);
138                 public abstract void CreatePropertyReference(string key);
139                 public abstract void CreateDependencyPropertyText(string text, Type propertyType);
140                 public abstract void CreateDependencyPropertyObject(Type type, string varName, string key);
141                 public abstract void CreateDependencyPropertyReference(string key);
142                 public abstract void CreatePropertyObject(Type type, string varName, string key);
143                 public abstract void EndDependencyPropertyObject(Type destType);
144                 public abstract void EndPropertyObject(Type destType);
145                 public abstract void EndObject();
146                 public abstract void EndProperty();
147                 public abstract void EndEvent();
148                 public abstract void CreateCode(string code);
149                 public abstract void Finish();
150
151         }
152 }