2 * Namespace: System.Web.UI.WebControls
\r
5 * Author: Gaurav Vaish
\r
6 * Maintainer: gvaish@iitk.ac.in
\r
7 * Implementation: yes
\r
8 * Contact: <gvaish@iitk.ac.in>
\r
11 * (C) Gaurav Vaish (2001)
\r
16 using System.Collections;
\r
17 using System.Collections.Specialized;
\r
19 using System.Web.Caching;
\r
20 using System.Web.UI;
\r
22 using System.Web.Utils;
\r
23 using System.ComponentModel;
\r
25 namespace System.Web.UI.WebControls
\r
27 [DefaultEvent("AdCreated")]
\r
28 [DefaultProperty("AdvertisementFile")]
\r
29 //TODO: [Designer("??")]
\r
30 [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" "
\r
31 + "Width=\"468\"></{0}:AdRotator>")]
\r
32 [PersistChildren(false)]
\r
33 [ParseChildren(true)]
\r
34 public class AdRotator: WebControl
\r
37 private string advertisementFile;
\r
38 private static readonly object AdCreatedEvent = new object();
\r
40 // Will be set values during (On)PreRender-ing
\r
41 private string alternateText;
\r
42 private string imageUrl;
\r
43 private string navigateUrl;
\r
45 private string fileDirectory;
\r
49 public IDictionary adProps;
\r
50 public int hits; // or impressions or clicks
\r
51 public string keyword;
\r
53 public AdRecord(IDictionary adProps)
\r
55 this.adProps = adProps;
\r
57 keyword = String.Empty;
\r
62 * Loading / Saving data from/to ad file and all the manipulations wrt to the URL...
\r
63 * are incorporated by the following functions.
\r
65 * LoadAdFile(string)
\r
66 * IsAdMatching(AdRecord)
\r
67 * ResolveAdUrl(string)
\r
69 * The exact control flow will be detailed. Let me first write the functions
\r
72 private AdRecord[] LoadAdFile(string file)
\r
77 XmlDocument document;
\r
78 XmlNode topNode, innerNode;
\r
79 IDictionary hybridDict = null;
\r
80 AdRecord[] adsArray = null;
\r
83 fStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
\r
84 } catch(Exception e)
\r
86 throw new HttpException("AdRotator: Unable to open file");
\r
90 list = new ArrayList();
\r
91 reader = new XmlTextReader(fStream);
\r
92 document = new XmlDocument();
\r
93 document.Load(reader);
\r
94 if(document.DocumentElement!=null)
\r
96 if(document.DocumentElement.LocalName=="Advertisements")
\r
98 topNode = document.DocumentElement.FirstChild;
\r
99 while(topNode!=null)
\r
101 if(topNode.LocalName=="Ad")
\r
103 innerNode = topNode.FirstChild;
\r
104 while(innerNode!=null)
\r
106 if(innerNode.NodeType==XmlNodeType.Element)
\r
108 if(hybridDict==null)
\r
110 hybridDict = new HybridDictionary();
\r
112 hybridDict.Add(innerNode.LocalName, innerNode.InnerText);
\r
114 innerNode = innerNode.NextSibling;
\r
116 if (hybridDict!=null) {
\r
117 list.Add (hybridDict);
\r
121 topNode = topNode.NextSibling;
\r
127 adsArray = new AdRecord[list.Count];
\r
128 for(int i=0; i < list.Count; i++)
\r
130 adsArray[i] = new AdRecord((IDictionary)list[i]);
\r
133 } catch(Exception e)
\r
135 throw new HttpException("AdRotator_Parse_Error" + file);
\r
140 if(adsArray == null)
\r
142 throw new HttpException("AdRotator_No_Advertisements_Found");
\r
147 [MonoTODO("CacheDependency does nothing")]
\r
148 private AdRecord[] GetData(string file)
\r
150 string physPath = MapPathSecure(file);
\r
151 string AdKey = "AdRotatorCache: " + physPath;
\r
152 fileDirectory = UrlUtils.GetDirectory(UrlUtils.Combine(TemplateSourceDirectory, file));
\r
153 Cache cache = HttpRuntime.Cache;
\r
154 AdRecord[] records = (AdRecord[])cache[AdKey];
\r
157 records = LoadAdFile(physPath);
\r
162 cache.Insert(AdKey, records, new CacheDependency(physPath));
\r
167 private IDictionary SelectAd()
\r
169 AdRecord[] records = GetData(AdvertisementFile);
\r
170 if(records!=null && records.Length!=0)
\r
172 int impressions = 0;
\r
173 for(int i=0 ; i < records.Length; i++)
\r
175 if(IsAdMatching(records[i]))
\r
176 impressions += records[i].hits;
\r
180 int rnd = (new Random()).Next(impressions) + 1;
\r
183 for(int i=0; i < records.Length; i++)
\r
185 if(IsAdMatching(records[i]))
\r
187 if(rnd <= (counter + records[i].hits))
\r
192 counter += records[i].hits;
\r
195 return records[index].adProps;
\r
197 //FIXME: the line below added. Where should i init hits to make
\r
198 //impressions not be 0?
\r
199 return records [0].adProps;
\r
204 private bool IsAdMatching(AdRecord currAd)
\r
206 if (KeywordFilter != String.Empty)
\r
207 return (0 == String.Compare (currAd.keyword, KeywordFilter, true));
\r
212 private string ResolveAdUrl(string relativeUrl)
\r
214 if(relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl(relativeUrl))
\r
215 return relativeUrl;
\r
216 string fullUrl = String.Empty;
\r
217 if(fileDirectory != null)
\r
218 fullUrl = fileDirectory;
\r
219 if(fullUrl.Length == 0)
\r
220 fullUrl = TemplateSourceDirectory;
\r
221 if(fullUrl.Length == 0)
\r
222 return relativeUrl;
\r
223 return (fullUrl + relativeUrl);
\r
226 [WebCategory("Action")]
\r
227 [WebSysDescription("AdRotator_OnAdCreated")]
\r
228 public event AdCreatedEventHandler AdCreated
\r
232 Events.AddHandler(AdCreatedEvent, value);
\r
236 Events.RemoveHandler(AdCreatedEvent, value);
\r
240 public AdRotator(): base()
\r
242 advertisementFile = string.Empty;
\r
243 fileDirectory = null;
\r
249 [WebCategory("Behaviour")]
\r
250 [WebSysDescription("AdRotator_AdvertisementFile")]
\r
251 public string AdvertisementFile
\r
255 return advertisementFile;
\r
259 advertisementFile = value;
\r
263 public override FontInfo Font
\r
273 [WebCategory("Behaviour")]
\r
274 [WebSysDescription("AdRotator_KeywordFilter")]
\r
275 public string KeywordFilter
\r
279 object o = ViewState["KeywordFilter"];
\r
282 return String.Empty;
\r
287 ViewState["KeywordFilter"] = value.Trim();
\r
293 [TypeConverter(typeof(TargetConverter))]
\r
294 [WebCategory("Behaviour")]
\r
295 [WebSysDescription("AdRotator_Target")]
\r
296 public string Target
\r
300 object o = ViewState["Target"];
\r
303 return String.Empty;
\r
307 ViewState["Target"] = value;
\r
311 protected override ControlCollection CreateControlCollection()
\r
313 return new EmptyControlCollection(this);
\r
316 protected virtual void OnAdCreated(AdCreatedEventArgs e)
\r
320 AdCreatedEventHandler aceh = (AdCreatedEventHandler)(Events[AdCreatedEvent]);
\r
326 protected override void OnPreRender(EventArgs e)
\r
328 if(AdvertisementFile!=String.Empty)
\r
330 AdCreatedEventArgs acea = new AdCreatedEventArgs(SelectAd());
\r
331 imageUrl = acea.ImageUrl;
\r
332 navigateUrl = acea.NavigateUrl;
\r
333 alternateText = acea.AlternateText;
\r
337 protected override void Render(HtmlTextWriter writer)
\r
339 HyperLink hLink = new HyperLink();
\r
340 Image adImage = new Image();
\r
341 foreach(IEnumerable current in Attributes.Keys)
\r
343 hLink.Attributes[(string)current] = Attributes[(string)current];
\r
345 if(ID != null && ID.Length > 0)
\r
347 hLink.Target = Target;
\r
348 hLink.AccessKey = AccessKey;
\r
349 hLink.Enabled = Enabled;
\r
350 hLink.TabIndex = TabIndex;
\r
351 if (navigateUrl != null && navigateUrl.Length != 0)
\r
352 hLink.NavigateUrl = ResolveAdUrl (navigateUrl);
\r
353 hLink.RenderBeginTag(writer);
\r
354 if(ControlStyleCreated)
\r
356 adImage.ApplyStyle(ControlStyle);
\r
358 if(imageUrl!=null && imageUrl.Length > 0)
\r
359 adImage.ImageUrl = ResolveAdUrl(imageUrl);
\r
360 adImage.AlternateText = alternateText;
\r
361 adImage.ToolTip = ToolTip;
\r
362 adImage.RenderControl(writer);
\r
363 hLink.RenderEndTag(writer);
\r