Use UNIX line endings consistently
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / AdRotator.cs
old mode 100755 (executable)
new mode 100644 (file)
index 0777e26..ea504d1
@@ -1,16 +1,10 @@
+// 
+// System.Web.UI.WebControls.AdRotator
 //
-// System.Web.UI.WebControls.AdRotator.cs
-//
-// Authors:
-//   Gaurav Vaish (gvaish@iitk.ac.in)
-//   Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
-//
-// (c) 2002 Ximian, Inc. (http://www.ximian.com)
-// (C) Gaurav Vaish (2002)
-// (C) 2003 Andreas Nahr
+// 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
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Specialized;
-using System.Web;
-using System.Web.Caching;
-using System.Web.UI;
 using System.Xml;
-using System.Web.Util;
+using System.Collections;
 using System.ComponentModel;
-using System.ComponentModel.Design;
+using System.Security.Permissions;
+using System.Web.Util;
+
+namespace System.Web.UI.WebControls {
 
-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, typeof (IDesigner))]
-       [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" "
-       + "Width=\"468\"></{0}:AdRotator>")]
-       public class AdRotator: WebControl
+       [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 
        {
-               string advertisementFile;
-               static readonly object AdCreatedEvent = new object();
-
-               // Will be set values during (On)PreRender-ing
-               string alternateText;
-               string imageUrl;
-               string navigateUrl;
-               string fileDirectory;
-               Random random;
-
-               public AdRotator ()
+#if NET_2_0
+               protected internal override void OnInit (EventArgs e)
                {
-                       advertisementFile = "";
-                       fileDirectory     = null;
+                       base.OnInit(e);
                }
-
-               AdRecord[] LoadAdFile (string file)
+#endif
+               
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void OnPreRender (EventArgs eee)
                {
-                       Stream fStream;
-                       try {
-                               fStream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read);
-                       } catch (Exception e) {
-                               throw new HttpException("AdRotator: Unable to open file", e);
+                       Hashtable ht = null;
+                       
+                       if (ad_file != "" && ad_file != null) {
+                               ReadAdsFromFile (
+#if NET_2_0
+                                       GetPhysicalFilePath (ad_file)
+#else
+                                       Page.MapPath (ad_file)
+#endif
+                               );
+                               ht = ChooseAd ();
                        }
 
-                       ArrayList list = new ArrayList ();
-                       try {
-                               IDictionary hybridDict = null;
-                               XmlDocument document = new XmlDocument ();
-                               document.Load (fStream);
-
-                               XmlElement docElem = document.DocumentElement;
-
-                               if (docElem == null)
-                                       throw new HttpException ("No advertisements found");
-
-                               if (docElem.LocalName != "Advertisements")
-                                       throw new HttpException ("No advertisements found: invalid document element");
-
-                               XmlNode node = docElem.FirstChild;
-                               while (node != null) {
-                                       if (node.LocalName == "Ad") {
-                                               XmlNode innerNode = node.FirstChild;
-                                               while (innerNode != null) {
-                                                       if (node.NodeType == XmlNodeType.Element) {
-                                                               if (hybridDict == null)
-                                                                       hybridDict = new HybridDictionary ();
-
-                                                               hybridDict.Add (innerNode.LocalName, innerNode.InnerText);
-                                                       }
-                                                       innerNode = innerNode.NextSibling;
-                                               }
-
-                                               if (hybridDict != null) {
-                                                       list.Add (hybridDict);
-                                                       hybridDict = null;
-                                               }
-                                       }
-                                       node = node.NextSibling;
-                               }
-
-                       } catch(Exception e) {
-                               throw new HttpException("Parse error:" + file, e);
-                       } finally {
-                               if (fStream != null)
-                                       fStream.Close();
-                       }
-
-                       if (list.Count == 0)
-                               throw new HttpException ("No advertisements found");
-
-                       AdRecord [] adsArray = new AdRecord [list.Count];
-                       int count = list.Count;
-                       for (int i = 0; i < count; i++)
-                               adsArray [i] = new AdRecord ((IDictionary) list [i]);
-
-                       return adsArray;
+                       AdCreatedEventArgs e = new AdCreatedEventArgs (ht);
+                       OnAdCreated (e);
+                       createdargs = e;
+                       
                }
 
-               AdRecord [] GetData (string file)
+#if NET_2_0
+               [MonoTODO ("Not implemented")]
+               protected internal override void PerformDataBinding (IEnumerable data)
                {
-                       string physPath = MapPathSecure (file);
-                       string AdKey = "AdRotatorCache: " + physPath;
-                       fileDirectory = UrlUtils.GetDirectory (UrlUtils.Combine (TemplateSourceDirectory, file));
-                       Cache cache = HttpRuntime.Cache;
-                       AdRecord[] records = (AdRecord[]) cache [AdKey];
-                       if (records == null) {
-                               records = LoadAdFile (physPath);
-                               cache.Insert (AdKey, records, new CacheDependency (physPath));
-                       }
-
-                       return records;
+                       throw new NotImplementedException ();
                }
 
-               IDictionary SelectAd ()
+               [MonoTODO ("Not implemented")]
+               protected override void PerformSelect ()
                {
-                       AdRecord[] records = GetData (AdvertisementFile);
-                       if (records == null || records.Length ==0)
-                               return null;
+                       throw new NotImplementedException ();
+               }
+#endif         
 
-                       int impressions = 0;
-                       int rlength = records.Length;
-                       for (int i=0 ; i < rlength; i++) {
-                               if (IsAdMatching (records [i]))
-                                       impressions += records [i].Hits;
-                       }
+               AdCreatedEventArgs createdargs;
 
-                       if (impressions == 0)
-                               return null;
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void Render (HtmlTextWriter w)
+               {
+                       AdCreatedEventArgs e = createdargs;
 
-                       if (random == null)
-                               random = new Random ();
+                       base.AddAttributesToRender (w);
 
-                       int rnd = random.Next (impressions) + 1;
-                       int counter = 0;
-                       int index = 0;
-                       for (int i = 0; i < rlength; i++) {
-                               if(IsAdMatching(records[i])) {
-                                       if (rnd <= (counter + records [i].Hits)) {
-                                               index = i;
-                                               break;
-                                       }
-                                       counter += records [i].Hits;
-                               }
-                       }
+                       if (e.NavigateUrl != null && e.NavigateUrl.Length > 0)
+                               w.AddAttribute (HtmlTextWriterAttribute.Href, ResolveAdUrl (e.NavigateUrl));
+                       if (Target != null && Target.Length > 0)
+                               w.AddAttribute (HtmlTextWriterAttribute.Target, Target);
+                       
+                       w.RenderBeginTag (HtmlTextWriterTag.A);
+
+                       if (e.ImageUrl != null && e.ImageUrl.Length > 0)
+                               w.AddAttribute (HtmlTextWriterAttribute.Src, ResolveAdUrl (e.ImageUrl));
 
-                       return records [index].Properties;
+                       w.AddAttribute (HtmlTextWriterAttribute.Alt, e.AlternateText == null ? "" : e.AlternateText);
+                       w.AddAttribute (HtmlTextWriterAttribute.Border, "0", false);
+                       w.RenderBeginTag (HtmlTextWriterTag.Img);
+                       w.RenderEndTag (); // img
+                       w.RenderEndTag (); // a
                }
 
-               private bool IsAdMatching (AdRecord currAd)
+               string ResolveAdUrl (string url)
                {
-                       if (KeywordFilter != String.Empty)
-                               return (0 == String.Compare (currAd.Keyword, KeywordFilter, true));
+                       string path = url;
 
-                       return true;
+                       if (AdvertisementFile != null && AdvertisementFile.Length > 0 && path [0] != '/' && path [0] != '~')
+                               try {
+                                       new Uri (path);
+                               }
+                               catch {
+                                       return UrlUtils.Combine (UrlUtils.GetDirectory (ResolveUrl (AdvertisementFile)), path);
+                               }
+                       
+                       return ResolveUrl (path);
                }
 
-               private string ResolveAdUrl (string relativeUrl)
+               //
+               // 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 ()
                {
-                       if (relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl (relativeUrl))
-                               return relativeUrl;
+                       // 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;
+                       }
 
-                       string fullUrl;
-                       if (fileDirectory != null)
-                               fullUrl = fileDirectory;
-                       else
-                               fullUrl = TemplateSourceDirectory;
+                       int r = new Random ().Next (total_imp);
 
-                       if (fullUrl.Length == 0)
-                               return relativeUrl;
+                       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;
+                       }
 
-                       return UrlUtils.Combine (fullUrl, relativeUrl);
+                       if (total_imp != 0)
+                               throw new Exception ("I should only get here if no ads matched");
+                       
+                       return null;
                }
 
-               [WebCategory("Action")]
-               [WebSysDescription("AdRotator_OnAdCreated")]
-               public event AdCreatedEventHandler AdCreated {
-                       add { Events.AddHandler (AdCreatedEvent, value); }
-                       remove { Events.RemoveHandler (AdCreatedEvent, value); }
+               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))]
-               [WebCategory("Behaviour")]
-               [WebSysDescription("AdRotator_AdvertisementFile")]
+               [Editor("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
+               [WebSysDescription("")]
+               [WebCategory("Behavior")]
                public string AdvertisementFile {
-                       get { return ((advertisementFile != null) ? advertisementFile : ""); }
-                       set { advertisementFile = value; }
+                       get {
+                               return ad_file;
+                       }
+                       set {
+                               ad_file = value;
+                       }
+                       
                }
 
-               [Browsable (false), EditorBrowsable (EditorBrowsableState.Never)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+#if NET_2_0
+               [DefaultValue ("AlternateText")]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               [MonoTODO ("Not implemented")]
+               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; }
+                       get {
+                               return base.Font;
+                       }
                }
 
-               [Bindable(true)]
-               [DefaultValue("")]
-               [WebCategory("Behaviour")]
-               [WebSysDescription("AdRotator_KeywordFilter")]
-               public string KeywordFilter {
+#if NET_2_0
+               [DefaultValue ("ImageUrl")]
+               [MonoTODO ("Not implemented")]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               public string ImageUrlField 
+               {
                        get {
-                               object o = ViewState ["KeywordFilter"];
-                               if (o != null)
-                                       return (string) o;
-
-                               return String.Empty;
+                               throw new NotImplementedException ();
                        }
                        set {
-                               if(value != null)
-                                       ViewState ["KeywordFilter"] = value.Trim ();
+                               throw new NotImplementedException ();
                        }
                }
+#endif         
+               
 
                [Bindable(true)]
                [DefaultValue("")]
-               [TypeConverter(typeof(TargetConverter))]
-               [WebCategory("Behaviour")]
-               [WebSysDescription("AdRotator_Target")]
-               public string Target {
+               [WebSysDescription("")]
+               [WebCategory("Behavior")]
+               public string KeywordFilter {
                        get {
-                               object o = ViewState ["Target"];
-                               if (o != null)
-                                       return (string) o;
-
-                               return "_top";
+                               return ViewState.GetString ("KeywordFilter", "");
                        }
                        set {
-                               ViewState["Target"] = value;
+                               ViewState ["KeywordFilter"] = value;
                        }
+                       
                }
 
-               protected override ControlCollection CreateControlCollection ()
+#if NET_2_0
+               [DefaultValue ("NavigateUrl")]
+               [MonoTODO ("Not implemented")]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               public string NavigateUrlField 
                {
-                       return new EmptyControlCollection (this);
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
                }
-
-               protected virtual void OnAdCreated (AdCreatedEventArgs e)
-               {
-                       if (Events == null)
-                               return;
-
-                       AdCreatedEventHandler aceh = (AdCreatedEventHandler) Events [AdCreatedEvent];
-                       if (aceh != null)
-                               aceh (this, e);
+#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;
+                       }
+                       
                }
 
-               protected override void OnPreRender (EventArgs e)
+#if NET_2_0
+               /* all these are listed in corcompare */
+               public override string UniqueID
                {
-                       if(AdvertisementFile == String.Empty)
-                               return;
-
-                       AdCreatedEventArgs acea = new AdCreatedEventArgs (SelectAd ());
-                       OnAdCreated (acea);
-                       imageUrl = acea.ImageUrl;
-                       navigateUrl = acea.NavigateUrl;
-                       alternateText = acea.AlternateText;
+                       get {
+                               return base.UniqueID;
+                       }
                }
 
-               protected override void Render (HtmlTextWriter writer)
+               protected override HtmlTextWriterTag TagKey 
                {
-                       HyperLink hLink = new HyperLink ();
-                       Image adImage = new Image();
-                       foreach (string current in Attributes.Keys)
-                               hLink.Attributes [current] = Attributes [current];
-
-                       if (ID != null && ID.Length > 0)
-                               hLink.ID = ID;
-
-                       hLink.Target = Target;
-                       hLink.AccessKey = AccessKey;
-                       hLink.Enabled  = Enabled;
-                       hLink.TabIndex = TabIndex;
-                       if (navigateUrl != null && navigateUrl.Length != 0)
-                               hLink.NavigateUrl = ResolveAdUrl (navigateUrl);
-
-                       hLink.RenderBeginTag (writer);
-                       if (ControlStyleCreated)
-                               adImage.ApplyStyle(ControlStyle);
-
-                       if(imageUrl!=null && imageUrl.Length > 0)
-                               adImage.ImageUrl = ResolveAdUrl (imageUrl);
-
-                       adImage.AlternateText = alternateText;
-                       adImage.ToolTip = ToolTip;
-                       adImage.RenderControl (writer);
-                       hLink.RenderEndTag (writer);
+                       get {
+                               return base.TagKey;
+                       }
                }
-
-               class AdRecord
+#endif         
+       
+               protected virtual void OnAdCreated (AdCreatedEventArgs e)
                {
-                       public IDictionary Properties;
-                       public int Hits; // or impressions or clicks
-                       public string Keyword;
+                       AdCreatedEventHandler h = (AdCreatedEventHandler) Events [AdCreatedEvent];
+                       if (h != null)
+                               h (this, e);
+               }
 
-                       public AdRecord (IDictionary adProps)
-                       {
-                               this.Properties = adProps;
-                               Keyword = Properties ["Keyword"] as string;
-                               if (Keyword == null)
-                                       Keyword = "";
+               static readonly object AdCreatedEvent = new object ();
 
-                               string imp = Properties ["Impressions"] as string;
-                               Hits = 1;
-                               if (imp != null) {
-                                       try {
-                                               Hits = Int32.Parse (imp);
-                                       } catch {
-                                       }
-                               }
-                       }
+               [WebSysDescription("")]
+               [WebCategory("Action")]
+               public event AdCreatedEventHandler AdCreated {
+                       add { Events.AddHandler (AdCreatedEvent, value); }
+                       remove { Events.RemoveHandler (AdCreatedEvent, value); }
                }
        }
 }
-