* Calendar.cs: Match MS postback data. This allows sites that
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / AdRotator.cs
index 3351fe204bfac4753481f76f54fdf756690569d4..829fb7a5469a24f23648ac1af6f21525df2e0bf5 100755 (executable)
-/**\r
- * Namespace: System.Web.UI.WebControls\r
- * Class:     AdRotator\r
- * \r
- * Author:  Gaurav Vaish\r
- * Contact: <gvaish@iitk.ac.in>\r
- * Status:  10??%\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.UI;\r
-using System.Xml;\r
-\r
-namespace System.Web.UI.WebControls\r
-{\r
-       public class AdRotator: WebControl\r
-       {\r
-\r
-               private string advertisementFile;\r
-               private string keywordFilter;\r
-               private string target;\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 fileDirctory;\r
-\r
-               private static class AdRecord\r
-               {\r
-                       public IDictionary adProps;\r
-                       public int         hits; // or impressions or clicks\r
-                       public string      keyword;\r
-\r
-                       public AdRecord()\r
-                       {\r
-                       }\r
-                       \r
-                       public void Initialize(IDictionary adProps)\r
-                       {\r
-                               this.adProps = adProps;\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
-                       //TODO: Implement me\r
-                       Stream      fSream;\r
-                       ArrayList   list;\r
-                       XmlReader   reader;\r
-                       XmlDocument document;\r
-                       XmlNode     topNode, innerNode;\r
-                       IDictionary hybridDict;\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(docuent.DocumentElement.LocalName=="Advertisements")\r
-                                       {\r
-                                               topNode = 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==NodeType.Element)\r
-                                                                       {\r
-                                                                               if(hybridDic==null)\r
-                                                                               {\r
-                                                                                       hybirdDict = new HybridDictionary();\r
-                                                                               }\r
-                                                                               hybridDic.Add(innerNode.LocalName, innerNode.InnerText);\r
-                                                                       }\r
-                                                                       innerNode = innerNode.NextSibling;\r
-                                                               }\r
-                                                               if(hybridDict!=null)\r
-                                                                       list.Add(hybridDict);\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.Item[i]);\r
-                                       }\r
-                               }\r
-                       } catch(Excetion e)\r
-                       {\r
-                               //TODO: Write error. Parsing error has occured\r
-                               throw new HttpException("AdRotator: Unable to parse file" + file);\r
-                       } finally\r
-                       {\r
-                               fStream.close();\r
-                       }\r
-                       if(adsArray == null)\r
-                       {\r
-                               throw new HttpException("AdRotator: No Advertisements Fount");\r
-                       }\r
-                       return adsArray;\r
-               }\r
-               \r
-               private AdRecord[] GetData(string file)\r
-               {\r
-                       //TODO: Implement me\r
-                       fileDirectory = TemplateSourceDirectory + MapPathSecure(file);\r
-                       //TODO: Do I need to check caching?\r
-               }\r
-               \r
-               private IDictionary SelectAd()\r
-               {\r
-                       //TODO: Implement Me\r
-               }\r
-               \r
-               private bool IsAdMatching(AdRecord currAd)\r
-               {\r
-                       //TODO: Implement me\r
-               }\r
-               \r
-               private string ResolveAdUrl(string)\r
-               {\r
-                       //TODO: Implement me\r
-               }\r
-               \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()\r
-               {\r
-                       base();\r
-                       advertisementFile = string.Empty;\r
-                       keywordFilter     = string.Empty;\r
-                       target            = string.Empty;\r
-               }\r
-               \r
-               public string AdvertisementFile\r
-               {\r
-                       get\r
-                       {\r
-                               return advertisementFile;\r
-                       }\r
-                       set\r
-                       {\r
-                               advertisementFile = value;\r
-                       }\r
-               }\r
-               \r
-               public string KeywordFilter\r
-               {\r
-                       get\r
-                       {\r
-                               return keywordFilter;\r
-                       }\r
-                       set\r
-                       {\r
-                               keywordFilter = value;\r
-                       }\r
-               }\r
-               \r
-               public string Target\r
-               {\r
-                       get\r
-                       {\r
-                               return target;\r
-                       }\r
-                       set\r
-                       {\r
-                               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     image;\r
-\r
-                       AttributeCollection attributeColl = base.Attributes;\r
-                       ICollection keys = attributeColl.Keys;\r
-                       IEnumerator iterator = keys.GetEnumerator();\r
-                       \r
-                       \r
-               }\r
-       }\r
-}\r
+//
+// 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
+//
+
+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.ComponentModel;
+using System.ComponentModel.Design;
+
+namespace System.Web.UI.WebControls
+{
+       [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
+       {
+               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 ()
+               {
+                       advertisementFile = "";
+                       fileDirectory     = null;
+               }
+
+               AdRecord[] LoadAdFile (string file)
+               {
+                       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);
+                       }
+
+                       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;
+               }
+
+               AdRecord [] GetData (string file)
+               {
+                       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;
+               }
+
+               IDictionary SelectAd ()
+               {
+                       AdRecord[] records = GetData (AdvertisementFile);
+                       if (records == null || records.Length ==0)
+                               return null;
+
+                       int impressions = 0;
+                       int rlength = records.Length;
+                       for (int i=0 ; i < rlength; i++) {
+                               if (IsAdMatching (records [i]))
+                                       impressions += records [i].Hits;
+                       }
+
+                       if (impressions == 0)
+                               return null;
+
+                       if (random == null)
+                               random = new Random ();
+
+                       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;
+                               }
+                       }
+
+                       return records [index].Properties;
+               }
+
+               private bool IsAdMatching (AdRecord currAd)
+               {
+                       if (KeywordFilter != String.Empty)
+                               return (0 == String.Compare (currAd.Keyword, KeywordFilter, true));
+
+                       return true;
+               }
+
+               private string ResolveAdUrl (string relativeUrl)
+               {
+                       if (relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl (relativeUrl))
+                               return relativeUrl;
+
+                       string fullUrl;
+                       if (fileDirectory != null)
+                               fullUrl = fileDirectory;
+                       else
+                               fullUrl = TemplateSourceDirectory;
+
+                       if (fullUrl.Length == 0)
+                               return relativeUrl;
+
+                       return UrlUtils.Combine (fullUrl, relativeUrl);
+               }
+
+               [WebCategory("Action")]
+               [WebSysDescription("AdRotator_OnAdCreated")]
+               public event AdCreatedEventHandler AdCreated {
+                       add { Events.AddHandler (AdCreatedEvent, value); }
+                       remove { Events.RemoveHandler (AdCreatedEvent, value); }
+               }
+
+               [Bindable(true)]
+               [DefaultValue("")]
+               [Editor ("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               [WebCategory("Behaviour")]
+               [WebSysDescription("AdRotator_AdvertisementFile")]
+               public string AdvertisementFile {
+                       get { return ((advertisementFile != null) ? advertisementFile : ""); }
+                       set { advertisementFile = value; }
+               }
+
+               [Browsable (false), EditorBrowsable (EditorBrowsableState.Never)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               public override FontInfo Font {
+                       get { return base.Font; }
+               }
+
+               [Bindable(true)]
+               [DefaultValue("")]
+               [WebCategory("Behaviour")]
+               [WebSysDescription("AdRotator_KeywordFilter")]
+               public string KeywordFilter {
+                       get {
+                               object o = ViewState ["KeywordFilter"];
+                               if (o != null)
+                                       return (string) o;
+
+                               return String.Empty;
+                       }
+                       set {
+                               if(value != null)
+                                       ViewState ["KeywordFilter"] = value.Trim ();
+                       }
+               }
+
+               [Bindable(true)]
+               [DefaultValue("")]
+               [TypeConverter(typeof(TargetConverter))]
+               [WebCategory("Behaviour")]
+               [WebSysDescription("AdRotator_Target")]
+               public string Target {
+                       get {
+                               object o = ViewState ["Target"];
+                               if (o != null)
+                                       return (string) o;
+
+                               return "_top";
+                       }
+                       set {
+                               ViewState["Target"] = value;
+                       }
+               }
+
+               protected override ControlCollection CreateControlCollection ()
+               {
+                       return new EmptyControlCollection (this);
+               }
+
+               protected virtual void OnAdCreated (AdCreatedEventArgs e)
+               {
+                       if (Events == null)
+                               return;
+
+                       AdCreatedEventHandler aceh = (AdCreatedEventHandler) Events [AdCreatedEvent];
+                       if (aceh != null)
+                               aceh (this, e);
+               }
+
+               protected override void OnPreRender (EventArgs e)
+               {
+                       if(AdvertisementFile == String.Empty)
+                               return;
+
+                       AdCreatedEventArgs acea = new AdCreatedEventArgs (SelectAd ());
+                       OnAdCreated (acea);
+                       imageUrl = acea.ImageUrl;
+                       navigateUrl = acea.NavigateUrl;
+                       alternateText = acea.AlternateText;
+               }
+
+               protected override void Render (HtmlTextWriter writer)
+               {
+                       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);
+               }
+
+               class AdRecord
+               {
+                       public IDictionary Properties;
+                       public int Hits; // or impressions or clicks
+                       public string Keyword;
+
+                       public AdRecord (IDictionary adProps)
+                       {
+                               this.Properties = adProps;
+                               Keyword = Properties ["Keyword"] as string;
+                               if (Keyword == null)
+                                       Keyword = "";
+
+                               string imp = Properties ["Impressions"] as string;
+                               Hits = 1;
+                               if (imp != null) {
+                                       try {
+                                               Hits = Int32.Parse (imp);
+                                       } catch {
+                                       }
+                               }
+                       }
+               }
+       }
+}
+