2 // System.Web.UI.WebControls.AdRotator.cs
5 // Gaurav Vaish (gvaish@iitk.ac.in)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 // Sanjay Gupta (gsanjay@novell.com)
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) Gaurav Vaish (2002)
12 // (C) 2003 Andreas Nahr
13 // (C) 2004 Novell, Inc. (http://www.novell.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 using System.Collections;
40 using System.Collections.Specialized;
42 using System.Web.Caching;
45 using System.Web.Util;
46 using System.ComponentModel;
47 using System.ComponentModel.Design;
49 namespace System.Web.UI.WebControls
51 [DefaultEvent("AdCreated")]
52 [DefaultProperty("AdvertisementFile")]
53 [Designer ("System.Web.UI.Design.WebControls.AdRotatorDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
54 [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" "
55 + "Width=\"468\"></{0}:AdRotator>")]
56 public class AdRotator:
63 string advertisementFile;
64 static readonly object AdCreatedEvent = new object();
66 // Will be set values during (On)PreRender-ing
75 advertisementFile = "";
79 AdRecord[] LoadAdFile (string file)
83 fStream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read);
84 } catch (Exception e) {
85 throw new HttpException("AdRotator: Unable to open file", e);
88 ArrayList list = new ArrayList ();
90 IDictionary hybridDict = null;
91 XmlDocument document = new XmlDocument ();
92 document.Load (fStream);
94 XmlElement docElem = document.DocumentElement;
97 throw new HttpException ("No advertisements found");
99 if (docElem.LocalName != "Advertisements")
100 throw new HttpException ("No advertisements found: invalid document element");
102 XmlNode node = docElem.FirstChild;
103 while (node != null) {
104 if (node.LocalName == "Ad") {
105 XmlNode innerNode = node.FirstChild;
106 while (innerNode != null) {
107 if (node.NodeType == XmlNodeType.Element) {
108 if (hybridDict == null)
109 hybridDict = new HybridDictionary ();
111 hybridDict.Add (innerNode.LocalName, innerNode.InnerText);
113 innerNode = innerNode.NextSibling;
116 if (hybridDict != null) {
117 list.Add (hybridDict);
121 node = node.NextSibling;
124 } catch(Exception e) {
125 throw new HttpException("Parse error:" + file, e);
132 throw new HttpException ("No advertisements found");
134 AdRecord [] adsArray = new AdRecord [list.Count];
135 int count = list.Count;
136 for (int i = 0; i < count; i++)
137 adsArray [i] = new AdRecord ((IDictionary) list [i]);
142 AdRecord [] GetData (string file)
144 string physPath = MapPathSecure (file);
145 string AdKey = "AdRotatorCache: " + physPath;
146 fileDirectory = UrlUtils.GetDirectory (UrlUtils.Combine (TemplateSourceDirectory, file));
147 Cache cache = HttpRuntime.Cache;
148 AdRecord[] records = (AdRecord[]) cache [AdKey];
149 if (records == null) {
150 records = LoadAdFile (physPath);
151 cache.Insert (AdKey, records, new CacheDependency (physPath));
157 IDictionary SelectAd ()
159 AdRecord[] records = GetData (AdvertisementFile);
160 if (records == null || records.Length ==0)
164 int rlength = records.Length;
165 for (int i=0 ; i < rlength; i++) {
166 if (IsAdMatching (records [i]))
167 impressions += records [i].Hits;
170 if (impressions == 0)
174 random = new Random ();
176 int rnd = random.Next (impressions) + 1;
179 for (int i = 0; i < rlength; i++) {
180 if(IsAdMatching(records[i])) {
181 if (rnd <= (counter + records [i].Hits)) {
185 counter += records [i].Hits;
189 return records [index].Properties;
192 private bool IsAdMatching (AdRecord currAd)
194 if (KeywordFilter != String.Empty)
195 return (0 == String.Compare (currAd.Keyword, KeywordFilter, true));
200 private string ResolveAdUrl (string relativeUrl)
202 if (relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl (relativeUrl))
206 if (fileDirectory != null)
207 fullUrl = fileDirectory;
209 fullUrl = TemplateSourceDirectory;
211 if (fullUrl.Length == 0)
214 return UrlUtils.Combine (fullUrl, relativeUrl);
217 [WebCategory("Action")]
218 [WebSysDescription("AdRotator_OnAdCreated")]
219 public event AdCreatedEventHandler AdCreated {
220 add { Events.AddHandler (AdCreatedEvent, value); }
221 remove { Events.RemoveHandler (AdCreatedEvent, value); }
226 [Editor ("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
227 [WebCategory("Behavior")]
228 [WebSysDescription("AdRotator_AdvertisementFile")]
233 public string AdvertisementFile {
234 get { return ((advertisementFile != null) ? advertisementFile : ""); }
235 set { advertisementFile = value; }
238 [Browsable (false), EditorBrowsable (EditorBrowsableState.Never)]
239 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
240 public override FontInfo Font {
241 get { return base.Font; }
246 [WebCategory("Behavior")]
247 [WebSysDescription("AdRotator_KeywordFilter")]
248 public string KeywordFilter {
250 object o = ViewState ["KeywordFilter"];
258 ViewState ["KeywordFilter"] = value.Trim ();
264 [TypeConverter(typeof(TargetConverter))]
265 [WebCategory("Behavior")]
266 [WebSysDescription("AdRotator_Target")]
267 public string Target {
269 object o = ViewState ["Target"];
276 ViewState["Target"] = value;
280 protected override ControlCollection CreateControlCollection ()
282 return new EmptyControlCollection (this);
285 protected virtual void OnAdCreated (AdCreatedEventArgs e)
290 AdCreatedEventHandler aceh = (AdCreatedEventHandler) Events [AdCreatedEvent];
295 protected override void OnPreRender (EventArgs e)
297 if(AdvertisementFile == String.Empty)
300 AdCreatedEventArgs acea = new AdCreatedEventArgs (SelectAd ());
302 imageUrl = acea.ImageUrl;
303 navigateUrl = acea.NavigateUrl;
304 alternateText = acea.AlternateText;
307 [MonoTODO ("Update method with net 2.0 properties added for AdRotator class")]
308 protected override void Render (HtmlTextWriter writer)
310 HyperLink hLink = new HyperLink ();
311 Image adImage = new Image();
312 foreach (string current in Attributes.Keys)
313 hLink.Attributes [current] = Attributes [current];
315 if (ID != null && ID.Length > 0)
318 hLink.Target = Target;
319 hLink.AccessKey = AccessKey;
320 hLink.Enabled = Enabled;
321 hLink.TabIndex = TabIndex;
322 if (navigateUrl != null && navigateUrl.Length != 0)
323 hLink.NavigateUrl = ResolveAdUrl (navigateUrl);
325 hLink.RenderBeginTag (writer);
326 if (ControlStyleCreated)
327 adImage.ApplyStyle(ControlStyle);
329 if(imageUrl!=null && imageUrl.Length > 0)
330 adImage.ImageUrl = ResolveAdUrl (imageUrl);
332 adImage.AlternateText = alternateText;
333 adImage.ToolTip = ToolTip;
334 adImage.RenderControl (writer);
335 hLink.RenderEndTag (writer);
341 [DefaultValueAttribute ("Banner")]
342 [WebCategoryAttribute ("Behavior")]
343 [WebSysDescriptionAttribute ("Advertisement of specific type is created by specified value")]
344 public AdType AdType {
345 get { return adType; }
346 set { adType = value; }
349 string alternateTextField;
351 [DefaultValueAttribute ("AlternateText")]
352 [WebCategoryAttribute ("Behavior")]
353 [WebSysDescriptionAttribute ("Alternate text is retrieved from the elmenet name specified.")]
354 //[VerificationAttribute ()]
355 public string AlternateTextField {
356 get { return alternateTextField; }
357 set { alternateTextField = value; }
362 [DefaultValueAttribute (false)]
363 [WebCategoryAttribute ("Site Counters")]
364 [WebSysDescriptionAttribute ("On clicking an advertisement, click-through events should be counted.")]
365 public bool CountClicks {
366 get { return countClicks; }
367 set { countClicks = value; }
372 [DefaultValueAttribute ("AdRotator")]
373 [WebCategoryAttribute ("Site Counters")]
374 [WebSysDescriptionAttribute ("Name of the group which takes care of counting.")]
375 public string CounterGroup {
376 get { return counterGroup; }
377 set { counterGroup = value; }
382 [DefaultValueAttribute ("")]
383 [WebCategoryAttribute ("Site Counters")]
384 [WebSysDescriptionAttribute ("Name of the group which takes care of counting.")]
385 public string CounterName {
386 get { return counterName; }
387 set { counterName = value; }
392 [DefaultValueAttribute (false)]
393 [WebCategoryAttribute ("Site Counters")]
394 [WebSysDescriptionAttribute ("On creation of an advertisement, view events should be counted.")]
395 public bool CountViews {
396 get { return countViews; }
397 set { countViews = value; }
400 string imageUrlField;
402 [DefaultValueAttribute ("ImageUrl")]
403 [WebCategoryAttribute ("Behavior")]
404 [WebSysDescriptionAttribute ("Image URL is retrieved from the elmenet name specified.")]
405 public string ImageUrlField {
406 get { return imageUrlField; }
407 set { imageUrlField = value; }
410 string navigateUrlField;
412 [DefaultValueAttribute ("NavigateUrl")]
413 [WebCategoryAttribute ("Behavior")]
414 [WebSysDescriptionAttribute ("Advertisement Web page URL is retrieved from the elmenet name specified.")]
415 public string NavigateUrlField {
416 get { return navigateUrlField; }
417 set { navigateUrlField = value; }
422 [DefaultValueAttribute ("100")]
423 [WebCategoryAttribute ("Behavior")]
424 [WebSysDescriptionAttribute ("Frequency in percentage for creation of Popup or PopUnder advertisement.")]
425 public int PopFrequency {
426 get { return popFrequency; }
427 set { popFrequency = value; }
432 [DefaultValueAttribute ("-1")]
433 [WebCategoryAttribute ("Appearance")]
434 [WebSysDescriptionAttribute ("Specifies X-coordinate in pixels of Popunder or Popup advertisements top-left corner.")]
435 public int PopPositionLeft {
436 get { return popPositionLeft; }
437 set { popPositionLeft = value; }
442 [DefaultValueAttribute ("-1")]
443 [WebCategoryAttribute ("Appearance")]
444 [WebSysDescriptionAttribute ("Specifies Y-coordinate in pixels of Popunder or Popup advertisements top-left corner.")]
445 public int PopPositionTop {
446 get { return popPositionTop; }
447 set { popPositionTop = value; }
452 [DefaultValueAttribute ("-1")]
453 [WebCategoryAttribute ("Site Counters")]
454 [WebSysDescriptionAttribute ("On a given day this many number of rows of data needs to be collected.")]
455 public int RowsPerDay {
456 get { return rowsPerDay; }
457 set { rowsPerDay = value; }
460 string siteCountersProvider;
462 [DefaultValueAttribute ("")]
463 [WebCategoryAttribute ("Site Counters")]
464 [WebSysDescriptionAttribute ("Control uses the specified provider.")]
465 public string SiteCountersProvider {
466 get { return siteCountersProvider; }
467 set { siteCountersProvider = value; }
470 bool trackApplicationName;
472 [DefaultValueAttribute (true)]
473 [WebCategoryAttribute ("Site Counters")]
474 [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the specified application name in a database.")]
475 public bool TrackApplicationName {
476 get { return trackApplicationName; }
477 set { trackApplicationName = value; }
480 bool trackNavigateUrl;
482 [DefaultValueAttribute (true)]
483 [WebCategoryAttribute ("Site Counters")]
484 [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the destination URL of click through event in a database.")]
485 public bool TrackNavigateUrl {
486 get { return trackNavigateUrl; }
487 set { trackNavigateUrl = value; }
492 [DefaultValueAttribute (true)]
493 [WebCategoryAttribute ("Site Counters")]
494 [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the originating page URL in a database.")]
495 public bool TrackPageUrl {
496 get { return trackPageUrl; }
497 set { trackPageUrl = value; }
503 public IDictionary Properties;
504 public int Hits; // or impressions or clicks
505 public string Keyword;
507 public AdRecord (IDictionary adProps)
509 this.Properties = adProps;
510 Keyword = Properties ["Keyword"] as string;
514 string imp = Properties ["Impressions"] as string;
518 Hits = Int32.Parse (imp);