* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / AdRotator.cs
old mode 100755 (executable)
new mode 100644 (file)
index 834d5f4..876598b
-/**\r
- * Namespace: System.Web.UI.WebControls\r
- * Class:     AdRotator\r
- *\r
- * Author:  Gaurav Vaish\r
- * Maintainer: gvaish@iitk.ac.in\r
- * Implementation: yes\r
- * Contact: <gvaish@iitk.ac.in>\r
- * Status:  100%\r
- *\r
- * (C) Gaurav Vaish (2001)\r
- */\r
-\r
-using System;\r
-using System.IO;\r
-using System.Collections;\r
-using System.Collections.Specialized;\r
-using System.Web;\r
-using System.Web.Caching;\r
-using System.Web.UI;\r
-using System.Xml;\r
-using System.Web.Utils;\r
-using System.ComponentModel;\r
-\r
-namespace System.Web.UI.WebControls\r
-{\r
-       [DefaultEvent("AdCreated")]\r
-       [DefaultProperty("AdvertisementFile")]\r
-       //TODO: [Designer("??")]\r
-       [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" "\r
-                    + "Width=\"468\"></{0}:AdRotator>")]\r
-       public class AdRotator: WebControl\r
-       {\r
-\r
-               private string advertisementFile;\r
-               private static readonly object AdCreatedEvent = new object();\r
-\r
-               // Will be set values during (On)PreRender-ing\r
-               private string alternateText;\r
-               private string imageUrl;\r
-               private string navigateUrl;\r
-\r
-               private string fileDirectory;\r
-\r
-               class AdRecord\r
-               {\r
-                       public IDictionary adProps;\r
-                       public int         hits; // or impressions or clicks\r
-                       public string      keyword;\r
-\r
-                       public AdRecord(IDictionary adProps)\r
-                       {\r
-                               this.adProps = adProps;\r
-                               hits         = 0;\r
-                               keyword      = String.Empty;\r
-                       }\r
-               }\r
-\r
-/*\r
- * Loading / Saving data from/to ad file and all the manipulations wrt to the URL...\r
- * are incorporated by the following functions.\r
- * GetData(string)\r
- * LoadAdFile(string)\r
- * IsAdMatching(AdRecord)\r
- * ResolveAdUrl(string)\r
- * SelectAd()\r
- * The exact control flow will be detailed. Let me first write the functions\r
- */\r
-\r
-               private AdRecord[] LoadAdFile(string file)\r
-               {\r
-                       Stream      fStream;\r
-                       ArrayList   list;\r
-                       XmlReader   reader;\r
-                       XmlDocument document;\r
-                       XmlNode     topNode, innerNode;\r
-                       IDictionary hybridDict = null;\r
-                       AdRecord[]  adsArray = null;\r
-                       try\r
-                       {\r
-                               fStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);\r
-                       } catch(Exception e)\r
-                       {\r
-                               throw new HttpException("AdRotator: Unable to open file");\r
-                       }\r
-                       try\r
-                       {\r
-                               list = new ArrayList();\r
-                               reader = new XmlTextReader(fStream);\r
-                               document = new XmlDocument();\r
-                               document.Load(reader);\r
-                               if(document.DocumentElement!=null)\r
-                               {\r
-                                       if(document.DocumentElement.LocalName=="Advertisements")\r
-                                       {\r
-                                               topNode = document.DocumentElement.FirstChild;\r
-                                               while(topNode!=null)\r
-                                               {\r
-                                                       if(topNode.LocalName=="Ad")\r
-                                                       {\r
-                                                               innerNode = topNode.FirstChild;\r
-                                                               while(innerNode!=null)\r
-                                                               {\r
-                                                                       if(innerNode.NodeType==XmlNodeType.Element)\r
-                                                                       {\r
-                                                                               if(hybridDict==null)\r
-                                                                               {\r
-                                                                                       hybridDict = new HybridDictionary();\r
-                                                                               }\r
-                                                                               hybridDict.Add(innerNode.LocalName, innerNode.InnerText);\r
-                                                                       }\r
-                                                                       innerNode = innerNode.NextSibling;\r
-                                                               }\r
-                                                               if (hybridDict!=null) {\r
-                                                                       list.Add (hybridDict);\r
-                                                                       hybridDict = null;\r
-                                                               }\r
-                                                       }\r
-                                                       topNode = topNode.NextSibling;\r
-                                               }\r
-                                       }\r
-                               }\r
-                               if(list.Count>0)\r
-                               {\r
-                                       adsArray = new AdRecord[list.Count];\r
-                                       for(int i=0; i < list.Count; i++)\r
-                                       {\r
-                                               adsArray[i] = new AdRecord((IDictionary)list[i]);\r
-                                       }\r
-                               }\r
-                       } catch(Exception e)\r
-                       {\r
-                               throw new HttpException("AdRotator_Parse_Error" + file);\r
-                       } finally\r
-                       {\r
-                               fStream.Close();\r
-                       }\r
-                       if(adsArray == null)\r
-                       {\r
-                               throw new HttpException("AdRotator_No_Advertisements_Found");\r
-                       }\r
-                       return adsArray;\r
-               }\r
-\r
-               [MonoTODO("CacheDependency does nothing")]\r
-               private AdRecord[] GetData(string file)\r
-               {\r
-                       string physPath = MapPathSecure(file);\r
-                       string AdKey = "AdRotatorCache: " + physPath;\r
-                       fileDirectory = UrlUtils.GetDirectory(UrlUtils.Combine(TemplateSourceDirectory, file));\r
-                       Cache cache = HttpRuntime.Cache;\r
-                       AdRecord[] records = (AdRecord[])cache[AdKey];\r
-                       if(records==null)\r
-                       {\r
-                               records = LoadAdFile(physPath);\r
-                               if(records==null)\r
-                               {\r
-                                       return null;\r
-                               }\r
-                               cache.Insert(AdKey, records, new CacheDependency(physPath));\r
-                       }\r
-                       return records;\r
-               }\r
-\r
-               private IDictionary SelectAd()\r
-               {\r
-                       AdRecord[] records = GetData(AdvertisementFile);\r
-                       if(records!=null && records.Length!=0)\r
-                       {\r
-                               int impressions = 0;\r
-                               for(int i=0 ; i < records.Length; i++)\r
-                               {\r
-                                       if(IsAdMatching(records[i]))\r
-                                               impressions += records[i].hits;\r
-                               }\r
-                               if(impressions!=0)\r
-                               {\r
-                                       int rnd = (new Random()).Next(impressions) + 1;\r
-                                       int counter = 0;\r
-                                       int index = 0;\r
-                                       for(int i=0; i < records.Length; i++)\r
-                                       {\r
-                                               if(IsAdMatching(records[i]))\r
-                                               {\r
-                                                       if(rnd <= (counter + records[i].hits))\r
-                                                       {\r
-                                                               index = i;\r
-                                                               break;\r
-                                                       }\r
-                                                       counter += records[i].hits;\r
-                                               }\r
-                                       }\r
-                                       return records[index].adProps;\r
-                               }\r
-                               //FIXME: the line below added. Where should i init hits to make\r
-                               //impressions not be 0?\r
-                               return records [0].adProps;\r
-                       }\r
-                       return null;\r
-               }\r
-\r
-               private bool IsAdMatching(AdRecord currAd)\r
-               {\r
-                       if (KeywordFilter != String.Empty)\r
-                               return (0 == String.Compare (currAd.keyword, KeywordFilter, true));\r
-\r
-                       return true;\r
-               }\r
-\r
-               private string ResolveAdUrl(string relativeUrl)\r
-               {\r
-                       if(relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl(relativeUrl))\r
-                               return relativeUrl;\r
-                       string fullUrl = String.Empty;\r
-                       if(fileDirectory != null)\r
-                               fullUrl = fileDirectory;\r
-                       if(fullUrl.Length == 0)\r
-                               fullUrl = TemplateSourceDirectory;\r
-                       if(fullUrl.Length == 0)\r
-                               return relativeUrl;\r
-                       return (fullUrl + relativeUrl);\r
-               }\r
-\r
-               [WebCategory("Action")]\r
-               [WebSysDescription("AdRotator_OnAdCreated")]\r
-               public event AdCreatedEventHandler AdCreated\r
-               {\r
-                       add\r
-                       {\r
-                               Events.AddHandler(AdCreatedEvent, value);\r
-                       }\r
-                       remove\r
-                       {\r
-                               Events.RemoveHandler(AdCreatedEvent, value);\r
-                       }\r
-               }\r
-\r
-               public AdRotator(): base()\r
-               {\r
-                       advertisementFile = string.Empty;\r
-                       fileDirectory     = null;\r
-               }\r
-\r
-               [Bindable(true)]\r
-               [DefaultValue("")]\r
-               //[Editor("??")]\r
-               [WebCategory("Behaviour")]\r
-               [WebSysDescription("AdRotator_AdvertisementFile")]\r
-               public string AdvertisementFile\r
-               {\r
-                       get\r
-                       {\r
-                               return advertisementFile;\r
-                       }\r
-                       set\r
-                       {\r
-                               advertisementFile = value;\r
-                       }\r
-               }\r
-\r
-               public override FontInfo Font\r
-               {\r
-                       get\r
-                       {\r
-                               return Font;\r
-                       }\r
-               }\r
-\r
-               [Bindable(true)]\r
-               [DefaultValue("")]\r
-               [WebCategory("Behaviour")]\r
-               [WebSysDescription("AdRotator_KeywordFilter")]\r
-               public string KeywordFilter\r
-               {\r
-                       get\r
-                       {\r
-                               object o = ViewState["KeywordFilter"];\r
-                               if(o!=null)\r
-                                       return (string)o;\r
-                               return String.Empty;\r
-                       }\r
-                       set\r
-                       {\r
-                               if(value!=null)\r
-                                       ViewState["KeywordFilter"] = value.Trim();\r
-                       }\r
-               }\r
-\r
-               [Bindable(true)]\r
-               [DefaultValue("")]\r
-               [TypeConverter(typeof(TargetConverter))]\r
-               [WebCategory("Behaviour")]\r
-               [WebSysDescription("AdRotator_Target")]\r
-               public string Target\r
-               {\r
-                       get\r
-                       {\r
-                               object o = ViewState["Target"];\r
-                               if(o!=null)\r
-                                       return (string)o;\r
-                               return String.Empty;\r
-                       }\r
-                       set\r
-                       {\r
-                               ViewState["Target"] = value;\r
-                       }\r
-               }\r
-\r
-               protected override ControlCollection CreateControlCollection()\r
-               {\r
-                       return new EmptyControlCollection(this);\r
-               }\r
-\r
-               protected virtual void OnAdCreated(AdCreatedEventArgs e)\r
-               {\r
-                       if(Events!=null)\r
-                       {\r
-                               AdCreatedEventHandler aceh = (AdCreatedEventHandler)(Events[AdCreatedEvent]);\r
-                               if(aceh!=null)\r
-                                       aceh(this, e);\r
-                       }\r
-               }\r
-\r
-               protected override void OnPreRender(EventArgs e)\r
-               {\r
-                       if(AdvertisementFile!=String.Empty)\r
-                       {\r
-                               AdCreatedEventArgs acea = new AdCreatedEventArgs(SelectAd());\r
-                               imageUrl      = acea.ImageUrl;\r
-                               navigateUrl   = acea.NavigateUrl;\r
-                               alternateText = acea.AlternateText;\r
-                       }\r
-               }\r
-\r
-               protected override void Render(HtmlTextWriter writer)\r
-               {\r
-                       HyperLink hLink = new HyperLink();\r
-                       Image adImage = new Image();\r
-                       foreach(IEnumerable current in Attributes.Keys)\r
-                       {\r
-                               hLink.Attributes[(string)current] = Attributes[(string)current];\r
-                       }\r
-                       if(ID != null && ID.Length > 0)\r
-                               hLink.ID = ID;\r
-                       hLink.Target    = Target;\r
-                       hLink.AccessKey = AccessKey;\r
-                       hLink.Enabled   = Enabled;\r
-                       hLink.TabIndex  = TabIndex;\r
-                       if (navigateUrl != null && navigateUrl.Length != 0)\r
-                               hLink.NavigateUrl = ResolveAdUrl (navigateUrl);\r
-                       hLink.RenderBeginTag(writer);\r
-                       if(ControlStyleCreated)\r
-                       {\r
-                               adImage.ApplyStyle(ControlStyle);\r
-                       }\r
-                       if(imageUrl!=null && imageUrl.Length > 0)\r
-                               adImage.ImageUrl = ResolveAdUrl(imageUrl);\r
-                       adImage.AlternateText = alternateText;\r
-                       adImage.ToolTip       = ToolTip;\r
-                       adImage.RenderControl(writer);\r
-                       hLink.RenderEndTag(writer);\r
-               }\r
-       }\r
-}\r
+// 
+// System.Web.UI.WebControls.AdRotator
+//
+// Author:
+//        Ben Maurer <bmaurer@novell.com>
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Xml;
+using System.Collections;
+using System.ComponentModel;
+using System.Security.Permissions;
+
+namespace System.Web.UI.WebControls {
+
+       // CAS
+       [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       // attributes
+       [DefaultEvent("AdCreated")]
+       [DefaultProperty("AdvertisementFile")]
+       [Designer("System.Web.UI.Design.WebControls.AdRotatorDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#if NET_2_0
+       [ToolboxData("<{0}:AdRotator runat=\"server\"></{0}:AdRotator>")]
+#else
+       [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" Width=\"468px\"></{0}:AdRotator>")]
+#endif         
+       public class AdRotator :
+#if NET_2_0
+       DataBoundControl
+#else          
+       WebControl
+#endif 
+       {
+#if NET_2_0
+               [MonoTODO]
+               protected internal override void OnInit (EventArgs e)
+               {
+                       base.OnInit(e);
+               }
+#endif
+               
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void OnPreRender (EventArgs eee)
+               {
+                       Hashtable ht = null;
+                       
+                       if (ad_file != "" && ad_file != null) {
+                               ReadAdsFromFile (Page.MapPath (ad_file));
+                               ht = ChooseAd ();
+                       }
+
+                       AdCreatedEventArgs e = new AdCreatedEventArgs (ht);
+                       OnAdCreated (e);
+                       createdargs = e;
+                       
+               }
+
+#if NET_2_0
+               [MonoTODO]
+               protected internal override void PerformDataBinding (IEnumerable data)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               protected override void PerformSelect ()
+               {
+                       throw new NotImplementedException ();
+               }
+#endif         
+
+               AdCreatedEventArgs createdargs;
+
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void Render (HtmlTextWriter w)
+               {
+                       AdCreatedEventArgs e = createdargs;
+
+                       base.AddAttributesToRender (w);
+                       
+                       if (e.NavigateUrl != null)
+                               w.AddAttribute (HtmlTextWriterAttribute.Href, ResolveUrl (e.NavigateUrl));
+                       w.AddAttribute (HtmlTextWriterAttribute.Target, Target);
+                       
+                       w.RenderBeginTag (HtmlTextWriterTag.A);
+
+                       if (e.NavigateUrl != null)
+                               w.AddAttribute (HtmlTextWriterAttribute.Src, ResolveUrl (e.ImageUrl));
+                       
+                       w.AddAttribute (HtmlTextWriterAttribute.Alt, e.AlternateText == null ? "" : e.AlternateText);
+                       w.AddAttribute (HtmlTextWriterAttribute.Border, "0");
+                       w.RenderBeginTag (HtmlTextWriterTag.Img);
+                       w.RenderEndTag (); // img
+                       w.RenderEndTag (); // a
+               }
+
+               //
+               // We take all the ads in the ad file and add up their
+               // impression weight. We then take a random number [0,
+               // TotalImpressions). We then choose the ad that is
+               // that number or less impressions for the beginning
+               // of the file. This lets us respect the weights
+               // given.
+               //
+               Hashtable ChooseAd ()
+               {
+                       // cache for performance
+                       string KeywordFilter = this.KeywordFilter;
+                       
+                       int total_imp = 0;
+                       int cur_imp = 0;
+                       
+                       foreach (Hashtable a in ads) {
+                               if (KeywordFilter == "" || KeywordFilter == (string) a ["Keyword"])
+                                       total_imp += a ["Impressions"] != null ? int.Parse ((string) a ["Impressions"]) : 1;
+                       }
+
+                       int r = new Random ().Next (total_imp);
+
+                       foreach (Hashtable a in ads) {
+                               if (KeywordFilter != "" && KeywordFilter != (string) a ["Keyword"])
+                                       continue;
+                               cur_imp += a ["Impressions"] != null ? int.Parse ((string) a ["Impressions"]) : 1;
+                               
+                               if (cur_imp > r)
+                                       return a;
+                       }
+
+                       if (total_imp != 0)
+                               throw new Exception ("I should only get here if no ads matched");
+                       
+                       return null;
+               }
+
+               ArrayList ads = new ArrayList ();
+               
+               void ReadAdsFromFile (string s)
+               {
+                       XmlDocument d = new XmlDocument ();
+                       try {
+                               d.Load (s);
+                       } catch (Exception e) {
+                               throw new HttpException ("AdRotator could not parse the xml file", e);
+                       }
+                       
+                       ads.Clear ();
+                       
+                       foreach (XmlNode n in d.DocumentElement.ChildNodes) {
+
+                               Hashtable ad = new Hashtable ();
+                               
+                               foreach (XmlNode nn in n.ChildNodes)
+                                       ad.Add (nn.Name, nn.InnerText);
+                               
+                               ads.Add (ad);
+                       }
+               }
+               
+               string ad_file = "";
+
+#if NET_2_0
+               [UrlProperty]
+#endif         
+               [Bindable(true)]
+               [DefaultValue("")]
+               [Editor("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
+               [WebSysDescription("")]
+               [WebCategory("Behavior")]
+               public string AdvertisementFile {
+                       get {
+                               return ad_file;
+                       }
+                       set {
+                               ad_file = value;
+                       }
+                       
+               }
+
+#if NET_2_0
+               [DefaultValue ("AlternateText")]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               [MonoTODO]
+               public string AlternateTextField 
+               {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+#endif         
+               
+               [Browsable(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [EditorBrowsable(EditorBrowsableState.Never)]
+               public override FontInfo Font {
+                       get {
+                               return base.Font;
+                       }
+               }
+
+#if NET_2_0
+               [DefaultValue ("ImageUrl")]
+               [MonoTODO]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               public string ImageUrlField 
+               {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+#endif         
+               
+
+               [Bindable(true)]
+               [DefaultValue("")]
+               [WebSysDescription("")]
+               [WebCategory("Behavior")]
+               public string KeywordFilter {
+                       get {
+                               return ViewState.GetString ("KeywordFilter", "");
+                       }
+                       set {
+                               ViewState ["KeywordFilter"] = value;
+                       }
+                       
+               }
+
+#if NET_2_0
+               [DefaultValue ("NavigateUrl")]
+               [MonoTODO]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               public string NavigateUrlField 
+               {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+#endif         
+               
+               [Bindable(true)]
+               [DefaultValue("_top")]
+               [TypeConverter(typeof(System.Web.UI.WebControls.TargetConverter))]
+               [WebSysDescription("")]
+               [WebCategory("Behavior")]
+               public string Target {
+                       get {
+                               return ViewState.GetString ("Target", "_top");
+                       }
+                       set {
+                               ViewState ["Target"] = value;
+                       }
+                       
+               }
+
+#if NET_2_0
+               /* all these are listed in corcompare */
+               [MonoTODO]
+               public override string UniqueID
+               {
+                       get {
+                               return base.UniqueID;
+                       }
+               }
+
+               [MonoTODO]
+               protected override HtmlTextWriterTag TagKey 
+               {
+                       get {
+                               return base.TagKey;
+                       }
+               }
+#endif         
+       
+               protected virtual void OnAdCreated (AdCreatedEventArgs e)
+               {
+                       AdCreatedEventHandler h = (AdCreatedEventHandler) Events [AdCreatedEvent];
+                       if (h != null)
+                               h (this, e);
+               }
+
+               static readonly object AdCreatedEvent = new object ();
+
+               [WebSysDescription("")]
+               [WebCategory("Action")]
+               public event AdCreatedEventHandler AdCreated {
+                       add { Events.AddHandler (AdCreatedEvent, value); }
+                       remove { Events.RemoveHandler (AdCreatedEvent, value); }
+               }
+       }
+}