9f286a0847df95e148360926d5579486f95a1e1a
[mono.git] / mcs / class / System.Web / System.Web.Compilation / DefaultResourceProvider.cs
1 // DefaultResourceProvider.cs
2 //
3 // Authors:
4 //      Marek Habersack (mhabersack@novell.com)
5 //
6 // (C) 2009 Novell, Inc (http://novell.com)
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 #if NET_2_0
29 using System;
30 using System.Collections.Generic;
31 using System.Globalization;
32 using System.IO;
33 using System.Resources;
34 using System.Reflection;
35 using System.Web;
36
37 namespace System.Web.Compilation
38 {
39         sealed class DefaultResourceProvider : IResourceProvider
40         {
41                 sealed class ResourceManagerCacheKey
42                 {
43                         readonly string _name;
44                         readonly Assembly _asm;
45
46                         public ResourceManagerCacheKey (string name, Assembly asm)
47                         {
48                                 _name = name;
49                                 _asm = asm;
50                         }
51
52                         public override bool Equals (object obj)
53                         {
54                                 if (!(obj is ResourceManagerCacheKey))
55                                         return false;
56                                 ResourceManagerCacheKey key = (ResourceManagerCacheKey) obj;
57                                 return key._asm == _asm && _name.Equals (key._name, StringComparison.Ordinal);
58                         }
59
60                         public override int GetHashCode ()
61                         {
62                                 return _name.GetHashCode () + _asm.GetHashCode ();
63                         }
64                 }
65                 
66                 [ThreadStatic]
67                 static Dictionary <ResourceManagerCacheKey, ResourceManager> resourceManagerCache;
68                 
69                 string resource;
70                 bool isGlobal;
71                 
72                 public IResourceReader ResourceReader {
73                         get {
74                                 Assembly asm;
75                                 string path;
76                                         
77                                 if (isGlobal) {
78                                         asm = HttpContext.AppGlobalResourcesAssembly;
79                                         path = resource;
80                                 } else {
81                                         asm = GetLocalResourcesAssembly ();
82                                         path = Path.GetFileName (resource);
83
84                                         if (String.IsNullOrEmpty (path))
85                                                 return null;
86
87                                         path += ".resources";
88                                 }
89                                                         
90                                 if (asm == null)
91                                         return null;
92
93                                 Stream ms = asm.GetManifestResourceStream (path);
94                                 if (ms == null)
95                                         return null;
96                                 
97                                 return new ResourceReader (ms);
98                         }
99                 }
100                 
101                 public DefaultResourceProvider (string resource, bool isGlobal)
102                 {
103                         if (String.IsNullOrEmpty (resource))
104                                 throw new ArgumentNullException ("resource");
105                         
106                         this.resource = resource;
107                         this.isGlobal = isGlobal;
108                 }
109
110                 public object GetObject (string resourceKey, CultureInfo culture)
111                 {
112                         if (String.IsNullOrEmpty (resourceKey))
113                                 return null;
114                         
115                         ResourceManager rm = GetResourceManager ();
116                         if (rm == null)
117                                 return null;
118
119                         return rm.GetObject (resourceKey, culture);
120                 }
121
122                 Assembly GetLocalResourcesAssembly ()
123                 {
124                         string path;
125                         Assembly asm;
126
127                         path = VirtualPathUtility.GetDirectory (resource);
128                         asm = AppResourcesCompiler.GetCachedLocalResourcesAssembly (path);
129                         if (asm == null) {
130                                 AppResourcesCompiler ac = new AppResourcesCompiler (path);
131                                 asm = ac.Compile ();
132                                 if (asm == null)
133                                         throw new MissingManifestResourceException ("A resource object was not found at the specified virtualPath.");
134                         }
135
136                         return asm;
137                 }
138                 
139                 ResourceManager GetResourceManager ()
140                 {
141                         string path;
142                         Assembly asm;
143
144                         if (isGlobal) {
145                                 asm = HttpContext.AppGlobalResourcesAssembly;
146                                 path = resource;
147                         } else {
148                                 asm = GetLocalResourcesAssembly ();
149                                 path = Path.GetFileName (resource);
150
151                                 if (String.IsNullOrEmpty (path))
152                                         return null;
153                         }
154
155                         if (asm == null)
156                                 return null;
157                         
158                         ResourceManager rm;
159                         try {
160                                 if (resourceManagerCache == null)
161                                         resourceManagerCache = new Dictionary <ResourceManagerCacheKey, ResourceManager> ();
162                                 
163                                 ResourceManagerCacheKey key = new ResourceManagerCacheKey (path, asm);
164                                 if (!resourceManagerCache.TryGetValue (key, out rm)) {
165                                         rm = new ResourceManager (path, asm);
166                                         rm.IgnoreCase = true;
167                                         resourceManagerCache.Add (key, rm);
168                                 }
169                                 
170                                 return rm;
171                         } catch (MissingManifestResourceException) {
172                                 throw;
173                         } catch (Exception ex) {
174                                 throw new HttpException ("Failed to retrieve the specified global resource object.", ex);
175                         }
176                 }
177         }
178 }
179 #endif