1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\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
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc {
\r
15 using System.Collections;
\r
16 using System.Web.UI;
\r
18 internal class ViewTypeParserFilter : PageParserFilter {
\r
20 private string _viewBaseType;
\r
21 private DirectiveType _directiveType = DirectiveType.Unknown;
\r
22 private bool _viewTypeControlAdded;
\r
24 public override void PreprocessDirective(string directiveName, IDictionary attributes) {
\r
25 base.PreprocessDirective(directiveName, attributes);
\r
27 string defaultBaseType = null;
\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
33 _directiveType = DirectiveType.Page;
\r
34 defaultBaseType = typeof(ViewPage).FullName;
\r
37 _directiveType = DirectiveType.UserControl;
\r
38 defaultBaseType = typeof(ViewUserControl).FullName;
\r
41 _directiveType = DirectiveType.Master;
\r
42 defaultBaseType = typeof(ViewMasterPage).FullName;
\r
46 if (_directiveType == DirectiveType.Unknown) {
\r
47 // If we're processing an unknown directive (e.g. a register directive), stop processing
\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
60 // Remember the full type string so we can later give it to the ControlBuilder
\r
61 _viewBaseType = inherits;
\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
72 public override void ParseComplete(ControlBuilder rootBuilder) {
\r
73 base.ParseComplete(rootBuilder);
\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
80 ViewUserControlControlBuilder userControlBuilder = rootBuilder as ViewUserControlControlBuilder;
\r
81 if (userControlBuilder != null) {
\r
82 userControlBuilder.UserControlBaseType = _viewBaseType;
\r
86 public override bool ProcessCodeConstruct(CodeConstructType codeType, string code) {
\r
87 if (!_viewTypeControlAdded &&
\r
88 _viewBaseType != null &&
\r
89 _directiveType == DirectiveType.Master) {
\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
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
97 Hashtable attribs = new Hashtable();
\r
98 attribs["typename"] = _viewBaseType;
\r
99 AddControl(typeof(ViewType), attribs);
\r
100 _viewTypeControlAdded = true;
\r
103 return base.ProcessCodeConstruct(codeType, code);
\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
109 public override bool AllowCode {
\r
115 public override bool AllowBaseType(Type baseType) {
\r
119 public override bool AllowControl(Type controlType, ControlBuilder builder) {
\r
123 public override bool AllowVirtualReference(string referenceVirtualPath, VirtualReferenceType referenceType) {
\r
127 public override bool AllowServerSideInclude(string includeVirtualPath) {
\r
131 public override int NumberOfControlsAllowed {
\r
137 public override int NumberOfDirectDependenciesAllowed {
\r
143 public override int TotalNumberOfDependenciesAllowed {
\r
149 private enum DirectiveType {
\r