New test.
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / ViewTypeParserFilter.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Collections;\r
16     using System.Web.UI;\r
17 \r
18     internal class ViewTypeParserFilter : PageParserFilter {\r
19 \r
20         private string _viewBaseType;\r
21         private DirectiveType _directiveType = DirectiveType.Unknown;\r
22         private bool _viewTypeControlAdded;\r
23 \r
24         public override void PreprocessDirective(string directiveName, IDictionary attributes) {\r
25             base.PreprocessDirective(directiveName, attributes);\r
26 \r
27             string defaultBaseType = null;\r
28 \r
29             // If we recognize the directive, keep track of what it was. If we don't recognize\r
30             // the directive then just stop.\r
31             switch (directiveName) {\r
32                 case "page":\r
33                     _directiveType = DirectiveType.Page;\r
34                     defaultBaseType = typeof(ViewPage).FullName;\r
35                     break;\r
36                 case "control":\r
37                     _directiveType = DirectiveType.UserControl;\r
38                     defaultBaseType = typeof(ViewUserControl).FullName;\r
39                     break;\r
40                 case "master":\r
41                     _directiveType = DirectiveType.Master;\r
42                     defaultBaseType = typeof(ViewMasterPage).FullName;\r
43                     break;\r
44             }\r
45 \r
46             if (_directiveType == DirectiveType.Unknown) {\r
47                 // If we're processing an unknown directive (e.g. a register directive), stop processing\r
48                 return;\r
49             }\r
50 \r
51             // Look for an inherit attribute\r
52             string inherits = (string)attributes["inherits"];\r
53             if (!String.IsNullOrEmpty(inherits)) {\r
54                 // If it doesn't look like a generic type, don't do anything special,\r
55                 // and let the parser do its normal processing\r
56                 if (IsGenericTypeString(inherits)) {\r
57                     // Remove the inherits attribute so the parser doesn't blow up\r
58                     attributes["inherits"] = defaultBaseType;\r
59 \r
60                     // Remember the full type string so we can later give it to the ControlBuilder\r
61                     _viewBaseType = inherits;\r
62                 }\r
63             }\r
64         }\r
65 \r
66         private static bool IsGenericTypeString(string typeName) {\r
67             // Detect C# and VB generic syntax\r
68             // REVIEW: what about other languages?\r
69             return typeName.IndexOfAny(new char[] { '<', '(' }) >= 0;\r
70         }\r
71 \r
72         public override void ParseComplete(ControlBuilder rootBuilder) {\r
73             base.ParseComplete(rootBuilder);\r
74 \r
75             // If it's our page ControlBuilder, give it the base type string\r
76             ViewPageControlBuilder pageBuilder = rootBuilder as ViewPageControlBuilder;\r
77             if (pageBuilder != null) {\r
78                 pageBuilder.PageBaseType = _viewBaseType;\r
79             }\r
80             ViewUserControlControlBuilder userControlBuilder = rootBuilder as ViewUserControlControlBuilder;\r
81             if (userControlBuilder != null) {\r
82                 userControlBuilder.UserControlBaseType = _viewBaseType;\r
83             }\r
84         }\r
85 \r
86         public override bool ProcessCodeConstruct(CodeConstructType codeType, string code) {\r
87             if (!_viewTypeControlAdded &&\r
88                 _viewBaseType != null &&\r
89                 _directiveType == DirectiveType.Master) {\r
90 \r
91                 // If we're dealing with a master page that needs to have its base type set, do it here.\r
92                 // It's done by adding the ViewType control, which has a builder that sets the base type.\r
93 \r
94                 // The code currently assumes that the file in question contains a code snippet, since\r
95                 // that's the item we key off of in order to know when to add the ViewType control.\r
96 \r
97                 Hashtable attribs = new Hashtable();\r
98                 attribs["typename"] = _viewBaseType;\r
99                 AddControl(typeof(ViewType), attribs);\r
100                 _viewTypeControlAdded = true;\r
101             }\r
102 \r
103             return base.ProcessCodeConstruct(codeType, code);\r
104         }\r
105 \r
106         // Everything else in this class is unrelated to our 'inherits' handling.\r
107         // Since PageParserFilter blocks everything by default, we need to unblock it\r
108 \r
109         public override bool AllowCode {\r
110             get {\r
111                 return true;\r
112             }\r
113         }\r
114 \r
115         public override bool AllowBaseType(Type baseType) {\r
116             return true;\r
117         }\r
118 \r
119         public override bool AllowControl(Type controlType, ControlBuilder builder) {\r
120             return true;\r
121         }\r
122 \r
123         public override bool AllowVirtualReference(string referenceVirtualPath, VirtualReferenceType referenceType) {\r
124             return true;\r
125         }\r
126 \r
127         public override bool AllowServerSideInclude(string includeVirtualPath) {\r
128             return true;\r
129         }\r
130 \r
131         public override int NumberOfControlsAllowed {\r
132             get {\r
133                 return -1;\r
134             }\r
135         }\r
136 \r
137         public override int NumberOfDirectDependenciesAllowed {\r
138             get {\r
139                 return -1;\r
140             }\r
141         }\r
142 \r
143         public override int TotalNumberOfDependenciesAllowed {\r
144             get {\r
145                 return -1;\r
146             }\r
147         }\r
148 \r
149         private enum DirectiveType {\r
150             Unknown,\r
151             Page,\r
152             UserControl,\r
153             Master,\r
154         }\r
155     }\r
156 }\r