SimpleWebHandlerParser.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 / SimpleWebHandlerParser.cs / 1305376 / SimpleWebHandlerParser.cs

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

/* 
 * Implements the parser for simple web handler files 
 *
 * Copyright (c) 2000 Microsoft Corporation 
 */

namespace System.Web.UI {
 
using System.Runtime.Serialization.Formatters;
using System.Text; 
using System.Runtime.Serialization; 

using System; 
using System.Reflection;
using System.IO;
using System.Collections;
using System.Collections.Specialized; 
using System.Text.RegularExpressions;
using System.CodeDom.Compiler; 
using System.Web; 
using System.Web.Hosting;
using System.Web.Caching; 
using System.Web.Compilation;
using System.CodeDom;
using System.Web.Util;
using Debug=System.Web.Util.Debug; 
using System.Web.RegularExpressions;
using System.Globalization; 
using System.Security.Permissions; 

 
/// 
/// 
///    [To be supplied.]
///  
public abstract class SimpleWebHandlerParser  : IAssemblyDependencyParser {
    private readonly static Regex directiveRegex = new SimpleDirectiveRegex(); 
 
    private SimpleHandlerBuildProvider _buildProvider;
 
    private TextReader _reader;

    private VirtualPath _virtualPath;
 
    // The line number in file currently being parsed
    private int _lineNumber; 
 
    // The column number in file currently being parsed
    private int _startColumn; 

    private bool _fFoundMainDirective;

    private string _typeName; 
    internal string TypeName {
        get { return _typeName; } 
    } 

    private CompilerType _compilerType; 

    // The string containing the code to be compiled
    private string _sourceString;
 
    // Assemblies to be linked with
    private AssemblySet _linkedAssemblies; 
 
    // The set of assemblies that the build system is telling us we will be linked with
    private ICollection _referencedAssemblies; 

    private static char[] s_newlineChars = new char[] { '\r', '\n' };

    private bool _ignoreParseErrors; 
    internal bool IgnoreParseErrors {
        get { return _ignoreParseErrors; } 
        set { _ignoreParseErrors = value; } 
    }
 
    internal void SetBuildProvider(SimpleHandlerBuildProvider buildProvider) {
        _buildProvider = buildProvider;
    }
 

    ///  
    ///    [To be supplied.] 
    /// 
 
    // Only allowed in full trust (ASURT 124397)
    [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
    protected SimpleWebHandlerParser(HttpContext context, string virtualPath, string physicalPath) {
 
        // These obsolete parameters should never be set
        Debug.Assert(context == null); 
        Debug.Assert(physicalPath == null); 

        Debug.Assert(virtualPath != null); 

        _virtualPath = VirtualPath.Create(virtualPath);
    }
 
    /*
     * Compile a web handler file into a Type.  Result is cached. 
     */ 

    ///  
    ///    [To be supplied.]
    /// 
    protected Type GetCompiledTypeFromCache() {
 
        //
        // This method is practically useless, but cannot be removed to avoid a breaking change 
        // 

        BuildResultCompiledType result = (BuildResultCompiledType) BuildManager.GetVPathBuildResult(_virtualPath); 

        return result.ResultType;
    }
 
    internal void Parse(ICollection referencedAssemblies) {
 
        _referencedAssemblies = referencedAssemblies; 

        AddSourceDependency(_virtualPath); 

        // Open a TextReader for the virtualPath we're parsing
        using (_reader = _buildProvider.OpenReaderInternal()) {
            ParseReader(); 
        }
    } 
 
    internal CompilerType CompilerType { get { return _compilerType; } }
 
    internal ICollection AssemblyDependencies { get { return _linkedAssemblies; } }
    private StringSet _sourceDependencies;
    internal ICollection SourceDependencies { get { return _sourceDependencies; } }
 
    internal CodeCompileUnit GetCodeModel() {
 
        // Do we have something to compile? 
        if (_sourceString == null)
            return null; 

        CodeSnippetCompileUnit snippetCompileUnit = new CodeSnippetCompileUnit(_sourceString);

        // Put in some context so that the file can be debugged. 
        snippetCompileUnit.LinePragma = BaseCodeDomTreeGenerator.CreateCodeLinePragmaHelper(
            _virtualPath.VirtualPathString, _lineNumber); 
 
        return snippetCompileUnit;
    } 

    internal IDictionary GetLinePragmasTable() {
        LinePragmaCodeInfo codeInfo = new LinePragmaCodeInfo();
        codeInfo._startLine = _lineNumber; 
        codeInfo._startColumn = _startColumn;
        codeInfo._startGeneratedColumn = 1; 
        codeInfo._codeLength = -1; 
        codeInfo._isCodeNugget = false;
 
        IDictionary linePragmasTable = new Hashtable();
        linePragmasTable[_lineNumber] = codeInfo;

        return linePragmasTable; 
    }
 
    internal bool HasInlineCode { get { return (_sourceString != null); } } 

    internal Type GetTypeToCache(Assembly builtAssembly) { 
        Type t = null;

        // First, try to get the type from the assembly that has been built (if any)
        if (builtAssembly != null) 
            t = builtAssembly.GetType(_typeName);
 
        // If not, try to get it from other assemblies 
        if (t == null)
            t = GetType(_typeName); 

        // Make sure the type derives from what we expect
        try {
            ValidateBaseType(t); 
        }
        catch (Exception e) { 
            throw new HttpParseException(e.Message, e, _virtualPath, _sourceString, _lineNumber); 
        }
 
        return t;
    }

    internal virtual void ValidateBaseType(Type t) { 
        // No restriction on the base type by default
    } 
 
    /*
     * Parse the contents of the TextReader 
     */
    private void ParseReader() {
        string s = _reader.ReadToEnd();
 
        try {
            ParseString(s); 
        } 
        catch (Exception e) {
            throw new HttpParseException(e.Message, e, _virtualPath, s, _lineNumber); 
        }
    }

    /* 
     * Parse the contents of the string
     */ 
    private void ParseString(string text) { 
        int textPos = 0;
        Match match; 
        _lineNumber = 1;

        // First, parse all the <%@ ... %> directives
        for (;;) { 
            match = directiveRegex.Match(text, textPos);
 
            // Done with the directives? 
            if (!match.Success)
                break; 

            _lineNumber += Util.LineCount(text, textPos, match.Index);
            textPos = match.Index;
 
            // Get all the directives into a bag
            IDictionary directive = CollectionsUtil.CreateCaseInsensitiveSortedList(); 
            string directiveName = ProcessAttributes(match, directive); 

            ProcessDirective(directiveName, directive); 

            _lineNumber += Util.LineCount(text, textPos, match.Index + match.Length);
            textPos = match.Index + match.Length;
 
            int newlineIndex = text.LastIndexOfAny(s_newlineChars, textPos-1);
            _startColumn = textPos - newlineIndex; 
        } 

        if (!_fFoundMainDirective && !IgnoreParseErrors) { 
            throw new HttpException(
                SR.GetString(SR.Missing_directive, DefaultDirectiveName));
        }
 
        // skip the directive
        string remainingText = text.Substring(textPos); 
 
        // If there is something else in the file, it needs to be compiled
        if (!Util.IsWhiteSpaceString(remainingText)) 
            _sourceString = remainingText;
    }

    private string ProcessAttributes(Match match, IDictionary attribs) { 
        string ret = String.Empty;
        CaptureCollection attrnames = match.Groups["attrname"].Captures; 
        CaptureCollection attrvalues = match.Groups["attrval"].Captures; 
        CaptureCollection equalsign = null;
        equalsign = match.Groups["equal"].Captures; 

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

            // Check if there is an equal sign. 
            bool fHasEqual = (equalsign[i].ToString().Length > 0); 

            if (attribName != null) { 
                // A <%@ %> block can have two formats:
                // <%@ directive foo=1 bar=hello %>
                // <%@ foo=1 bar=hello %>
                // Check if we have the first format 
                if (!fHasEqual && i==0) {
                    ret = attribName; 
                    continue; 
                }
 
                try {
                    if (attribs != null)
                        attribs.Add(attribName, attribValue);
                } 
                catch (ArgumentException) {
 
                    // Ignore the duplicate attributes when called from CBM 
                    if (IgnoreParseErrors) continue;
 
                    throw new HttpException(
                        SR.GetString(SR.Duplicate_attr_in_tag, attribName));
                }
            } 
        }
 
        return ret; 
    }
 

    /// 
    ///    [To be supplied.]
    ///  
    protected abstract string DefaultDirectiveName { get; }
 
    private static void ProcessCompilationParams(IDictionary directive, CompilerParameters compilParams) { 
        bool fDebug = false;
        if (Util.GetAndRemoveBooleanAttribute(directive, "debug", ref fDebug)) 
            compilParams.IncludeDebugInformation = fDebug;

        if (compilParams.IncludeDebugInformation &&
            !HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Medium)) { 
            throw new HttpException(SR.GetString(SR.Insufficient_trust_for_attribute, "debug"));
        } 
 
        int warningLevel=0;
        if (Util.GetAndRemoveNonNegativeIntegerAttribute(directive, "warninglevel", ref warningLevel)) { 
            compilParams.WarningLevel = warningLevel;
            if (warningLevel > 0)
                compilParams.TreatWarningsAsErrors = true;
        } 

        string compilerOptions = Util.GetAndRemoveNonEmptyAttribute( 
            directive, "compileroptions"); 
        if (compilerOptions != null) {
            CompilationUtil.CheckCompilerOptionsAllowed(compilerOptions, false /*config*/, null, 0); 
            compilParams.CompilerOptions = compilerOptions;
        }
    }
 
    /*
     * Process a <%@ %> block 
     */ 
    internal virtual void ProcessDirective(string directiveName, IDictionary directive) {
 
        // Empty means default
        if (directiveName.Length == 0)
            directiveName = DefaultDirectiveName;
 
        // Check for the main directive
        if (IsMainDirective(directiveName)) { 
 
            // Make sure the main directive was not already specified
            if (_fFoundMainDirective && !IgnoreParseErrors) { 
                throw new HttpException(
                    SR.GetString(SR.Only_one_directive_allowed, DefaultDirectiveName));
            }
 
            _fFoundMainDirective = true;
 
            // Since description is a no op, just remove it if it's there 
            directive.Remove("description");
 
            // Similarily, ignore 'codebehind' attribute (ASURT 4591)
            directive.Remove("codebehind");

            string language = Util.GetAndRemoveNonEmptyAttribute(directive, "language"); 

            // Get the compiler for the specified language (if any) 
            if (language != null) { 
                _compilerType = _buildProvider.GetDefaultCompilerTypeForLanguageInternal(language);
            } 
            else {
                // Get a default from config
                _compilerType = _buildProvider.GetDefaultCompilerTypeInternal();
            } 

            _typeName = Util.GetAndRemoveRequiredAttribute(directive, "class"); 
 
            if (_compilerType.CompilerParameters != null)
                ProcessCompilationParams(directive, _compilerType.CompilerParameters); 
        }
        else if (StringUtil.EqualsIgnoreCase(directiveName, "assembly")) {
            // Assembly directive
 
            // Remove the attributes as we get them from the dictionary
            string assemblyName = Util.GetAndRemoveNonEmptyAttribute(directive, "name"); 
            VirtualPath src = Util.GetAndRemoveVirtualPathAttribute(directive, "src"); 

            if (assemblyName != null && src != null && !IgnoreParseErrors) { 
                throw new HttpException(
                    SR.GetString(SR.Attributes_mutually_exclusive, "Name", "Src"));
            }
 
            if (assemblyName != null) {
                AddAssemblyDependency(assemblyName); 
            } 
            // Is it a source file that needs to be compiled on the fly
            else if (src != null) { 
                ImportSourceFile(src);
            }
            else if (!IgnoreParseErrors) {
                throw new HttpException(SR.GetString(SR.Missing_attr, "name")); 
            }
        } 
        else if (!IgnoreParseErrors) { 
            throw new HttpException(
                SR.GetString(SR.Unknown_directive, directiveName)); 
        }

        // If there are some attributes left, fail
        Util.CheckUnknownDirectiveAttributes(directiveName, directive); 
    }
 
    internal virtual bool IsMainDirective(string directiveName) { 
        return (string.Compare(directiveName, DefaultDirectiveName,
            StringComparison.OrdinalIgnoreCase) == 0); 
    }

    /*
     * Compile a source file into an assembly, and import it 
     */
    private void ImportSourceFile(VirtualPath virtualPath) { 
 
        // Get a full path to the source file
        VirtualPath baseVirtualDir = _virtualPath.Parent; 
        VirtualPath fullVirtualPath = baseVirtualDir.Combine(virtualPath);

        // Add the source file to the list of files we depend on
        AddSourceDependency(fullVirtualPath); 

        // 
 
        CompilationUtil.GetCompilerInfoFromVirtualPath(fullVirtualPath);
 
        // Compile it into an assembly

        BuildResultCompiledAssembly result = (BuildResultCompiledAssembly) BuildManager.GetVPathBuildResult(
            fullVirtualPath); 
        Assembly a = result.ResultAssembly;
 
        // Add a dependency to the assembly 
        AddAssemblyDependency(a);
    } 

    /*
     * Add a file as a dependency for the DLL we're building
     */ 
    internal void AddSourceDependency(VirtualPath fileName) {
        if (_sourceDependencies == null) 
            _sourceDependencies = new CaseInsensitiveStringSet(); 

        _sourceDependencies.Add(fileName.VirtualPathString); 
    }

    private void AddAssemblyDependency(string assemblyName) {
 
        // Load and keep track of the assembly
        Assembly a = Assembly.Load(assemblyName); 
 
        AddAssemblyDependency(a);
    } 

    private void AddAssemblyDependency(Assembly assembly) {

        if (_linkedAssemblies == null) 
            _linkedAssemblies = new AssemblySet();
        _linkedAssemblies.Add(assembly); 
    } 

    /* 
     * Look for a type by name in the assemblies available to this page
     */
    private Type GetType(string typeName) {
 
        Type t;
 
        // If it contains an assembly name, just call Type.GetType (ASURT 53589) 
        if (Util.TypeNameContainsAssembly(typeName)) {
            try { 
                t = Type.GetType(typeName, true);
            }
            catch (Exception e) {
                throw new HttpParseException(null, e, _virtualPath, _sourceString, _lineNumber); 
            }
 
            return t; 
        }
 
        t = Util.GetTypeFromAssemblies(_referencedAssemblies, typeName, false /*ignoreCase*/);
        if (t != null)
            return t;
 
        t = Util.GetTypeFromAssemblies(_linkedAssemblies, typeName, false /*ignoreCase*/);
        if (t != null) 
            return t; 

        throw new HttpParseException( 
            SR.GetString(SR.Could_not_create_type, typeName),
            null, _virtualPath, _sourceString, _lineNumber);
    }
 

    ///  
    ICollection IAssemblyDependencyParser.AssemblyDependencies { 
        get {
            return AssemblyDependencies; 
        }
    }
}
 

///  
///  
///    [To be supplied.]
///  
internal class WebHandlerParser: SimpleWebHandlerParser {

    internal WebHandlerParser(string virtualPath)
        : base(null /*context*/, virtualPath, null /*physicalPath*/) {} 

 
    ///  
    ///    [To be supplied.]
    ///  
    protected override string DefaultDirectiveName {
        get { return "webhandler"; }
    }
 
    internal override void ValidateBaseType(Type t) {
        // Make sure the type has the correct base class 
        Util.CheckAssignableType(typeof(IHttpHandler), t); 
    }
} 


/// 
///  
///    [To be supplied.]
///  
public class WebServiceParser: SimpleWebHandlerParser { 

 
    /// 
    ///    [To be supplied.]
    /// 
 
    // Only allowed in full trust (ASURT 123890)
    [SecurityPermission(SecurityAction.Demand, Unrestricted=true)] 
    public static Type GetCompiledType(string inputFile, HttpContext context) { 

        // NOTE: the inputFile parameter should be named virtualPath, but cannot be changed 
        // as it would be a minor breaking change! (VSWhidbey 80997).
        BuildResultCompiledType result = (BuildResultCompiledType) BuildManager.GetVPathBuildResult(
            context, VirtualPath.Create(inputFile));
 
        return result.ResultType;
    } 
 
    internal WebServiceParser(string virtualPath)
        : base(null /*context*/, virtualPath, null /*physicalPath*/) { } 


    /// 
    ///    [To be supplied.] 
    /// 
    protected override string DefaultDirectiveName { 
        get { return "webservice"; } 
    }
} 

}

// 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