Almost eliminate wrong use of Constants.WsaNamespace.
[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                                         string providerName = DefaultProviderName;
65                                         lock (defaultProviderInitLock) {
66                                                 if (defaultProvider == null)
67                                                         defaultProvider = new InMemoryOutputCacheProvider ();
68                                         }
69                                 }
70
71                                 return defaultProvider;
72                         }
73                 }
74                 
75                 public static OutputCacheProviderCollection Providers {
76                         get {
77                                 Init ();
78                                 return providers;
79                         }
80                 }
81                 
82                 [SecurityPermission (SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)]
83                 public static object Deserialize (Stream stream)
84                 {
85                         if (stream == null)
86                                 throw new ArgumentNullException ("stream");
87
88                         object o = new BinaryFormatter ().Deserialize (stream);
89                         if (o == null || IsInvalidType (o))
90                                 throw new ArgumentException ("The provided parameter is not of a supported type for serialization and/or deserialization.");
91
92                         return o;
93                 }
94
95                 [SecurityPermission (SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)]
96                 public static void Serialize (Stream stream, object data)
97                 {
98                         if (stream == null)
99                                 throw new ArgumentNullException ("stream");                     
100
101                         // LAMESPEC: data == null doesn't throw ArgumentNullException
102                         if (data == null || IsInvalidType (data))
103                                 throw new ArgumentException ("The provided parameter is not of a supported type for serialization and/or deserialization.");
104                         
105                         new BinaryFormatter ().Serialize (stream, data);
106                 }
107
108                 internal static OutputCacheProvider GetProvider (string providerName)
109                 {
110                         if (String.IsNullOrEmpty (providerName))
111                                 return null;
112
113                         if (String.Compare (providerName, DEFAULT_PROVIDER_NAME, StringComparison.Ordinal) == 0)
114                                 return DefaultProvider;
115
116                         OutputCacheProviderCollection providers = OutputCache.Providers;
117                         return (providers != null ? providers [providerName] : null);
118                 }
119                 
120                 static bool IsInvalidType (object data)
121                 {
122                         return !(data is MemoryResponseElement) &&
123                                 !(data is FileResponseElement) &&
124                                 !(data is SubstitutionResponseElement);
125                 }
126                 
127                 static void Init ()
128                 {
129                         if (initialized)
130                                 return;
131
132                         lock (initLock) {
133                                 if (initialized)
134                                         return;
135                                 
136                                 var cfg = WebConfigurationManager.GetWebApplicationSection ("system.web/caching/outputCache") as OutputCacheSection;
137                                 ProviderSettingsCollection cfgProviders = cfg.Providers;
138
139                                 defaultProviderName = cfg.DefaultProviderName;
140                                 if (cfgProviders != null && cfgProviders.Count > 0) {
141                                         var coll = new OutputCacheProviderCollection ();
142
143                                         foreach (ProviderSettings ps in cfgProviders)
144                                                 coll.Add (LoadProvider (ps));
145
146                                         coll.SetReadOnly ();
147                                         providers = coll;
148                                 }
149
150                                 initialized = true;
151                         }
152                 }
153
154                 static OutputCacheProvider LoadProvider (ProviderSettings ps)
155                 {
156                         Type type = HttpApplication.LoadType (ps.Type, false);
157                         if (type == null)
158                                 throw new ConfigurationErrorsException (String.Format ("Could not load type '{0}'.", ps.Type));
159                         
160                         var ret = Activator.CreateInstance (type) as OutputCacheProvider;
161                         ret.Initialize (ps.Name, ps.Parameters);
162
163                         return ret;
164                 }
165
166                 internal static void RemoveFromProvider (string key, string providerName)
167                 {
168                         if (providerName == null)
169                                 return;
170
171                         OutputCacheProviderCollection providers = Providers;
172                         OutputCacheProvider provider;
173                         
174                         if (providers == null || providers.Count == 0)
175                                 provider = null;
176                         else
177                                 provider = providers [providerName];
178
179                         if (provider == null)
180                                 throw new ProviderException ("Provider '" + providerName + "' was not found.");
181
182                         provider.Remove (key);
183                 }
184         }
185 }