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
: WebControl
58 string advertisementFile
;
59 static readonly object AdCreatedEvent
= new object();
61 // Will be set values during (On)PreRender-ing
70 advertisementFile
= "";
74 AdRecord
[] LoadAdFile (string file
)
78 fStream
= new FileStream (file
, FileMode
.Open
, FileAccess
.Read
, FileShare
.Read
);
79 } catch (Exception e
) {
80 throw new HttpException("AdRotator: Unable to open file", e
);
83 ArrayList list
= new ArrayList ();
85 IDictionary hybridDict
= null;
86 XmlDocument document
= new XmlDocument ();
87 document
.Load (fStream
);
89 XmlElement docElem
= document
.DocumentElement
;
92 throw new HttpException ("No advertisements found");
94 if (docElem
.LocalName
!= "Advertisements")
95 throw new HttpException ("No advertisements found: invalid document element");
97 XmlNode node
= docElem
.FirstChild
;
98 while (node
!= null) {
99 if (node
.LocalName
== "Ad") {
100 XmlNode innerNode
= node
.FirstChild
;
101 while (innerNode
!= null) {
102 if (node
.NodeType
== XmlNodeType
.Element
) {
103 if (hybridDict
== null)
104 hybridDict
= new HybridDictionary ();
106 hybridDict
.Add (innerNode
.LocalName
, innerNode
.InnerText
);
108 innerNode
= innerNode
.NextSibling
;
111 if (hybridDict
!= null) {
112 list
.Add (hybridDict
);
116 node
= node
.NextSibling
;
119 } catch(Exception e
) {
120 throw new HttpException("Parse error:" + file
, e
);
127 throw new HttpException ("No advertisements found");
129 AdRecord
[] adsArray
= new AdRecord
[list
.Count
];
130 int count
= list
.Count
;
131 for (int i
= 0; i
< count
; i
++)
132 adsArray
[i
] = new AdRecord ((IDictionary
) list
[i
]);
137 AdRecord
[] GetData (string file
)
139 string physPath
= MapPathSecure (file
);
140 string AdKey
= "AdRotatorCache: " + physPath
;
141 fileDirectory
= UrlUtils
.GetDirectory (UrlUtils
.Combine (TemplateSourceDirectory
, file
));
142 Cache cache
= HttpRuntime
.Cache
;
143 AdRecord
[] records
= (AdRecord
[]) cache
[AdKey
];
144 if (records
== null) {
145 records
= LoadAdFile (physPath
);
146 cache
.Insert (AdKey
, records
, new CacheDependency (physPath
));
152 IDictionary
SelectAd ()
154 AdRecord
[] records
= GetData (AdvertisementFile
);
155 if (records
== null || records
.Length
==0)
159 int rlength
= records
.Length
;
160 for (int i
=0 ; i
< rlength
; i
++) {
161 if (IsAdMatching (records
[i
]))
162 impressions
+= records
[i
].Hits
;
165 if (impressions
== 0)
169 random
= new Random ();
171 int rnd
= random
.Next (impressions
) + 1;
174 for (int i
= 0; i
< rlength
; i
++) {
175 if(IsAdMatching(records
[i
])) {
176 if (rnd
<= (counter
+ records
[i
].Hits
)) {
180 counter
+= records
[i
].Hits
;
184 return records
[index
].Properties
;
187 private bool IsAdMatching (AdRecord currAd
)
189 if (KeywordFilter
!= String
.Empty
)
190 return (0 == String
.Compare (currAd
.Keyword
, KeywordFilter
, true));
195 private string ResolveAdUrl (string relativeUrl
)
197 if (relativeUrl
.Length
==0 || !UrlUtils
.IsRelativeUrl (relativeUrl
))
201 if (fileDirectory
!= null)
202 fullUrl
= fileDirectory
;
204 fullUrl
= TemplateSourceDirectory
;
206 if (fullUrl
.Length
== 0)
209 return UrlUtils
.Combine (fullUrl
, relativeUrl
);
212 [WebCategory("Action")]
213 [WebSysDescription("AdRotator_OnAdCreated")]
214 public event AdCreatedEventHandler AdCreated
{
215 add { Events.AddHandler (AdCreatedEvent, value); }
216 remove { Events.RemoveHandler (AdCreatedEvent, value); }
221 [Editor ("System.Web.UI.Design.XmlUrlEditor, " + Consts
.AssemblySystem_Design
, typeof (System
.Drawing
.Design
.UITypeEditor
))]
222 [WebCategory("Behavior")]
223 [WebSysDescription("AdRotator_AdvertisementFile")]
228 public string AdvertisementFile
{
229 get { return ((advertisementFile != null) ? advertisementFile : ""); }
230 set { advertisementFile = value; }
233 [Browsable (false), EditorBrowsable (EditorBrowsableState
.Never
)]
234 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
235 public override FontInfo Font
{
236 get { return base.Font; }
241 [WebCategory("Behavior")]
242 [WebSysDescription("AdRotator_KeywordFilter")]
243 public string KeywordFilter
{
245 object o
= ViewState
["KeywordFilter"];
253 ViewState
["KeywordFilter"] = value.Trim ();
259 [TypeConverter(typeof(TargetConverter
))]
260 [WebCategory("Behavior")]
261 [WebSysDescription("AdRotator_Target")]
262 public string Target
{
264 object o
= ViewState
["Target"];
271 ViewState
["Target"] = value;
275 protected override ControlCollection
CreateControlCollection ()
277 return new EmptyControlCollection (this);
280 protected virtual void OnAdCreated (AdCreatedEventArgs e
)
285 AdCreatedEventHandler aceh
= (AdCreatedEventHandler
) Events
[AdCreatedEvent
];
290 protected override void OnPreRender (EventArgs e
)
292 if(AdvertisementFile
== String
.Empty
)
295 AdCreatedEventArgs acea
= new AdCreatedEventArgs (SelectAd ());
297 imageUrl
= acea
.ImageUrl
;
298 navigateUrl
= acea
.NavigateUrl
;
299 alternateText
= acea
.AlternateText
;
302 [MonoTODO ("Update method with net 2.0 properties added for AdRotator class")]
303 protected override void Render (HtmlTextWriter writer
)
305 HyperLink hLink
= new HyperLink ();
306 Image adImage
= new Image();
307 foreach (string current
in Attributes
.Keys
)
308 hLink
.Attributes
[current
] = Attributes
[current
];
310 if (ID
!= null && ID
.Length
> 0)
313 hLink
.Target
= Target
;
314 hLink
.AccessKey
= AccessKey
;
315 hLink
.Enabled
= Enabled
;
316 hLink
.TabIndex
= TabIndex
;
317 if (navigateUrl
!= null && navigateUrl
.Length
!= 0)
318 hLink
.NavigateUrl
= ResolveAdUrl (navigateUrl
);
320 hLink
.RenderBeginTag (writer
);
321 if (ControlStyleCreated
)
322 adImage
.ApplyStyle(ControlStyle
);
324 if(imageUrl
!=null && imageUrl
.Length
> 0)
325 adImage
.ImageUrl
= ResolveAdUrl (imageUrl
);
327 adImage
.AlternateText
= alternateText
;
328 adImage
.ToolTip
= ToolTip
;
329 adImage
.RenderControl (writer
);
330 hLink
.RenderEndTag (writer
);
336 [DefaultValueAttribute ("Banner")]
337 [WebCategoryAttribute ("Behavior")]
338 [WebSysDescriptionAttribute ("Advertisement of specific type is created by specified value")]
339 public AdType AdType
{
340 get { return adType; }
341 set { adType = value; }
344 string alternateTextField
;
346 [DefaultValueAttribute ("AlternateText")]
347 [WebCategoryAttribute ("Behavior")]
348 [WebSysDescriptionAttribute ("Alternate text is retrieved from the elmenet name specified.")]
349 //[VerificationAttribute ()]
350 public string AlternateTextField
{
351 get { return alternateTextField; }
352 set { alternateTextField = value; }
357 [DefaultValueAttribute (false)]
358 [WebCategoryAttribute ("Site Counters")]
359 [WebSysDescriptionAttribute ("On clicking an advertisement, click-through events should be counted.")]
360 public bool CountClicks
{
361 get { return countClicks; }
362 set { countClicks = value; }
367 [DefaultValueAttribute ("AdRotator")]
368 [WebCategoryAttribute ("Site Counters")]
369 [WebSysDescriptionAttribute ("Name of the group which takes care of counting.")]
370 public string CounterGroup
{
371 get { return counterGroup; }
372 set { counterGroup = value; }
377 [DefaultValueAttribute ("")]
378 [WebCategoryAttribute ("Site Counters")]
379 [WebSysDescriptionAttribute ("Name of the group which takes care of counting.")]
380 public string CounterName
{
381 get { return counterName; }
382 set { counterName = value; }
387 [DefaultValueAttribute (false)]
388 [WebCategoryAttribute ("Site Counters")]
389 [WebSysDescriptionAttribute ("On creation of an advertisement, view events should be counted.")]
390 public bool CountViews
{
391 get { return countViews; }
392 set { countViews = value; }
395 string imageUrlField
;
397 [DefaultValueAttribute ("ImageUrl")]
398 [WebCategoryAttribute ("Behavior")]
399 [WebSysDescriptionAttribute ("Image URL is retrieved from the elmenet name specified.")]
400 public string ImageUrlField
{
401 get { return imageUrlField; }
402 set { imageUrlField = value; }
405 string navigateUrlField
;
407 [DefaultValueAttribute ("NavigateUrl")]
408 [WebCategoryAttribute ("Behavior")]
409 [WebSysDescriptionAttribute ("Advertisement Web page URL is retrieved from the elmenet name specified.")]
410 public string NavigateUrlField
{
411 get { return navigateUrlField; }
412 set { navigateUrlField = value; }
417 [DefaultValueAttribute ("100")]
418 [WebCategoryAttribute ("Behavior")]
419 [WebSysDescriptionAttribute ("Frequency in percentage for creation of Popup or PopUnder advertisement.")]
420 public int PopFrequency
{
421 get { return popFrequency; }
422 set { popFrequency = value; }
427 [DefaultValueAttribute ("-1")]
428 [WebCategoryAttribute ("Appearance")]
429 [WebSysDescriptionAttribute ("Specifies X-coordinate in pixels of Popunder or Popup advertisements top-left corner.")]
430 public int PopPositionLeft
{
431 get { return popPositionLeft; }
432 set { popPositionLeft = value; }
437 [DefaultValueAttribute ("-1")]
438 [WebCategoryAttribute ("Appearance")]
439 [WebSysDescriptionAttribute ("Specifies Y-coordinate in pixels of Popunder or Popup advertisements top-left corner.")]
440 public int PopPositionTop
{
441 get { return popPositionTop; }
442 set { popPositionTop = value; }
447 [DefaultValueAttribute ("-1")]
448 [WebCategoryAttribute ("Site Counters")]
449 [WebSysDescriptionAttribute ("On a given day this many number of rows of data needs to be collected.")]
450 public int RowsPerDay
{
451 get { return rowsPerDay; }
452 set { rowsPerDay = value; }
455 string siteCountersProvider
;
457 [DefaultValueAttribute ("")]
458 [WebCategoryAttribute ("Site Counters")]
459 [WebSysDescriptionAttribute ("Control uses the specified provider.")]
460 public string SiteCountersProvider
{
461 get { return siteCountersProvider; }
462 set { siteCountersProvider = value; }
465 bool trackApplicationName
;
467 [DefaultValueAttribute (true)]
468 [WebCategoryAttribute ("Site Counters")]
469 [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the specified application name in a database.")]
470 public bool TrackApplicationName
{
471 get { return trackApplicationName; }
472 set { trackApplicationName = value; }
475 bool trackNavigateUrl
;
477 [DefaultValueAttribute (true)]
478 [WebCategoryAttribute ("Site Counters")]
479 [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the destination URL of click through event in a database.")]
480 public bool TrackNavigateUrl
{
481 get { return trackNavigateUrl; }
482 set { trackNavigateUrl = value; }
487 [DefaultValueAttribute (true)]
488 [WebCategoryAttribute ("Site Counters")]
489 [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the originating page URL in a database.")]
490 public bool TrackPageUrl
{
491 get { return trackPageUrl; }
492 set { trackPageUrl = value; }
498 public IDictionary Properties
;
499 public int Hits
; // or impressions or clicks
500 public string Keyword
;
502 public AdRecord (IDictionary adProps
)
504 this.Properties
= adProps
;
505 Keyword
= Properties
["Keyword"] as string;
509 string imp
= Properties
["Impressions"] as string;
513 Hits
= Int32
.Parse (imp
);