TagNameToTypeMapper.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 / UI / TagNameToTypeMapper.cs / 5 / TagNameToTypeMapper.cs

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

/* 
 * Base Control factory implementation 
 *
 * Copyright (c) 1998 Microsoft Corporation 
 */

namespace System.Web.UI {
 
    using System;
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Collections.Specialized;
    using System.ComponentModel.Design; 
    using System.Reflection;
    using System.Globalization;
    using System.Web.Hosting;
    using System.Web.Util; 
    using System.Web.Compilation;
    using System.Web.Configuration; 
#if !FEATURE_PAL 
    using System.Web.UI.Design;
#endif // !FEATURE_PAL 

//

 

 
    ///  
    ///    Maps a sequence of text characters to a .NET Framework
    ///       type when an .aspx file is processed on the server. 
    /// 
    internal interface ITagNameToTypeMapper {
        /*
         * Return the Type of the control that should handle a tag with the 
         * passed in properties.
         */ 
 
        /// 
        ///    Retrieves the .NET Framework type that should process 
        ///       the control declared in the .aspx file.
        ///    
        Type GetControlType(string tagName, IDictionary attribs);
    } 

 
    internal class NamespaceTagNameToTypeMapper : ITagNameToTypeMapper { 
        private TagNamespaceRegisterEntry _nsRegisterEntry;
        private Assembly _assembly; 
        private TemplateParser _parser;

        internal NamespaceTagNameToTypeMapper(TagNamespaceRegisterEntry nsRegisterEntry, Assembly assembly, TemplateParser parser) {
            _nsRegisterEntry = nsRegisterEntry; 
            _assembly = assembly;
            _parser = parser; 
        } 

        public TagNamespaceRegisterEntry RegisterEntry { 
            get {
                return _nsRegisterEntry;
            }
        } 

        Type ITagNameToTypeMapper.GetControlType(string tagName, IDictionary attribs) { 
            string typeName; 
            string ns = _nsRegisterEntry.Namespace;
            if (String.IsNullOrEmpty(ns)) { 
                typeName = tagName;
            }
            else {
                typeName = ns + "." + tagName; 
            }
 
            // Look up the type name (case insensitive) 
            if (_assembly != null) {
                Type type = null; 

                // If loading the type from the assembly depends on a referenced assembly that cannot
                // be loaded, we should throw the actual exception, instead of later reporting a more
                // generic error saying the type was not found (Devdiv 138674) 
                try {
                    type = _assembly.GetType(typeName, true /*throwOnError*/, true /*ignoreCase*/); 
                } 
                catch (System.IO.FileNotFoundException) {
                    throw; 
                }
                catch (System.IO.FileLoadException) {
                    throw;
                } 
                catch (BadImageFormatException) {
                    throw; 
                } 
                catch {
                    // For all other exceptions, such as when the type is not present in the assembly, 
                    // we ignore the exception so that we can continue to check other assemblies to look
                    // for the type.
                }
                return type; 
            }
 
#if !FEATURE_PAL 
            // If we're in the designer, check the WebFormsReferenceManager and ITypeResolutionService first.
            if (_parser.FInDesigner && (_parser.DesignerHost != null)) { 
                // If we are in the DesignTimeThemes Host, we can't actually go down this code path, let the TypeResolutionService try instead
                if (_parser.DesignerHost.RootComponent != null) {
                    WebFormsRootDesigner rootDesigner = _parser.DesignerHost.GetDesigner(_parser.DesignerHost.RootComponent) as WebFormsRootDesigner;
                    if (rootDesigner != null) { 
                        WebFormsReferenceManager referenceManager = rootDesigner.ReferenceManager;
                        if (referenceManager != null) { 
                            Type type = referenceManager.GetType(_nsRegisterEntry.TagPrefix, tagName); 
                            if (type != null) {
                                // Only return the type if we found it. Otherwise fall back to the next service. 
                                return type;
                            }
                        }
                    } 
                }
 
                ITypeResolutionService typeResolutionService = (ITypeResolutionService)_parser.DesignerHost.GetService(typeof(ITypeResolutionService)); 
                if (typeResolutionService != null) {
                    Type type = typeResolutionService.GetType(typeName, false, true); 
                    if (type != null) {
                        // Only return the type if we found it. Otherwise fall back to the next service.
                        return type;
                    } 
                }
            } 
 
#endif // !FEATURE_PAL
 
            // Nothing more to try in non-hosted appdomains
            if (!HostingEnvironment.IsHosted)
                return null;
 
            // If the assembly was not specified, look for the type in the code assemblies (including sub code assemblies)
            return BuildManager.GetTypeFromCodeAssembly(typeName, true /*ignoreCase*/); 
        } 
    }
 
    internal class TagPrefixTagNameToTypeMapper : ITagNameToTypeMapper {

        private string _tagPrefix;
        private ArrayList _mappers; 

        internal TagPrefixTagNameToTypeMapper(string tagPrefix) { 
            _tagPrefix = tagPrefix; 
            _mappers = new ArrayList();
        } 

        internal void AddNamespaceMapper(NamespaceTagNameToTypeMapper mapper) {
            _mappers.Add(mapper);
        } 

        Type ITagNameToTypeMapper.GetControlType(string tagName, IDictionary attribs) { 
            Type foundType = null; 
            Exception loadException = null;
 
            try {
                foreach (NamespaceTagNameToTypeMapper nsMapper in _mappers) {
                    Type t = ((ITagNameToTypeMapper)nsMapper).GetControlType(tagName, attribs);
                    if (t != null) { 
                        if (foundType == null) {
                            foundType = t; 
                        } 
                        else if (foundType != t) {
                            throw new HttpParseException(SR.GetString(SR.Ambiguous_server_tag, _tagPrefix + ":" + tagName), 
                                                         null, nsMapper.RegisterEntry.VirtualPath, null, nsMapper.RegisterEntry.Line);
                        }
                    }
                } 
            }
            catch (System.IO.FileNotFoundException e) { 
                loadException = e; 
            }
            catch (System.IO.FileLoadException e) { 
                loadException = e;
            }
            catch (BadImageFormatException e) {
                loadException = e; 
            }
 
            if (loadException != null) { 
                throw new HttpException(SR.GetString(SR.ControlAdapters_TypeNotFound, _tagPrefix + ":" + tagName) + " " + loadException.Message, loadException);
            } 

            if (foundType == null) {
                throw new HttpException(SR.GetString(SR.Unknown_server_tag, _tagPrefix + ":" + tagName));
            } 

            return foundType; 
        } 
    }
 

    internal class MainTagNameToTypeMapper {

        private BaseTemplateParser _parser; 

        // Mapping from a tag prefix to an ITagNameToTypeMapper for that prefix 
        private IDictionary _prefixedMappers; 

        // Mapping from a tag name (possibly with a prefix) to a Type 
        private IDictionary _mappedTags;

        // Create the Html tag mapper
        private ITagNameToTypeMapper _htmlMapper = new HtmlTagNameToTypeMapper(); 

        // List of UserControl <%@ Register %> directives 
        // Key = "prefix:tagname", Value = UserControlRegisterEntry 
        private Hashtable _userControlRegisterEntries;
 
        // List of custom control <%@ Register %> directives
        private List _tagRegisterEntries;

        //  
        private TagNamespaceRegisterEntryTable _tagNamespaceRegisterEntries;
 
        internal MainTagNameToTypeMapper(BaseTemplateParser parser) { 
            _parser = parser;
 
            if (parser != null) {
                PagesSection pagesConfig = parser.PagesConfig;
                if (pagesConfig != null) {
                    // Clone it so we don't modify the config settings 
                    _tagNamespaceRegisterEntries = pagesConfig.TagNamespaceRegisterEntriesInternal;
                    if (_tagNamespaceRegisterEntries != null) { 
                        _tagNamespaceRegisterEntries = (TagNamespaceRegisterEntryTable)_tagNamespaceRegisterEntries.Clone(); 
                    }
 
                    _userControlRegisterEntries = pagesConfig.UserControlRegisterEntriesInternal;
                    if (_userControlRegisterEntries != null) {
                        _userControlRegisterEntries = (Hashtable)_userControlRegisterEntries.Clone();
                    } 
                }
 
                // 

 

                if (parser.FInDesigner && (_tagNamespaceRegisterEntries == null)) {
                    _tagNamespaceRegisterEntries = new TagNamespaceRegisterEntryTable();
 
                    foreach (TagNamespaceRegisterEntry entry in PagesSection.DefaultTagNamespaceRegisterEntries) {
                        _tagNamespaceRegisterEntries[entry.TagPrefix] = new ArrayList(new object[] { entry }); 
                    } 
                }
            } 
        }

        internal ICollection UserControlRegisterEntries {
            get { 
                if (_userControlRegisterEntries != null) {
                    return _userControlRegisterEntries.Values; 
                } 

                return null; 
            }
        }

        internal List TagRegisterEntries { 
            get {
                if (_tagRegisterEntries == null) { 
                    _tagRegisterEntries = new List(); 
                }
                return _tagRegisterEntries; 
            }
        }

        // Called to process register directive on pages 
        internal void ProcessTagNamespaceRegistration(TagNamespaceRegisterEntry nsRegisterEntry) {
            string tagPrefix = nsRegisterEntry.TagPrefix; 
 
            // See if there are entries registered in config with same tag prefix
            ArrayList registerEntries = null; 
            if (_tagNamespaceRegisterEntries != null) {
                registerEntries = (ArrayList)_tagNamespaceRegisterEntries[tagPrefix];
            }
 
            // If there are config-based entries, and theres no mapper for them, make sure
            // a mapper has been created 
            // We need all namespaces for a particular tag prefix to have a mapper, so we 
            // can look for ambiguous types when a tag is parsed.
            if ((registerEntries != null) && 
                ((_prefixedMappers == null) || (_prefixedMappers[tagPrefix] == null))) {
                ProcessTagNamespaceRegistration(registerEntries);
            }
            ProcessTagNamespaceRegistrationCore(nsRegisterEntry); 
        }
 
        private void ProcessTagNamespaceRegistration(ArrayList nsRegisterEntries) { 
            foreach (TagNamespaceRegisterEntry nsRegisterEntry in nsRegisterEntries) {
                try { 
                    ProcessTagNamespaceRegistrationCore(nsRegisterEntry);
                }
                catch (Exception e) {
                    // Make sure we throw the exception with the correct file/line info 
                    throw new HttpParseException(e.Message, e,
                        nsRegisterEntry.VirtualPath, null, nsRegisterEntry.Line); 
                } 
            }
        } 

        private void ProcessTagNamespaceRegistrationCore(TagNamespaceRegisterEntry nsRegisterEntry) {
            // Load the assembly if it was specified
            Assembly assembly = null; 
            if (!String.IsNullOrEmpty(nsRegisterEntry.AssemblyName))
                assembly = _parser.AddAssemblyDependency(nsRegisterEntry.AssemblyName); 
 
            // Import the namespace if there is one
            if (!String.IsNullOrEmpty(nsRegisterEntry.Namespace)) 
                _parser.AddImportEntry(nsRegisterEntry.Namespace);

            // Create a mapper for this specific namespace/assembly pair
            NamespaceTagNameToTypeMapper mapper = new NamespaceTagNameToTypeMapper(nsRegisterEntry, assembly, _parser); 

            // Figure out which prefix mapper this new namespace mapper goes into 
            if (_prefixedMappers == null) { 
                _prefixedMappers = new Hashtable(StringComparer.OrdinalIgnoreCase);
            } 

            TagPrefixTagNameToTypeMapper prefixMapper = (TagPrefixTagNameToTypeMapper)_prefixedMappers[nsRegisterEntry.TagPrefix];
            if (prefixMapper == null) {
                prefixMapper = new TagPrefixTagNameToTypeMapper(nsRegisterEntry.TagPrefix); 
                _prefixedMappers[nsRegisterEntry.TagPrefix] = prefixMapper;
            } 
 
            prefixMapper.AddNamespaceMapper(mapper);
 
            TagRegisterEntries.Add(nsRegisterEntry);
        }

        internal void ProcessUserControlRegistration(UserControlRegisterEntry ucRegisterEntry) { 
            Type type = null;
 
            if (_parser.FInDesigner) { 
                // Get the designer to load the appropriate type
                type = _parser.GetDesignTimeUserControlType(ucRegisterEntry.TagPrefix, 
                    ucRegisterEntry.TagName);
            }
            else {
                // Compile it into a Type 
                type = _parser.GetUserControlType(ucRegisterEntry.UserControlSource.VirtualPathString);
            } 
 
            if (type == null)
                return; 

            if (_userControlRegisterEntries == null) {
                _userControlRegisterEntries = new Hashtable();
            } 
            _userControlRegisterEntries[ucRegisterEntry.TagPrefix + ":" + ucRegisterEntry.TagName] = ucRegisterEntry;
 
            // Register the new tag, including its prefix 
            RegisterTag(ucRegisterEntry.TagPrefix + ":" + ucRegisterEntry.TagName, type);
        } 

        /*
         * Check if the tagName can be handled by a user control register directive.
         * If so, process the directive and return true. 
         */
        private bool TryUserControlRegisterDirectives(string tagName) { 
 
            if (_userControlRegisterEntries == null)
                return false; 

            // Is there a registered user control for this tag
            UserControlRegisterEntry ucRegisterEntry = (UserControlRegisterEntry)
                _userControlRegisterEntries[tagName]; 
            if (ucRegisterEntry == null)
                return false; 
 
            // Don't allow a config registered user control to be used by a
            // page that lives in the same directory, to avoid circular references. 
            // More specifically, this would break batching because our simple dependency
            // parser would not be able to detect the *implicit* dependency triggered
            // by the presence of a tag (VSWhidbey 165042).
            if (ucRegisterEntry.ComesFromConfig) { 
                VirtualPath ucDirectory = ucRegisterEntry.UserControlSource.Parent;
                if (ucDirectory == _parser.BaseVirtualDir) { 
                    throw new HttpException( 
                        SR.GetString(SR.Invalid_use_of_config_uc,
                            _parser.CurrentVirtualPath, ucRegisterEntry.UserControlSource)); 
                }
            }

            try { 
                ProcessUserControlRegistration(ucRegisterEntry);
            } 
            catch (Exception e) { 
                // Make sure we throw the exception with the correct file/line info
                throw new HttpParseException(e.Message, e, 
                    ucRegisterEntry.VirtualPath, null, ucRegisterEntry.Line);
            }
            return true;
        } 

        /* 
         * Check if the tagName can be handled by a namespace register directive. 
         * If so, process the directive and return true.
         */ 
        private bool TryNamespaceRegisterDirectives(string prefix) {
            if (_tagNamespaceRegisterEntries == null)
                return false;
 
            // Are there registered entries for this prefix
            ArrayList entries = (ArrayList)_tagNamespaceRegisterEntries[prefix]; 
            if (entries == null) { 
                return false;
            } 

            ProcessTagNamespaceRegistration(entries);
            return true;
        } 

        internal void RegisterTag(string tagName, Type type) { 
            if (_mappedTags == null) 
                _mappedTags = new Hashtable(StringComparer.OrdinalIgnoreCase);
 
            try {
                _mappedTags.Add(tagName, type);
            }
            catch (ArgumentException) { 
                // Duplicate mapping
                throw new HttpException(SR.GetString( 
                    SR.Duplicate_registered_tag, tagName)); 
            }
        } 

        internal /*public*/ Type GetControlType(string tagName, IDictionary attribs, bool fAllowHtmlTags) {
            Type type = GetControlType2(tagName, attribs, fAllowHtmlTags);
 
            if ((type != null) && _parser != null && !_parser.FInDesigner) {
                Hashtable tagMapEntries = _parser.PagesConfig.TagMapping.TagTypeMappingInternal; 
                if (tagMapEntries != null) { 
                    Type mappedType = (Type)tagMapEntries[type];
                    if (mappedType != null) { 
                        type = mappedType;
                    }
                }
            } 

            return type; 
        } 

        private /*public*/ Type GetControlType2(string tagName, IDictionary attribs, bool fAllowHtmlTags) { 
            Type type;

            // First, check it the tag name has been mapped
            if (_mappedTags != null) { 
                type = (Type) _mappedTags[tagName];
 
                if (type == null) { 
                    // Maybe there is a register directive that we haven't yet processed
                    if (TryUserControlRegisterDirectives(tagName)) 
                        type = (Type) _mappedTags[tagName];
                }

                if (type != null) { 
                    // If this is the special NoCompile UserControl specified by the PageParserFilter, give it the
                    // virtualPath via the attribute bag 
                    if (_parser != null && _parser._pageParserFilter != null && _parser._pageParserFilter.GetNoCompileUserControlType() == type) { 
                        UserControlRegisterEntry ucRegisterEntry = (UserControlRegisterEntry)_userControlRegisterEntries[tagName];
                        attribs["virtualpath"] = ucRegisterEntry.UserControlSource; 
                    }

                    return type;
                } 
            }
 
            // Check if there is a prefix 
            int colonIndex = tagName.IndexOf(':');
            if (colonIndex >= 0) { 
                // If ends with : don't try to match (88398)
                if (colonIndex == tagName.Length-1)
                    return null;
 
                // If so, parse the prefix and tagname
                string prefix = tagName.Substring(0, colonIndex); 
                tagName = tagName.Substring(colonIndex+1); 

                // Look for a mapper for the prefix 

                ITagNameToTypeMapper mapper = null;
                if (_prefixedMappers != null)
                    mapper = (ITagNameToTypeMapper) _prefixedMappers[prefix]; 

                if (mapper == null) { 
                    // Maybe there is a register directive that we haven't yet processed 
                    if (TryNamespaceRegisterDirectives(prefix) && _prefixedMappers != null) {
                        mapper = (ITagNameToTypeMapper)_prefixedMappers[prefix]; 
                    }
                }

                if (mapper == null) { 
                    return null;
                } 
 
                // Try to get the type from the prefix mapper
                return mapper.GetControlType(tagName, attribs); 
            }
            else {
                // There is no prefix.
                // Try the Html mapper if allowed 
                if (fAllowHtmlTags) {
                    return _htmlMapper.GetControlType(tagName, attribs); 
                } 
            }
 
            return null;
        }
    }
}
                        

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