| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- //
- // System.Web.UI.SimpleWebHandlerParser
- //
- // Authors:
- // Gonzalo Paniagua Javier ([email protected])
- //
- // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
- //
- using System;
- using System.CodeDom.Compiler;
- using System.Collections;
- using System.IO;
- using System.Reflection;
- using System.Text;
- using System.Web;
- using System.Web.Compilation;
- using System.Web.Util;
- namespace System.Web.UI
- {
- public abstract class SimpleWebHandlerParser
- {
- HttpContext context;
- string vPath;
- string physPath;
- string className;
- string codeBehind;
- bool debug;
- string language;
- string program;
- bool gotDefault;
- ArrayList assemblies;
- ArrayList dependencies;
- Hashtable anames;
- string privateBinPath;
- string baseDir;
- string baseVDir;
- protected SimpleWebHandlerParser (HttpContext context, string virtualPath, string physicalPath)
- {
- this.context = context;
- this.vPath = virtualPath;
- this.physPath = physicalPath;
- assemblies = new ArrayList ();
- assemblies.Add ("System.dll");
- assemblies.Add ("System.Drawing.dll");
- assemblies.Add ("System.Data.dll");
- assemblies.Add ("System.Web.dll");
- assemblies.Add ("System.Web.Services.dll");
- assemblies.Add ("System.Xml.dll");
- AddAssembliesInBin ();
- GetDirectivesAndContent ();
- }
- void GetDirectivesAndContent ()
- {
- StreamReader reader = new StreamReader (File.OpenRead (physPath));
- string line;
- bool directiveFound = false;
- StringBuilder content = new StringBuilder ();
- while ((line = reader.ReadLine ()) != null) {
- string trimmed = line.Trim ();
- if (!directiveFound && trimmed == String.Empty)
- continue;
-
- if (trimmed.StartsWith ("<")) {
- ParseDirective (trimmed);
- directiveFound = true;
- continue;
- }
- content.Append (line + "\n");
- content.Append (reader.ReadToEnd ());
- }
- if (!gotDefault)
- throw new ParseException (null, "No @WebService directive found");
-
- this.program = content.ToString ();
- reader.Close ();
- }
- void TagParsed (ILocation location, System.Web.Compilation.TagType tagtype, string tagid, TagAttributes attributes)
- {
- if (tagtype != System.Web.Compilation.TagType.Directive)
- throw new ParseException (location, "Unexpected tag");
- if (String.Compare (tagid, DefaultDirectiveName, true) == 0) {
- AddDefaultDirective (location, attributes);
- } else if (String.Compare (tagid, "Assembly", true) == 0) {
- AddAssemblyDirective (location, attributes);
- } else {
- throw new ParseException (location, "Unexpected directive: " + tagid);
- }
- }
- void TextParsed (ILocation location, string text)
- {
- if (text.Trim () != "")
- throw new ParseException (location, "Text not allowed here");
- }
- void ParseError (ILocation location, string message)
- {
- throw new ParseException (location, message);
- }
- static string GetAndRemove (Hashtable table, string key)
- {
- string o = table [key] as string;
- table.Remove (key);
- return o;
- }
-
- void ParseDirective (string line)
- {
- AspParser parser = new AspParser (physPath, new StringReader (line));
- parser.Error += new ParseErrorHandler (ParseError);
- parser.TagParsed += new TagParsedHandler (TagParsed);
- parser.TextParsed += new TextParsedHandler (TextParsed);
- parser.Parse ();
- }
- internal virtual void AddDefaultDirective (ILocation location, TagAttributes attrs)
- {
- if (gotDefault)
- throw new ParseException (location, "duplicate " + DefaultDirectiveName + " directive");
- gotDefault = true;
- Hashtable attributes = attrs.GetDictionary (null);
- className = GetAndRemove (attributes, "class");
- if (className == null)
- throw new ParseException (null, "No Class attribute found.");
-
- string d = GetAndRemove (attributes, "debug");
- if (d != null) {
- debug = (String.Compare (d, "true", true) == 0);
- if (debug == false && String.Compare (d, "false", true) != 0)
- throw new ParseException (null, "Invalid value for Debug attribute");
- }
- language = GetAndRemove (attributes, "language");
- if (language != null) {
- if (0 != String.Compare (language, "C#", true))
- throw new ParseException (null, "Only C# language is supported by now.");
- }
- codeBehind = GetAndRemove (attributes, "codebehind");
- if (attributes.Count > 0)
- throw new ParseException (location, "Unrecognized attribute in " +
- DefaultDirectiveName + " directive");
- }
- internal virtual void AddAssemblyDirective (ILocation location, TagAttributes attrs)
- {
- Hashtable tbl = attrs.GetDictionary (null);
- string name = GetAndRemove (tbl, "Name");
- string src = GetAndRemove (tbl, "Src");
- if (name == null && src == null)
- throw new ParseException (location, "You gotta specify Src or Name");
- if (name != null && src != null)
- throw new ParseException (location, "Src and Name cannot be used together");
- if (name != null) {
- AddAssemblyByName (name, location);
- } else {
- GetAssemblyFromSource (src, location);
- }
- if (tbl.Count > 0)
- throw new ParseException (location, "Unrecognized attribute in Assembly directive");
- }
- internal virtual void AddAssembly (Assembly assembly, bool fullPath)
- {
- if (anames == null)
- anames = new Hashtable ();
- string name = assembly.GetName ().Name;
- string loc = assembly.Location;
- if (fullPath) {
- if (!assemblies.Contains (loc)) {
- assemblies.Add (loc);
- }
- anames [name] = loc;
- anames [loc] = assembly;
- } else {
- if (!assemblies.Contains (name)) {
- assemblies.Add (name);
- }
- anames [name] = assembly;
- }
- }
- internal virtual Assembly AddAssemblyByName (string name, ILocation location)
- {
- if (anames == null)
- anames = new Hashtable ();
- if (anames.Contains (name)) {
- object o = anames [name];
- if (o is string)
- o = anames [o];
- return (Assembly) o;
- }
- bool fullpath = true;
- Assembly assembly = LoadAssemblyFromBin (name);
- if (assembly != null) {
- AddAssembly (assembly, fullpath);
- return assembly;
- }
- try {
- assembly = Assembly.Load (name);
- string loc = assembly.Location;
- fullpath = (Path.GetDirectoryName (loc) == PrivateBinPath);
- } catch (Exception e) {
- throw new ParseException (location, "Assembly " + name + " not found", e);
- }
- AddAssembly (assembly, fullpath);
- return assembly;
- }
- void AddAssembliesInBin ()
- {
- if (!Directory.Exists (PrivateBinPath))
- return;
- string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
- foreach (string dll in binDlls) {
- Assembly assembly = Assembly.LoadFrom (dll);
- AddAssembly (assembly, true);
- }
- }
- Assembly LoadAssemblyFromBin (string name)
- {
- Assembly assembly;
- if (!Directory.Exists (PrivateBinPath))
- return null;
- string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
- foreach (string dll in binDlls) {
- string fn = Path.GetFileName (dll);
- fn = Path.ChangeExtension (fn, null);
- if (fn != name)
- continue;
- assembly = Assembly.LoadFrom (dll);
- return assembly;
- }
- return null;
- }
- Assembly GetAssemblyFromSource (string vpath, ILocation location)
- {
- vpath = UrlUtils.Combine (BaseVirtualDir, vpath);
- string realPath = context.Request.MapPath (vpath);
- if (!File.Exists (realPath))
- throw new ParseException (location, "File " + vpath + " not found");
- AddDependency (realPath);
- CompilerResults result = CachingCompiler.Compile (realPath, realPath, assemblies);
- if (result.NativeCompilerReturnValue != 0) {
- StreamReader reader = new StreamReader (realPath);
- throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
- }
- AddAssembly (result.CompiledAssembly, true);
- return result.CompiledAssembly;
- }
-
- internal Type GetTypeFromBin (string typeName)
- {
- if (!Directory.Exists (PrivateBinPath))
- throw new HttpException (String.Format ("Type {0} not found.", typeName));
- string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
- Type result = null;
- foreach (string dll in binDlls) {
- Assembly assembly = Assembly.LoadFrom (dll);
- Type type = assembly.GetType (typeName, false);
- if (type != null) {
- if (result != null)
- throw new HttpException (String.Format ("Type {0} is not unique.", typeName));
- result = type;
- }
- }
- if (result == null)
- throw new HttpException (String.Format ("Type {0} not found.", typeName));
- return result;
- }
-
- internal virtual void AddDependency (string filename)
- {
- if (dependencies == null)
- dependencies = new ArrayList ();
- if (!dependencies.Contains (filename))
- dependencies.Add (filename);
- }
-
- // Properties
- protected abstract string DefaultDirectiveName { get; }
- internal HttpContext Context {
- get { return context; }
- }
- internal string VirtualPath {
- get { return vPath; }
- }
- internal string PhysicalPath {
- get { return physPath; }
- }
- internal string ClassName {
- get { return className; }
- }
- internal string CodeBehind {
- get { return codeBehind; }
- }
- internal bool Debug {
- get { return debug; }
- }
- internal string Language {
- get { return language; }
- }
- internal string Program {
- get { return program; }
- }
- internal ArrayList Assemblies {
- get { return assemblies; }
- }
- internal ArrayList Dependencies {
- get { return dependencies; }
- }
- internal string PrivateBinPath {
- get {
- if (privateBinPath != null)
- return privateBinPath;
- AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
- privateBinPath = setup.PrivateBinPath;
-
- if (!Path.IsPathRooted (privateBinPath)) {
- string appbase = setup.ApplicationBase;
- if (appbase.StartsWith ("file://")) {
- appbase = appbase.Substring (7);
- if (Path.DirectorySeparatorChar != '/')
- appbase = appbase.Replace ('/', Path.DirectorySeparatorChar);
- }
- privateBinPath = Path.Combine (appbase, privateBinPath);
- }
- return privateBinPath;
- }
- }
- internal string BaseDir {
- get {
- if (baseDir == null)
- baseDir = context.Request.MapPath (BaseVirtualDir);
- return baseDir;
- }
- }
- internal virtual string BaseVirtualDir {
- get {
- if (baseVDir == null)
- baseVDir = UrlUtils.GetDirectory (context.Request.FilePath);
- return baseVDir;
- }
- }
- }
- }
|