BatchParser.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / UI / BatchParser.cs / 1305376 / BatchParser.cs

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

namespace System.Web.UI { 
using System; 
using System.IO;
using System.Web.Configuration; 
using System.Collections;
using System.Collections.Specialized;
using System.Threading;
using System.Globalization; 
using System.Web.Hosting;
using System.Web.Caching; 
using System.Web.Util; 
using System.Web.Compilation;
using HttpException = System.Web.HttpException; 
using Debug=System.Web.Util.Debug;
using System.Text.RegularExpressions;

 
internal abstract class DependencyParser : BaseParser {
 
    private VirtualPath _virtualPath; 
    private StringSet _virtualPathDependencies;
 
    // Used to detect circular references
    private StringSet _circularReferenceChecker = new CaseInsensitiveStringSet();

    // The  config section 
    private PagesSection _pagesConfig;
    protected PagesSection PagesConfig { 
        get { return _pagesConfig; } 
    }
 
    internal void Init(VirtualPath virtualPath) {
        CurrentVirtualPath = virtualPath;
        _virtualPath = virtualPath;
        _pagesConfig = MTConfigUtil.GetPagesConfig(virtualPath); 
    }
 
    internal ICollection GetVirtualPathDependencies() { 

        // Always set the culture to Invariant when parsing (ASURT 99071) 
        Thread currentThread = Thread.CurrentThread;
        CultureInfo prevCulture = currentThread.CurrentCulture;
        HttpRuntime.SetCurrentThreadCultureWithAssert(CultureInfo.InvariantCulture);
 
        try {
            try { 
                PrepareParse(); 
                ParseFile();
            } 
            finally {
                // Restore the previous culture
                HttpRuntime.SetCurrentThreadCultureWithAssert(prevCulture);
            } 
        }
        catch { throw; }    // Prevent Exception Filter Security Issue (ASURT 122835) 
 
        return _virtualPathDependencies;
    } 

    protected void AddDependency(VirtualPath virtualPath) {
        virtualPath = ResolveVirtualPath(virtualPath);
        Debug.Trace("Template", "Parsed dependency: " + _virtualPath + " depends on " + virtualPath); 

        if (_virtualPathDependencies == null) 
            _virtualPathDependencies = new CaseInsensitiveStringSet(); 

        _virtualPathDependencies.Add(virtualPath.VirtualPathString); 
    }

    internal abstract string DefaultDirectiveName { get; }
 
    protected virtual void PrepareParse() {}
 
    private void ParseFile() { 
        ParseFile(null /*physicalPath*/, _virtualPath);
    } 

    private void ParseFile(string physicalPath, VirtualPath virtualPath) {

        // Determine the file used for the circular references checker.  Normally, 
        // we use the virtualPath, but we use the physical path if it specified,
        // as is the case for  
        string fileToReferenceCheck = physicalPath != null ? physicalPath : virtualPath.VirtualPathString; 

        // Check for circular references of include files 
        if (_circularReferenceChecker.Contains(fileToReferenceCheck)) {
            throw new HttpException(
                SR.GetString(SR.Circular_include));
        } 

        // Add the current file to the circular references checker. 
        _circularReferenceChecker.Add(fileToReferenceCheck); 

        try { 
            // Open a TextReader either from the physical or virtual path
            TextReader reader;
            if (physicalPath != null) {
                using (reader = Util.ReaderFromFile(physicalPath, virtualPath)) { 
                    ParseReader(reader);
                } 
            } 
            else {
                using (Stream stream = virtualPath.OpenFile()) { 
                    reader = Util.ReaderFromStream(stream, virtualPath);
                    ParseReader(reader);
                }
            } 
        }
        finally { 
            // Remove the current file from the circular references checker 
            _circularReferenceChecker.Remove(fileToReferenceCheck);
        } 
    }

    private void ParseReader(TextReader input) {
        ParseString(input.ReadToEnd()); 
    }
 
    private void ParseString(string text) { 

        int textPos = 0; 

        for (;;) {
            Match match;
 
            // 1: scan for text up to the next tag.
 
            if ((match = textRegex.Match(text, textPos)).Success) { 
                textPos = match.Index + match.Length;
            } 

            // we might be done now

            if (textPos == text.Length) 
                break;
 
            // 2: handle constructs that start with < 

            // Check to see if it's a directive (i.e. <%@ %> block) 

            if ((match = directiveRegex.Match(text, textPos)).Success) {
                IDictionary directive = CollectionsUtil.CreateCaseInsensitiveSortedList();
                string directiveName = ProcessAttributes(match, directive); 
                ProcessDirective(directiveName, directive);
                textPos = match.Index + match.Length; 
            } 

            else if ((match = includeRegex.Match(text, textPos)).Success) { 
                ProcessServerInclude(match);
                textPos = match.Index + match.Length;
            }
 
            else if ((match = commentRegex.Match(text, textPos)).Success) {
                // Just skip it 
                textPos = match.Index + match.Length; 
            }
 
            else {
                int newPos = text.IndexOf("<%@", textPos, StringComparison.Ordinal);
                // 2nd condition is used to catch invalid directives, e.g. <%@ attr="value_without_end_quote >
                if (newPos == -1 || newPos == textPos) { 
                    return;
                } 
 
                textPos = newPos;
            } 

            // we might be done now
            if (textPos == text.Length)
                return; 
        }
    } 
 
    /*
     * Process a server side include.  e.g.  
     */
    private void ProcessServerInclude(Match match) {

        string pathType = match.Groups["pathtype"].Value; 
        string filename = match.Groups["filename"].Value;
 
        if (filename.Length == 0) return; 

        VirtualPath newVirtualPath; 
        string newPhysicalPath = null;

        if (StringUtil.EqualsIgnoreCase(pathType, "file")) {
 
            if (UrlPath.IsAbsolutePhysicalPath(filename)) {
                // If it's an absolute physical path, use it as is 
                newPhysicalPath = filename; 

                // Reuse the current virtual path 
                newVirtualPath = CurrentVirtualPath;
            }
            else {
 
                // If it's relative, just treat it as virtual
                newVirtualPath = ResolveVirtualPath(VirtualPath.Create(filename)); 
            } 
        }
        else if (StringUtil.EqualsIgnoreCase(pathType, "virtual")) { 
            newVirtualPath = ResolveVirtualPath(VirtualPath.Create(filename));
        }
        else {
            // Unknown #include type: ignore it 
            return;
        } 
 
        VirtualPath prevVirtualPath = _virtualPath;
        try { 
            _virtualPath = newVirtualPath;

            // Parse the included file recursively
            ParseFile(newPhysicalPath, newVirtualPath); 
        }
        finally { 
            // Restore the paths 
            _virtualPath = prevVirtualPath;
        } 
    }

    /*
     * Process a <%@ %> block 
     */
    internal virtual void ProcessDirective(string directiveName, IDictionary directive) { 
        // Get all the directives into a bag 
        // Check for the main directive (e.g. "page" for an aspx)
        if (directiveName == null || 
            StringUtil.EqualsIgnoreCase(directiveName, DefaultDirectiveName) ) {
            ProcessMainDirective(directive);
        }
        else if (StringUtil.EqualsIgnoreCase(directiveName, "register")) { 

            VirtualPath src = Util.GetAndRemoveVirtualPathAttribute(directive, "src"); 
 
            if (src != null) {
                AddDependency(src); 
            }
        }
        else if (StringUtil.EqualsIgnoreCase(directiveName, "reference")) {
 
            VirtualPath virtualPath = Util.GetAndRemoveVirtualPathAttribute(directive, "virtualpath");
            if (virtualPath != null) 
                AddDependency(virtualPath); 

            VirtualPath page = Util.GetAndRemoveVirtualPathAttribute(directive, "page"); 
            if (page != null)
                AddDependency(page);

            VirtualPath control = Util.GetAndRemoveVirtualPathAttribute(directive, "control"); 
            if (control != null)
                AddDependency(control); 
        } 
        else if (StringUtil.EqualsIgnoreCase(directiveName, "assembly")) {
 
            VirtualPath src = Util.GetAndRemoveVirtualPathAttribute(directive, "src");
            if (src != null)
                AddDependency(src);
        } 
    }
 
    private void ProcessMainDirective(IDictionary mainDirective) { 

        // Go through all the attributes on the directive 
        foreach (DictionaryEntry entry in mainDirective) {

            string attribName = ((string)entry.Key).ToLower(CultureInfo.InvariantCulture);
 
            // Parse out the device name, if any
            string name; 
            string deviceName = Util.ParsePropertyDeviceFilter(attribName, out name); 

            // Process the attribute 
            ProcessMainDirectiveAttribute(deviceName, name, (string) entry.Value);
        }
    }
 
    internal virtual void ProcessMainDirectiveAttribute(string deviceName, string name,
        string value) { 
 
        // A "src" attribute is equivalent to an imported source file
        if (name == "src") { 
            string src = Util.GetNonEmptyAttribute(name, value);
            AddDependency(VirtualPath.Create(src));
        }
    } 

    /* 
     * Adds attributes and their values to the attribs 
     */
    private string ProcessAttributes(Match match, IDictionary attribs) { 
        string ret = null;
        CaptureCollection attrnames = match.Groups["attrname"].Captures;
        CaptureCollection attrvalues = match.Groups["attrval"].Captures;
        CaptureCollection equalsign = match.Groups["equal"].Captures; 

        for (int i = 0; i < attrnames.Count; i++) { 
            string attribName = attrnames[i].ToString(); 
            string attribValue = attrvalues[i].ToString();
            bool fHasEqual = (equalsign[i].ToString().Length > 0); 

            if (attribName != null && !fHasEqual && ret == null) {
                ret = attribName;
                continue; 
            }
 
            try { 
                if (attribs != null)
                    attribs.Add(attribName, attribValue); 
            }
            catch (ArgumentException) {}
        }
 
        return ret;
    } 
} 

 
internal abstract class TemplateControlDependencyParser : DependencyParser {

    internal override void ProcessMainDirectiveAttribute(string deviceName, string name,
        string value) { 

        switch (name) { 
 
        case "masterpagefile":
            value = value.Trim(); 
            if (value.Length > 0) {
                // Add a dependency on the master, whether it has a device filter or not
                AddDependency(VirtualPath.Create(value));
            } 
            break;
 
        default: 
            // We didn't handle the attribute.  Try the base class
            base.ProcessMainDirectiveAttribute(deviceName, name, value); 
            break;
        }
    }
} 

internal class PageDependencyParser : TemplateControlDependencyParser { 
    internal override string DefaultDirectiveName { 
        get { return PageParser.defaultDirectiveName; }
    } 

    protected override void PrepareParse() {
        if (PagesConfig != null) {
            if (PagesConfig.MasterPageFileInternal != null && PagesConfig.MasterPageFileInternal.Length != 0) 
                AddDependency(VirtualPath.Create(PagesConfig.MasterPageFileInternal));
        } 
    } 

    internal override void ProcessDirective(string directiveName, IDictionary directive) { 
        base.ProcessDirective(directiveName, directive);

        if (StringUtil.EqualsIgnoreCase(directiveName, "previousPageType") ||
            StringUtil.EqualsIgnoreCase(directiveName, "masterType")) { 

            VirtualPath virtualPath = Util.GetAndRemoveVirtualPathAttribute(directive, "virtualPath"); 
            if (virtualPath != null) 
                AddDependency(virtualPath);
        } 
    }
}

internal class UserControlDependencyParser : TemplateControlDependencyParser { 
    internal override string DefaultDirectiveName {
        get { return UserControlParser.defaultDirectiveName; } 
    } 
}
 
internal class MasterPageDependencyParser : UserControlDependencyParser {
    internal override string DefaultDirectiveName {
        get { return MasterPageParser.defaultDirectiveName; }
    } 

    internal override void ProcessDirective(string directiveName, IDictionary directive) { 
        base.ProcessDirective(directiveName, directive); 

        if (StringUtil.EqualsIgnoreCase(directiveName, "masterType")) { 
            VirtualPath virtualPath = Util.GetAndRemoveVirtualPathAttribute(directive, "virtualPath");
            if (virtualPath != null)
                AddDependency(virtualPath);
        } 
    }
} 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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