2002-10-08 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 8 Oct 2002 04:29:52 +0000 (04:29 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 8 Oct 2002 04:29:52 +0000 (04:29 -0000)
* System.Web/HttpApplication.cs: use handlers from configuration.
* System.Web/HttpContext.cs: get handlers from ConfigurationSettings.

* System.Web.Caching/Cache.cs: little fixes.

* System.Web.Configuration/HttpHandlerTypeMapper.cs: removed.
* System.Web.Configuration/HandlerFactoryConfiguration.cs: readded. I
removed it by mistake.
* System.Web.Configuration/HandlerItem.cs: only load the type if
we gotta validate it. Implemented initial IsMatch.
* System.Web.Configuration/HttpConfigurationContext.cs: New file.
* System.Web.Configuration/HttpHandlersSectionHandler.cs: validate is
optional (default true).  Use HttpHandlerTypeMapper.

* System.Web.UI/SimpleHandlerFactory.cs: new handler for .ashx files.

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

14 files changed:
mcs/class/System.Web/System.Web.Caching/Cache.cs
mcs/class/System.Web/System.Web.Caching/ChangeLog
mcs/class/System.Web/System.Web.Configuration/ChangeLog
mcs/class/System.Web/System.Web.Configuration/HandlerFactoryConfiguration.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.Configuration/HandlerItem.cs
mcs/class/System.Web/System.Web.Configuration/HttpConfigurationContext.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.Configuration/HttpHandlerTypeMapper.cs [deleted file]
mcs/class/System.Web/System.Web.Configuration/HttpHandlersSectionHandler.cs
mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/SimpleHandlerFactory.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web/ChangeLog
mcs/class/System.Web/System.Web/HttpApplication.cs
mcs/class/System.Web/System.Web/HttpContext.cs
mcs/class/System.Web/list

index 5e331aa43c480a62030afd23e71d7ab8b695b50b..921578f6923f76992dc759db31bfbe9093cdd25c 100644 (file)
@@ -135,7 +135,7 @@ namespace System.Web.Caching
                /// <summary>\r
                /// Virtual override of the IEnumerable.GetEnumerator() method, returns a specialized enumerator.\r
                /// </summary>\r
-               public virtual System.Collections.IDictionaryEnumerator GetEnumerator()\r
+               public System.Collections.IDictionaryEnumerator GetEnumerator()\r
                {\r
                        return CreateEnumerator();\r
                }\r
@@ -458,7 +458,7 @@ namespace System.Web.Caching
                /// <summary>\r
                /// Gets the number of items stored in the cache.\r
                /// </summary>\r
-               long Count\r
+               public long Count\r
                {\r
                        get \r
                        {\r
index c5c581c0072b168a345130404a40b4e4c6c65084..57a31c1fb1b253ba3047a18772c36e9a3e601cb4 100644 (file)
@@ -1,3 +1,7 @@
+2002-10-08  Gonzalo Paniagua Javier <gonzalo@ximian.com>\r
+\r
+       * Cache.cs: little fixes.\r
+\r
 2002-07-28  Gonzalo Paniagua Javier <gonzalo@ximian.com>\r
 \r
        * CacheDefinitions.cs: fixed a couple of enums.\r
index 0c39a27646a7e9f2a52b1d38b829226f66ebc96b..016bffc94dfcc0a87382e735f6ff1d22bcdab4b3 100644 (file)
@@ -1,3 +1,13 @@
+2002-10-08  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * HttpHandlerTypeMapper.cs: removed.
+       * HandlerFactoryConfiguration.cs: readded. I removed it by mistake.
+       * HandlerItem.cs: only load the type if we gotta validate it.
+       Implemented initial IsMatch.
+       * HttpConfigurationContext.cs: New file.
+       * HttpHandlersSectionHandler.cs: validate is optional (default true). 
+       Use HttpHandlerTypeMapper.
+
 2002-10-06  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * System.Web.Configuration/HandlerFactoryConfiguration.cs: removed.
diff --git a/mcs/class/System.Web/System.Web.Configuration/HandlerFactoryConfiguration.cs b/mcs/class/System.Web/System.Web.Configuration/HandlerFactoryConfiguration.cs
new file mode 100644 (file)
index 0000000..c80ac69
--- /dev/null
@@ -0,0 +1,75 @@
+// 
+// System.Web.Configuration.HandlerFactoryConfiguration
+//
+// Authors:
+//     Patrik Torstensson (ptorsten@hotmail.com)
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+
+using System.Collections;
+
+namespace System.Web.Configuration
+{
+       class HandlerFactoryConfiguration
+       {
+               ArrayList mappings;
+
+               public HandlerFactoryConfiguration () : this (null)
+               {
+               }
+
+               public HandlerFactoryConfiguration (HandlerFactoryConfiguration parent)
+               {
+                       if (parent != null)
+                               mappings = new ArrayList (parent.mappings);
+                       else
+                               mappings = new ArrayList ();
+               }
+
+               public void Add (HandlerItem mapping)
+               {
+                       mappings.Add (mapping);
+               }
+
+               public HandlerItem Remove (string verb, string path)
+               {
+                       int i = GetIndex (verb, path);
+                       if (i == -1)
+                               return null;
+                       
+                       HandlerItem item = (HandlerItem) mappings [i];
+                       mappings.RemoveAt (i);
+                       return item;
+               }
+
+               public void Clear ()
+               {
+                       mappings.Clear ();
+               }
+
+               public HandlerItem FindHandler (string verb, string path)
+               {
+                       int i = GetIndex (verb, path);
+                       if (i == -1)
+                               return null;
+
+                       return (HandlerItem) mappings [i];
+               }
+
+               int GetIndex (string verb, string path)
+               {
+                       int end = mappings.Count;
+
+                       for (int i = 0; i < end; i++) {
+                               HandlerItem item = (HandlerItem) mappings [i];
+                               if (item.IsMatch (verb, path))
+                                       return i;
+                       }
+
+                       return -1;
+               }
+       }
+}
+
index 99b2f487b57e30a536e2c6035a125a56be02e97f..ae134b3883fb784845bedab7a7b80a1ad98920d8 100644 (file)
 // 
 // System.Web.Configuration.HandlerItem
 //
-// Author:
-//   Patrik Torstensson (ptorsten@hotmail.com)
+// Authors:
+//     Patrik Torstensson (ptorsten@hotmail.com)
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+//   (c) 2002 Ximian, Inc. (http://www.ximian.com) 
 //
 using System;
+using System.Collections;
+using System.Text;
+using System.Text.RegularExpressions;
 
-namespace System.Web.Configuration {
-       public class HandlerItem {
+namespace System.Web.Configuration
+{
+       public class HandlerItem
+       {
                private Type _type;
                private string _typeName;
                private string _path;
                private string _requestType;
-               bool validate;
+               private Regex requestRegex;
+               private Regex pathRegex;
+               static Hashtable regexCache;
 
-               public HandlerItem(string requestType, string path, string type, bool validate) {
+               public HandlerItem (string requestType, string path, string type, bool validate)
+               {
                        _typeName = type;
                        _path = path;
-                       _requestType = requestType.Replace(" ", "");
-                       this.validate = validate;
-
-                       _type = Type.GetType(type, true);
-                       if (!typeof(IHttpHandler).IsAssignableFrom(_type)) {
-                               if (!typeof(IHttpHandlerFactory).IsAssignableFrom(_type)) {
-                                       throw new HttpException(HttpRuntime.FormatResourceString("type_not_factory_or_handler"));
-                               }
-                       }
+                       _requestType = requestType.Replace (" ", "");
+                       requestRegex = GetRegex (_requestType);
+                       pathRegex = GetRegex (_path);
+                       if (validate)
+                               DoValidation ();
                }
 
-               public object Create() {
-                       return HttpRuntime.CreateInternalObject(_type);
+               public object Create ()
+               {
+                       if (_type == null)
+                               DoValidation ();
+
+                       return HttpRuntime.CreateInternalObject (_type);
                }
 
-               public Type Type {
+               public Type Type
+               {
                        get {
+                               if (_type == null)
+                                       DoValidation ();
                                return _type;
                        }
                }
 
                public bool IsMatch (string type, string path)
                {
-                       return (MatchVerb (type) && MatchExtension (path));
+                       return (MatchVerb (type) && MatchPath (path));
                }
 
                bool MatchVerb (string verb)
                {
-                       //FIXME: implement me
-                       return true;
+                       return requestRegex.IsMatch (verb);
+               }
+
+               bool MatchPath (string path)
+               {
+                       return pathRegex.IsMatch (path);
                }
 
-               bool MatchExtension (string path)
+               void DoValidation ()
                {
-                       //FIXME: implement me
-                       return true;
+                       _type = Type.GetType (_typeName, true);
+                       if (typeof (IHttpHandler).IsAssignableFrom (_type))
+                               return;
+                       
+                       if (typeof (IHttpHandlerFactory).IsAssignableFrom (_type))
+                               return;
+
+                       throw new HttpException (HttpRuntime.FormatResourceString ("type_not_factory_or_handler"));
+               }
+
+               static string ToRegexPattern (string dosPattern)
+               {
+                       string result = dosPattern.Replace (".", "\\.");
+                       result = result.Replace ("*", ".*");
+                       result = result.Replace ('?', '.');
+                       return result;
+               }
+                       
+               static Regex GetRegex (string verb)
+               {
+                       EnsureCache ();
+                       if (regexCache.ContainsKey (verb))
+                               return (Regex) regexCache [verb];
+
+                       StringBuilder result = new StringBuilder ("\\A");
+                       string [] expressions = verb.Split (',');
+                       int end = expressions.Length;
+                       for (int i = 0; i < end; i++) {
+                               string regex = ToRegexPattern (expressions [i]);
+                               if (i + 1 < end) {
+                                       result.AppendFormat ("{0}\\z|\\A", regex);
+                               } else {
+                                       result.AppendFormat ("({0})\\z", regex);
+                               }
+                       }
+
+                       Regex r = new Regex (result.ToString ());
+                       regexCache [verb] = r;
+                       return r;
+               }
+
+               static void EnsureCache ()
+               {
+                       if (regexCache == null)
+                               regexCache = new Hashtable ();
                }
        }
 }
+
diff --git a/mcs/class/System.Web/System.Web.Configuration/HttpConfigurationContext.cs b/mcs/class/System.Web/System.Web.Configuration/HttpConfigurationContext.cs
new file mode 100644 (file)
index 0000000..192b3ad
--- /dev/null
@@ -0,0 +1,29 @@
+//
+// System.Web.Configuration.HttpConfigurationContext
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+
+namespace System.Web.Configuration
+{
+       public class HttpConfigurationContext
+       {
+               private string virtualPath;
+
+               internal HttpConfigurationContext (string virtualPath)
+               {
+                       this.virtualPath = virtualPath;
+               }
+
+               public string VirtualPath
+               {
+                       get {
+                               return virtualPath;
+                       }
+               }
+       }
+}
+
diff --git a/mcs/class/System.Web/System.Web.Configuration/HttpHandlerTypeMapper.cs b/mcs/class/System.Web/System.Web.Configuration/HttpHandlerTypeMapper.cs
deleted file mode 100644 (file)
index 621b6db..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// System.Web.Configuration.HttpHandlerTypeMapper
-//
-// Authors:
-//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//
-// (C) 2002 Ximian, Inc (http://www.ximian.com)
-//
-
-using System.Collections;
-
-namespace System.Web.Configuration
-{
-       class HttpHandlerTypeMapper
-       {
-               ArrayList mappings;
-
-               public HttpHandlerTypeMapper () : this (null)
-               {
-               }
-
-               public HttpHandlerTypeMapper (HttpHandlerTypeMapper parent)
-               {
-                       if (parent != null)
-                               mappings = new ArrayList (parent.mappings);
-                       else
-                               mappings = new ArrayList ();
-               }
-
-               public void Add (HandlerItem mapping)
-               {
-                       mappings.Add (mapping);
-               }
-
-               public HandlerItem Remove (string verb, string path)
-               {
-                       int i = SearchHandler (verb, path);
-                       if (i == -1)
-                               return null;
-                       
-                       HandlerItem item = (HandlerItem) mappings [i];
-                       mappings.RemoveAt (i);
-                       return item;
-               }
-
-               public void Clear ()
-               {
-                       mappings.Clear ();
-               }
-
-               public HandlerItem FindHandler (string verb, string path)
-               {
-                       int i = SearchHandler (verb, path);
-                       if (i == -1)
-                               return null;
-
-                       return (HandlerItem) mappings [i];
-               }
-
-               int SearchHandler (string verb, string path)
-               {
-                       int end = mappings.Count;
-
-                       for (int i = 0; i < end; i++) {
-                               HandlerItem item = (HandlerItem) mappings [i];
-                               if (item.IsMatch (verb, path))
-                                       return i;
-                       }
-
-                       return -1;
-               }
-               
-       }
-}
-
index af33d03db4e80ca275edb29918c5f0853606ea97..152e38f797435abf34323feecf58d7d452ddf298 100644 (file)
@@ -7,6 +7,7 @@
 // (C) 2002 Ximian, Inc (http://www.ximian.com)
 //
 
+using System.Collections;
 using System.Configuration;
 using System.Xml;
 
@@ -16,45 +17,53 @@ namespace System.Web.Configuration
        {
                public virtual object Create (object parent, object configContext, XmlNode section)
                {
-                       HttpHandlerTypeMapper mapper;
+                       HandlerFactoryConfiguration mapper;
                        
-                       if (parent is HttpHandlerTypeMapper)
-                               mapper = new HttpHandlerTypeMapper ((HttpHandlerTypeMapper) parent);
+                       if (parent is HandlerFactoryConfiguration)
+                               mapper = new HandlerFactoryConfiguration ((HandlerFactoryConfiguration) parent);
                        else
-                               mapper = new HttpHandlerTypeMapper ();
+                               mapper = new HandlerFactoryConfiguration ();
                        
                        if (section.Attributes != null && section.Attributes.Count != 0)
-                               throw new ConfigurationException ("Unrecognized attribute", section);
+                               ThrowException ("Unrecognized attribute", section);
 
-                       foreach (XmlNode child in section.ChildNodes) {
+                       XmlNodeList httpHandlers = section.ChildNodes;
+                       foreach (XmlNode child in httpHandlers) {
                                XmlNodeType ntype = child.NodeType;
                                if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
                                        continue;
+
+                               if (ntype != XmlNodeType.Element)
+                                       ThrowException ("Only elements allowed", child);
                                
                                if (ntype != XmlNodeType.Element)
-                                       throw new ConfigurationException ("Unexpected node type", child);
+                                       ThrowException ("Unexpected node type", child);
 
                                string name = child.Name;
                                if (name == "clear") {
                                        if (child.Attributes.Count != 0)
-                                               throw new ConfigurationException ("Unrecognized attribute", child);
+                                               ThrowException ("Unrecognized attribute", child);
 
                                        mapper.Clear ();
                                        continue;
                                }
                                        
-                               string verb = ExtractAttributeValue ("verb", child);
-                               string path = ExtractAttributeValue ("path", child);
-                               string validateStr = ExtractAttributeValue ("validate", child);
-                               bool validate = (validateStr == "true");
-                               if (!validate && validateStr != "false")
-                                       throw new ConfigurationException ("Invalid value for validate attribute.",
-                                                                          child);
+                               string verb = ExtractAttributeValue ("verb", child, false);
+                               string path = ExtractAttributeValue ("path", child, false);
+                               string validateStr = ExtractAttributeValue ("validate", child, true);
+                               bool validate;
+                               if (validateStr == null) {
+                                       validate = true;
+                               } else {
+                                       validate = validateStr == "true";
+                                       if (!validate && validateStr != "false")
+                                               ThrowException ("Invalid value for validate attribute.", child);
+                               }
 
                                if (name == "add") {
-                                       string type = ExtractAttributeValue ("type", child);
+                                       string type = ExtractAttributeValue ("type", child, false);
                                        if (child.Attributes.Count != 0)
-                                               throw new ConfigurationException ("Unrecognized attribute", child);
+                                               ThrowException ("Unrecognized attribute", child);
 
                                        HandlerItem item = new HandlerItem (verb, path, type, validate);
                                        mapper.Add (item);
@@ -63,32 +72,43 @@ namespace System.Web.Configuration
 
                                if (name == "remove") {
                                        if (child.Attributes.Count != 0)
-                                               throw new ConfigurationException ("Unrecognized attribute", child);
+                                               ThrowException ("Unrecognized attribute", child);
 
                                        if (validate && mapper.Remove (verb, path) == null)
-                                               throw new ConfigurationException ("There's no mapping to remove",
-                                                                                 child);
+                                               ThrowException ("There's no mapping to remove", child);
                                        
                                        continue;
                                }
-                               throw new ConfigurationException ("Unexpected element", child);
+                               ThrowException ("Unexpected element", child);
                        }
 
                        return mapper;
                }
 
-               static string ExtractAttributeValue (string attKey, XmlNode node)
+               static string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
                {
                        XmlNode att = node.Attributes.RemoveNamedItem (attKey);
-                       if (att == null)
-                               throw new ConfigurationException ("Required attribute not found.", node);
+                       if (att == null) {
+                               if (optional)
+                                       return null;
+                               ThrowException ("Required attribute not found: " + attKey, node);
+                       }
 
                        string value = att.Value;
-                       if (value == String.Empty)
-                               throw new ConfigurationException ("Required attribute is empty.", node);
+                       if (value == String.Empty) {
+                               string opt = optional ? "Optional" : "Required";
+                               ThrowException (opt + " attribute is empty: " + attKey, node);
+                       }
 
                        return value;
                }
+
+               static void ThrowException (string msg, XmlNode node)
+               {
+                       if (node != null && node.Name != String.Empty)
+                               msg = msg + " (node name: " + node.Name + ") ";
+                       throw new ConfigurationException (msg, node);
+               }
        }
 }
 
index 8e096f1b1a557598ba4cf07f7c1e361a27404e15..04a2ac0b61a7804e16697eb390250ae877b33a04 100644 (file)
@@ -1,3 +1,7 @@
+2002-10-08  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * SimpleHandlerFactory.cs: new handler for .ashx files.
+
 2002-09-28  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * System.Web.UI/PageHandlerFactory.cs: new file.
diff --git a/mcs/class/System.Web/System.Web.UI/SimpleHandlerFactory.cs b/mcs/class/System.Web/System.Web.UI/SimpleHandlerFactory.cs
new file mode 100644 (file)
index 0000000..5d0da1d
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// System.Web.UI.SimpleHandlerFactory
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+
+using System.Web;
+
+namespace System.Web.UI
+{
+       class SimpleHandlerFactory : IHttpHandlerFactory
+       {
+               [MonoTODO]
+               public virtual IHttpHandler GetHandler (HttpContext context,
+                                                       string requestType,
+                                                       string virtualPath,
+                                                       string path)
+               {
+                       // This should handle *.ashx files
+                       throw new NotImplementedException ();
+               }
+
+               public virtual void ReleaseHandler (System.Web.IHttpHandler handler)
+               {
+               }
+       }
+}
+
index 3741f793a161438a4e3d73486c473f04b4da9eeb..7efaa13c1e09193f091c935f30734fa3453ca66d 100644 (file)
@@ -1,3 +1,8 @@
+2002-10-08  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * HttpApplication.cs: use handlers from configuration.
+       * HttpContext.cs: get handlers from ConfigurationSettings.
+
 2002-10-02  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * HttpMethodNotAllowedHandler.cs:
index eeb7342ea0c720492ed6e6e0720f939ac7095257..d99ab47091f0c6ef2a774886e12d917fce751b92 100644 (file)
@@ -682,14 +682,14 @@ namespace System.Web {
                #endregion\r
 \r
                #region Methods\r
-               [MonoTODO("Deal with other handlers")]\r
-               private IHttpHandler CreateHttpHandler(HttpContext context, string type, string file, string path) {\r
-                       //return (IHttpHandler) HandlerFactoryConfiguration.FindHandler(type, path).Create();\r
-                       // FIXME: dummy stuff that should be replaced with machine.config + web.config stuff\r
-                       if (file.EndsWith (".aspx"))\r
-                               return new PageHandlerFactory ().GetHandler (context, type, file, path);\r
-                       else\r
-                               return new StaticFileHandler ();\r
+               private IHttpHandler CreateHttpHandler (HttpContext context, string type, string file, string path)\r
+               {\r
+                       HandlerFactoryConfiguration handler = HttpContext.GetAppConfig ("system.web/httpHandlers")\r
+                                                               as HandlerFactoryConfiguration;\r
+                       if (handler == null)\r
+                               throw new HttpException ("Cannot get system.web/httpHandlers handler.");\r
+\r
+                       return (IHttpHandler) handler.FindHandler (type, path).Create ();\r
                }\r
 \r
                [MonoTODO()]\r
index a610867217052d16e696fbed79ae80ef5fab88ff..09f8ed7bd0e758326c436b57b091b6ce5d3c8c54 100644 (file)
@@ -6,6 +6,7 @@
 //
 using System;
 using System.Collections;
+using System.Configuration;
 using System.Security.Principal;
 using System.Web.Caching;
 using System.Web.Configuration;
@@ -264,22 +265,10 @@ namespace System.Web
                        throw new NotImplementedException();
                }
 
-               [MonoTODO("GetAppConfig(string name)")]
+               [MonoTODO("We gotta deal with web.config files too")]
                public static object GetAppConfig (string name)
                {
-                       if (null == name)
-                               throw new NotImplementedException();
-
-                       // This is a temp hack to fix the config stuff
-                       if  (name.ToLower() == "system.web/httpmodules") {
-                               return new ModulesConfiguration();
-                       }
-
-                       if (name.ToLower() == "system.web/globalization") {
-                               return new System.Web.Configuration.GlobalizationConfiguration();
-                       }
-
-                       throw new NotImplementedException();
+                       return ConfigurationSettings.GetConfig (name);
                }
 
                object IServiceProvider.GetService (Type service)
index 976cd40f0eac475e0c1da15dd44c0ecdd7fb8015..f777c6b203ab7e8f9afabb984e63ac3ee45040e5 100755 (executable)
@@ -66,8 +66,9 @@ System.Web.Configuration/FormsAuthPasswordFormat.cs
 System.Web.Configuration/FormsProtectionEnum.cs
 System.Web.Configuration/GlobalizationConfiguration.cs
 System.Web.Configuration/HttpCapabilitiesBase.cs
+System.Web.Configuration/HandlerFactoryConfiguration.cs
 System.Web.Configuration/HandlerFactoryProxy.cs
-System.Web.Configuration/HttpHandlerTypeMapper.cs
+System.Web.Configuration/HttpConfigurationContext.cs
 System.Web.Configuration/HttpHandlersSectionHandler.cs
 System.Web.Configuration/HandlerItem.cs
 System.Web.Configuration/ModulesConfiguration.cs
@@ -125,6 +126,7 @@ System.Web.UI/ParseChildrenAttribute.cs
 System.Web.UI/PartialCachingAttribute.cs
 System.Web.UI/PersistChildrenAttribute.cs
 System.Web.UI/PersistenceModeAttribute.cs
+System.Web.UI/SimpleHandlerFactory.cs
 System.Web.UI/TagPrefixAttribute.cs
 System.Web.UI/TemplateContainerAttribute.cs
 System.Web.UI/TemplateControlParser.cs