[System.Web] Reference source import
[mono.git] / mcs / class / System.Web / System.Web.Caching / OutputCache.cs
1 //
2 // Authors:
3 //   Marek Habersack <mhabersack@novell.com>
4 //
5 // (C) 2010 Novell, Inc (http://novell.com/)
6 //
7
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.Configuration;
30 using System.Configuration.Provider;
31 using System.IO;
32 using System.Runtime.Serialization.Formatters.Binary;
33 using System.Security.Permissions;
34 using System.Web;
35 using System.Web.Configuration;
36
37 namespace System.Web.Caching
38 {
39         public static class OutputCache
40         {
41                 internal const string DEFAULT_PROVIDER_NAME = "AspNetInternalProvider";
42                 
43                 static readonly object initLock = new object ();
44                 static readonly object defaultProviderInitLock = new object();
45                 
46                 static bool initialized;
47                 static string defaultProviderName;
48                 static OutputCacheProviderCollection providers;
49                 static OutputCacheProvider defaultProvider;
50                 
51                 public static string DefaultProviderName {
52                         get {
53                                 Init ();
54                                 if (String.IsNullOrEmpty (defaultProviderName))
55                                         return DEFAULT_PROVIDER_NAME;
56                                 
57                                 return defaultProviderName;
58                         }
59                 }
60
61                 internal static OutputCacheProvider DefaultProvider {
62                         get {
63                                 if (defaultProvider == null) {
64                                         lock (defaultProviderInitLock) {
65                                                 if (defaultProvider == null)
66                                                         defaultProvider = new InMemoryOutputCacheProvider ();
67                                         }
68                                 }
69
70                                 return defaultProvider;
71                         }
72                 }
73                 
74                 public static OutputCacheProviderCollection Providers {
75                         get {
76                                 Init ();
77                                 return providers;
78                         }
79                 }
80                 
81                 [SecurityPermission (SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)]
82                 public static object Deserialize (Stream stream)
83                 {
84                         if (stream == null)
85                                 throw new ArgumentNullException ("stream");
86
87                         object o = new BinaryFormatter ().Deserialize (stream);
88                         if (o == null || IsInvalidType (o))
89                                 throw new ArgumentException ("The provided parameter is not of a supported type for serialization and/or deserialization.");
90
91                         return o;
92                 }
93
94                 [SecurityPermission (SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)]
95                 public static void Serialize (Stream stream, object data)
96                 {
97                         if (stream == null)
98                                 throw new ArgumentNullException ("stream");                     
99
100                         // LAMESPEC: data == null doesn't throw ArgumentNullException
101                         if (data == null || IsInvalidType (data))
102                                 throw new ArgumentException ("The provided parameter is not of a supported type for serialization and/or deserialization.");
103                         
104                         new BinaryFormatter ().Serialize (stream, data);
105                 }
106
107                 internal static OutputCacheProvider GetProvider (string providerName)
108                 {
109                         if (String.IsNullOrEmpty (providerName))
110                                 return null;
111
112                         if (String.Compare (providerName, DEFAULT_PROVIDER_NAME, StringComparison.Ordinal) == 0)
113                                 return DefaultProvider;
114
115                         OutputCacheProviderCollection providers = OutputCache.Providers;
116                         return (providers != null ? providers [providerName] : null);
117                 }
118                 
119                 static bool IsInvalidType (object data)
120                 {
121                         return !(data is MemoryResponseElement) &&
122                                 !(data is FileResponseElement) &&
123                                 !(data is SubstitutionResponseElement);
124                 }
125                 
126                 static void Init ()
127                 {
128                         if (initialized)
129                                 return;
130
131                         lock (initLock) {
132                                 if (initialized)
133                                         return;
134                                 
135                                 var cfg = WebConfigurationManager.GetWebApplicationSection ("system.web/caching/outputCache") as OutputCacheSection;
136                                 ProviderSettingsCollection cfgProviders = cfg.Providers;
137
138                                 defaultProviderName = cfg.DefaultProviderName;
139                                 if (cfgProviders != null && cfgProviders.Count > 0) {
140                                         var coll = new OutputCacheProviderCollection ();
141
142                                         foreach (ProviderSettings ps in cfgProviders)
143                                                 coll.Add (LoadProvider (ps));
144
145                                         coll.SetReadOnly ();
146                                         providers = coll;
147                                 }
148
149                                 initialized = true;
150                         }
151                 }
152
153                 static OutputCacheProvider LoadProvider (ProviderSettings ps)
154                 {
155                         Type type = HttpApplication.LoadType (ps.Type, false);
156                         if (type == null)
157                                 throw new ConfigurationErrorsException (String.Format ("Could not load type '{0}'.", ps.Type));
158                         
159                         var ret = Activator.CreateInstance (type) as OutputCacheProvider;
160                         ret.Initialize (ps.Name, ps.Parameters);
161
162                         return ret;
163                 }
164
165                 internal static void RemoveFromProvider (string key, string providerName)
166                 {
167                         if (providerName == null)
168                                 return;
169
170                         OutputCacheProviderCollection providers = Providers;
171                         OutputCacheProvider provider;
172                         
173                         if (providers == null || providers.Count == 0)
174                                 provider = null;
175                         else
176                                 provider = providers [providerName];
177
178                         if (provider == null)
179                                 throw new ProviderException ("Provider '" + providerName + "' was not found.");
180
181                         provider.Remove (key);
182                 }
183         }
184 }