svn path=/branches/mono-1-1-9/mcs/; revision=51216
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / AdRotator.cs
1 // 
2 // System.Web.UI.WebControls.AdRotator
3 //
4 // Author:
5 //        Ben Maurer <bmaurer@novell.com>
6 //
7 // (c) 2005 Novell
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Xml;
30 using System.Collections;
31 using System.ComponentModel;
32
33 namespace System.Web.UI.WebControls {
34         [DefaultEvent("AdCreated")]
35         [DefaultProperty("AdvertisementFile")]
36         [Designer("System.Web.UI.Design.WebControls.AdRotatorDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
37 #if NET_2_0
38         [ToolboxData("<{0}:AdRotator runat=\"server\"></{0}:AdRotator>")]
39 #else
40         [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" Width=\"468px\"></{0}:AdRotator>")]
41 #endif          
42         public class AdRotator :
43 #if NET_2_0
44         DataBoundControl
45 #else           
46         WebControl
47 #endif  
48         {
49 #if NET_2_0
50                 [MonoTODO]
51                 protected internal override void OnInit (EventArgs e)
52                 {
53                         base.OnInit(e);
54                 }
55 #endif
56                 
57 #if NET_2_0
58                 protected internal
59 #else           
60                 protected
61 #endif          
62                 override void OnPreRender (EventArgs eee)
63                 {
64                         Hashtable ht = null;
65                         
66                         if (ad_file != "" && ad_file != null) {
67                                 ReadAdsFromFile (Page.MapPath (ad_file));
68                                 ht = ChooseAd ();
69                         }
70
71                         AdCreatedEventArgs e = new AdCreatedEventArgs (ht);
72                         OnAdCreated (e);
73                         createdargs = e;
74                         
75                 }
76
77 #if NET_2_0
78                 [MonoTODO]
79                 protected internal override void PerformDataBinding (IEnumerable data)
80                 {
81                         throw new NotImplementedException ();
82                 }
83
84                 [MonoTODO]
85                 protected override void PerformSelect ()
86                 {
87                         throw new NotImplementedException ();
88                 }
89 #endif          
90
91                 AdCreatedEventArgs createdargs;
92
93 #if NET_2_0
94                 protected internal
95 #else           
96                 protected
97 #endif          
98                 override void Render (HtmlTextWriter w)
99                 {
100                         AdCreatedEventArgs e = createdargs;
101
102                         base.AddAttributesToRender (w);
103                         
104                         if (e.NavigateUrl != null)
105                                 w.AddAttribute (HtmlTextWriterAttribute.Href, ResolveUrl (e.NavigateUrl));
106                         w.AddAttribute (HtmlTextWriterAttribute.Target, Target);
107                         
108                         w.RenderBeginTag (HtmlTextWriterTag.A);
109
110                         if (e.NavigateUrl != null)
111                                 w.AddAttribute (HtmlTextWriterAttribute.Src, ResolveUrl (e.ImageUrl));
112                         
113                         w.AddAttribute (HtmlTextWriterAttribute.Alt, e.AlternateText == null ? "" : e.AlternateText);
114                         w.AddAttribute (HtmlTextWriterAttribute.Border, "0");
115                         w.RenderBeginTag (HtmlTextWriterTag.Img);
116                         w.RenderEndTag (); // img
117                         w.RenderEndTag (); // a
118                 }
119
120                 //
121                 // We take all the ads in the ad file and add up their
122                 // impression weight. We then take a random number [0,
123                 // TotalImpressions). We then choose the ad that is
124                 // that number or less impressions for the beginning
125                 // of the file. This lets us respect the weights
126                 // given.
127                 //
128                 Hashtable ChooseAd ()
129                 {
130                         // cache for performance
131                         string KeywordFilter = this.KeywordFilter;
132                         
133                         int total_imp = 0;
134                         int cur_imp = 0;
135                         
136                         foreach (Hashtable a in ads) {
137                                 if (KeywordFilter == "" || KeywordFilter == (string) a ["Keyword"])
138                                         total_imp += a ["Impressions"] != null ? int.Parse ((string) a ["Impressions"]) : 1;
139                         }
140
141                         int r = new Random ().Next (total_imp);
142
143                         foreach (Hashtable a in ads) {
144                                 if (KeywordFilter != "" && KeywordFilter != (string) a ["Keyword"])
145                                         continue;
146                                 cur_imp += a ["Impressions"] != null ? int.Parse ((string) a ["Impressions"]) : 1;
147                                 
148                                 if (cur_imp > r)
149                                         return a;
150                         }
151
152                         if (total_imp != 0)
153                                 throw new Exception ("I should only get here if no ads matched");
154                         
155                         return null;
156                 }
157
158                 ArrayList ads = new ArrayList ();
159                 
160                 void ReadAdsFromFile (string s)
161                 {
162                         XmlDocument d = new XmlDocument ();
163                         try {
164                                 d.Load (s);
165                         } catch (Exception e) {
166                                 throw new HttpException ("AdRotator could not parse the xml file", e);
167                         }
168                         
169                         ads.Clear ();
170                         
171                         foreach (XmlNode n in d.DocumentElement.ChildNodes) {
172
173                                 Hashtable ad = new Hashtable ();
174                                 
175                                 foreach (XmlNode nn in n.ChildNodes)
176                                         ad.Add (nn.Name, nn.InnerText);
177                                 
178                                 ads.Add (ad);
179                         }
180                 }
181                 
182                 string ad_file = "";
183
184 #if NET_2_0
185                 [UrlProperty]
186 #endif          
187                 [Bindable(true)]
188                 [DefaultValue("")]
189                 [Editor("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
190                 [WebSysDescription("")]
191                 [WebCategory("Behavior")]
192                 public string AdvertisementFile {
193                         get {
194                                 return ad_file;
195                         }
196                         set {
197                                 ad_file = value;
198                         }
199                         
200                 }
201
202 #if NET_2_0
203                 [DefaultValue ("AlternateText")]
204                 [WebSysDescriptionAttribute ("")]
205                 [WebCategoryAttribute ("Behavior")]
206                 [MonoTODO]
207                 public string AlternateTextField 
208                 {
209                         get {
210                                 throw new NotImplementedException ();
211                         }
212                         set {
213                                 throw new NotImplementedException ();
214                         }
215                 }
216 #endif          
217                 
218                 [Browsable(false)]
219                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
220                 [EditorBrowsable(EditorBrowsableState.Never)]
221                 public override FontInfo Font {
222                         get {
223                                 return base.Font;
224                         }
225                 }
226
227 #if NET_2_0
228                 [DefaultValue ("ImageUrl")]
229                 [MonoTODO]
230                 [WebSysDescriptionAttribute ("")]
231                 [WebCategoryAttribute ("Behavior")]
232                 public string ImageUrlField 
233                 {
234                         get {
235                                 throw new NotImplementedException ();
236                         }
237                         set {
238                                 throw new NotImplementedException ();
239                         }
240                 }
241 #endif          
242                 
243
244                 [Bindable(true)]
245                 [DefaultValue("")]
246                 [WebSysDescription("")]
247                 [WebCategory("Behavior")]
248                 public string KeywordFilter {
249                         get {
250                                 return ViewState.GetString ("KeywordFilter", "");
251                         }
252                         set {
253                                 ViewState ["KeywordFilter"] = value;
254                         }
255                         
256                 }
257
258 #if NET_2_0
259                 [DefaultValue ("NavigateUrl")]
260                 [MonoTODO]
261                 [WebSysDescriptionAttribute ("")]
262                 [WebCategoryAttribute ("Behavior")]
263                 public string NavigateUrlField 
264                 {
265                         get {
266                                 throw new NotImplementedException ();
267                         }
268                         set {
269                                 throw new NotImplementedException ();
270                         }
271                 }
272
273                 /* listed in corcompare */
274                 [MonoTODO]
275                 public override Page Page 
276                 {
277                         get {
278                                 return base.Page;
279                         }
280                         set {
281                                 base.Page = value;
282                         }
283                 }
284 #endif          
285                 
286                 [Bindable(true)]
287                 [DefaultValue("_top")]
288                 [TypeConverter(typeof(System.Web.UI.WebControls.TargetConverter))]
289                 [WebSysDescription("")]
290                 [WebCategory("Behavior")]
291                 public string Target {
292                         get {
293                                 return ViewState.GetString ("Target", "_top");
294                         }
295                         set {
296                                 ViewState ["Target"] = value;
297                         }
298                         
299                 }
300
301 #if NET_2_0
302                 /* all these are listed in corcompare */
303                 [MonoTODO]
304                 public override string UniqueID
305                 {
306                         get {
307                                 return base.UniqueID;
308                         }
309                 }
310
311                 [MonoTODO]
312                 protected override HtmlTextWriterTag TagKey 
313                 {
314                         get {
315                                 return base.TagKey;
316                         }
317                 }
318
319                 [MonoTODO]
320                 protected override StateBag ViewState 
321                 {
322                         get {
323                                 return base.ViewState;
324                         }
325                 }
326 #endif          
327         
328                 protected virtual void OnAdCreated (AdCreatedEventArgs e)
329                 {
330                         AdCreatedEventHandler h = (AdCreatedEventHandler) Events [AdCreatedEvent];
331                         if (h != null)
332                                 h (this, e);
333                 }
334
335                 static readonly object AdCreatedEvent = new object ();
336
337                 [WebSysDescription("")]
338                 [WebCategory("Action")]
339                 public event AdCreatedEventHandler AdCreated {
340                         add { Events.AddHandler (AdCreatedEvent, value); }
341                         remove { Events.RemoveHandler (AdCreatedEvent, value); }
342                 }
343         }
344 }