System.Web.Configuration.(AdapterDictionary,AuthenticationMode,MachineKeyValidation...
[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                 internal string ProviderName {
105                         get; set;
106                 }
107                 internal abstract Control CreateControl ();
108
109                 public override void Dispose ()
110                 {
111                         if (dependency != null) {
112                                 dependency.Dispose ();
113                                 dependency = null;
114                         }
115                 }
116
117                 void RetrieveCachedContents ()
118                 {
119                         cacheKey = CreateKey ();
120                         OutputCacheProvider provider = GetProvider ();
121                         cachedData = provider.Get (cacheKey) as string;
122                 }
123                 OutputCacheProvider GetProvider ()
124                 {
125                         string providerName = ProviderName;
126                         OutputCacheProvider provider;
127
128                         if (String.IsNullOrEmpty (providerName))
129                                 provider = OutputCache.DefaultProvider;
130                         else {
131                                 provider = OutputCache.GetProvider (providerName);
132                                 if (provider == null)
133                                         provider = OutputCache.DefaultProvider;
134                         }
135
136                         return provider;
137                 }
138                 
139                 void OnDependencyChanged (string key, object value, CacheItemRemovedReason reason)
140                 {
141                         Console.WriteLine ("{0}.OnDependencyChanged (\"{0}\", {1}, {2})", this, key, value, reason);
142                         GetProvider ().Remove (key);
143                 }
144                 
145                 internal override void InitRecursive (Control namingContainer)
146                 {
147                         RetrieveCachedContents ();
148                         if (cachedData == null) {
149                                 control = CreateControl ();
150                                 Controls.Add (control);
151                         } else
152                                 control = null;
153                         
154                         base.InitRecursive (namingContainer);
155                 }
156                 protected internal override void Render (HtmlTextWriter output)
157                 {
158                         if (cachedData != null) {
159                                 output.Write (cachedData);
160                                 return;
161                         }
162
163                         if (control == null) {
164                                 base.Render (output);
165                                 return;
166                         }
167                         
168                         HttpContext context = HttpContext.Current;
169                         StringWriter writer = new StringWriter ();
170                         TextWriter prev = context.Response.SetTextWriter (writer);
171                         HtmlTextWriter txt_writer = new HtmlTextWriter (writer);
172                         string text;
173                         try {
174                                 control.RenderControl (txt_writer);
175                         } finally {
176                                 text = writer.ToString ();
177                                 context.Response.SetTextWriter (prev);
178                                 output.Write (text);
179                         }
180                         OutputCacheProvider provider = GetProvider ();
181                         DateTime utcExpire = DateTime.UtcNow.AddSeconds (duration);
182                         provider.Set (cacheKey, text, utcExpire);;
183                         context.InternalCache.Insert (cacheKey, text, dependency, utcExpire.ToLocalTime (),
184                                                       Cache.NoSlidingExpiration, CacheItemPriority.Normal,
185                                                       null);
186                 }
187
188                 public ControlCachePolicy CachePolicy 
189                 {
190                         get {
191                                 if (cachePolicy == null)
192                                         cachePolicy = new ControlCachePolicy (this);
193
194                                 return cachePolicy;
195                         }
196                 }
197
198                 public CacheDependency Dependency {
199                         get {return dependency;}
200                         set {dependency = value;}
201                 }
202
203                 string CreateKey ()
204                 {
205                         StringBuilder builder = new StringBuilder ();
206                         HttpContext context = HttpContext.Current;
207
208                         builder.Append ("PartialCachingControl\n");
209                         builder.Append ("GUID: " + guid + "\n");
210
211                         if (varyby_params != null && varyby_params.Length > 0) {
212                                 string[] prms = varyby_params.Split (';');
213                                 for (int i=0; i<prms.Length; i++) {
214                                         string val = context.Request.Params [prms [i]];
215                                         builder.Append ("VP:");
216                                         builder.Append (prms [i]);
217                                         builder.Append ('=');
218                                         builder.Append (val != null ? val : "__null__");
219                                         builder.Append ('\n');
220                                 }
221                         }
222
223                         if (varyby_controls != null && varyby_params.Length > 0) {
224                                 string[] prms = varyby_controls.Split (';');
225                                 for (int i=0; i<prms.Length; i++) {
226                                         string val = context.Request.Params [prms [i]];
227                                         builder.Append ("VCN:");
228                                         builder.Append (prms [i]);
229                                         builder.Append ('=');
230                                         builder.Append (val != null ? val : "__null__");
231                                         builder.Append ('\n');
232                                 }
233                         }
234
235                         if (varyby_custom != null) {
236                                 string val = context.ApplicationInstance.GetVaryByCustomString (context,
237                                                 varyby_custom);
238                                 builder.Append ("VC:");
239                                 builder.Append (varyby_custom);
240                                 builder.Append ('=');
241                                 builder.Append (val != null ? val : "__null__");
242                                 builder.Append ('\n');
243                         }
244
245                         return builder.ToString ();
246                 }
247         }
248 }
249