ResourceManager.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. //
  2. // System.Resources.ResourceManager.cs
  3. //
  4. // Authors:
  5. // Duncan Mak ([email protected])
  6. // Dick Porter ([email protected])
  7. //
  8. // (C) 2001, 2002 Ximian, Inc. http://www.ximian.com
  9. //
  10. using System.Collections;
  11. using System.Reflection;
  12. using System.Globalization;
  13. using System.IO;
  14. namespace System.Resources
  15. {
  16. [Serializable]
  17. public class ResourceManager
  18. {
  19. public static readonly int HeaderVersionNumber = 1;
  20. public static readonly int MagicNumber = unchecked((int)0xBEEFCACE);
  21. protected string BaseNameField;
  22. protected Assembly MainAssembly;
  23. // Maps cultures to ResourceSet objects
  24. protected Hashtable ResourceSets;
  25. private bool ignoreCase;
  26. private Type resourceSetType;
  27. private String resourceDir;
  28. /* Recursing through culture parents stops here */
  29. private CultureInfo neutral_culture;
  30. // constructors
  31. protected ResourceManager () {
  32. ResourceSets=new Hashtable();
  33. ignoreCase=false;
  34. resourceSetType=typeof(ResourceSet);
  35. resourceDir=null;
  36. neutral_culture=null;
  37. }
  38. public ResourceManager (Type resourceSource) : this()
  39. {
  40. if (resourceSource == null)
  41. throw new ArgumentNullException ("resourceSource is null.");
  42. BaseNameField = resourceSource.FullName;
  43. MainAssembly = resourceSource.Assembly;
  44. resourceSetType = resourceSource;
  45. neutral_culture = GetNeutralResourcesLanguage(MainAssembly);
  46. }
  47. public ResourceManager (string baseName, Assembly assembly) : this()
  48. {
  49. if (baseName == null)
  50. throw new ArgumentNullException ("baseName is null.");
  51. if(assembly == null)
  52. throw new ArgumentNullException ("assembly is null.");
  53. BaseNameField = baseName;
  54. MainAssembly = assembly;
  55. neutral_culture = GetNeutralResourcesLanguage(MainAssembly);
  56. }
  57. private Type CheckResourceSetType(Type usingResourceSet)
  58. {
  59. if(usingResourceSet==null) {
  60. return(typeof(ResourceSet));
  61. } else {
  62. if (!usingResourceSet.IsSubclassOf (typeof (ResourceSet)))
  63. throw new ArgumentException ("Type must be from ResourceSet.");
  64. return(usingResourceSet);
  65. }
  66. }
  67. public ResourceManager (string baseName, Assembly assembly, Type usingResourceSet) : this()
  68. {
  69. if (baseName == null)
  70. throw new ArgumentNullException ("baseName is null.");
  71. if(assembly == null)
  72. throw new ArgumentNullException ("assembly is null.");
  73. BaseNameField = baseName;
  74. MainAssembly = assembly;
  75. resourceSetType = CheckResourceSetType(usingResourceSet);
  76. neutral_culture = GetNeutralResourcesLanguage(MainAssembly);
  77. }
  78. /* Private constructor for CreateFileBasedResourceManager */
  79. private ResourceManager(String baseName, String resourceDir, Type usingResourceSet) : this()
  80. {
  81. if(baseName==null) {
  82. throw new ArgumentNullException("The base name is null");
  83. }
  84. if(baseName.EndsWith(".resources")) {
  85. throw new ArgumentException("The base name ends in '.resources'");
  86. }
  87. if(resourceDir==null) {
  88. throw new ArgumentNullException("The resourceDir is null");
  89. }
  90. BaseNameField = baseName;
  91. MainAssembly = null;
  92. resourceSetType = CheckResourceSetType(usingResourceSet);
  93. this.resourceDir = resourceDir;
  94. }
  95. public static ResourceManager CreateFileBasedResourceManager (string baseName,
  96. string resourceDir, Type usingResourceSet)
  97. {
  98. return new ResourceManager(baseName, resourceDir, usingResourceSet);
  99. }
  100. public virtual string BaseName
  101. {
  102. get { return BaseNameField; }
  103. }
  104. public virtual bool IgnoreCase
  105. {
  106. get { return ignoreCase; }
  107. set { ignoreCase = value; }
  108. }
  109. public virtual Type ResourceSetType
  110. {
  111. get { return resourceSetType; }
  112. }
  113. public virtual object GetObject(string name)
  114. {
  115. return(GetObject(name, null));
  116. }
  117. public virtual object GetObject(string name, CultureInfo culture)
  118. {
  119. if(name==null) {
  120. throw new ArgumentNullException("name is null");
  121. }
  122. if(culture==null) {
  123. culture=CultureInfo.CurrentUICulture;
  124. }
  125. lock(this) {
  126. ResourceSet set=InternalGetResourceSet(culture, true, true);
  127. object obj=null;
  128. if(set != null) {
  129. obj=set.GetObject(name, ignoreCase);
  130. if(obj != null) {
  131. return(obj);
  132. }
  133. }
  134. /* Try parent cultures */
  135. do {
  136. culture=culture.Parent;
  137. set=InternalGetResourceSet(culture, true, true);
  138. if(set!=null) {
  139. obj=set.GetObject(name, ignoreCase);
  140. if(obj != null) {
  141. return(obj);
  142. }
  143. }
  144. } while(!culture.Equals(neutral_culture) &&
  145. !culture.Equals(CultureInfo.InvariantCulture));
  146. }
  147. return(null);
  148. }
  149. public virtual ResourceSet GetResourceSet (CultureInfo culture,
  150. bool createIfNotExists, bool tryParents)
  151. {
  152. if (culture == null) {
  153. throw new ArgumentNullException ("CultureInfo is a null reference.");
  154. }
  155. lock(this) {
  156. return(InternalGetResourceSet(culture, createIfNotExists, tryParents));
  157. }
  158. }
  159. public virtual string GetString (string name)
  160. {
  161. return(GetString(name, null));
  162. }
  163. public virtual string GetString (string name, CultureInfo culture)
  164. {
  165. if (name == null) {
  166. throw new ArgumentNullException ("Name is null.");
  167. }
  168. if(culture==null) {
  169. culture=CultureInfo.CurrentUICulture;
  170. }
  171. lock(this) {
  172. ResourceSet set=InternalGetResourceSet(culture, true, true);
  173. string str=null;
  174. if(set!=null) {
  175. str=set.GetString(name, ignoreCase);
  176. if(str!=null) {
  177. return(str);
  178. }
  179. }
  180. /* Try parent cultures */
  181. do {
  182. culture=culture.Parent;
  183. set=InternalGetResourceSet(culture, true, true);
  184. if(set!=null) {
  185. str=set.GetString(name, ignoreCase);
  186. if(str!=null) {
  187. return(str);
  188. }
  189. }
  190. } while(!culture.Equals(neutral_culture) &&
  191. !culture.Equals(CultureInfo.InvariantCulture));
  192. }
  193. return(null);
  194. }
  195. protected virtual string GetResourceFileName (CultureInfo culture)
  196. {
  197. if(culture.Equals(CultureInfo.InvariantCulture)) {
  198. return(BaseNameField + ".resources");
  199. } else {
  200. return(BaseNameField + culture.Name + ".resources");
  201. }
  202. }
  203. protected virtual ResourceSet InternalGetResourceSet (CultureInfo culture, bool Createifnotexists, bool tryParents)
  204. {
  205. ResourceSet set;
  206. /* if we already have this resource set, return it */
  207. set=(ResourceSet)ResourceSets[culture];
  208. if(set!=null) {
  209. return(set);
  210. }
  211. if(MainAssembly != null) {
  212. /* Assembly resources */
  213. Stream stream;
  214. string filename=GetResourceFileName(culture);
  215. stream=MainAssembly.GetManifestResourceStream(filename);
  216. if(stream==null) {
  217. /* Try a satellite assembly */
  218. Version sat_version=GetSatelliteContractVersion(MainAssembly);
  219. Assembly a=MainAssembly.GetSatelliteAssembly(culture, sat_version);
  220. stream=a.GetManifestResourceStream(filename);
  221. }
  222. if(stream!=null && Createifnotexists==true) {
  223. object[] args=new Object[1];
  224. args[0]=stream;
  225. /* should we catch
  226. * MissingMethodException, or
  227. * just let someone else deal
  228. * with it?
  229. */
  230. set=(ResourceSet)Activator.CreateInstance(resourceSetType, args);
  231. }
  232. } else if(resourceDir != null) {
  233. /* File resources */
  234. string filename=Path.Combine(resourceDir, this.GetResourceFileName(culture));
  235. if(File.Exists(filename) &&
  236. Createifnotexists==true) {
  237. object[] args=new Object[1];
  238. args[0]=filename;
  239. /* should we catch
  240. * MissingMethodException, or
  241. * just let someone else deal
  242. * with it?
  243. */
  244. set=(ResourceSet)Activator.CreateInstance(resourceSetType, args);
  245. }
  246. }
  247. if(set==null && tryParents==true) {
  248. set=this.InternalGetResourceSet(culture.Parent, Createifnotexists, tryParents);
  249. }
  250. if(set!=null) {
  251. ResourceSets.Add(culture, set);
  252. }
  253. return(set);
  254. }
  255. public virtual void ReleaseAllResources ()
  256. {
  257. lock(this)
  258. {
  259. foreach (ResourceSet r in ResourceSets)
  260. r.Close();
  261. ResourceSets.Clear();
  262. }
  263. }
  264. protected static CultureInfo GetNeutralResourcesLanguage (Assembly a)
  265. {
  266. object[] attrs;
  267. attrs=a.GetCustomAttributes(typeof(NeutralResourcesLanguageAttribute), false);
  268. if(attrs.Length==0) {
  269. return(CultureInfo.InvariantCulture);
  270. } else {
  271. NeutralResourcesLanguageAttribute res_attr=(NeutralResourcesLanguageAttribute)attrs[0];
  272. return(new CultureInfo(res_attr.CultureName));
  273. }
  274. }
  275. protected static Version GetSatelliteContractVersion (Assembly a)
  276. {
  277. object[] attrs;
  278. attrs=a.GetCustomAttributes(typeof(SatelliteContractVersionAttribute), false);
  279. if(attrs.Length==0) {
  280. return(null);
  281. } else {
  282. SatelliteContractVersionAttribute sat_attr=(SatelliteContractVersionAttribute)attrs[0];
  283. /* Version(string) can throw
  284. * ArgumentException if the version is
  285. * invalid, but the spec for
  286. * GetSatelliteContractVersion says we
  287. * can throw the same exception for
  288. * the same reason, so dont bother to
  289. * catch it.
  290. */
  291. return(new Version(sat_attr.Version));
  292. }
  293. }
  294. }
  295. }