2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[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                                 return null;
75                         }
76                 }
77                 
78                 public DefaultResourceProvider (string resource, bool isGlobal)
79                 {
80                         if (String.IsNullOrEmpty (resource))
81                                 throw new ArgumentNullException ("resource");
82                         
83                         this.resource = resource;
84                         this.isGlobal = isGlobal;
85                 }
86
87                 public object GetObject (string resourceKey, CultureInfo culture)
88                 {
89                         if (isGlobal) {
90                                 if (HttpContext.AppGlobalResourcesAssembly == null)
91                                         return null;
92                                 
93                                 return GetResourceObject (resource, resourceKey, culture, HttpContext.AppGlobalResourcesAssembly);
94                         }
95
96                         string path = VirtualPathUtility.GetDirectory (resource);
97                         Assembly asm = AppResourcesCompiler.GetCachedLocalResourcesAssembly (path);
98                         if (asm == null) {
99                                 AppResourcesCompiler ac = new AppResourcesCompiler (path);
100                                 asm = ac.Compile ();
101                                 if (asm == null)
102                                         throw new MissingManifestResourceException ("A resource object was not found at the specified virtualPath.");
103                         }
104                         
105                         path = Path.GetFileName (resource);
106                         return GetResourceObject (path, resourceKey, culture, asm);
107                 }
108
109                 static object GetResourceObject (string classKey, string resourceKey, CultureInfo culture, Assembly assembly)
110                 {
111                         ResourceManager rm;
112                         try {
113                                 if (resourceManagerCache == null)
114                                         resourceManagerCache = new Dictionary <ResourceManagerCacheKey, ResourceManager> ();
115                                 
116                                 ResourceManagerCacheKey key = new ResourceManagerCacheKey (classKey, assembly);
117                                 if (!resourceManagerCache.TryGetValue (key, out rm)) {
118                                         rm = new ResourceManager (classKey, assembly);
119                                         rm.IgnoreCase = true;
120                                         resourceManagerCache.Add (key, rm);
121                                 }
122                                 
123                                 return rm.GetObject (resourceKey, culture);
124                         } catch (MissingManifestResourceException) {
125                                 throw;
126                         } catch (Exception ex) {
127                                 throw new HttpException ("Failed to retrieve the specified global resource object.", ex);
128                         }
129                 }
130         }
131 }
132 #endif