8083b6969d73117a73479a9735c5a3d4fa50b956
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / AdRotator.cs
1 /**\r
2  * Namespace: System.Web.UI.WebControls\r
3  * Class:     AdRotator\r
4  *\r
5  * Author:  Gaurav Vaish\r
6  * Maintainer: gvaish@iitk.ac.in\r
7  * Implementation: yes\r
8  * Contact: <gvaish@iitk.ac.in>\r
9  * Status:  100%\r
10  *\r
11  * (C) Gaurav Vaish (2001)\r
12  */\r
13 \r
14 using System;\r
15 using System.IO;\r
16 using System.Collections;\r
17 using System.Collections.Specialized;\r
18 using System.Web;\r
19 using System.Web.Caching;\r
20 using System.Web.UI;\r
21 using System.Xml;\r
22 using System.Web.Utils;\r
23 using System.ComponentModel;\r
24 \r
25 namespace System.Web.UI.WebControls\r
26 {\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         public class AdRotator: WebControl\r
33         {\r
34 \r
35                 private string advertisementFile;\r
36                 private static readonly object AdCreatedEvent = new object();\r
37 \r
38                 // Will be set values during (On)PreRender-ing\r
39                 private string alternateText;\r
40                 private string imageUrl;\r
41                 private string navigateUrl;\r
42 \r
43                 private string fileDirectory;\r
44 \r
45                 private class AdRecord\r
46                 {\r
47                         public IDictionary adProps;\r
48                         public int         hits; // or impressions or clicks\r
49                         public string      keyword;\r
50 \r
51                         public AdRecord(IDictionary adProps)\r
52                         {\r
53                                 this.adProps = adProps;\r
54                                 hits         = 0;\r
55                                 keyword      = String.Empty;\r
56                         }\r
57                 }\r
58 \r
59 /*\r
60  * Loading / Saving data from/to ad file and all the manipulations wrt to the URL...\r
61  * are incorporated by the following functions.\r
62  * GetData(string)\r
63  * LoadAdFile(string)\r
64  * IsAdMatching(AdRecord)\r
65  * ResolveAdUrl(string)\r
66  * SelectAd()\r
67  * The exact control flow will be detailed. Let me first write the functions\r
68  */\r
69 \r
70                 private AdRecord[] LoadAdFile(string file)\r
71                 {\r
72                         Stream      fStream;\r
73                         ArrayList   list;\r
74                         XmlReader   reader;\r
75                         XmlDocument document;\r
76                         XmlNode     topNode, innerNode;\r
77                         IDictionary hybridDict = null;\r
78                         AdRecord[]  adsArray = null;\r
79                         try\r
80                         {\r
81                                 fStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);\r
82                         } catch(Exception e)\r
83                         {\r
84                                 throw new HttpException("AdRotator: Unable to open file");\r
85                         }\r
86                         try\r
87                         {\r
88                                 list = new ArrayList();\r
89                                 reader = new XmlTextReader(fStream);\r
90                                 document = new XmlDocument();\r
91                                 document.Load(reader);\r
92                                 if(document.DocumentElement!=null)\r
93                                 {\r
94                                         if(document.DocumentElement.LocalName=="Advertisements")\r
95                                         {\r
96                                                 topNode = document.DocumentElement.FirstChild;\r
97                                                 while(topNode!=null)\r
98                                                 {\r
99                                                         if(topNode.LocalName=="Ad")\r
100                                                         {\r
101                                                                 innerNode = topNode.FirstChild;\r
102                                                                 while(innerNode!=null)\r
103                                                                 {\r
104                                                                         if(innerNode.NodeType==XmlNodeType.Element)\r
105                                                                         {\r
106                                                                                 if(hybridDict==null)\r
107                                                                                 {\r
108                                                                                         hybridDict = new HybridDictionary();\r
109                                                                                 }\r
110                                                                                 hybridDict.Add(innerNode.LocalName, innerNode.InnerText);\r
111                                                                         }\r
112                                                                         innerNode = innerNode.NextSibling;\r
113                                                                 }\r
114                                                                 if(hybridDict!=null)\r
115                                                                         list.Add(hybridDict);\r
116                                                         }\r
117                                                         topNode = topNode.NextSibling;\r
118                                                 }\r
119                                         }\r
120                                 }\r
121                                 if(list.Count>0)\r
122                                 {\r
123                                         adsArray = new AdRecord[list.Count];\r
124                                         for(int i=0; i < list.Count; i++)\r
125                                         {\r
126                                                 adsArray[i] = new AdRecord((IDictionary)list[i]);\r
127                                         }\r
128                                 }\r
129                         } catch(Exception e)\r
130                         {\r
131                                 throw new HttpException("AdRotator_Parse_Error" + file);\r
132                         } finally\r
133                         {\r
134                                 fStream.Close();\r
135                         }\r
136                         if(adsArray == null)\r
137                         {\r
138                                 throw new HttpException("AdRotator_No_Advertisements_Found");\r
139                         }\r
140                         return adsArray;\r
141                 }\r
142 \r
143                 private AdRecord[] GetData(string file)\r
144                 {\r
145                         string physPath = MapPathSecure(file);\r
146                         string AdKey = "AdRotatorCache: " + physPath;\r
147                         fileDirectory = UrlUtils.GetDirectory(UrlUtils.Combine(TemplateSourceDirectory, file));\r
148                         Cache cache = HttpRuntime.Cache;\r
149                         AdRecord[] records = (AdRecord[])cache[AdKey];\r
150                         if(records==null)\r
151                         {\r
152                                 records = LoadAdFile(physPath);\r
153                                 if(records==null)\r
154                                 {\r
155                                         return null;\r
156                                 }\r
157                                 cache.Insert(AdKey, records, new CacheDependency(physPath));\r
158                         }\r
159                         return records;\r
160                 }\r
161 \r
162                 private IDictionary SelectAd()\r
163                 {\r
164                         AdRecord[] records = GetData(AdvertisementFile);\r
165                         if(records!=null && records.Length!=0)\r
166                         {\r
167                                 int impressions = 0;\r
168                                 for(int i=0 ; i < records.Length; i++)\r
169                                 {\r
170                                         if(IsAdMatching(records[i]))\r
171                                                 impressions += records[1].hits;\r
172                                 }\r
173                                 if(impressions!=0)\r
174                                 {\r
175                                         int rnd = (new Random()).Next(impressions) + 1;\r
176                                         int counter = 0;\r
177                                         int index = 0;\r
178                                         for(int i=0; i < records.Length; i++)\r
179                                         {\r
180                                                 if(IsAdMatching(records[i]))\r
181                                                 {\r
182                                                         if(rnd <= (counter + records[i].hits))\r
183                                                         {\r
184                                                                 index = i;\r
185                                                                 break;\r
186                                                         }\r
187                                                         counter += records[i].hits;\r
188                                                 }\r
189                                         }\r
190                                         return records[index].adProps;\r
191                                 }\r
192                         }\r
193                         return null;\r
194                 }\r
195 \r
196                 private bool IsAdMatching(AdRecord currAd)\r
197                 {\r
198                         if(KeywordFilter!=String.Empty)\r
199                         {\r
200                                 if(currAd.keyword.ToLower() == KeywordFilter.ToLower())\r
201                                         return false;\r
202                         }\r
203                         return true;\r
204                 }\r
205 \r
206                 private string ResolveAdUrl(string relativeUrl)\r
207                 {\r
208                         if(relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl(relativeUrl))\r
209                                 return relativeUrl;\r
210                         string fullUrl = String.Empty;\r
211                         if(fileDirectory != null)\r
212                                 fullUrl = fileDirectory;\r
213                         if(fullUrl.Length == 0)\r
214                                 fullUrl = TemplateSourceDirectory;\r
215                         if(fullUrl.Length == 0)\r
216                                 return relativeUrl;\r
217                         return (fullUrl + relativeUrl);\r
218                 }\r
219 \r
220                 public event AdCreatedEventHandler AdCreated\r
221                 {\r
222                         add\r
223                         {\r
224                                 Events.AddHandler(AdCreatedEvent, value);\r
225                         }\r
226                         remove\r
227                         {\r
228                                 Events.RemoveHandler(AdCreatedEvent, value);\r
229                         }\r
230                 }\r
231 \r
232                 public AdRotator(): base()\r
233                 {\r
234                         advertisementFile = string.Empty;\r
235                         fileDirectory     = null;\r
236                 }\r
237 \r
238                 public string AdvertisementFile\r
239                 {\r
240                         get\r
241                         {\r
242                                 return advertisementFile;\r
243                         }\r
244                         set\r
245                         {\r
246                                 advertisementFile = value;\r
247                         }\r
248                 }\r
249 \r
250                 public override FontInfo Font\r
251                 {\r
252                         get\r
253                         {\r
254                                 return Font;\r
255                         }\r
256                 }\r
257 \r
258                 public string KeywordFilter\r
259                 {\r
260                         get\r
261                         {\r
262                                 object o = ViewState["KeywordFilter"];\r
263                                 if(o!=null)\r
264                                         return (string)o;\r
265                                 return String.Empty;\r
266                         }\r
267                         set\r
268                         {\r
269                                 if(value!=null)\r
270                                         ViewState["KeywordFilter"] = value.Trim();\r
271                         }\r
272                 }\r
273 \r
274                 public string Target\r
275                 {\r
276                         get\r
277                         {\r
278                                 object o = ViewState["Target"];\r
279                                 if(o!=null)\r
280                                         return (string)o;\r
281                                 return String.Empty;\r
282                         }\r
283                         set\r
284                         {\r
285                                 ViewState["Target"] = value;\r
286                         }\r
287                 }\r
288 \r
289                 protected override ControlCollection CreateControlCollection()\r
290                 {\r
291                         return new EmptyControlCollection(this);\r
292                 }\r
293 \r
294                 protected virtual void OnAdCreated(AdCreatedEventArgs e)\r
295                 {\r
296                         if(Events!=null)\r
297                         {\r
298                                 AdCreatedEventHandler aceh = (AdCreatedEventHandler)(Events[AdCreatedEvent]);\r
299                                 if(aceh!=null)\r
300                                         aceh(this, e);\r
301                         }\r
302                 }\r
303 \r
304                 protected override void OnPreRender(EventArgs e)\r
305                 {\r
306                         if(AdvertisementFile!=String.Empty)\r
307                         {\r
308                                 AdCreatedEventArgs acea = new AdCreatedEventArgs(SelectAd());\r
309                                 imageUrl      = acea.ImageUrl;\r
310                                 navigateUrl   = acea.NavigateUrl;\r
311                                 alternateText = acea.AlternateText;\r
312                         }\r
313                 }\r
314 \r
315                 protected override void Render(HtmlTextWriter writer)\r
316                 {\r
317                         HyperLink hLink = new HyperLink();\r
318                         Image adImage = new Image();\r
319                         foreach(IEnumerable current in Attributes.Keys)\r
320                         {\r
321                                 hLink.Attributes[(string)current] = Attributes[(string)current];\r
322                         }\r
323                         if(ID != null && ID.Length > 0)\r
324                                 hLink.ID = ID;\r
325                         hLink.Target    = Target;\r
326                         hLink.AccessKey = AccessKey;\r
327                         hLink.Enabled   = Enabled;\r
328                         hLink.TabIndex  = TabIndex;\r
329                         hLink.RenderBeginTag(writer);\r
330                         if(ControlStyleCreated)\r
331                         {\r
332                                 adImage.ApplyStyle(ControlStyle);\r
333                         }\r
334                         if(imageUrl!=null && imageUrl.Length > 0)\r
335                                 adImage.ImageUrl = ResolveAdUrl(imageUrl);\r
336                         adImage.AlternateText = alternateText;\r
337                         adImage.ToolTip       = ToolTip;\r
338                         adImage.RenderControl(writer);\r
339                         hLink.RenderEndTag(writer);\r
340                 }\r
341         }\r
342 }\r