[asp.net] Removed the DEBUG ifdefs, for the tests to compile.
[mono.git] / mcs / class / System.Web / System.Web.UI / BasePartialCachingControl.cs
1 //
2 // System.Web.UI.BasePartialCachingControl.cs
3 //
4 // Author:
5 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
6 //   Jackson Harper (jackson@ximian.com)
7 //
8 // (C) 2003 Andreas Nahr
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.IO;
32 using System.Text;
33 using System.ComponentModel;
34 using System.Security.Permissions;
35 using System.Web.Caching;
36
37 namespace System.Web.UI
38 {
39         // CAS
40         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42         // attributes
43         [ToolboxItem (false)]
44         public abstract class BasePartialCachingControl : Control
45         {
46                 CacheDependency dependency;
47                 string ctrl_id;
48                 string guid;
49                 int duration;
50                 string varyby_params;
51                 string varyby_controls;
52                 string varyby_custom;
53                 DateTime expirationTime;
54                 bool slidingExpiration;
55                 
56                 Control control;
57                 ControlCachePolicy cachePolicy;
58                 string cacheKey;
59                 string cachedData;
60                 
61                 protected BasePartialCachingControl()
62                 {
63                 }
64
65                 internal string CtrlID {
66                         get { return ctrl_id; }
67                         set { ctrl_id = value; }
68                 }
69
70                 internal string Guid {
71                         get { return guid; }
72                         set { guid = value; }
73                 }
74
75                 internal int Duration {
76                         get { return duration; }
77                         set { duration = value; }
78                 }
79
80                 internal string VaryByParams {
81                         get { return varyby_params; }
82                         set { varyby_params = value; }
83                 }
84
85                 internal string VaryByControls {
86                         get { return varyby_controls; }
87                         set { varyby_controls = value; }
88                 }
89
90                 internal string VaryByCustom {
91                         get { return varyby_custom; }
92                         set { varyby_custom = value; }
93                 }
94
95                 internal DateTime ExpirationTime {
96                         get { return expirationTime; }
97                         set { expirationTime = value; }
98                 }
99
100                 internal bool SlidingExpiration {
101                         get { return slidingExpiration; }
102                         set { slidingExpiration = value; }
103                 }
104 #if NET_4_0
105                 internal string ProviderName {
106                         get; set;
107                 }
108 #endif
109                 internal abstract Control CreateControl ();
110
111                 public override void Dispose ()
112                 {
113                         if (dependency != null) {
114                                 dependency.Dispose ();
115                                 dependency = null;
116                         }
117                 }
118
119                 void RetrieveCachedContents ()
120                 {
121                         cacheKey = CreateKey ();
122 #if NET_4_0
123                         OutputCacheProvider provider = GetProvider ();
124                         cachedData = provider.Get (cacheKey) as string;
125 #else
126                         Cache cache = HttpRuntime.InternalCache;
127                         cachedData = cache [cacheKey] as string;
128 #endif
129                 }
130 #if NET_4_0
131                 OutputCacheProvider GetProvider ()
132                 {
133                         string providerName = ProviderName;
134                         OutputCacheProvider provider;
135
136                         if (String.IsNullOrEmpty (providerName))
137                                 provider = OutputCache.DefaultProvider;
138                         else {
139                                 provider = OutputCache.GetProvider (providerName);
140                                 if (provider == null)
141                                         provider = OutputCache.DefaultProvider;
142                         }
143
144                         return provider;
145                 }
146                 
147                 void OnDependencyChanged (string key, object value, CacheItemRemovedReason reason)
148                 {
149                         Console.WriteLine ("{0}.OnDependencyChanged (\"{0}\", {1}, {2})", this, key, value, reason);
150                         GetProvider ().Remove (key);
151                 }
152                 
153                 internal override void InitRecursive (Control namingContainer)
154                 {
155                         RetrieveCachedContents ();
156                         if (cachedData == null) {
157                                 control = CreateControl ();
158                                 Controls.Add (control);
159                         } else
160                                 control = null;
161                         
162                         base.InitRecursive (namingContainer);
163                 }
164 #else
165                 protected internal override void OnInit (EventArgs e)
166                 {
167                         control = CreateControl ();
168                         Controls.Add (control);
169                 }
170 #endif
171                 protected internal override void Render (HtmlTextWriter output)
172                 {
173 #if !NET_4_0
174                         RetrieveCachedContents ();
175 #endif
176                         if (cachedData != null) {
177                                 output.Write (cachedData);
178                                 return;
179                         }
180
181                         if (control == null) {
182                                 base.Render (output);
183                                 return;
184                         }
185                         
186                         HttpContext context = HttpContext.Current;
187                         StringWriter writer = new StringWriter ();
188                         TextWriter prev = context.Response.SetTextWriter (writer);
189                         HtmlTextWriter txt_writer = new HtmlTextWriter (writer);
190                         string text;
191                         try {
192                                 control.RenderControl (txt_writer);
193                         } finally {
194                                 text = writer.ToString ();
195                                 context.Response.SetTextWriter (prev);
196                                 output.Write (text);
197                         }
198 #if NET_4_0
199                         OutputCacheProvider provider = GetProvider ();
200                         DateTime utcExpire = DateTime.UtcNow.AddSeconds (duration);
201                         provider.Set (cacheKey, text, utcExpire);;
202                         context.InternalCache.Insert (cacheKey, text, dependency, utcExpire.ToLocalTime (),
203                                                       Cache.NoSlidingExpiration, CacheItemPriority.Normal,
204                                                       null);
205 #else
206                         context.InternalCache.Insert (cacheKey, text, dependency,
207                                                       DateTime.Now.AddSeconds (duration),
208                                                       Cache.NoSlidingExpiration,
209                                                       CacheItemPriority.Normal, null);
210 #endif
211                 }
212
213                 public ControlCachePolicy CachePolicy 
214                 {
215                         get {
216                                 if (cachePolicy == null)
217                                         cachePolicy = new ControlCachePolicy (this);
218
219                                 return cachePolicy;
220                         }
221                 }
222
223                 public CacheDependency Dependency {
224                         get {return dependency;}
225                         set {dependency = value;}
226                 }
227
228                 string CreateKey ()
229                 {
230                         StringBuilder builder = new StringBuilder ();
231                         HttpContext context = HttpContext.Current;
232
233                         builder.Append ("PartialCachingControl\n");
234                         builder.Append ("GUID: " + guid + "\n");
235
236                         if (varyby_params != null && varyby_params.Length > 0) {
237                                 string[] prms = varyby_params.Split (';');
238                                 for (int i=0; i<prms.Length; i++) {
239                                         string val = context.Request.Params [prms [i]];
240                                         builder.Append ("VP:");
241                                         builder.Append (prms [i]);
242                                         builder.Append ('=');
243                                         builder.Append (val != null ? val : "__null__");
244                                         builder.Append ('\n');
245                                 }
246                         }
247
248                         if (varyby_controls != null && varyby_params.Length > 0) {
249                                 string[] prms = varyby_controls.Split (';');
250                                 for (int i=0; i<prms.Length; i++) {
251                                         string val = context.Request.Params [prms [i]];
252                                         builder.Append ("VCN:");
253                                         builder.Append (prms [i]);
254                                         builder.Append ('=');
255                                         builder.Append (val != null ? val : "__null__");
256                                         builder.Append ('\n');
257                                 }
258                         }
259
260                         if (varyby_custom != null) {
261                                 string val = context.ApplicationInstance.GetVaryByCustomString (context,
262                                                 varyby_custom);
263                                 builder.Append ("VC:");
264                                 builder.Append (varyby_custom);
265                                 builder.Append ('=');
266                                 builder.Append (val != null ? val : "__null__");
267                                 builder.Append ('\n');
268                         }
269
270                         return builder.ToString ();
271                 }
272         }
273 }
274