Exemplo n.º 1
0
        /// <summary>
        /// Gets the file data for the specified resource, storing a cached version if specified.
        /// IMPORTANT:
        /// NOTE: Make sure any and all await calls inside this function and its children
        ///       use ConfigureAwait(false). This is because the parent has to support
        ///       a synchronous version of this call, so the method cannot sync back with
        ///       its calling context without risk of deadlock.
        /// </summary>
        /// <param name="pathFormat">The path to the desired resource, containing {0} in place of the culture</param>
        /// <param name="constructData">The function that takes the file data and converts it into the format required by the provider</param>
        /// <param name="culture">The culture to use. If not specified, the default culture is used</param>
        /// <returns></returns>
        protected async Task <T> GetResourceDocumentAsync <T>(ResourceDefinition pathFormat, Func <Stream, T> constructData, string culture = null)
        {
            try
            {
                await mSelfLock.WaitAsync();

                // Get culture path
                var resourcePath = ResourceFormatProviderHelpers.GetCulturePath(pathFormat.Location, culture);

                // Make sure list has been initialized
                if (mCache == null)
                {
                    mCache = new Dictionary <string, object>();
                }

                // If we have a document already, return that
                if (mCache.ContainsKey(resourcePath))
                {
                    return((T)mCache[resourcePath]);
                }

                // Otherwise try and get it
                var resourceDocument = default(T);

                try
                {
                    // Try to get the stream for this resource
                    using (var stream = await ResourceFormatProviderHelpers.GetStreamAsync(pathFormat.Type, resourcePath).ConfigureAwait(false))
                    {
                        // If successful, try and convert that data into a usable resource object
                        if (stream != null)
                        {
                            resourceDocument = constructData(stream);
                        }
                    }
                }
                finally
                {
                    // Add resource document if found or not (except for Urls, never add failed Urls in case of bad Internet connection
                    if (mCacheResourceFiles && pathFormat.Type != ResourceDefinitionType.Url)
                    {
                        mCache.Add(resourcePath, resourceDocument);
                    }
                }

                // Return what we found, if anything
                return(resourceDocument);
            }
            finally
            {
                mSelfLock.Release();
            }
        }
        /// <summary>
        /// Gets the format of this resource
        /// </summary>
        /// <param name="resourceDefinition">The resource definition</param>
        /// <returns></returns>
        public static string GetFormat(ResourceDefinition resourceDefinition)
        {
            var extension = resourceDefinition.ExplicitFormat;

            // If not, get it from the file extension
            if (string.IsNullOrEmpty(resourceDefinition.ExplicitFormat))
            {
                extension = Path.GetExtension(resourceDefinition.Location);
                if (extension != null && extension.StartsWith("."))
                {
                    extension = extension.Substring(1);
                }
            }

            return(extension);
        }
        /// <summary>
        /// Finds a string of the given name, taking into account the culture information.
        /// If no culture is specified, the default culture is used
        ///
        /// IMPORTANT:
        /// NOTE: Make sure any and all await calls inside this function and its children
        ///       use ConfigureAwait(false). This is because the parent has to support
        ///       a synchronous version of this call, so the method cannot sync back with
        ///       its calling context without risk of deadlock.
        /// </summary>
        public async Task <bool> GetStringAsync(ResourceDefinition resource, string name, string culture, Action <string> onResult)
        {
            // Get string document for this culture
            var document = await GetResourceDocumentAsync(resource, XDocument.Load, culture).ConfigureAwait(false);

            // If it is null, try and find the default culture if specified
            if (document == null)
            {
                if (resource.UseDefaultCultureIfNotFound)
                {
                    document = await GetResourceDocumentAsync(resource, XDocument.Load).ConfigureAwait(false);
                }

                // Document not found so return false
                if (document == null)
                {
                    return(false);
                }
            }

            // Null check for root document
            if (document.Root == null)
            {
                return(false);
            }

            // Get the first element that matches the given name (ignore case)
            var element = document.Root.Elements().FirstOrDefault(
                f => f.Attributes().Any(a => a.Name.LocalName == "Name") &&
                string.Equals(name, f.Attributes().First(a => a.Name.LocalName == "Name").Value, StringComparison.CurrentCultureIgnoreCase));

            // Return false if not found
            if (element == null)
            {
                return(false);
            }

            // Otherwise we found the value so return it
            onResult(element.Value);

            return(true);
        }