PageThemeCodeDomTreeGenerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Compilation / PageThemeCodeDomTreeGenerator.cs / 1 / PageThemeCodeDomTreeGenerator.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

using System; 
using System.Collections; 
using System.Collections.Specialized;
using System.Reflection; 
using System.ComponentModel;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Globalization; 
using System.IO;
using System.Web.UI; 
using System.Web.Util; 
using Debug=System.Web.Util.Debug;
 
namespace System.Web.Compilation {

    internal class PageThemeCodeDomTreeGenerator : BaseTemplateCodeDomTreeGenerator {
 
        private Hashtable _controlSkinTypeNameCollection = new Hashtable();
        private ArrayList _controlSkinBuilderEntryList = new ArrayList(); 
 
        private int _controlCount = 0;
        private CodeTypeReference _controlSkinDelegateType = new CodeTypeReference(typeof(ControlSkinDelegate)); 
        private CodeTypeReference _controlSkinType = new CodeTypeReference(typeof(ControlSkin));

        private PageThemeParser _themeParser;
        private const string _controlSkinsVarName = "__controlSkins"; 
        private const string _controlSkinsPropertyName = "ControlSkins";
        private const string _linkedStyleSheetsVarName = "__linkedStyleSheets"; 
        private const string _linkedStyleSheetsPropertyName = "LinkedStyleSheets"; 

        internal PageThemeCodeDomTreeGenerator(PageThemeParser parser) : base(parser) { 
            _themeParser = parser;
        }

        private void AddMemberOverride(string name, Type type, CodeExpression expr) { 
            CodeMemberProperty member = new CodeMemberProperty();
            member.Name = name; 
            member.Attributes = MemberAttributes.Override | MemberAttributes.Family; 
            member.Type = new CodeTypeReference(type.FullName);
            CodeMethodReturnStatement returnStmt = new CodeMethodReturnStatement(expr); 
            member.GetStatements.Add(returnStmt);
            _sourceDataClass.Members.Add(member);
        }
 
        private void BuildControlSkins(CodeStatementCollection statements) {
            foreach (ControlSkinBuilderEntry entry in _controlSkinBuilderEntryList) { 
                string skinID = entry.SkinID; 
                ControlBuilder builder = entry.Builder;
                statements.Add(BuildControlSkinAssignmentStatement(builder, skinID)); 
            }
        }

        private CodeStatement BuildControlSkinAssignmentStatement( 
            ControlBuilder builder, string skinID) {
 
            Type controlType = builder.ControlType; 

            string keyVarName = GetMethodNameForBuilder(buildMethodPrefix, builder) + "_skinKey"; 

            // e.g.
            // private static object __BuildControl__control3_skinKey = PageTheme.CreateSkinKey(typeof({controlType}), {skinID});
            CodeMemberField field = new CodeMemberField(typeof(object), keyVarName); 
            field.Attributes = MemberAttributes.Static | MemberAttributes.Private;
            CodeMethodInvokeExpression cmie = new CodeMethodInvokeExpression(); 
            cmie.Method = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(PageTheme)), "CreateSkinKey"); 
            cmie.Parameters.Add(new CodeTypeOfExpression(controlType));
            cmie.Parameters.Add(new CodePrimitiveExpression(skinID)); 
            field.InitExpression = cmie;
            _sourceDataClass.Members.Add(field);

            // e.g. this.__namedControlSkins[keyVarName] = 
            //          new System.Web.UI.ControlSkin(typeof(System.Web.UI.WebControls.Label),
            //          new System.Web.UI.ControlSkinDelegate(this.__BuildControl__control3)); 
            CodeFieldReferenceExpression varExpr = new CodeFieldReferenceExpression( 
                new CodeThisReferenceExpression(),
                _controlSkinsVarName); 

            CodeIndexerExpression indexerExpr = new CodeIndexerExpression(
                varExpr,
                new CodeExpression[] { 
                    new CodeVariableReferenceExpression(keyVarName)
                } 
            ); 

            CodeDelegateCreateExpression del = new CodeDelegateCreateExpression( 
                                                            _controlSkinDelegateType,
                                                            new CodeThisReferenceExpression(),
                                                            GetMethodNameForBuilder(buildMethodPrefix, builder));
            CodeObjectCreateExpression valueExpr = new CodeObjectCreateExpression(_controlSkinType); 
            valueExpr.Parameters.Add(new CodeTypeOfExpression(controlType));
            valueExpr.Parameters.Add(del); 
 
            return new CodeAssignStatement(indexerExpr, valueExpr);
        } 

        private void BuildControlSkinMember() {
            // e.g.
            // private System.Collections.Specialized.HybridDictionary __cssFileList = 
            //     new System.Collections.Specialized.HybridDictionary(2);
            int initialSize = _controlSkinBuilderEntryList.Count; 
            CodeMemberField field = new CodeMemberField(typeof(HybridDictionary).FullName, _controlSkinsVarName); 
            CodeObjectCreateExpression expr = new CodeObjectCreateExpression(typeof(HybridDictionary));
            expr.Parameters.Add(new CodePrimitiveExpression(initialSize)); 
            field.InitExpression = expr;
            _sourceDataClass.Members.Add(field);
        }
 
        private void BuildControlSkinProperty() {
            // e.g. 
            //  protected override System.Collections.IDictionary ControlSkins { 
            //       get { return this.__controlSkins; }
            //  } 
            CodeFieldReferenceExpression accessExpr = new CodeFieldReferenceExpression(
                                                            new CodeThisReferenceExpression(),
                                                            _controlSkinsVarName);
 
            AddMemberOverride(_controlSkinsPropertyName, typeof(IDictionary), accessExpr);
        } 
 
        private void BuildLinkedStyleSheetMember() {
 
            // e.g.
            // private System.String[] __linkedStyleSheets = new String[] {
            //     "linkedStyleSheet1 vdirs",
            //     "linkedStyleSheet2 vdirs", 
            // }
            CodeMemberField field = new CodeMemberField(typeof(String[]), _linkedStyleSheetsVarName); 
 
            if (_themeParser.CssFileList != null && _themeParser.CssFileList.Count > 0) {
                CodeExpression[] cssFiles = new CodeExpression[_themeParser.CssFileList.Count]; 
                int i = 0;
                foreach(String cssFile in _themeParser.CssFileList) {
                    cssFiles[i++] = new CodePrimitiveExpression(cssFile);
                } 

                CodeArrayCreateExpression initExpr = new CodeArrayCreateExpression(typeof(String), cssFiles); 
                field.InitExpression = initExpr; 
            }
            else { 
                field.InitExpression = new CodePrimitiveExpression(null);
            }
            _sourceDataClass.Members.Add(field);
        } 

        private void BuildLinkedStyleSheetProperty() { 
            // e.g. 
            //  protected override String[] LinkedStyleSheets {
            //       get { return this.__linkedStyleSheets; } 
            //  }
            CodeFieldReferenceExpression accessExpr = new CodeFieldReferenceExpression(
                                                            new CodeThisReferenceExpression(),
                                                            _linkedStyleSheetsVarName); 

            AddMemberOverride(_linkedStyleSheetsPropertyName, typeof(String[]), accessExpr); 
        } 

        protected override void BuildInitStatements(CodeStatementCollection trueStatements, CodeStatementCollection topLevelStatements) { 
            base.BuildInitStatements(trueStatements, topLevelStatements);
            BuildControlSkins(topLevelStatements);
        }
 
        protected override void BuildMiscClassMembers() {
            base.BuildMiscClassMembers(); 
 
            AddMemberOverride(templateSourceDirectoryName, typeof(String),
                new CodePrimitiveExpression(_themeParser.VirtualDirPath.VirtualPathString)); 

            BuildSourceDataTreeFromBuilder(_themeParser.RootBuilder,
                false /*fInTemplate*/, false /*topLevelControlInTemplate*/, null /*pse*/);
 
            BuildControlSkinMember();
            BuildControlSkinProperty(); 
            BuildLinkedStyleSheetMember(); 
            BuildLinkedStyleSheetProperty();
        } 

        protected override void BuildSourceDataTreeFromBuilder(ControlBuilder builder,
                                                bool fInTemplate, bool topLevelControlInTemplate,
                                                PropertyEntry pse) { 

            // Don't do anything for code blocks 
            if (builder is CodeBlockBuilder) 
                return;
 
            // Is the current builder for a template?
            bool fTemplate = (builder is TemplateBuilder);

            // Is the current builder the root builder? 
            bool fRootBuilder = (builder == _themeParser.RootBuilder);
 
            // Is this a control theme? 
            bool fControlSkin = !fInTemplate && !fTemplate && topLevelControlInTemplate;
 
            // Ignore the ID attribute, always auto generate ID.
            _controlCount++;
            builder.ID = "__control" + _controlCount.ToString(NumberFormatInfo.InvariantInfo);
            builder.IsGeneratedID = true; 

            // Check for the SkinID property. 
            if (fControlSkin && !(builder is DataBoundLiteralControlBuilder)) { 

                Type ctrlType = builder.ControlType; 
                Debug.Assert(typeof(Control).IsAssignableFrom(ctrlType));
                Debug.Assert(ThemeableAttribute.IsTypeThemeable(ctrlType));

                string skinID = builder.SkinID; 
                object skinKey = PageTheme.CreateSkinKey(builder.ControlType, skinID);
 
                if (_controlSkinTypeNameCollection.Contains(skinKey)) { 
                    if (String.IsNullOrEmpty(skinID)) {
                        throw new HttpParseException(SR.GetString(SR.Page_theme_default_theme_already_defined, 
                            builder.ControlType.FullName), null, builder.VirtualPath, null, builder.Line);
                    }
                    else {
                        throw new HttpParseException(SR.GetString(SR.Page_theme_skinID_already_defined, skinID), 
                            null, builder.VirtualPath, null, builder.Line);
                    } 
                } 

                _controlSkinTypeNameCollection.Add(skinKey, true); 
                _controlSkinBuilderEntryList.Add(new ControlSkinBuilderEntry(builder, skinID));
            }

            // Process the children 
            // only root builders and template builders are processed.
            if (builder.SubBuilders != null) { 
                foreach (object child in builder.SubBuilders) { 
                    if (child is ControlBuilder) {
                        bool isTopLevelCtrlInTemplate = fTemplate && typeof(Control).IsAssignableFrom(((ControlBuilder)child).ControlType); 
                        BuildSourceDataTreeFromBuilder((ControlBuilder)child, fInTemplate, isTopLevelCtrlInTemplate, null);
                    }
                }
            } 

            foreach (TemplatePropertyEntry entry in builder.TemplatePropertyEntries) { 
                BuildSourceDataTreeFromBuilder(((TemplatePropertyEntry)entry).Builder, true, false /*topLevelControlInTemplate*/, entry); 
            }
 
            foreach (ComplexPropertyEntry entry in builder.ComplexPropertyEntries) {
                if (!(entry.Builder is StringPropertyBuilder)) {
                    BuildSourceDataTreeFromBuilder(((ComplexPropertyEntry)entry).Builder, fInTemplate, false /*topLevelControlInTemplate*/, entry);
                } 
            }
 
            // Build a Build method for the control 
            // fControlSkin indicates whether the method is a theme build method.
            if (!fRootBuilder) { 
                BuildBuildMethod(builder, fTemplate, fInTemplate, topLevelControlInTemplate, pse,
                    fControlSkin);
            }
 
            // Build a Render method for the control, unless it has no code
            if (!fControlSkin && builder.HasAspCode) { 
                BuildRenderMethod(builder, fTemplate); 
            }
 
            // Build a method to extract values from the template
            BuildExtractMethod(builder);

            // Build a property binding method for the control 
            BuildPropertyBindingMethod(builder, fControlSkin);
        } 
 
        internal override CodeExpression BuildStringPropertyExpression(PropertyEntry pse) {
            // Make the UrlProperty based on virtualDirPath for control themes. 
            if (pse.PropertyInfo != null) {
                UrlPropertyAttribute urlAttrib = Attribute.GetCustomAttribute(pse.PropertyInfo, typeof(UrlPropertyAttribute)) as UrlPropertyAttribute;

                if (urlAttrib != null) { 
                    if (pse is SimplePropertyEntry) {
                        SimplePropertyEntry spse = (SimplePropertyEntry)pse; 
 
                        string strValue = (string)spse.Value;
                        if (UrlPath.IsRelativeUrl(strValue) && !UrlPath.IsAppRelativePath(strValue)) { 
                            spse.Value = UrlPath.MakeVirtualPathAppRelative(UrlPath.Combine(_themeParser.VirtualDirPath.VirtualPathString, strValue));
                        }
                    }
                    else { 
                        Debug.Assert(pse is ComplexPropertyEntry);
                        ComplexPropertyEntry cpe = (ComplexPropertyEntry)pse; 
                        StringPropertyBuilder builder = (StringPropertyBuilder)cpe.Builder; 

                        string strValue = (string)builder.BuildObject(); 
                        if (UrlPath.IsRelativeUrl(strValue) && !UrlPath.IsAppRelativePath(strValue)) {
                            cpe.Builder = new StringPropertyBuilder(UrlPath.MakeVirtualPathAppRelative(UrlPath.Combine(_themeParser.VirtualDirPath.VirtualPathString, strValue)));
                        }
                    } 
                }
            } 
 
            return base.BuildStringPropertyExpression(pse);
        } 

        protected override CodeAssignStatement BuildTemplatePropertyStatement(CodeExpression ctrlRefExpr) {

            // e.g. __ctrl.AppRelativeTemplateSourceDirectory = this.AppRelativeTemplateSourceDirectory; 
            CodeAssignStatement assign = new CodeAssignStatement();
            assign.Left = new CodePropertyReferenceExpression(ctrlRefExpr, templateSourceDirectoryName); 
            assign.Right = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), templateSourceDirectoryName); 
            return assign;
        } 

        protected override string GetGeneratedClassName() {
            string className = _themeParser.VirtualDirPath.FileName;
            className = System.Web.UI.Util.MakeValidTypeNameFromString(className); 

            return className; 
        } 

        protected override bool UseResourceLiteralString(string s) { 
            // never use resource literal string, page theme does not support the required methods.
            return false;
        }
 
        // Don't build the Profile property in Theme classes
        protected override bool NeedProfileProperty { get { return false; } } 
 
        private class ControlSkinBuilderEntry {
            private ControlBuilder _builder; 
            private string _id;

            public ControlSkinBuilderEntry (ControlBuilder builder, string skinID) {
                _builder = builder; 
                _id = skinID;
            } 
 
            public ControlBuilder Builder {
                get { return _builder; } 
            }

            public String SkinID {
                get { return _id == null? String.Empty : _id; } 
            }
        } 
    } 
}
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK