Example #1
0
        /// <summary>
        /// Given a visible <paramref name="id"/>, return the display name in the requested <paramref name="locale"/>.
        /// If there is no directly supported id corresponding to this id, return
        /// null.
        /// </summary>
        public virtual string GetDisplayName(string id, UCultureInfo locale)
        {
            IDictionary <string, IServiceFactory> m = GetVisibleIDMap();

            if (m.TryGetValue(id, out IServiceFactory f) && f != null)
            {
                return(f.GetDisplayName(id, locale));
            }

            ICUServiceKey key = CreateKey(id);

            while (key.Fallback())
            {
                if (m.TryGetValue(key.CurrentID, out f) && f != null)
                {
                    return(f.GetDisplayName(id, locale));
                }
            }

            return(null);
        }
Example #2
0
        /// <summary>
        /// Given a visible <paramref name="id"/>, return the display name in the requested <paramref name="locale"/>.
        /// If there is no directly supported id corresponding to this id, return
        /// null.
        /// </summary>
        public virtual string GetDisplayName(string id, ULocale locale)
        {
            IDictionary <string, IServiceFactory> m = GetVisibleIDMap();
            IServiceFactory f = m.Get(id);

            if (f != null)
            {
                return(f.GetDisplayName(id, locale));
            }

            ICUServiceKey key = CreateKey(id);

            while (key.Fallback())
            {
                f = m.Get(key.CurrentID);
                if (f != null)
                {
                    return(f.GetDisplayName(id, locale));
                }
            }

            return(null);
        }
Example #3
0
        private CacheEntry GetKeyCacheEntry(ICUServiceKey key, IServiceFactory factory)
        {
            if (DEBUG)
            {
                Console.Out.WriteLine("Service: " + m_name + " key: " + key.CanonicalID);
            }

            if (key != null)
            {
                try
                {
                    // The factory list can't be modified until we're done,
                    // otherwise we might update the cache with an invalid result.
                    // The cache has to stay in synch with the factory list.
                    factoryLock.AcquireRead();

                    IDictionary <string, CacheEntry> cache = this.cache; // copy so we don't need to sync on this
                    if (cache == null)
                    {
                        if (DEBUG)
                        {
                            Console.Out.WriteLine("Service " + m_name + " cache was empty");
                        }
                        // synchronized since additions and queries on the cache must be atomic
                        // they can be interleaved, though
                        cache = new ConcurrentDictionary <string, CacheEntry>();
                    }

                    string        currentDescriptor   = null;
                    List <string> cacheDescriptorList = null;
                    bool          putInCache          = false;

                    int NDebug = 0;

                    int  startIndex  = 0;
                    int  limit       = factories.Count;
                    bool cacheResult = true;
                    if (factory != null)
                    {
                        for (int i = 0; i < limit; ++i)
                        {
                            if (factory == factories[i])
                            {
                                startIndex = i + 1;
                                break;
                            }
                        }
                        if (startIndex == 0)
                        {
                            throw new InvalidOperationException("Factory " + factory + "not registered with service: " + this);
                        }
                        cacheResult = false;
                    }


                    CacheEntry result;
                    //outer:
                    do
                    {
                        currentDescriptor = key.GetCurrentDescriptor();
                        if (DEBUG)
                        {
                            Console.Out.WriteLine(m_name + "[" + NDebug++ + "] looking for: " + currentDescriptor);
                        }
                        if (cache.TryGetValue(currentDescriptor, out result) && result != null)
                        {
                            if (DEBUG)
                            {
                                Console.Out.WriteLine(m_name + " found with descriptor: " + currentDescriptor);
                            }
                            goto outer_break;
                        }
                        else
                        {
                            if (DEBUG)
                            {
                                Console.Out.WriteLine("did not find: " + currentDescriptor + " in cache");
                            }
                        }

                        // first test of cache failed, so we'll have to update
                        // the cache if we eventually succeed-- that is, if we're
                        // going to update the cache at all.
                        putInCache = cacheResult;

                        //  int n = 0;
                        int index = startIndex;
                        while (index < limit)
                        {
                            IServiceFactory f = factories[index++];
                            if (DEBUG)
                            {
                                Console.Out.WriteLine("trying factory[" + (index - 1) + "] " + f.ToString());
                            }
                            object service = f.Create(key, this);
                            if (service != null)
                            {
                                result = new CacheEntry(currentDescriptor, service);
                                if (DEBUG)
                                {
                                    Console.Out.WriteLine(m_name + " factory supported: " + currentDescriptor + ", caching");
                                }
                                goto outer_break;
                            }
                            else
                            {
                                if (DEBUG)
                                {
                                    Console.Out.WriteLine("factory did not support: " + currentDescriptor);
                                }
                            }
                        }

                        // prepare to load the cache with all additional ids that
                        // will resolve to result, assuming we'll succeed.  We
                        // don't want to keep querying on an id that's going to
                        // fallback to the one that succeeded, we want to hit the
                        // cache the first time next goaround.
                        if (cacheDescriptorList == null)
                        {
                            cacheDescriptorList = new List <string>(5);
                        }
                        cacheDescriptorList.Add(currentDescriptor);
                    } while (key.Fallback());
                    outer_break : { }

                    if (result != null)
                    {
                        if (putInCache)
                        {
                            if (DEBUG)
                            {
                                Console.Out.WriteLine("caching '" + result.actualDescriptor + "'");
                            }
                            cache[result.actualDescriptor] = result;
                            if (cacheDescriptorList != null)
                            {
                                foreach (string desc in cacheDescriptorList)
                                {
                                    if (DEBUG)
                                    {
                                        Console.Out.WriteLine(m_name + " adding descriptor: '" + desc + "' for actual: '" + result.actualDescriptor + "'");
                                    }

                                    cache[desc] = result;
                                }
                            }
                            // Atomic update.  We held the read lock all this time
                            // so we know our cache is consistent with the factory list.
                            // We might stomp over a cache that some other thread
                            // rebuilt, but that's the breaks.  They're both good.
                            this.cache = cache;
                        }

                        if (DEBUG)
                        {
                            Console.Out.WriteLine("found in service: " + m_name);
                        }

                        return(result);
                    }
                }
                finally
                {
                    factoryLock.ReleaseRead();
                }
            }

            if (DEBUG)
            {
                Console.Out.WriteLine("not found in service: " + m_name);
            }

            return(null);
        }