From f9e281c5178b6cd491b8e39fff8198d6dd7078ff Mon Sep 17 00:00:00 2001 From: Gonzalo Paniagua Javier Date: Tue, 15 Apr 2003 03:00:06 +0000 Subject: 2003-04-15 Gonzalo Paniagua Javier * list: added CollectionBuilder and TemplateBuilder. * System.Web.UI/CollectionBuilder.cs: * System.Web.UI/TemplateBuilder.cs: new classes derived from ControlBuilder that represent a property or a ITemplate. * System.Web.UI/ControlBuilder.cs: implemented all the missing bits. * System.Web.UI/TemplateParser.cs: added mapping from tag name to Type feature. svn path=/trunk/mcs/; revision=13632 --- .../System.Web/System.Web.UI/ControlBuilder.cs | 216 ++++++++++++++++----- 1 file changed, 171 insertions(+), 45 deletions(-) (limited to 'mcs/class/System.Web/System.Web.UI/ControlBuilder.cs') diff --git a/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs b/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs index 7acb206a3a3..4cbb8fffd45 100755 --- a/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs +++ b/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs @@ -1,18 +1,26 @@ // // System.Web.UI.ControlBuilder.cs // -// Duncan Mak (duncan@ximian.com) +// Authors: +// Duncan Mak (duncan@ximian.com) +// Gonzalo Paniagua Javier (gonzalo@ximian.com) // -// (C) Ximian, Inc. +// (C) 2002, 2003 Ximian, Inc. (http://www.ximian.com) // using System; using System.Collections; +using System.Reflection; namespace System.Web.UI { public class ControlBuilder { + internal static BindingFlags flagsNoCase = BindingFlags.Public | + BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.IgnoreCase; + TemplateParser parser; ControlBuilder parentBuilder; Type type; @@ -21,16 +29,24 @@ namespace System.Web.UI { IDictionary attribs; int line; string fileName; + bool childrenAsProperties; + bool isIParserAccessor; + bool hasAspCode; + ControlBuilder defaultPropertyBuilder; + ArrayList children; public ControlBuilder () { } - - internal ControlBuilder ( - TemplateParser parser, ControlBuilder parentBuilder, - Type type, string tagName, string id, - IDictionary attribs, int line, string sourceFileName) + internal ControlBuilder (TemplateParser parser, + ControlBuilder parentBuilder, + Type type, + string tagName, + string id, + IDictionary attribs, + int line, + string sourceFileName) { this.parser = parser; @@ -47,35 +63,47 @@ namespace System.Web.UI { get { return type; } } - [MonoTODO] public bool FChildrenAsProperties { - get { return false; } + get { return childrenAsProperties; } } - [MonoTODO] public bool FIsNonParserAccessor { - get { return false; } + get { return isIParserAccessor; } } - [MonoTODO] public bool HasAspCode { - get { return false; } + get { return hasAspCode; } } public string ID { get { return id; } - set { id = value; } } + protected void SetControlType (Type t) + { + type = t; + } + [MonoTODO] public bool InDesigner { get { return false; } } - [MonoTODO] public Type NamingContainerType { - get { return null; } + get { + if (parentBuilder == null) + return typeof (Control); + + Type ptype = parentBuilder.ControlType; + if (ptype == null) + return typeof (Control); + + if (!typeof (INamingContainer).IsAssignableFrom (type)) + return parentBuilder.NamingContainerType; + + return type; + } } protected TemplateParser Parser { @@ -86,10 +114,9 @@ namespace System.Web.UI { get { return tagName; } } - [MonoTODO] public virtual bool AllowWhitespaceLiterals () { - return false; + return true; } [MonoTODO] @@ -98,69 +125,168 @@ namespace System.Web.UI { throw new NotImplementedException (); } - [MonoTODO] public virtual void AppendSubBuilder (ControlBuilder subBuilder) { - throw new NotImplementedException (); + if (children == null) + children = new ArrayList (); + + subBuilder.OnAppendToParentBuilder (this); + children.Add (subBuilder); } - [MonoTODO] public virtual void CloseControl () { } - [MonoTODO] - public static ControlBuilder CreateBuilderFromType ( - TemplateParser parser, ControlBuilder parentBuilder, - Type type, string tagName, string id, - IDictionary attribs, int line, string sourceFileName) + public static ControlBuilder CreateBuilderFromType (TemplateParser parser, + ControlBuilder parentBuilder, + Type type, + string tagName, + string id, + IDictionary attribs, + int line, + string sourceFileName) { - return new ControlBuilder (parser, parentBuilder, type, - tagName, id, attribs, line, sourceFileName); + ControlBuilder builder; + object [] atts = type.GetCustomAttributes (typeof (ControlBuilderAttribute), true); + if (atts != null && atts.Length > 0) { + ControlBuilderAttribute att = (ControlBuilderAttribute) atts [0]; + builder = (ControlBuilder) Activator.CreateInstance (att.BuilderType); + } else { + builder = new ControlBuilder (); + } + + builder.Init (parser, parentBuilder, type, tagName, id, attribs); + builder.line = line; + builder.fileName = sourceFileName; + return builder; } - [MonoTODO] public virtual Type GetChildControlType (string tagName, IDictionary attribs) { - return attribs [tagName] as Type; + return null; } - [MonoTODO] public virtual bool HasBody () { - return false; + return true; } - [MonoTODO] public virtual bool HtmlDecodeLiterals () { return false; } - [MonoTODO] - public virtual void Init ( - TemplateParser parser, ControlBuilder parentBuilder, - Type type, string tagName, string id, IDictionary attribs) + ControlBuilder CreatePropertyBuilder (string propName, TemplateParser parser) { - throw new NotImplementedException (); + PropertyInfo prop = type.GetProperty (propName, flagsNoCase); + if (prop == null) { + string msg = String.Format ("Property {0} not found in type {1}", propName, type); + throw new HttpException (msg); + } + + Type propType = prop.PropertyType; + ControlBuilder builder = null; + if (typeof (ICollection).IsAssignableFrom (propType)) + builder = new CollectionBuilder (); + else if (typeof (ITemplate).IsAssignableFrom (propType)) + builder = new TemplateBuilder (); + else + return CreateBuilderFromType (parser, + parentBuilder, + propType, + propName, + null, + null, + line, + fileName); + + builder.Init (parser, this, null, tagName, null, null); + builder.fileName = fileName; + builder.line = line; + return builder; + } + + public virtual void Init (TemplateParser parser, + ControlBuilder parentBuilder, + Type type, + string tagName, + string id, + IDictionary attribs) + { + this.parser = parser; + this.parentBuilder = parentBuilder; + this.type = type; + this.tagName = tagName; + this.id = id; + this.attribs = attribs; + if (type == null) + return; + + if (!typeof (IParserAccessor).IsAssignableFrom (type)) { + isIParserAccessor = false; + childrenAsProperties = true; + } else { + object [] atts = type.GetCustomAttributes (typeof (ParseChildrenAttribute), true); + if (atts != null && atts.Length > 0) { + ParseChildrenAttribute att = (ParseChildrenAttribute) atts [0]; + childrenAsProperties = att.ChildrenAsProperties; + if (childrenAsProperties && att.DefaultProperty != "") + defaultPropertyBuilder = CreatePropertyBuilder (att.DefaultProperty, + parser); + } + } } - [MonoTODO] public virtual bool NeedsTagInnerText () { - throw new NotImplementedException (); + return false; } - [MonoTODO] - public virtual void OnAppendToParentBuilder () + public virtual void OnAppendToParentBuilder (ControlBuilder parentBuilder) { - throw new NotImplementedException (); + if (parentBuilder.defaultPropertyBuilder == null) + return; + + ControlBuilder old = parentBuilder.defaultPropertyBuilder; + defaultPropertyBuilder = null; + AppendSubBuilder (old); } - [MonoTODO] public virtual void SetTagInnerText (string text) { - throw new NotImplementedException (); + } + + internal virtual object CreateInstance () + { + // HtmlGenericControl, HtmlTableCell... + object [] atts = type.GetCustomAttributes (typeof (ConstructorNeedsTagAttribute), true); + object [] args = null; + if (atts != null && atts.Length > 0) { + ConstructorNeedsTagAttribute att = (ConstructorNeedsTagAttribute) atts [0]; + if (att.NeedsTag) + args = new object [] {tagName}; + } + + return Activator.CreateInstance (type, args); + } + + internal virtual void CreateChildren (object parent) + { + if (children == null || children.Count == 0) + return; + + IParserAccessor parser = parent as IParserAccessor; + if (parser == null) + return; + + foreach (object o in children) { + if (o is string) { + parser.AddParsedSubObject (new LiteralControl ((string) o)); + } else { + parser.AddParsedSubObject (((ControlBuilder) o).CreateInstance ()); + } + } } } } -- cgit v1.2.3