Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
ResourceManagerCache.cs245 linesDownload Raw Back to utils
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Reflection;6using System.Resources;7 8namespace System.Management.Automation9{10    /// <summary>11    /// </summary>12    internal static class ResourceManagerCache13    {14        /// <summary>15        /// Maintains a cache of ResourceManager objects. This is a dictionary that is keyed based on the path16        /// to the default resource assembly. The value is another dictionary that is keyed based on the base17        /// name for the resource that is being retrieved. The value for this dictionary is the ResourceManager.18        /// </summary>19        private static readonly Dictionary<string, Dictionary<string, ResourceManager>> s_resourceManagerCache =20            new Dictionary<string, Dictionary<string, ResourceManager>>(StringComparer.OrdinalIgnoreCase);21 22        /// <summary>23        /// Used to synchronize access to the ResourceManagerCache.24        /// </summary>25        private static readonly object s_syncRoot = new object();26 27        /// <summary>28        /// Gets the ResourceManager from the cache or gets an instance of the ResourceManager29        /// and returns it if it isn't already present in the cache.30        /// </summary>31        /// <param name="assembly">32        /// The assembly to be used as the base for resource lookup.33        /// </param>34        /// <param name="baseName">35        /// The base name of the resources to get the ResourceManager for.36        /// </param>37        /// <returns>38        /// A ResourceManager instance for the assembly and base name that were specified.39        /// </returns>40        internal static ResourceManager GetResourceManager(41            Assembly assembly,42            string baseName)43        {44            if (assembly == null)45            {46                throw PSTraceSource.NewArgumentNullException(nameof(assembly));47            }48 49            if (string.IsNullOrEmpty(baseName))50            {51                throw PSTraceSource.NewArgumentException(nameof(baseName));52            }53 54            // Check to see if the manager is already in the cache55 56            ResourceManager manager = null;57            Dictionary<string, ResourceManager> baseNameCache;58 59            string assemblyManifestFileLocation = assembly.Location;60            lock (s_syncRoot)61            {62                // First do the lookup based on the assembly location63 64                if (s_resourceManagerCache.TryGetValue(assemblyManifestFileLocation, out baseNameCache) && baseNameCache != null)65                {66                    // Now do the lookup based on the resource base name67                    baseNameCache.TryGetValue(baseName, out manager);68                }69            }70 71            // If it's not in the cache, create it an add it.72            if (manager == null)73            {74                manager = InitRMWithAssembly(baseName, assembly);75 76                // Add the new resource manager to the hash77 78                if (baseNameCache != null)79                {80                    lock (s_syncRoot)81                    {82                        // Since the assembly is already cached, we just have83                        // to cache the base name entry84 85                        baseNameCache[baseName] = manager;86                    }87                }88                else89                {90                    // Since the assembly wasn't cached, we have to create base name91                    // cache entry and then add it into the cache keyed by the assembly92                    // location93 94                    var baseNameCacheEntry = new Dictionary<string, ResourceManager>();95 96                    baseNameCacheEntry[baseName] = manager;97 98                    lock (s_syncRoot)99                    {100                        s_resourceManagerCache[assemblyManifestFileLocation] = baseNameCacheEntry;101                    }102                }103            }104 105            Diagnostics.Assert(106                manager != null,107                "If the manager was not already created, it should have been dynamically created or an exception should have been thrown");108 109            return manager;110        }111 112        /// <summary>113        /// Design For Testability -- assert on failed resource lookup.114        /// </summary>115        private static bool s_DFT_monitorFailingResourceLookup = true;116 117        internal static bool DFT_DoMonitorFailingResourceLookup118        {119            get { return ResourceManagerCache.s_DFT_monitorFailingResourceLookup; }120 121            set { ResourceManagerCache.s_DFT_monitorFailingResourceLookup = value; }122        }123 124        /// <summary>125        /// Gets the string from the resource manager based on the assembly,126        /// base name, resource ID, and culture specified.127        /// </summary>128        /// <param name="assembly">129        /// The base assembly from which to get the resources from.130        /// </param>131        /// <param name="baseName">132        /// The base name of the resource to retrieve the string from.133        /// </param>134        /// <param name="resourceId">135        /// Resource ID for which the localized string needs to be retrieved136        /// </param>137        /// <returns>138        /// Localized String, or null if the string does not exist139        /// </returns>140        /// <remarks>141        /// The current thread's UI culture is used.142        /// </remarks>143        /// <throws>144        /// ArgumentException if <paramref name="baseName"/> or <paramref name="resourceId"/>145        ///     are null or empty..146        /// InvalidOperationException if the value of the specified resource is not a string147        /// MissingManifestResourceException if no usable set of resources have been found, and148        ///     there are no neutral culture resources.149        /// </throws>150        internal static string GetResourceString(151            Assembly assembly,152            string baseName,153            string resourceId)154        {155            if (assembly == null)156            {157                throw PSTraceSource.NewArgumentNullException(nameof(assembly));158            }159 160            if (string.IsNullOrEmpty(baseName))161            {162                throw PSTraceSource.NewArgumentException(nameof(baseName));163            }164 165            if (string.IsNullOrEmpty(resourceId))166            {167                throw PSTraceSource.NewArgumentException(nameof(resourceId));168            }169 170            ResourceManager resourceManager = null;171            string text = string.Empty;172 173            // For a non-existing resource defined by {assembly,baseName,resourceId}174            // MissingManifestResourceException is thrown only at the time when resource retrieval method175            // such as ResourceManager.GetString or ResourceManager.GetObject is called,176            // not when you instantiate a ResourceManager object.177            try178            {179                // try with original baseName first180                // if it fails then try with alternative resource path format181                resourceManager = GetResourceManager(assembly, baseName);182                text = resourceManager.GetString(resourceId);183            }184            catch (MissingManifestResourceException)185            {186                const string resourcesSubstring = ".resources.";187                int resourcesSubstringIndex = baseName.IndexOf(resourcesSubstring);188                string newBaseName = string.Empty;189                if (resourcesSubstringIndex != -1)190                {191                    newBaseName = baseName.Substring(resourcesSubstringIndex + resourcesSubstring.Length); // e.g.  "FileSystemProviderStrings"192                }193                else194                {195                    newBaseName = string.Concat(assembly.GetName().Name, resourcesSubstring, baseName); // e.g. "System.Management.Automation.resources.FileSystemProviderStrings"196                }197 198                resourceManager = GetResourceManager(assembly, newBaseName);199                text = resourceManager.GetString(resourceId);200            }201 202            if (string.IsNullOrEmpty(text) && s_DFT_monitorFailingResourceLookup)203            {204                Diagnostics.Assert(false,205                    "Lookup failure: baseName " + baseName + " resourceId " + resourceId);206            }207 208            return text;209        }210 211        /// <summary>212        /// Creates a Resource manager instance based on the assembly specified.213        /// </summary>214        /// <param name="baseName">215        /// The root name of the resources.216        /// For example, the root name for the resource file217        /// named "MyResource.en-US.resources" is "MyResource".218        /// </param>219        /// <param name="assemblyToUse">220        /// The main Assembly for the resources221        /// </param>222        /// <returns>Resource Manager instance.</returns>223        /// <exception cref="ArgumentException">224        /// Thrown if the resource manager instance could not be created225        /// </exception>226        private static ResourceManager InitRMWithAssembly(string baseName, Assembly assemblyToUse)227        {228            ResourceManager rm = null;229 230            if (baseName != null && assemblyToUse != null)231            {232                rm = new ResourceManager(baseName, assemblyToUse);233            }234            else235            {236                // 2004/10/11-JonN Do we need a better error message?  I don't think so,237                // since this is private.238                throw PSTraceSource.NewArgumentException(nameof(assemblyToUse));239            }240 241            return rm;242        }243    }244}245