* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / AdRotator.cs
old mode 100755 (executable)
new mode 100644 (file)
index 4323455..876598b
@@ -1,18 +1,10 @@
+// 
+// System.Web.UI.WebControls.AdRotator
 //
-// System.Web.UI.WebControls.AdRotator.cs
-//
-// Authors:
-//   Gaurav Vaish (gvaish@iitk.ac.in)
-//   Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
-//   Sanjay Gupta (gsanjay@novell.com)
-//
-// (c) 2002 Ximian, Inc. (http://www.ximian.com)
-// (C) Gaurav Vaish (2002)
-// (C) 2003 Andreas Nahr
-// (C) 2004 Novell, Inc. (http://www.novell.com)
+// Author:
+//        Ben Maurer <bmaurer@novell.com>
 //
-
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Specialized;
-using System.Web;
-using System.Web.Caching;
-using System.Web.UI;
 using System.Xml;
-using System.Web.Util;
+using System.Collections;
 using System.ComponentModel;
-using System.ComponentModel.Design;
+using System.Security.Permissions;
 
-namespace System.Web.UI.WebControls
-{
+namespace System.Web.UI.WebControls {
+
+       // CAS
+       [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       // attributes
        [DefaultEvent("AdCreated")]
        [DefaultProperty("AdvertisementFile")]
-       [Designer ("System.Web.UI.Design.WebControls.AdRotatorDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
-       [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" "
-       + "Width=\"468\"></{0}:AdRotator>")]
-       public class AdRotator: 
+       [Designer("System.Web.UI.Design.WebControls.AdRotatorDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
 #if NET_2_0
-               DataBoundControl
+       [ToolboxData("<{0}:AdRotator runat=\"server\"></{0}:AdRotator>")]
 #else
-               WebControl
-#endif
+       [ToolboxData("<{0}:AdRotator runat=\"server\" Height=\"60px\" Width=\"468px\"></{0}:AdRotator>")]
+#endif         
+       public class AdRotator :
+#if NET_2_0
+       DataBoundControl
+#else          
+       WebControl
+#endif 
        {
-               string advertisementFile;
-               static readonly object AdCreatedEvent = new object();
-
-               // Will be set values during (On)PreRender-ing
-               string alternateText;
-               string imageUrl;
-               string navigateUrl;
-               string fileDirectory;
-               Random random;
-
-               public AdRotator ()
+#if NET_2_0
+               [MonoTODO]
+               protected internal override void OnInit (EventArgs e)
                {
-                       advertisementFile = "";
-                       fileDirectory     = null;
+                       base.OnInit(e);
                }
-
-               AdRecord[] LoadAdFile (string file)
+#endif
+               
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void OnPreRender (EventArgs eee)
                {
-                       Stream fStream;
-                       try {
-                               fStream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read);
-                       } catch (Exception e) {
-                               throw new HttpException("AdRotator: Unable to open file", e);
+                       Hashtable ht = null;
+                       
+                       if (ad_file != "" && ad_file != null) {
+                               ReadAdsFromFile (Page.MapPath (ad_file));
+                               ht = ChooseAd ();
                        }
 
-                       ArrayList list = new ArrayList ();
-                       try {
-                               IDictionary hybridDict = null;
-                               XmlDocument document = new XmlDocument ();
-                               document.Load (fStream);
-
-                               XmlElement docElem = document.DocumentElement;
-
-                               if (docElem == null)
-                                       throw new HttpException ("No advertisements found");
-
-                               if (docElem.LocalName != "Advertisements")
-                                       throw new HttpException ("No advertisements found: invalid document element");
-
-                               XmlNode node = docElem.FirstChild;
-                               while (node != null) {
-                                       if (node.LocalName == "Ad") {
-                                               XmlNode innerNode = node.FirstChild;
-                                               while (innerNode != null) {
-                                                       if (node.NodeType == XmlNodeType.Element) {
-                                                               if (hybridDict == null)
-                                                                       hybridDict = new HybridDictionary ();
-
-                                                               hybridDict.Add (innerNode.LocalName, innerNode.InnerText);
-                                                       }
-                                                       innerNode = innerNode.NextSibling;
-                                               }
-
-                                               if (hybridDict != null) {
-                                                       list.Add (hybridDict);
-                                                       hybridDict = null;
-                                               }
-                                       }
-                                       node = node.NextSibling;
-                               }
-
-                       } catch(Exception e) {
-                               throw new HttpException("Parse error:" + file, e);
-                       } finally {
-                               if (fStream != null)
-                                       fStream.Close();
-                       }
-
-                       if (list.Count == 0)
-                               throw new HttpException ("No advertisements found");
-
-                       AdRecord [] adsArray = new AdRecord [list.Count];
-                       int count = list.Count;
-                       for (int i = 0; i < count; i++)
-                               adsArray [i] = new AdRecord ((IDictionary) list [i]);
-
-                       return adsArray;
+                       AdCreatedEventArgs e = new AdCreatedEventArgs (ht);
+                       OnAdCreated (e);
+                       createdargs = e;
+                       
                }
 
-               AdRecord [] GetData (string file)
+#if NET_2_0
+               [MonoTODO]
+               protected internal override void PerformDataBinding (IEnumerable data)
                {
-                       string physPath = MapPathSecure (file);
-                       string AdKey = "AdRotatorCache: " + physPath;
-                       fileDirectory = UrlUtils.GetDirectory (UrlUtils.Combine (TemplateSourceDirectory, file));
-                       Cache cache = HttpRuntime.Cache;
-                       AdRecord[] records = (AdRecord[]) cache [AdKey];
-                       if (records == null) {
-                               records = LoadAdFile (physPath);
-                               cache.Insert (AdKey, records, new CacheDependency (physPath));
-                       }
-
-                       return records;
+                       throw new NotImplementedException ();
                }
 
-               IDictionary SelectAd ()
+               [MonoTODO]
+               protected override void PerformSelect ()
                {
-                       AdRecord[] records = GetData (AdvertisementFile);
-                       if (records == null || records.Length ==0)
-                               return null;
-
-                       int impressions = 0;
-                       int rlength = records.Length;
-                       for (int i=0 ; i < rlength; i++) {
-                               if (IsAdMatching (records [i]))
-                                       impressions += records [i].Hits;
-                       }
-
-                       if (impressions == 0)
-                               return null;
-
-                       if (random == null)
-                               random = new Random ();
-
-                       int rnd = random.Next (impressions) + 1;
-                       int counter = 0;
-                       int index = 0;
-                       for (int i = 0; i < rlength; i++) {
-                               if(IsAdMatching(records[i])) {
-                                       if (rnd <= (counter + records [i].Hits)) {
-                                               index = i;
-                                               break;
-                                       }
-                                       counter += records [i].Hits;
-                               }
-                       }
-
-                       return records [index].Properties;
+                       throw new NotImplementedException ();
                }
+#endif         
 
-               private bool IsAdMatching (AdRecord currAd)
-               {
-                       if (KeywordFilter != String.Empty)
-                               return (0 == String.Compare (currAd.Keyword, KeywordFilter, true));
-
-                       return true;
-               }
+               AdCreatedEventArgs createdargs;
 
-               private string ResolveAdUrl (string relativeUrl)
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void Render (HtmlTextWriter w)
+               {
+                       AdCreatedEventArgs e = createdargs;
+
+                       base.AddAttributesToRender (w);
+                       
+                       if (e.NavigateUrl != null)
+                               w.AddAttribute (HtmlTextWriterAttribute.Href, ResolveUrl (e.NavigateUrl));
+                       w.AddAttribute (HtmlTextWriterAttribute.Target, Target);
+                       
+                       w.RenderBeginTag (HtmlTextWriterTag.A);
+
+                       if (e.NavigateUrl != null)
+                               w.AddAttribute (HtmlTextWriterAttribute.Src, ResolveUrl (e.ImageUrl));
+                       
+                       w.AddAttribute (HtmlTextWriterAttribute.Alt, e.AlternateText == null ? "" : e.AlternateText);
+                       w.AddAttribute (HtmlTextWriterAttribute.Border, "0");
+                       w.RenderBeginTag (HtmlTextWriterTag.Img);
+                       w.RenderEndTag (); // img
+                       w.RenderEndTag (); // a
+               }
+
+               //
+               // We take all the ads in the ad file and add up their
+               // impression weight. We then take a random number [0,
+               // TotalImpressions). We then choose the ad that is
+               // that number or less impressions for the beginning
+               // of the file. This lets us respect the weights
+               // given.
+               //
+               Hashtable ChooseAd ()
                {
-                       if (relativeUrl.Length==0 || !UrlUtils.IsRelativeUrl (relativeUrl))
-                               return relativeUrl;
+                       // cache for performance
+                       string KeywordFilter = this.KeywordFilter;
+                       
+                       int total_imp = 0;
+                       int cur_imp = 0;
+                       
+                       foreach (Hashtable a in ads) {
+                               if (KeywordFilter == "" || KeywordFilter == (string) a ["Keyword"])
+                                       total_imp += a ["Impressions"] != null ? int.Parse ((string) a ["Impressions"]) : 1;
+                       }
 
-                       string fullUrl;
-                       if (fileDirectory != null)
-                               fullUrl = fileDirectory;
-                       else
-                               fullUrl = TemplateSourceDirectory;
+                       int r = new Random ().Next (total_imp);
 
-                       if (fullUrl.Length == 0)
-                               return relativeUrl;
+                       foreach (Hashtable a in ads) {
+                               if (KeywordFilter != "" && KeywordFilter != (string) a ["Keyword"])
+                                       continue;
+                               cur_imp += a ["Impressions"] != null ? int.Parse ((string) a ["Impressions"]) : 1;
+                               
+                               if (cur_imp > r)
+                                       return a;
+                       }
 
-                       return UrlUtils.Combine (fullUrl, relativeUrl);
+                       if (total_imp != 0)
+                               throw new Exception ("I should only get here if no ads matched");
+                       
+                       return null;
                }
 
-               [WebCategory("Action")]
-               [WebSysDescription("AdRotator_OnAdCreated")]
-               public event AdCreatedEventHandler AdCreated {
-                       add { Events.AddHandler (AdCreatedEvent, value); }
-                       remove { Events.RemoveHandler (AdCreatedEvent, value); }
+               ArrayList ads = new ArrayList ();
+               
+               void ReadAdsFromFile (string s)
+               {
+                       XmlDocument d = new XmlDocument ();
+                       try {
+                               d.Load (s);
+                       } catch (Exception e) {
+                               throw new HttpException ("AdRotator could not parse the xml file", e);
+                       }
+                       
+                       ads.Clear ();
+                       
+                       foreach (XmlNode n in d.DocumentElement.ChildNodes) {
+
+                               Hashtable ad = new Hashtable ();
+                               
+                               foreach (XmlNode nn in n.ChildNodes)
+                                       ad.Add (nn.Name, nn.InnerText);
+                               
+                               ads.Add (ad);
+                       }
                }
+               
+               string ad_file = "";
 
+#if NET_2_0
+               [UrlProperty]
+#endif         
                [Bindable(true)]
                [DefaultValue("")]
-               [Editor ("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               [Editor("System.Web.UI.Design.XmlUrlEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
+               [WebSysDescription("")]
                [WebCategory("Behavior")]
-               [WebSysDescription("AdRotator_AdvertisementFile")]
-#if NET_2_0
-               [Localizable (true)]
-               [UrlProperty ()]
-#endif
                public string AdvertisementFile {
-                       get { return ((advertisementFile != null) ? advertisementFile : ""); }
-                       set { advertisementFile = value; }
+                       get {
+                               return ad_file;
+                       }
+                       set {
+                               ad_file = value;
+                       }
+                       
                }
 
-               [Browsable (false), EditorBrowsable (EditorBrowsableState.Never)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+#if NET_2_0
+               [DefaultValue ("AlternateText")]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               [MonoTODO]
+               public string AlternateTextField 
+               {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+#endif         
+               
+               [Browsable(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [EditorBrowsable(EditorBrowsableState.Never)]
                public override FontInfo Font {
-                       get { return base.Font; }
+                       get {
+                               return base.Font;
+                       }
+               }
+
+#if NET_2_0
+               [DefaultValue ("ImageUrl")]
+               [MonoTODO]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               public string ImageUrlField 
+               {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
                }
+#endif         
+               
 
                [Bindable(true)]
                [DefaultValue("")]
+               [WebSysDescription("")]
                [WebCategory("Behavior")]
-               [WebSysDescription("AdRotator_KeywordFilter")]
                public string KeywordFilter {
                        get {
-                               object o = ViewState ["KeywordFilter"];
-                               if (o != null)
-                                       return (string) o;
-
-                               return String.Empty;
+                               return ViewState.GetString ("KeywordFilter", "");
                        }
                        set {
-                               if(value != null)
-                                       ViewState ["KeywordFilter"] = value.Trim ();
+                               ViewState ["KeywordFilter"] = value;
                        }
+                       
                }
 
+#if NET_2_0
+               [DefaultValue ("NavigateUrl")]
+               [MonoTODO]
+               [WebSysDescriptionAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+               public string NavigateUrlField 
+               {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+#endif         
+               
                [Bindable(true)]
-               [DefaultValue("")]
-               [TypeConverter(typeof(TargetConverter))]
+               [DefaultValue("_top")]
+               [TypeConverter(typeof(System.Web.UI.WebControls.TargetConverter))]
+               [WebSysDescription("")]
                [WebCategory("Behavior")]
-               [WebSysDescription("AdRotator_Target")]
                public string Target {
                        get {
-                               object o = ViewState ["Target"];
-                               if (o != null)
-                                       return (string) o;
-
-                               return "_top";
+                               return ViewState.GetString ("Target", "_top");
                        }
                        set {
-                               ViewState["Target"] = value;
+                               ViewState ["Target"] = value;
                        }
+                       
                }
 
-               protected override ControlCollection CreateControlCollection ()
+#if NET_2_0
+               /* all these are listed in corcompare */
+               [MonoTODO]
+               public override string UniqueID
                {
-                       return new EmptyControlCollection (this);
+                       get {
+                               return base.UniqueID;
+                       }
                }
 
-               protected virtual void OnAdCreated (AdCreatedEventArgs e)
+               [MonoTODO]
+               protected override HtmlTextWriterTag TagKey 
                {
-                       if (Events == null)
-                               return;
-
-                       AdCreatedEventHandler aceh = (AdCreatedEventHandler) Events [AdCreatedEvent];
-                       if (aceh != null)
-                               aceh (this, e);
+                       get {
+                               return base.TagKey;
+                       }
                }
-
-               protected override void OnPreRender (EventArgs e)
+#endif         
+       
+               protected virtual void OnAdCreated (AdCreatedEventArgs e)
                {
-                       if(AdvertisementFile == String.Empty)
-                               return;
-
-                       AdCreatedEventArgs acea = new AdCreatedEventArgs (SelectAd ());
-                       OnAdCreated (acea);
-                       imageUrl = acea.ImageUrl;
-                       navigateUrl = acea.NavigateUrl;
-                       alternateText = acea.AlternateText;
+                       AdCreatedEventHandler h = (AdCreatedEventHandler) Events [AdCreatedEvent];
+                       if (h != null)
+                               h (this, e);
                }
 
-               [MonoTODO ("Update method with net 2.0 properties added for AdRotator class")]
-               protected override void Render (HtmlTextWriter writer)
-               {
-                       HyperLink hLink = new HyperLink ();
-                       Image adImage = new Image();
-                       foreach (string current in Attributes.Keys)
-                               hLink.Attributes [current] = Attributes [current];
-
-                       if (ID != null && ID.Length > 0)
-                               hLink.ID = ID;
-
-                       hLink.Target = Target;
-                       hLink.AccessKey = AccessKey;
-                       hLink.Enabled  = Enabled;
-                       hLink.TabIndex = TabIndex;
-                       if (navigateUrl != null && navigateUrl.Length != 0)
-                               hLink.NavigateUrl = ResolveAdUrl (navigateUrl);
-
-                       hLink.RenderBeginTag (writer);
-                       if (ControlStyleCreated)
-                               adImage.ApplyStyle(ControlStyle);
+               static readonly object AdCreatedEvent = new object ();
 
-                       if(imageUrl!=null && imageUrl.Length > 0)
-                               adImage.ImageUrl = ResolveAdUrl (imageUrl);
-
-                       adImage.AlternateText = alternateText;
-                       adImage.ToolTip = ToolTip;
-                       adImage.RenderControl (writer);
-                       hLink.RenderEndTag (writer);
-               }
-
-#if NET_2_0
-               AdType adType;
-               
-               [DefaultValueAttribute ("Banner")]
-               [WebCategoryAttribute ("Behavior")]
-               [WebSysDescriptionAttribute ("Advertisement of specific type is created by specified value")]
-               public AdType AdType {
-                       get { return adType; }
-                       set { adType = value; }
-               }
-
-               string alternateTextField;
-
-               [DefaultValueAttribute ("AlternateText")]
-               [WebCategoryAttribute ("Behavior")]
-               [WebSysDescriptionAttribute ("Alternate text is retrieved from the elmenet name specified.")]
-               //[VerificationAttribute ()]
-               public string AlternateTextField {
-                       get { return alternateTextField; }
-                       set { alternateTextField = value; }
-               }
-
-               bool countClicks;
-               
-               [DefaultValueAttribute (false)]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("On clicking an advertisement, click-through events should be counted.")]
-               public bool CountClicks {
-                       get { return countClicks; }
-                       set { countClicks = value; }
-               }
-
-               string counterGroup;
-               
-               [DefaultValueAttribute ("AdRotator")]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("Name of the group which takes care of counting.")]
-               public string CounterGroup {
-                       get { return counterGroup; }
-                       set { counterGroup = value; }
-               }
-
-               string counterName;
-
-               [DefaultValueAttribute ("")]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("Name of the group which takes care of counting.")]
-               public string CounterName {
-                       get { return counterName; }
-                       set { counterName = value; }
-               }
-
-               bool countViews;
-               
-               [DefaultValueAttribute (false)]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("On creation of an advertisement, view events should be counted.")]
-               public bool CountViews {
-                       get { return countViews; }
-                       set { countViews = value; }
-               }
-
-               string imageUrlField;
-
-               [DefaultValueAttribute ("ImageUrl")]
-               [WebCategoryAttribute ("Behavior")]
-               [WebSysDescriptionAttribute ("Image URL is retrieved from the elmenet name specified.")]
-               public string ImageUrlField {
-                       get { return imageUrlField; }
-                       set { imageUrlField = value; }
-               }
-
-               string navigateUrlField;
-
-               [DefaultValueAttribute ("NavigateUrl")]
-               [WebCategoryAttribute ("Behavior")]
-               [WebSysDescriptionAttribute ("Advertisement Web page URL is retrieved from the elmenet name specified.")]
-               public string NavigateUrlField {
-                       get { return navigateUrlField; }
-                       set { navigateUrlField = value; }
-               }
-
-               int popFrequency;
-
-               [DefaultValueAttribute ("100")]
-               [WebCategoryAttribute ("Behavior")]
-               [WebSysDescriptionAttribute ("Frequency in percentage for creation of Popup or PopUnder advertisement.")]
-               public int PopFrequency {
-                       get { return popFrequency; }
-                       set { popFrequency = value; }
-               }
-
-               int popPositionLeft;
-
-               [DefaultValueAttribute ("-1")]
-               [WebCategoryAttribute ("Appearance")]
-               [WebSysDescriptionAttribute ("Specifies X-coordinate in pixels of Popunder or Popup advertisements top-left corner.")]
-               public int PopPositionLeft {
-                       get { return popPositionLeft; }
-                       set { popPositionLeft = value; }
-               }
-
-               int popPositionTop;
-
-               [DefaultValueAttribute ("-1")]
-               [WebCategoryAttribute ("Appearance")]
-               [WebSysDescriptionAttribute ("Specifies Y-coordinate in pixels of Popunder or Popup advertisements top-left corner.")]
-               public int PopPositionTop {
-                       get { return popPositionTop; }
-                       set { popPositionTop = value; }
-               }
-
-               int rowsPerDay;
-
-               [DefaultValueAttribute ("-1")]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("On a given day this many number of rows of data needs to be collected.")]
-               public int RowsPerDay {
-                       get { return rowsPerDay; }
-                       set { rowsPerDay = value; }
-               }
-               string siteCountersProvider;
-
-               [DefaultValueAttribute ("")]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("Control uses the specified provider.")]
-               public string SiteCountersProvider {
-                       get { return siteCountersProvider; }
-                       set { siteCountersProvider = value; }
-               }
-
-               bool trackApplicationName;
-
-               [DefaultValueAttribute (true)]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the specified application name in a database.")]
-               public bool TrackApplicationName {
-                       get { return trackApplicationName; }
-                       set { trackApplicationName = value; }
-               }
-
-               bool trackNavigateUrl;
-
-               [DefaultValueAttribute (true)]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the destination URL of click through event in a database.")]
-               public bool TrackNavigateUrl {
-                       get { return trackNavigateUrl; }
-                       set { trackNavigateUrl = value; }
-               }
-
-               bool trackPageUrl;
-
-               [DefaultValueAttribute (true)]
-               [WebCategoryAttribute ("Site Counters")]
-               [WebSysDescriptionAttribute ("SiteCounters service tracks and stores the originating page URL in a database.")]
-               public bool TrackPageUrl {
-                       get { return trackPageUrl; }
-                       set { trackPageUrl = value; }
-               }
-#endif
-
-               class AdRecord
-               {
-                       public IDictionary Properties;
-                       public int Hits; // or impressions or clicks
-                       public string Keyword;
-
-                       public AdRecord (IDictionary adProps)
-                       {
-                               this.Properties = adProps;
-                               Keyword = Properties ["Keyword"] as string;
-                               if (Keyword == null)
-                                       Keyword = "";
-
-                               string imp = Properties ["Impressions"] as string;
-                               Hits = 1;
-                               if (imp != null) {
-                                       try {
-                                               Hits = Int32.Parse (imp);
-                                       } catch {
-                                       }
-                               }
-                       }
+               [WebSysDescription("")]
+               [WebCategory("Action")]
+               public event AdCreatedEventHandler AdCreated {
+                       add { Events.AddHandler (AdCreatedEvent, value); }
+                       remove { Events.RemoveHandler (AdCreatedEvent, value); }
                }
        }
 }
-