2002-08-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Fri, 16 Aug 2002 05:36:06 +0000 (05:36 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Fri, 16 Aug 2002 05:36:06 +0000 (05:36 -0000)
* System.Web.Compilation/AspElements.cs:
* System.Web.Compilation/AspParser.cs:
* System.Web.Compilation/AspTokenizer.cs:
* System.Web.Compilation/ChangeLog:
* System.Web.Compilation/PageCompiler.cs:
* System.Web.Compilation/TemplateFactory.cs:
* System.Web.UI/ApplicationFileParser.cs:
* System.Web.UI/BaseParser.cs:
* System.Web.UI/PageParser.cs:
* System.Web.UI/TemplateControl.cs:
* System.Web.UI/TemplateControlParser.cs:
* System.Web.UI/TemplateParser.cs: first steps to move xsp into
System.Web.

svn path=/trunk/mcs/; revision=6668

13 files changed:
mcs/class/System.Web/System.Web.Compilation/AspElements.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.Compilation/AspParser.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.Compilation/AspTokenizer.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.Compilation/ChangeLog
mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.Compilation/TemplateFactory.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI/BaseParser.cs
mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/PageParser.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI/TemplateControl.cs
mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI/TemplateParser.cs

diff --git a/mcs/class/System.Web/System.Web.Compilation/AspElements.cs b/mcs/class/System.Web/System.Web.Compilation/AspElements.cs
new file mode 100644 (file)
index 0000000..d580779
--- /dev/null
@@ -0,0 +1,774 @@
+//
+// System.Web.Compilation.AspElements
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Text;
+using System.Web.UI;
+using System.Web.UI.HtmlControls;
+using System.Web.UI.WebControls;
+
+namespace System.Web.Compilation
+{
+       
+       public enum ElementType
+       {
+               TAG,
+               PLAINTEXT
+       }
+
+       public abstract class Element
+       {
+               private ElementType elementType;
+
+               public Element (ElementType type)
+               {
+                       elementType = type;
+               }
+               
+               public ElementType GetElementType
+               {
+                       get { return elementType; }
+               }
+       } // class Element
+
+       public class PlainText : Element
+       {
+               private StringBuilder text;
+
+               public PlainText () : base (ElementType.PLAINTEXT)
+               {
+                       text = new StringBuilder ();
+               }
+
+               public PlainText (StringBuilder text) : base (ElementType.PLAINTEXT)
+               {
+                       this.text = text;
+               }
+
+               public PlainText (string text) : this ()
+               {
+                       this.text.Append (text);
+               }
+
+               public void Append (string more)
+               {
+                       text.Append (more);
+               }
+               
+               public string Text
+               {
+                       get { return text.ToString (); }
+               }
+
+               public override string ToString ()
+               {
+                       return "PlainText: " + Text;
+               }
+       }
+
+       public enum TagType
+       {
+               DIRECTIVE,
+               HTML,
+               HTMLCONTROL,
+               SERVERCONTROL,
+               INLINEVAR,
+               INLINECODE,
+               CLOSING,
+               SERVEROBJECT,
+               PROPERTYTAG,
+               CODERENDER,
+               DATABINDING,
+               NOTYET
+       }
+
+       /*
+        * Attributes and values are stored in a couple of ArrayList in Add ().
+        * When MakeHash () is called, they are converted to a Hashtable. If there are any
+        * attributes duplicated it throws an ArgumentException.
+        *
+        * The [] operator works with the Hashtable if the values are in it, otherwise
+        * it uses the ArrayList's.
+        *
+        * Why? You can have a tag in HTML like <a att="value" att="xxx">, but not in tags
+        * marked runat=server and Hashtable requires the key to be unique.
+        * 
+        */
+       public class TagAttributes
+       {
+               private Hashtable atts_hash;
+               private ArrayList keys;
+               private ArrayList values;
+               private bool got_hashed;
+
+               public TagAttributes ()
+               {
+                       got_hashed = false;
+                       keys = new ArrayList ();
+                       values = new ArrayList ();
+               }
+
+               private void MakeHash ()
+               {
+                       atts_hash = new Hashtable (new CaseInsensitiveHashCodeProvider (),
+                                                  new CaseInsensitiveComparer ());
+                       for (int i = 0; i < keys.Count; i++)
+                               atts_hash.Add (keys [i], values [i]);
+                       got_hashed = true;
+                       keys = null;
+                       values = null;
+               }
+               
+               public bool IsRunAtServer ()
+               {
+                       return got_hashed;
+               }
+
+               public void Add (object key, object value)
+               {
+                       if (key != null && value != null &&
+                           0 == String.Compare ((string) key,  "runat", true) &&
+                           0 == String.Compare ((string) value,  "server", true))
+                               MakeHash ();
+
+                       if (got_hashed)
+                               atts_hash.Add (key, value);
+                       else {
+                               keys.Add (key);
+                               values.Add (value);
+                       }
+               }
+               
+               public ICollection Keys 
+               {
+                       get { return (got_hashed ? atts_hash.Keys : keys); }
+               }
+
+               private int CaseInsensitiveSearch (string key)
+               {
+                       // Hope not to have many attributes when the tag is not a server tag...
+                       for (int i = 0; i < keys.Count; i++){
+                               if (0 == String.Compare ((string) keys [i], key, true))
+                                       return i;
+                       }
+                       return -1;
+               }
+               
+               public object this [object key]
+               {
+                       get {
+                               if (got_hashed)
+                                       return atts_hash [key];
+
+                               int idx = CaseInsensitiveSearch ((string) key);
+                               if (idx == -1)
+                                       return null;
+                                               
+                               return values [idx];
+                       }
+
+                       set {
+                               if (got_hashed)
+                                       atts_hash [key] = value;
+                               else {
+                                       int idx = CaseInsensitiveSearch ((string) key);
+                                       keys [idx] = value;
+                               }
+                       }
+               }
+               
+               public int Count 
+               {
+                       get { return (got_hashed ? atts_hash.Count : keys.Count);}
+               }
+
+               public bool IsDataBound (string att)
+               {
+                       if (att == null || !got_hashed)
+                               return false;
+
+                       return (att.StartsWith ("<%#") && att.EndsWith ("%>"));
+               }
+               
+               public override string ToString ()
+               {
+                       string ret = "";
+                       string value;
+                       foreach (string key in Keys){
+                               value = (string) this [key];
+                               value = value == null ? "" : value;
+                               ret += key + "=" + value + " ";
+                       }
+
+                       return ret;
+               }
+       }
+
+       public class Tag : Element
+       {
+               protected string tag;
+               protected TagType tagType;
+               protected TagAttributes attributes;
+               protected bool self_closing;
+               protected bool hasDefaultID;
+               private static int ctrlNumber = 1;
+
+               internal Tag (Tag other) :
+                       this (other.tag, other.attributes, other.self_closing)
+               {
+                       this.tagType = other.tagType;
+               }
+
+               public Tag (string tag, TagAttributes attributes, bool self_closing) :
+                         base (ElementType.TAG)
+               {
+                       if (tag == null)
+                               throw new ArgumentNullException ();
+
+                       this.tag = tag;
+                       this.attributes = attributes;
+                       this.tagType = TagType.NOTYET;
+                       this.self_closing = self_closing;
+                       this.hasDefaultID = false;
+               }
+               
+               public string TagID
+               {
+                       get { return tag; }
+               }
+
+               public TagType TagType
+               {
+                       get { return tagType; }
+               }
+
+               public bool SelfClosing
+               {
+                       get { return self_closing; }
+               }
+
+               public TagAttributes Attributes
+               {
+                       get { return attributes; }
+               }
+
+               public string PlainHtml
+               {
+                       get {
+                               StringBuilder plain = new StringBuilder ();
+                               plain.Append ('<');
+                               if (tagType == TagType.CLOSING)
+                                       plain.Append ('/');
+                               plain.Append (tag);
+                               if (attributes != null){
+                                       plain.Append (' ');
+                                       foreach (string key in attributes.Keys){
+                                               plain.Append (key);
+                                               if (attributes [key] != null){
+                                                       plain.Append ("=\"");
+                                                       plain.Append ((string) attributes [key]);
+                                                       plain.Append ("\" ");
+                                               }
+                                       }
+                               }
+                               
+                               if (self_closing)
+                                       plain.Append ('/');
+                               plain.Append ('>');
+                               return plain.ToString ();
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       return TagID + " " + Attributes + " " + self_closing;
+               }
+
+               public bool HasDefaultID
+               {
+                       get { return hasDefaultID; }
+               }
+               
+               protected void SetNewID ()
+               {
+                       if (attributes == null)
+                               attributes = new TagAttributes ();
+                       attributes.Add ("ID", GetDefaultID ());
+                       hasDefaultID = true;
+               }
+
+               public static string GetDefaultID ()
+               {
+                       return "_control" + ctrlNumber++;
+               }
+       }
+
+       public class CloseTag : Tag
+       {
+               public CloseTag (string tag) : base (tag, null, false)
+               {
+                       tagType = TagType.CLOSING;
+               }
+       }
+
+       public class Directive : Tag
+       {
+               private static Hashtable directivesHash;
+               private static string [] page_atts = {  "AspCompat", "AutoEventWireup ", "Buffer",
+                                                       "ClassName", "ClientTarget", "CodePage",
+                                                       "CompilerOptions", "ContentType", "Culture", "Debug",
+                                                       "Description", "EnableSessionState", "EnableViewState",
+                                                       "EnableViewStateMac", "ErrorPage", "Explicit",
+                                                       "Inherits", "Language", "LCID", "ResponseEncoding",
+                                                       "Src", "SmartNavigation", "Strict", "Trace",
+                                                       "TraceMode", "Transaction", "UICulture",
+                                                       "WarningLevel" };
+
+               private static string [] control_atts = { "AutoEventWireup", "ClassName", "CompilerOptions",
+                                                         "Debug", "Description", "EnableViewState",
+                                                         "Explicit", "Inherits", "Language", "Strict", "Src",
+                                                         "WarningLevel" };
+
+               private static string [] import_atts = { "namespace" };
+               private static string [] implements_atts = { "interface" };
+               private static string [] assembly_atts = { "name", "src" };
+               private static string [] register_atts = { "tagprefix", "tagname", "Namespace",
+                                                          "Src", "Assembly" };
+
+               private static string [] outputcache_atts = { "Duration", "Location", "VaryByControl", 
+                                                             "VaryByCustom", "VaryByHeader", "VaryByParam" };
+               private static string [] reference_atts = { "page", "control" };
+
+               static Directive ()
+               {
+                       InitHash ();
+               }
+               
+               private static void InitHash ()
+               {
+                       CaseInsensitiveHashCodeProvider provider = new CaseInsensitiveHashCodeProvider ();
+                       CaseInsensitiveComparer comparer =  new CaseInsensitiveComparer ();
+
+                       directivesHash = new Hashtable (provider, comparer); 
+
+                       // Use Hashtable 'cause is O(1) in Contains (ArrayList is O(n))
+                       Hashtable valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in page_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("PAGE", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in control_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("CONTROL", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in import_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("IMPORT", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in implements_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("IMPLEMENTS", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in register_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("REGISTER", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in assembly_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("ASSEMBLY", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in outputcache_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("OUTPUTCACHE", valid_attributes);
+
+                       valid_attributes = new Hashtable (provider, comparer);
+                       foreach (string att in reference_atts) valid_attributes.Add (att, null);
+                       directivesHash.Add ("REFERENCE", valid_attributes);
+               }
+               
+               public Directive (string tag, TagAttributes attributes) :
+                      base (tag, attributes, true)
+               {
+                       CheckAttributes ();
+                       tagType = TagType.DIRECTIVE;
+               }
+
+               private void CheckAttributes ()
+               {
+                       Hashtable atts;
+                       if (!(directivesHash [tag] is Hashtable))
+                               throw new ApplicationException ("Unknown directive: " + tag);
+
+                       atts = (Hashtable) directivesHash [tag];
+                       foreach (string att in attributes.Keys){
+                               if (!atts.Contains (att))
+                                       throw new ApplicationException ("Attribute " + att +
+                                                                       " not valid for tag " + tag);
+                       }
+               }
+
+               public static bool IsDirectiveID (string id)
+               {
+                       return directivesHash.Contains (id);
+               }
+               
+               public override string ToString ()
+               {
+                       return "Directive: " + tag;
+               }
+       }
+
+       public class ServerObjectTag : Tag
+       {
+               public ServerObjectTag (Tag tag) :
+                       base (tag.TagID, tag.Attributes, tag.SelfClosing) 
+               {
+                       tagType = TagType.SERVEROBJECT;
+                       if (!attributes.IsRunAtServer ())
+                               throw new ApplicationException ("<object> without runat=server");
+                       
+                       if (attributes.Count != 3 || !SelfClosing || ObjectID == null || ObjectClass == null)
+                               throw new ApplicationException ("Incorrect syntax: <object id=\"name\" " + 
+                                                               "class=\"full.class.name\" runat=\"server\" />");
+               }
+
+               public string ObjectID
+               {
+                       get { return (string) attributes ["id"]; }
+               }
+                       
+               public string ObjectClass
+               {
+                       get { return (string) attributes ["class"]; }
+               }
+       }
+
+       public class HtmlControlTag : Tag
+       {
+               private Type control_type;
+               private bool is_container;
+
+               private static Hashtable controls;
+               private static Hashtable inputTypes;
+
+               private static void InitHash ()
+               {
+                       controls = new Hashtable (new CaseInsensitiveHashCodeProvider (),
+                                                 new CaseInsensitiveComparer ()); 
+
+                       controls.Add ("A", typeof (HtmlAnchor));
+                       controls.Add ("BUTTON", typeof (HtmlButton));
+                       controls.Add ("FORM", typeof (HtmlForm));
+                       controls.Add ("IMG", typeof (HtmlImage));
+                       controls.Add ("INPUT", "INPUT");
+                       controls.Add ("SELECT", typeof (HtmlSelect));
+                       controls.Add ("TABLE", typeof (HtmlTable));
+                       controls.Add ("TD", typeof (HtmlTableCell));
+                       controls.Add ("TH", typeof (HtmlTableCell));
+                       controls.Add ("TR", typeof (HtmlTableRow));
+                       controls.Add ("TEXTAREA", typeof (HtmlTextArea));
+
+                       inputTypes = new Hashtable (new CaseInsensitiveHashCodeProvider (),
+                                                   new CaseInsensitiveComparer ());
+
+                       inputTypes.Add ("BUTTON", typeof (HtmlInputButton));
+                       inputTypes.Add ("SUBMIT", typeof (HtmlInputButton));
+                       inputTypes.Add ("RESET", typeof (HtmlInputButton));
+                       inputTypes.Add ("CHECKBOX", typeof (HtmlInputCheckBox));
+                       inputTypes.Add ("FILE", typeof (HtmlInputFile));
+                       inputTypes.Add ("HIDDEN", typeof (HtmlInputHidden));
+                       inputTypes.Add ("IMAGE", typeof (HtmlInputImage));
+                       inputTypes.Add ("RADIO", typeof (HtmlInputRadioButton));
+                       inputTypes.Add ("TEXT", typeof (HtmlInputText));
+                       inputTypes.Add ("PASSWORD", typeof (HtmlInputText));
+               }
+               
+               static HtmlControlTag ()
+               {
+                       InitHash ();
+               }
+               
+               public HtmlControlTag (string tag, TagAttributes attributes, bool self_closing) : 
+                       base (tag, attributes, self_closing) 
+               {
+                       SetData ();
+                       if (attributes == null || attributes ["ID"] == null)
+                               SetNewID ();
+               }
+
+               public HtmlControlTag (Tag source_tag) :
+                       this (source_tag.TagID, source_tag.Attributes, source_tag.SelfClosing) 
+               {
+               }
+
+               private void SetData ()
+               {
+                       tagType = TagType.HTMLCONTROL; 
+                       if (!(controls [tag] is string)){
+                               control_type = (Type) controls [tag];
+                               if (control_type == null)
+                                       control_type = typeof (HtmlGenericControl);
+                               is_container = (0 != String.Compare (tag, "img", true));
+                       } else {
+                               string type_value = (string) attributes ["TYPE"];
+                               if (type_value== null)
+                                       throw new ArgumentException ("INPUT tag without TYPE attribute!!!");
+
+                               control_type = (Type) inputTypes [type_value];
+                               //TODO: what does MS with this one?
+                               if (control_type == null)
+                                       throw new ArgumentException ("Unknown input type -> " + type_value);
+                               is_container = false;
+                               self_closing = true; // All <input ...> are self-closing
+                       }
+               }
+
+               public Type ControlType
+               {
+                       get { return control_type; }
+               }
+
+               public string ControlID
+               {
+                       get { return (string) attributes ["ID"]; }
+               }
+
+               public bool IsContainer
+               {
+                       get { return is_container; }
+               }
+
+               public override string ToString ()
+               {
+                       string ret = "HtmlControlTag: " + tag + " Name: " + ControlID + "Type:" +
+                                    control_type.ToString () + "\n\tAttributes:\n";
+
+                       foreach (string key in attributes.Keys){
+                               ret += "\t" + key + "=" + attributes [key];
+                       }
+                       return ret;
+               }
+       }
+
+       public enum ChildrenKind
+       {
+               NONE,
+               /* 
+                * Children must be ASP.NET server controls. Literal text is passed as LiteralControl.
+                * Child controls and text are added using AddParsedSubObject ().
+                */
+               CONTROLS, 
+               /*
+                * Children must correspond to properties of the parent control. No literal text allowed.
+                */
+               PROPERTIES,
+               /*
+                * Special case used inside <columns>...</columns>
+                * Only allow DataGridColumn and derived classes.
+                */
+               DBCOLUMNS,
+               /*
+                * Special case for list controls (ListBox, DropDownList...)
+                */
+               LISTITEM,
+               /* For HtmlSelect children. They are <option> tags that must
+                * be treated as ListItem
+                */
+               OPTION
+       }
+
+       // TODO: support for ControlBuilderAttribute that may be used in custom controls
+       public class Component : Tag
+       {
+               private Type type;
+               private string alias;
+               private string control_type;
+               private bool is_close_tag;
+               private bool allow_children;
+               private ChildrenKind children_kind;
+               private string defaultPropertyName;
+
+               private ChildrenKind GuessChildrenKind (Type type)
+               {
+                       object [] custom_atts = type.GetCustomAttributes (true);
+                       foreach (object custom_att in custom_atts){
+                               if (custom_att is ParseChildrenAttribute){
+                                       /* FIXME
+                                        * When adding full support for custom controls, we gotta
+                                        * bear in mind the pca.DefaultProperty value
+                                        */
+                                       ParseChildrenAttribute pca = custom_att as ParseChildrenAttribute;
+                                       defaultPropertyName = pca.DefaultProperty;
+                                       /* this property will be true for all controls derived from
+                                        * WebControls. */
+                                       if (pca.ChildrenAsProperties == false)
+                                               return ChildrenKind.CONTROLS;
+                                       else if (defaultPropertyName == "")
+                                               return ChildrenKind.PROPERTIES;
+                                       else
+                                               return ChildrenKind.LISTITEM;
+                               }
+                       }
+
+                       return ChildrenKind.NONE;
+               }
+
+               private static bool GuessAllowChildren (Type type)
+               {
+                       PropertyInfo controls = type.GetProperty ("Controls");
+                       if (controls == null)
+                               return false;
+                       MethodInfo getm = controls.GetGetMethod ();
+                       object control_instance = Activator.CreateInstance (type);
+                       object control_collection = getm.Invoke (control_instance, null);
+                       return (!(control_collection is System.Web.UI.EmptyControlCollection));
+               }
+               
+               public Component (Tag input_tag, Type type) :
+                       base (input_tag)
+               {
+                       tagType = TagType.SERVERCONTROL;
+                       this.is_close_tag = input_tag is CloseTag;
+                       this.type = type;
+                       this.defaultPropertyName = "";
+                       this.allow_children = GuessAllowChildren (type);
+                       if (input_tag.SelfClosing)
+                               this.children_kind = ChildrenKind.NONE;
+                       else if (type == typeof (System.Web.UI.WebControls.DataGridColumn) ||
+                                type.IsSubclassOf (typeof (System.Web.UI.WebControls.DataGridColumn)))
+                               this.children_kind = ChildrenKind.PROPERTIES;
+                       else if (type == typeof (System.Web.UI.WebControls.ListItem))
+                               this.children_kind = ChildrenKind.CONTROLS;
+                       else
+                               this.children_kind = GuessChildrenKind (type);
+
+                       int pos = input_tag.TagID.IndexOf (':');
+                       alias = tag.Substring (0, pos);
+                       control_type = tag.Substring (pos + 1);
+                       if (attributes == null || attributes ["ID"] == null)
+                               SetNewID ();
+               }
+
+               public Type ComponentType
+               {
+                       get { return type; }
+               }
+               
+               public string ControlID
+               {
+                       get { return (string) attributes ["ID"]; }
+               }
+
+               public bool IsCloseTag
+               {
+                       get { return is_close_tag; }
+               }
+
+               public bool AllowChildren
+               {
+                       get { return allow_children; }
+               }
+
+               public ChildrenKind ChildrenKind
+               {
+                       get { return children_kind; }   
+               }
+
+               public string DefaultPropertyName
+               {
+                       get { return defaultPropertyName; }     
+               }
+                       
+                       
+               public override string ToString ()
+               {
+                       return type.ToString () + " Alias: " + alias + " ID: " + (string) attributes ["id"];
+               }
+       }
+
+       public class PropertyTag : Tag
+       {
+               private Type type;
+               private string name;
+
+               public PropertyTag (Tag tag, Type type, string name)
+                       : base (tag)
+               {
+                       tagType = TagType.PROPERTYTAG;
+                       SetNewID ();
+                       this.name = name;
+                       this.type = type;
+               }
+
+               public Type PropertyType
+               {
+                       get { return type; }
+               }
+
+               public string PropertyID
+               {
+                       get { return (string) attributes ["ID"]; }
+               }
+
+               public string PropertyName
+               {
+                       get { return name; }
+               }
+       }
+
+       public class CodeRenderTag : Tag
+       {
+               private string code;
+               private bool isVarName;
+
+               public CodeRenderTag (bool isVarName, string code) : base ("", null, false)
+               {
+                       tagType = TagType.CODERENDER;
+                       this.isVarName = isVarName;
+                       this.code = code.Trim ();
+               }
+
+               public string Code
+               {
+                       get { return code; }
+               }
+
+               public bool IsVarName
+               {
+                       get { return isVarName; }
+               }
+
+               public string AsText
+               {
+                       get { return "<%" + (IsVarName ? "=" : "") + Code + "%>"; }
+               }       
+       }
+
+       public class DataBindingTag : Tag
+       {
+               private string data;
+
+               public DataBindingTag (string data) : base ("", null, false)
+               {
+                       tagType = TagType.DATABINDING;
+                       this.data = data.Trim ();
+               }
+
+               public string Data
+               {
+                       get { return data; }
+               }
+
+               public string AsText
+               {
+                       get { return "<%#" + Data + "%>"; }
+               }       
+       }
+}
+
diff --git a/mcs/class/System.Web/System.Web.Compilation/AspParser.cs b/mcs/class/System.Web/System.Web.Compilation/AspParser.cs
new file mode 100644 (file)
index 0000000..bf5b0e2
--- /dev/null
@@ -0,0 +1,240 @@
+//
+// System.Web.Compilation.AspParser
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+namespace System.Web.Compilation
+{
+       class AspParser {
+               private AspTokenizer tokenizer;
+               private ArrayList elements; // List of processed elements in the HTML page.
+
+               private void error ()
+               {
+                       Console.WriteLine ("Error: " + tokenizer.location);
+                       Environment.Exit (-1); //FIXME
+               }
+
+               private void error (string msg)
+               {
+                       Console.WriteLine ("Error: "+ msg + "\n" + tokenizer.location);
+                       Environment.Exit (-1); //FIXME
+               }
+
+               public AspParser (AspTokenizer tokenizer)
+               {
+                       this.tokenizer = tokenizer;
+                       elements = new ArrayList ();
+               }
+
+               public AspParser (string filename, Stream input) : 
+                       this (new AspTokenizer (filename, input))
+               {
+               }
+
+               public ArrayList Elements
+               {
+                       get { return elements; }
+               }
+
+               private bool Eat (int expected_token)
+               {
+                       if (tokenizer.get_token () != expected_token) {
+                               tokenizer.put_back ();
+                               return false;
+                       }
+                       return true;
+               }
+
+               private void AddPlainText (string newText)
+               {
+                       if (elements.Count > 0){
+                               Element element = (Element) elements [elements.Count - 1];
+                               if (element is PlainText){
+                                       ((PlainText) element).Append (newText);
+                                       return;
+                               }
+                       }
+                       elements.Add (new PlainText (newText));
+               }
+               
+               public void Parse ()
+               {
+                       int token;
+                       Element element;
+                       Tag tag_element;
+                       string tag = "";
+
+                       while ((token = tokenizer.get_token ()) != Token.EOF){
+                               if (tokenizer.Verbatim){
+                                       string end_verbatim = "</" + tag + ">";
+                                       string verbatim_text = GetVerbatim (token, end_verbatim);
+
+                                       if (verbatim_text == null)
+                                               error ("Unexpected EOF processing " + tag);
+
+                                       AddPlainText (verbatim_text);
+                                       elements.Add (new CloseTag (tag));
+                                       tokenizer.Verbatim = false;
+                               }
+                               else if (token == '<'){
+                                       element = GetTag ();
+                                       if (element == null)
+                                               error ();
+                                       if (!(element is Tag)){
+                                               AddPlainText (((PlainText) element).Text);
+                                               continue;
+                                       }
+
+                                       elements.Add (element);
+
+                                       tag_element = element as Tag;
+                                       tag = tag_element.TagID.ToUpper ();
+                                       if (!tag_element.SelfClosing && (tag == "SCRIPT" || tag == "PRE"))
+                                               tokenizer.Verbatim = true;
+                               }
+                               else {
+                                       StringBuilder text =  new StringBuilder ();
+                                       do {
+                                               text.Append (tokenizer.value);
+                                               token = tokenizer.get_token ();
+                                       } while (token != '<' && token != Token.EOF);
+                                       tokenizer.put_back ();
+                                       AddPlainText (text.ToString ());
+                               }
+                       }
+               }
+
+               private Element GetTag ()
+               {
+                       int token = tokenizer.get_token ();
+                       string id;
+                       TagAttributes attributes;
+
+                       switch (token){
+                       case '%':
+                               if (Eat ('@')){
+                                       id = (Eat (Token.DIRECTIVE) ? tokenizer.value : "Page");
+                                       attributes = GetAttributes ();
+                                       if (!Eat ('%') || !Eat ('>'))
+                                               error ("expecting '%>'");
+
+                                       return new Directive (id, attributes);
+                               }
+
+                               bool varname = Eat ('=');
+                               bool databinding = !varname && Eat ('#');
+                               tokenizer.Verbatim = true;
+                               string inside_tags = GetVerbatim (tokenizer.get_token (), "%>");
+                               tokenizer.Verbatim = false;
+                               if (databinding)
+                                       return new DataBindingTag (inside_tags);
+                               return new CodeRenderTag (varname, inside_tags);
+                       case '/':
+                               if (!Eat (Token.IDENTIFIER))
+                                       error ("expecting TAGNAME");
+                               id = tokenizer.value;
+                               if (!Eat ('>'))
+                                       error ("expecting '>'");
+                               return new CloseTag (id);
+                       case '!':
+                               bool double_dash = Eat (Token.DOUBLEDASH);
+                               if (double_dash)
+                                       tokenizer.put_back ();
+
+                               tokenizer.Verbatim = true;
+                               string end = double_dash ? "-->" : ">";
+                               string comment = GetVerbatim (tokenizer.get_token (), end);
+                               tokenizer.Verbatim = false;
+                               if (comment == null)
+                                       error ("Unfinished HTML comment/DTD");
+
+                               return new PlainText ("<!" + comment + end);
+                       case Token.IDENTIFIER:
+                               id = tokenizer.value;
+                               Tag tag = new Tag (id, GetAttributes (), Eat ('/'));
+                               if (!Eat ('>'))
+                                       error ("expecting '>'");
+                               return tag;
+                       default:
+                               return null;
+                       }
+               }
+
+               private TagAttributes GetAttributes ()
+               {
+                       int token;
+                       TagAttributes attributes;
+                       string id;
+
+                       attributes = new TagAttributes ();
+                       while ((token = tokenizer.get_token ())  != Token.EOF){
+                               if (token != Token.IDENTIFIER)
+                                       break;
+                               id = tokenizer.value;
+                               if (Eat ('=')){
+                                       if (Eat (Token.ATTVALUE)){
+                                               attributes.Add (id, tokenizer.value);
+                                       } else {
+                                               //TODO: support data binding syntax without quotes
+                                               error ("expected ATTVALUE");
+                                               return null;
+                                       }
+                                       
+                               } else {
+                                       attributes.Add (id, null);
+                               }
+                       }
+
+                       tokenizer.put_back ();
+                       if (attributes.Count == 0)
+                               return null;
+
+                       return attributes;
+               }
+
+               private string GetVerbatim (int token, string end)
+               {
+                       StringBuilder vb_text = new StringBuilder ();
+                       int i = 0;
+
+                       if (tokenizer.value.Length > 1){
+                               // May be we have a put_back token that is not a single character
+                               vb_text.Append (tokenizer.value);
+                               token = tokenizer.get_token ();
+                       }
+
+                       while (token != Token.EOF){
+                               if (Char.ToUpper ((char) token) == end [i]){
+                                       if (++i >= end.Length)
+                                               break;
+                                       token = tokenizer.get_token ();
+                                       continue;
+                               }
+                               else {
+                                       for (int j = 0; j < i; j++)
+                                               vb_text.Append (end [j]);
+                               }
+
+                               i = 0;
+                               vb_text.Append ((char) token);
+                               token = tokenizer.get_token ();
+                       } 
+
+                       if (token == Token.EOF)
+                               return null;
+
+                       return vb_text.ToString ();
+               }
+       }
+
+}
+
diff --git a/mcs/class/System.Web/System.Web.Compilation/AspTokenizer.cs b/mcs/class/System.Web/System.Web.Compilation/AspTokenizer.cs
new file mode 100644 (file)
index 0000000..0b72bef
--- /dev/null
@@ -0,0 +1,215 @@
+//
+// System.Web.Compilation.AspTokenizer
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+namespace System.Web.Compilation {
+       
+       class Token
+       {
+               public const int EOF            = 0;
+               public const int IDENTIFIER     = 1000;
+               public const int DIRECTIVE      = 1001;
+               public const int ATTVALUE       = 1002;
+               public const int TEXT           = 1003;
+               public const int DOUBLEDASH     = 1004;
+               public const int CLOSING        = 1005;
+       }
+
+       class AspTokenizer {
+               private StreamReader sr;
+               private int current_token;
+               private StringBuilder sb;
+               private int col, line;
+               private bool inTag;
+               private bool hasPutBack;
+               private bool verbatim;
+               private string filename;
+               
+               public AspTokenizer (string filename, Stream stream)
+               {
+                       if (filename == null || stream == null)
+                               throw new ArgumentNullException ();
+
+                       this.sr = new StreamReader (stream);
+                       this.filename = filename;
+                       sb = new StringBuilder ();
+                       col = line = 1;
+                       hasPutBack = inTag = false;
+               }
+
+               public bool Verbatim
+               {
+                       get { return verbatim; }
+                       set { verbatim = value; }
+               }
+
+               public void put_back ()
+               {
+                       if (hasPutBack)
+                               throw new ApplicationException ("put_back called twice!");
+                               
+                       hasPutBack = true;
+               }
+               
+               public int get_token ()
+               {
+                       if (hasPutBack){
+                               hasPutBack = false;
+                               return current_token;
+                       }
+
+                       current_token = NextToken ();
+                       return current_token;
+               }
+
+               bool is_identifier_start_character (char c)
+               {
+                       return (Char.IsLetter (c) || c == '_' );
+               }
+
+               bool is_identifier_part_character (char c)
+               {
+                       return (Char.IsLetterOrDigit (c) || c == '_' || c == '-');
+               }
+
+               private int read_char ()
+               {
+                       int c = sr.Read ();
+
+                       if (c == '\r' && sr.Peek () == '\n')
+                               c = sr.Read ();
+
+                       if (c == '\n'){
+                               col = 0;
+                               line++;
+                       }
+                       else if (c != -1)
+                               col++;
+
+                       return c;
+               }
+
+               private int NextToken ()
+               {
+                       int c;
+                       
+                       sb.Length = 0;
+                       while ((c = read_char ()) != -1){
+                               if (verbatim){
+                                       inTag = false;
+                                       sb.Append  ((char) c);
+                                       return c;
+                               }
+
+                               if (inTag && (c == '"' || c == '\'')){
+                                       int previous;
+                                       int start = c;
+
+                                       previous = 0;
+                                       while ((c = sr.Peek ()) != -1) {
+                                               if (c == start && previous != '\\'){
+                                                       read_char ();
+                                                       break;
+                                               }
+                                               sb.Append ((char) read_char ());
+                                               previous = c;
+                                       }
+                                       
+                                       return Token.ATTVALUE;
+                               }
+                               
+                               if (c == '<'){
+                                       inTag = true;
+                                       sb.Append ((char) c);
+                                       return c;
+                               }
+
+                               if (c == '>'){
+                                       inTag = false;
+                                       sb.Append ((char) c);
+                                       return c;
+                               }
+
+                               if (current_token == '<' && "%/!".IndexOf ((char) c) != -1){
+                                       sb.Append ((char) c);
+                                       return c;
+                               }
+
+                               if (inTag && current_token == '%' && "@#=".IndexOf ((char) c) != -1){
+                                       sb.Append ((char) c);
+                                       return c;
+                               }
+
+                               if (inTag && c == '-' && sr.Peek () == '-'){
+                                       sb.Append ("--");
+                                       read_char ();
+                                       return Token.DOUBLEDASH;
+                               }
+
+                               if (!inTag){
+                                       sb.Append ((char) c);
+                                       while ((c = sr.Peek ()) != -1 && c != '<')
+                                               sb.Append ((char) read_char ());
+
+                                       return (c != -1 || sb.Length > 0) ? Token.TEXT : Token.EOF;
+                               }
+
+                               if (inTag && current_token == '=' && !Char.IsWhiteSpace ((char) c)){ 
+                                       sb.Append ((char) c);
+                                       while ((c = sr.Peek ()) != -1) {
+                                               if (Char.IsWhiteSpace ((char) c) || c == '/' || c == '>')
+                                                       break;
+                                               sb.Append ((char) read_char ());
+                                       }
+
+                                       return Token.ATTVALUE;
+                               }
+
+                               if (inTag && is_identifier_start_character ((char) c)){
+                                       sb.Append ((char) c);
+                                       while ((c = sr.Peek ()) != -1) {
+                                               if (!is_identifier_part_character ((char) c) && c != ':')
+                                                       break;
+                                               sb.Append ((char) read_char ());
+                                       }
+
+                                       if (current_token == '@' && Directive.IsDirectiveID (sb.ToString ()))
+                                               return Token.DIRECTIVE;
+
+                                       return Token.IDENTIFIER;
+                               }
+
+                               if (!Char.IsWhiteSpace ((char) c))
+                                       return c;
+                       }
+
+                       return Token.EOF;
+               }
+
+               public string value 
+               {
+                       get { return sb.ToString (); }
+               }
+
+               public string location 
+               {
+                       get { 
+                               string msg = filename;
+                               msg += " (" + line + ", " + col + "): " + sb.ToString ();
+                               return msg;
+                       }
+               }
+
+       }
+}
+
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..204ece1c2386b51246bf5d7fbb9f21c4266ebf72 100644 (file)
@@ -0,0 +1,9 @@
+2002-08-16  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * AspElements.cs:
+       * AspParser.cs:
+       * AspTokenizer.cs:
+       * ChangeLog:
+       * PageCompiler.cs:
+       * TemplateFactory.cs: first steps to move xsp into System.Web.
+
diff --git a/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs
new file mode 100644 (file)
index 0000000..c0fdc14
--- /dev/null
@@ -0,0 +1,28 @@
+//
+// System.Web.Compilation.PageCompiler
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+using System;
+using System.Web.UI;
+
+namespace System.Web.Compilation
+{
+       class PageCompiler
+       {
+               private PageParser pageParser;
+
+               internal PageCompiler (PageParser pageParser)
+               {
+                       this.pageParser = pageParser;
+               }
+
+               public static Type CompilePageType (PageParser pageParser)
+               {
+                       return TemplateFactory.GetTypeFromSource (pageParser.InputFile);
+               }
+       }
+}
diff --git a/mcs/class/System.Web/System.Web.Compilation/TemplateFactory.cs b/mcs/class/System.Web/System.Web.Compilation/TemplateFactory.cs
new file mode 100644 (file)
index 0000000..da66429
--- /dev/null
@@ -0,0 +1,214 @@
+//\r
+// System.Web.Compilation.TemplateFactory\r
+//\r
+// Authors:\r
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)\r
+//\r
+// (C) 2002 Ximian, Inc (http://www.ximian.com)\r
+//\r
+using System;\r
+using System.Collections;\r
+using System.Diagnostics;\r
+using System.IO;\r
+using System.Reflection;\r
+using System.Text;\r
+using System.Web.UI;\r
+\r
+namespace System.Web.Compilation\r
+{\r
+       class TemplateFactory\r
+       {\r
+               internal class PageBuilder\r
+               {\r
+                       private StringBuilder cscOptions;\r
+                       private string fileName;\r
+                       private string csFileName;\r
+                       private string className;\r
+                       public static char dirSeparator = Path.DirectorySeparatorChar;\r
+                       private static Hashtable cachedData = new Hashtable ();\r
+                       private static Random rnd_file = new Random ();\r
+\r
+                       private PageBuilder ()\r
+                       {\r
+                       }\r
+\r
+                       internal PageBuilder (string fileName)\r
+                       {\r
+                               this.fileName = fileName;\r
+                               csFileName = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".cs");\r
+\r
+                               cscOptions = new StringBuilder ();\r
+                               cscOptions.Append ("--target library ");\r
+                               cscOptions.Append ("-L . ");\r
+                               AddReference ("corlib");\r
+                               AddReference ("System");\r
+                               AddReference ("System.Data");\r
+                               AddReference ("System.Web");\r
+                               AddReference ("System.Drawing");\r
+                       }\r
+\r
+                       internal Type Build ()\r
+                       {\r
+                               string dll;\r
+                               if (Xsp (fileName, csFileName) == false){\r
+                                       Console.WriteLine ("Error running xsp. " + \r
+                                                          "Take a look at the output file.");\r
+                                       return null;\r
+                               }\r
+\r
+                               StreamReader st_file = new StreamReader (File.OpenRead ("output" +\r
+                                                                                       dirSeparator +\r
+                                                                                       csFileName));\r
+                               \r
+                               StringReader file_content = new StringReader (st_file.ReadToEnd ());\r
+                               st_file.Close ();\r
+                               if (GetBuildOptions (file_content) == false)\r
+                                       return null;\r
+\r
+                               dll = "output" + dirSeparator;\r
+                               dll += rnd_file.Next () + Path.GetFileName (fileName).Replace (".aspx", ".dll");\r
+                               if (Compile (csFileName, dll) == true){\r
+                                       Assembly assembly = Assembly.LoadFrom (dll);\r
+                                       Type type = assembly.GetType ("ASP." + className);\r
+                                       return type;\r
+                               }\r
+\r
+                               return null;\r
+                       }\r
+\r
+                       private static bool Xsp (string fileName, string csFileName)\r
+                       {\r
+                               return RunProcess ("mono", \r
+                                                  "xsp.exe " + fileName, \r
+                                                  GeneratedXspFileName (fileName),\r
+                                                  "output" + dirSeparator + "xsp_" + Path.GetFileName (fileName) + \r
+                                                  ".sh");\r
+                       }\r
+\r
+                       private static bool RunProcess (string exe, string arguments, string output_file, string script_file)\r
+                       {\r
+                               Console.WriteLine ("{0} {1}", exe, arguments);\r
+                               Console.WriteLine ("Output goes to {0}", output_file);\r
+                               Console.WriteLine ("Script file is {0}", script_file);\r
+                               Process proc = new Process ();\r
+\r
+                               proc.StartInfo.FileName = "redirector.sh";\r
+                               proc.StartInfo.Arguments = exe + " " + output_file + " " + arguments;\r
+                               proc.Start ();\r
+                               proc.WaitForExit ();\r
+                               int result = proc.ExitCode;\r
+                               proc.Close ();\r
+\r
+                               StreamWriter bat_output = new StreamWriter (File.Create (script_file));\r
+                               bat_output.Write ("redirector.sh" + " " + exe + " " + output_file + " " + arguments);\r
+                               bat_output.Close ();\r
+/*\r
+ * Use this code when redirection works properly\r
+ *\r
+                               proc.StartInfo.FileName = exe;\r
+                               proc.StartInfo.Arguments = arguments;\r
+                               proc.StartInfo.UseShellExecute = false;\r
+                               proc.StartInfo.RedirectStandardOutput = true;\r
+                               proc.Start ();\r
+                               string poutput = proc.StandardOutput.ReadToEnd();\r
+                               proc.WaitForExit ();\r
+                               int result = proc.ExitCode;\r
+                               proc.Close ();\r
+\r
+                               StreamWriter cmd_output = new StreamWriter (File.Create (output_file));\r
+                               cmd_output.Write (poutput);\r
+                               cmd_output.Close ();\r
+                               StreamWriter bat_output = new StreamWriter (File.Create (script_file));\r
+                               bat_output.Write (exe + " " + arguments);\r
+                               bat_output.Close ();\r
+*/\r
+\r
+                               return (result == 0);\r
+                       }\r
+\r
+                       private bool GetBuildOptions (StringReader genCode)\r
+                       {\r
+                               string line;\r
+                               string dll;\r
+\r
+                               while ((line = genCode.ReadLine ()) != String.Empty) {\r
+                                       if (line.StartsWith ("//<class ")){\r
+                                               className = GetAttributeValue (line, "name");\r
+                                       } else if (line.StartsWith ("//<compileandreference ")) {\r
+                                               string src = GetAttributeValue (line, "src");\r
+                                               dll = src.Replace (".cs", ".dll"); //FIXME\r
+                                               //File.Delete (dll);\r
+                                               if (Compile (src, dll) == false){\r
+                                                       Console.WriteLine ("Error compiling {0}. See the output file.", src);\r
+                                                       return false;\r
+                                               }\r
+                                               AddReference (dll.Replace (".dll", ""));\r
+                                       } else if (line.StartsWith ("//<reference ")) {\r
+                                               dll = GetAttributeValue (line, "dll");\r
+                                               AddReference (dll);\r
+                                       } else if (line.StartsWith ("//<compileroptions ")) {\r
+                                               string options = GetAttributeValue (line, "options");\r
+                                               cscOptions.Append (" " + options + " ");\r
+                                       } else {\r
+                                               Console.WriteLine ("This is the build option line i get:\n" + line);\r
+                                               return false;\r
+                                       }\r
+                               }\r
+\r
+                               return true;\r
+                       }\r
+\r
+                       private void AddReference (string reference)\r
+                       {\r
+                               string arg = String.Format ("/r:{0} ", reference);\r
+                               cscOptions.Append (arg);\r
+                       }\r
+                       \r
+                       private string GetAttributeValue (string line, string att)\r
+                       {\r
+                               string att_start = att + "=\"";\r
+                               int begin = line.IndexOf (att_start);\r
+                               int end = line.Substring (begin + att_start.Length).IndexOf ('"');\r
+                               if (begin == -1 || end == -1)\r
+                                       throw new ApplicationException ("Error in reference option:\n" + line);\r
+\r
+                               return line.Substring (begin + att_start.Length, end);\r
+                       }\r
+                       \r
+                       private bool Compile (string csName, string dllName)\r
+                       {\r
+                               cscOptions.AppendFormat ("/out:{0} ", dllName);\r
+                               cscOptions.Append ("output" + dirSeparator + csName);\r
+\r
+                               string cmdline = cscOptions.ToString ();\r
+                               string noext = csName.Replace (".cs", "");\r
+                               string output_file = "output" + dirSeparator + "output_from_compilation_" + noext + ".txt";\r
+                               string bat_file = "output" + dirSeparator + "last_compilation_" + noext + ".bat";\r
+                               return RunProcess ("mcs", cmdline, output_file, bat_file);\r
+                       }\r
+               }\r
+\r
+               internal static string CompilationOutputFileName (string fileName)\r
+               {\r
+                       string name = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".txt");\r
+                       return "output" + PageBuilder.dirSeparator + "output_from_compilation_" + name;\r
+               }\r
+\r
+               internal static string GeneratedXspFileName (string fileName)\r
+               {\r
+                       string name = Path.GetFileName (fileName).Replace (".aspx", ".cs");\r
+                       return "output" + PageBuilder.dirSeparator + "xsp_" + name;\r
+               }\r
+\r
+               private TemplateFactory ()\r
+               {\r
+               }\r
+\r
+               internal static Type GetTypeFromSource (string fileName)\r
+               {\r
+                       PageBuilder builder = new PageBuilder (fileName);\r
+                       return builder.Build ();\r
+               }\r
+       }\r
+}\r
+\r
diff --git a/mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs b/mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs
new file mode 100644 (file)
index 0000000..de9df55
--- /dev/null
@@ -0,0 +1,46 @@
+//
+// System.Web.UI.ApplicationfileParser
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+using System;
+using System.Web;
+
+namespace System.Web.UI
+{
+       internal sealed class ApplicationFileParser : TemplateParser
+       {
+               [MonoTODO]
+               protected override Type CompileIntoType ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               internal static Type GetCompiledApplicationType (string inputFile, 
+                                                                HttpContext context,
+                                                                ref ApplicationFileParser parser)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               protected override Type DefaultBaseType
+               {
+                       get {
+                               return typeof (HttpApplication);
+                       }
+               }
+
+               protected override string DefaultDirectiveName
+               {
+                       get {
+                               return "application";
+                       }
+               }
+       }
+
+}
+
index 981cc5d0828193de54281cfa4f6615de1e78d90b..379b5f6c3f56671cc954afd1f66b662e930c2382 100755 (executable)
@@ -1,14 +1,73 @@
 //
 // System.Web.UI.BaseParser.cs
 //
-// Duncan Mak  (duncan@ximian.com)
+// Authors:
+//     Duncan Mak  (duncan@ximian.com)
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
-// (C) Ximian, Inc.
+// (C) 2002 Ximian, Inc. (http://www.ximian.com)
 //
+using System.IO;
+using System.Web;
 
-namespace System.Web.UI {
+namespace System.Web.UI
+{
        public class BaseParser
        {
-               // LAMESPEC: We know nothing about this class from the docs.
+               private HttpContext context;
+               private string baseDir;
+               private string baseVDir;
+               private string vPath;
+
+               internal string MapPath (string path)
+               {
+                       return MapPath (path, true);
+               }
+
+               internal string MapPath (string path, bool allowCrossAppMapping)
+               {
+                       return context.Request.MapPath (path, baseVDir, allowCrossAppMapping);
+               }
+
+               internal string PhysicalPath (string path)
+               {
+                       if (Path.DirectorySeparatorChar != '/')
+                               path = path.Replace ('/', '\\');
+                               
+                       return Path.GetFullPath (Path.Combine (baseVDir, path));
+               }
+
+               internal HttpContext Context
+               {
+                       get {
+                               return context;
+                       }
+               }
+
+               internal string BaseDir
+               {
+                       get {
+                               if (baseDir == null)
+                                       baseDir = MapPath (baseVDir, false);
+
+                               return baseDir;
+                       }
+               }
+
+               internal string BaseVirtualDir
+               {
+                       get {
+                               return baseVDir;
+                       }
+               }
+
+               internal string CurrentVirtualPath
+               {
+                       get {
+                               return vPath;
+                       }
+               }
        }
+
 }
+
index d38385663340cec79c91441cb5f7fc22396f150d..7fcd53428607cd9520a5e599cdb9eb848b639f2d 100644 (file)
@@ -1,3 +1,13 @@
+2002-08-16  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * System.Web.UI/ApplicationFileParser.cs:
+       * System.Web.UI/BaseParser.cs:
+       * System.Web.UI/PageParser.cs:
+       * System.Web.UI/TemplateControl.cs:
+       * System.Web.UI/TemplateControlParser.cs:
+       * System.Web.UI/TemplateParser.cs: first steps to move xsp into
+       System.Web.
+
 2002-07-30  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * Page.cs: request to render postback script can be after form started
diff --git a/mcs/class/System.Web/System.Web.UI/PageParser.cs b/mcs/class/System.Web/System.Web.UI/PageParser.cs
new file mode 100644 (file)
index 0000000..7e45a7a
--- /dev/null
@@ -0,0 +1,45 @@
+//
+// System.Web.UI.PageParser
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+using System;
+using System.Web;
+using System.Web.Compilation;
+
+namespace System.Web.UI
+{
+       public sealed class PageParser : TemplateControlParser
+       {
+               public static IHttpHandler GetCompiledPageInstance (string virtualPath,
+                                                                   string inputFile, 
+                                                                   HttpContext context)
+               {
+                       PageParser pp = new PageParser ();
+                       return (IHttpHandler) pp.GetCompiledInstance (virtualPath, inputFile, context);
+               }
+
+               protected override Type CompileIntoType ()
+               {
+                       return PageCompiler.CompilePageType (this);
+               }
+
+               protected override Type DefaultBaseType
+               {
+                       get {
+                               return typeof (Page);
+                       }
+               }
+
+               protected override string DefaultDirectiveName
+               {
+                       get {
+                               return "page";
+                       }
+               }
+       }
+}
+
index 2108376413630fc6272fd62cb6a92ad0c4b2be09..c117fcdcf4536f81cfd4b0e16338d29c68758c36 100755 (executable)
@@ -12,24 +12,29 @@ namespace System.Web.UI {
 
        public abstract class TemplateControl : Control, INamingContainer
        {
+               private object abortTransaction = new object ();
+               private object commitTransaction = new object ();
+               private object error = new object ();
+
                #region Constructor
                protected TemplateControl ()
                {
+                       Construct ();
                }
 
                #endregion
 
                #region Properties
 
-               [MonoTODO]
-               protected virtual int AutoHandlers {
-                       get { return 1; }
+               protected virtual int AutoHandlers
+               {
+                       get { return 0; }
                        set { }
                }
 
-               [MonoTODO]
-               protected virtual bool SupportAutoEvents {
-                       get { return false; }
+               protected virtual bool SupportAutoEvents
+               {
+                       get { return true; }
                }
 
                #endregion
@@ -41,13 +46,13 @@ namespace System.Web.UI {
                }
 
                [MonoTODO]
-               protected virtual LiteralControl CreateResourceBasedLiteralControl (
-                       int offset, int size, bool fAsciiOnly)
+               protected virtual LiteralControl CreateResourceBasedLiteralControl (int offset,
+                                                                                   int size,
+                                                                                   bool fAsciiOnly)
                {
                        return null;
                }
 
-               [MonoTODO]
                protected virtual void FrameworkInitialize ()
                {
                }
@@ -64,19 +69,25 @@ namespace System.Web.UI {
                        return null;
                }
 
-               [MonoTODO]
                protected virtual void OnAbortTransaction (EventArgs e)
                {
+                       EventHandler eh = (EventHandler) Events [error];
+                       if (eh != null)
+                               eh.Invoke (this, e);
                }
 
-               [MonoTODO]
                protected virtual void OnCommitTransaction (EventArgs e)
                {
+                       EventHandler eh = (EventHandler) Events [commitTransaction];
+                       if (eh != null)
+                               eh.Invoke (this, e);
                }
 
-               [MonoTODO]
                protected virtual void OnError (EventArgs e)
                {
+                       EventHandler eh = (EventHandler) Events [abortTransaction];
+                       if (eh != null)
+                               eh.Invoke (this, e);
                }
 
                [MonoTODO]
@@ -107,9 +118,39 @@ namespace System.Web.UI {
 
                #region Events
 
-               public event EventHandler AbortTransaction;
-               public event EventHandler CommitTransaction;
-               public event EventHandler Error;
+               public event EventHandler AbortTransaction
+               {
+                       add {
+                               Events.AddHandler (abortTransaction, value);
+                       }
+
+                       remove {
+                               Events.RemoveHandler (abortTransaction, value);
+                       }
+               }
+
+               public event EventHandler CommitTransaction
+               {
+                       add {
+                               Events.AddHandler (commitTransaction, value);
+                       }
+
+                       remove {
+                               Events.RemoveHandler (commitTransaction, value);
+                       }
+               }
+
+               public event EventHandler Error
+               {
+                       add {
+                               Events.AddHandler (error, value);
+                       }
+
+                       remove {
+                               Events.RemoveHandler (error, value);
+                       }
+               }
+
                #endregion
        }
 }
diff --git a/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs b/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs
new file mode 100644 (file)
index 0000000..3a4aac8
--- /dev/null
@@ -0,0 +1,28 @@
+//
+// System.Web.UI.TemplateControlParser
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+using System;
+using System.IO;
+using System.Web.Compilation;
+
+namespace System.Web.UI
+{
+       public abstract class TemplateControlParser : TemplateParser
+       {
+               internal object GetCompiledInstance (string virtualPath, string inputFile, HttpContext context)
+               {
+                       InputFile = Path.Combine (MapPath (virtualPath, false), inputFile);
+                       Type type = CompileIntoType ();
+                       if (type == null)
+                               return null;
+
+                       return Activator.CreateInstance (type);
+               }
+       }
+}
+
index 9121da5131a1e1e85175c9c084487544d0e870e8..816fc4f201e4b16e820a03f5816de0d01ebbcfe0 100755 (executable)
@@ -1,17 +1,46 @@
 //
-// System.Web.UI.TemplateParser.cs
+// System.Web.UI.TemplateParser
 //
-// Duncan Mak  (duncan@ximian.com)
+// Authors:
+//     Duncan Mak (duncan@ximian.com)
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
-// (C) Ximian, Inc.
+// (C) 2002 Ximian, Inc. (http://www.ximian.com)
 //
-
 using System;
+using System.Web;
 
-namespace System.Web.UI {
-
+namespace System.Web.UI
+{
        public abstract class TemplateParser : BaseParser
        {
+               private string inputFile;
+               private string text;
+               private Type baseType;
+
                protected abstract Type CompileIntoType ();
+
+               protected abstract Type DefaultBaseType { get; }
+
+               protected abstract string DefaultDirectiveName { get; }
+
+               internal string InputFile
+               {
+                       get { return inputFile; }
+                       set { inputFile = value; }
+               }
+
+               internal string Text
+               {
+                       get { return text; }
+                       set { text = value; }
+               }
+
+               internal Type BaseType
+               {
+                       get { return baseType; }
+                       set { baseType = value; }
+               }
        }
 }
+