-/**\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); }
+ }
+ }
+}