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)
9 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
10 // (C) Gaurav Vaish (2002)
11 // (C) 2003 Andreas Nahr
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System.Collections;
38 using System.Collections.Specialized;
40 using System.Web.Caching;
43 using System.Web.Util;
44 using System.ComponentModel;
45 using System.ComponentModel.Design;
47 namespace System.Web.UI.WebControls
49 [DefaultEvent("AdCreated")]
50 [DefaultProperty("AdvertisementFile")]
51 [Designer ("System.Web.UI.Design.WebControls.AdRotatorDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
52 [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" "
53 + "Width=\"468\"></{0}:AdRotator>")]
54 public class AdRotator: WebControl
56 string advertisementFile;
57 static readonly object AdCreatedEvent = new object();
59 // Will be set values during (On)PreRender-ing
68 advertisementFile = "";
72 AdRecord[] LoadAdFile (string file)
76 fStream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read);
77 } catch (Exception e) {
78 throw new HttpException("AdRotator: Unable to open file", e);
81 ArrayList list = new ArrayList ();
83 IDictionary hybridDict = null;
84 XmlDocument document = new XmlDocument ();
85 document.Load (fStream);
87 XmlElement docElem = document.DocumentElement;
90 throw new HttpException ("No advertisements found");
92 if (docElem.LocalName != "Advertisements")
93 throw new HttpException ("No advertisements found: invalid document element");
95 XmlNode node = docElem.FirstChild;
96 while (node != null) {
97 if (node.LocalName == "Ad") {
98 XmlNode innerNode = node.FirstChild;
99 while (innerNode != null) {
100 if (node.NodeType == XmlNodeType.Element) {
101 if (hybridDict == null)
102 hybridDict = new HybridDictionary ();
104 hybridDict.Add (innerNode.LocalName, innerNode.InnerText);
106 innerNode = innerNode.NextSibling;
109 if (hybridDict != null) {
110 list.Add (hybridDict);
114 node = node.NextSibling;
117 } catch(Exception e) {
118 throw new HttpException("Parse error:" + file, e);
125 throw new HttpException ("No advertisements found");
127 AdRecord [] adsArray = new AdRecord [list.Count];
128 int count = list.Count;
129 for (int i = 0; i < count; i++)
130 adsArray [i] = new AdRecord ((IDictionary) list [i]);
135 AdRecord [] GetData (string file)
137 string physPath = MapPathSecure (file);
138 string AdKey = "AdRotatorCache: " + physPath;
139 fileDirectory = UrlUtils.GetDirectory (UrlUtils.Combine (TemplateSourceDirectory, file));
140 Cache cache = HttpRuntime.Cache;
141 AdRecord[] records = (AdRecord[]) cache [AdKey];
142 if (records == null) {
143 records = LoadAdFile (physPath);
144 cache.Insert (AdKey, records, new CacheDependency (physPath));
150 IDictionary SelectAd ()
152 AdRecord[] records = GetData (AdvertisementFile);
153 if (records == null || records.Length ==0)
157 int rlength = records.Length;
158 for (int i=0 ; i < rlength; i++) {
159 if (IsAdMatching (records [i]))
160 impressions += records [i].Hits;
163 if (impressions == 0)
167 random = new Random ();
169 int rnd = random.Next (impressions) + 1;
172 for (int i = 0; i < rlength; i++) {
173 if(IsAdMatching(records[i])) {
174 if (rnd <= (counter + records [i].Hits)) {
178 counter += records [i].Hits;
182 return records [index].Properties;
185 private bool IsAdMatching (AdRecord currAd)
187 if (KeywordFilter != String.Empty)
188 return (0 == String.Compare (currAd.Keyword, KeywordFilter, true));
193 private string ResolveAdUrl (string relativeUrl)
195 if (relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl (relativeUrl))
199 if (fileDirectory != null)
200 fullUrl = fileDirectory;
202 fullUrl = TemplateSourceDirectory;
204 if (fullUrl.Length == 0)
207 return UrlUtils.Combine (fullUrl, relativeUrl);
210 [WebCategory("Action")]
211 [WebSysDescription("AdRotator_OnAdCreated")]
212 public event AdCreatedEventHandler AdCreated {
213 add { Events.AddHandler (AdCreatedEvent, value); }
214 remove { Events.RemoveHandler (AdCreatedEvent, value); }
219 [Editor ("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
220 [WebCategory("Behaviour")]
221 [WebSysDescription("AdRotator_AdvertisementFile")]
222 public string AdvertisementFile {
223 get { return ((advertisementFile != null) ? advertisementFile : ""); }
224 set { advertisementFile = value; }
227 [Browsable (false), EditorBrowsable (EditorBrowsableState.Never)]
228 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
229 public override FontInfo Font {
230 get { return base.Font; }
235 [WebCategory("Behaviour")]
236 [WebSysDescription("AdRotator_KeywordFilter")]
237 public string KeywordFilter {
239 object o = ViewState ["KeywordFilter"];
247 ViewState ["KeywordFilter"] = value.Trim ();
253 [TypeConverter(typeof(TargetConverter))]
254 [WebCategory("Behaviour")]
255 [WebSysDescription("AdRotator_Target")]
256 public string Target {
258 object o = ViewState ["Target"];
265 ViewState["Target"] = value;
269 protected override ControlCollection CreateControlCollection ()
271 return new EmptyControlCollection (this);
274 protected virtual void OnAdCreated (AdCreatedEventArgs e)
279 AdCreatedEventHandler aceh = (AdCreatedEventHandler) Events [AdCreatedEvent];
284 protected override void OnPreRender (EventArgs e)
286 if(AdvertisementFile == String.Empty)
289 AdCreatedEventArgs acea = new AdCreatedEventArgs (SelectAd ());
291 imageUrl = acea.ImageUrl;
292 navigateUrl = acea.NavigateUrl;
293 alternateText = acea.AlternateText;
296 protected override void Render (HtmlTextWriter writer)
298 HyperLink hLink = new HyperLink ();
299 Image adImage = new Image();
300 foreach (string current in Attributes.Keys)
301 hLink.Attributes [current] = Attributes [current];
303 if (ID != null && ID.Length > 0)
306 hLink.Target = Target;
307 hLink.AccessKey = AccessKey;
308 hLink.Enabled = Enabled;
309 hLink.TabIndex = TabIndex;
310 if (navigateUrl != null && navigateUrl.Length != 0)
311 hLink.NavigateUrl = ResolveAdUrl (navigateUrl);
313 hLink.RenderBeginTag (writer);
314 if (ControlStyleCreated)
315 adImage.ApplyStyle(ControlStyle);
317 if(imageUrl!=null && imageUrl.Length > 0)
318 adImage.ImageUrl = ResolveAdUrl (imageUrl);
320 adImage.AlternateText = alternateText;
321 adImage.ToolTip = ToolTip;
322 adImage.RenderControl (writer);
323 hLink.RenderEndTag (writer);
328 public IDictionary Properties;
329 public int Hits; // or impressions or clicks
330 public string Keyword;
332 public AdRecord (IDictionary adProps)
334 this.Properties = adProps;
335 Keyword = Properties ["Keyword"] as string;
339 string imp = Properties ["Impressions"] as string;
343 Hits = Int32.Parse (imp);