/// <summary> /// Return a snapshot of the mapping from display names to visible IDs for /// this service. This set will not change as factories are added or removed, /// but the supported ids will, so there is no guarantee that all and only /// the ids in the returned map will be visible and supported by the service /// in subsequent calls, nor is there any guarantee that the current display /// names match those in the set. The display names are sorted based on the /// comparator provided. /// </summary> /// public SortedList GetDisplayNames(ULocale locale, IComparer com, String matchID) { SortedList dncache = null; ICUService.LocaleRef xref = dnref; if (xref != null) { dncache = xref.Get(locale, com); } while (dncache == null) { lock (this) { if (xref == dnref || dnref == null) { dncache = new SortedList(com); // sorted IDictionary m = GetVisibleIDMap(); IIterator ei = new ILOG.J2CsMapping.Collections.IteratorAdapter(m.GetEnumerator()); while (ei.HasNext()) { DictionaryEntry e = (DictionaryEntry)ei.Next(); String id_0 = (String)((DictionaryEntry)e).Key; ICUService.Factory f = (ICUService.Factory)((DictionaryEntry)e).Value; ILOG.J2CsMapping.Collections.Collections.Put(dncache, f.GetDisplayName(id_0, locale), id_0); } dncache = /*ILOG.J2CsMapping.Collections.Generics.Collections.UnmodifiableSortedMap(*/ dncache /*)*/; dnref = new ICUService.LocaleRef(dncache, locale, com); } else { xref = dnref; dncache = xref.Get(locale, com); } } } ICUService.Key matchKey = CreateKey(matchID); if (matchKey == null) { return(dncache); } SortedList result = new SortedList(dncache); IIterator iter = new ILOG.J2CsMapping.Collections.IteratorAdapter(result.GetEnumerator()); while (iter.HasNext()) { DictionaryEntry e_1 = (DictionaryEntry)iter.Next(); if (!matchKey.IsFallbackOf((String)((DictionaryEntry)e_1).Value)) { iter.Remove(); } } return(result); }
/// <summary> /// Return the service instance if the factory's id is equal to the key's /// currentID. Service is ignored. /// </summary> /// public virtual Object Create(ICUService.Key key, ICUService service) { if (id.Equals(key.CurrentID())) { return(instance); } return(null); }
protected internal bool HandlesKey(ICUService.Key key) { if (key != null) { String id = key.CurrentID(); ILOG.J2CsMapping.Collections.ISet supported = GetSupportedIDs(); return(ILOG.J2CsMapping.Collections.Collections.Contains(id, supported)); } return(false); }
/// <summary> /// Returns the service object if kind/locale match. Service is not used. /// </summary> /// public override Object Create(ICUService.Key key, ICUService service) { ICULocaleService.LocaleKey lkey = (ICULocaleService.LocaleKey)key; if (kind == IBM.ICU.Impl.ICULocaleService.LocaleKey.KIND_ANY || kind == lkey.Kind()) { String keyID = lkey.CurrentID(); if (id.Equals(keyID)) { return(obj); } } return(null); }
/// <summary> /// Implement superclass abstract method. This checks the currentID of /// the key against the supported IDs, and passes the canonicalLocale and /// kind off to handleCreate (which subclasses must implement). /// </summary> /// public virtual Object Create(ICUService.Key key, ICUService service) { if (HandlesKey(key)) { ICULocaleService.LocaleKey lkey = (ICULocaleService.LocaleKey)key; int kind_0 = lkey.Kind(); ULocale uloc = lkey.CurrentLocale(); return(HandleCreate(uloc, kind_0, service)); } else { // System.out.println("factory: " + this + // " did not support id: " + key.currentID()); // System.out.println("supported ids: " + getSupportedIDs()); } return(null); }
/// <summary> /// Given a visible id, return the display name in the requested locale. If /// there is no directly supported id corresponding to this id, return null. /// </summary> /// public String GetDisplayName(String id_0, ULocale locale) { IDictionary m = GetVisibleIDMap(); ICUService.Factory f = (ICUService.Factory)ILOG.J2CsMapping.Collections.Collections.Get(m, id_0); if (f != null) { return(f.GetDisplayName(id_0, locale)); } ICUService.Key key = CreateKey(id_0); while (key.Fallback()) { f = (ICUService.Factory)ILOG.J2CsMapping.Collections.Collections.Get(m, key.CurrentID()); if (f != null) { return(f.GetDisplayName(id_0, locale)); } } return(null); }
/// <summary> /// <p> /// Return a snapshot of the visible IDs for this service. This set will not /// change as Factories are added or removed, but the supported ids will, so /// there is no guarantee that all and only the ids in the returned set are /// visible and supported by the service in subsequent calls. /// </p> /// <p> /// matchID is passed to createKey to create a key. If the key is not null, /// it is used to filter out ids that don't have the key as a fallback. /// </summary> /// public ILOG.J2CsMapping.Collections.ISet GetVisibleIDs(String matchID) { ILOG.J2CsMapping.Collections.ISet result = new ILOG.J2CsMapping.Collections.ListSet(GetVisibleIDMap().Keys); ICUService.Key fallbackKey = CreateKey(matchID); if (fallbackKey != null) { ILOG.J2CsMapping.Collections.ISet temp = new HashedSet(result.Count); IIterator iter = new ILOG.J2CsMapping.Collections.IteratorAdapter(result.GetEnumerator()); while (iter.HasNext()) { String id_0 = (String)iter.Next(); if (fallbackKey.IsFallbackOf(id_0)) { ILOG.J2CsMapping.Collections.Generics.Collections.Add(temp, id_0); } } result = temp; } return(result); }
/// <summary> /// Convenience override for callers using locales. This uses /// createKey(ULocale.toString(), kind) to create a key, calls getKey, and /// then if actualReturn is not null, returns the actualResult from getKey /// (stripping any prefix) into a ULocale. /// </summary> /// public Object Get(ULocale locale, int kind, ULocale[] actualReturn) { ICUService.Key key = CreateKey(locale, kind); if (actualReturn == null) { return(GetKey(key)); } String[] temp = new String[1]; Object result = GetKey(key, temp); if (result != null) { int n = temp[0].IndexOf("/"); if (n >= 0) { temp[0] = temp[0].Substring(n + 1); } actualReturn[0] = new ULocale(temp[0]); } return(result); }
/// <summary> /// Default handler for this service if no factory in the list handled the /// key. /// </summary> /// protected internal virtual Object HandleDefault(ICUService.Key key, String[] actualIDReturn) { return(null); }
// debugging // Map hardRef; public Object GetKey(ICUService.Key key, String[] actualReturn, ICUService.Factory factory) { if (factories.Count == 0) { return(HandleDefault(key, actualReturn)); } if (DEBUG) { System.Console.Out.WriteLine("Service: " + name + " key: " + key.CanonicalID()); } ICUService.CacheEntry result = null; 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 cache = null; WeakReference cref = cacheref; // copy so we don't need to sync // on this if (cref != null) { if (DEBUG) { System.Console.Out.WriteLine("Service " + name + " ref exists"); } cache = (IDictionary)cref.Target; } if (cache == null) { if (DEBUG) { System.Console.Out.WriteLine("Service " + name + " cache was empty"); } // synchronized since additions and queries on the cache // must be atomic // they can be interleaved, though cache = ILOG.J2CsMapping.Collections.Generics.Collections.SynchronizedMap(new Hashtable()); // hardRef = cache; // debug cref = new WeakReference(cache); } String currentDescriptor = null; ArrayList 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 ((Object)factory == factories[i]) { startIndex = i + 1; break; } } if (startIndex == 0) { throw new InvalidOperationException("Factory " + factory + "not registered with service: " + this); } cacheResult = false; } outer : { do { currentDescriptor = key.CurrentDescriptor(); if (DEBUG) { System.Console.Out.WriteLine(name + "[" + NDebug++ + "] looking for: " + currentDescriptor); } result = (ICUService.CacheEntry)ILOG.J2CsMapping.Collections.Collections.Get(cache, currentDescriptor); if (result != null) { if (DEBUG) { System.Console.Out.WriteLine(name + " found with descriptor: " + currentDescriptor); } goto gotoouter; } else { if (DEBUG) { System.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) { ICUService.Factory f = (ICUService.Factory)factories[index++]; if (DEBUG) { System.Console.Out.WriteLine("trying factory[" + (index - 1) + "] " + f.ToString()); } Object service = f.Create(key, this); if (service != null) { result = new ICUService.CacheEntry(currentDescriptor, service); if (DEBUG) { System.Console.Out.WriteLine(name + " factory supported: " + currentDescriptor + ", caching"); } goto gotoouter; } else { if (DEBUG) { System.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 ArrayList(5); } ILOG.J2CsMapping.Collections.Generics.Collections.Add(cacheDescriptorList, currentDescriptor); } while (key.Fallback()); } gotoouter: ; if (result != null) { if (putInCache) { if (DEBUG) { System.Console.Out.WriteLine("caching '" + result.actualDescriptor + "'"); } ILOG.J2CsMapping.Collections.Collections.Put(cache, result.actualDescriptor, result); if (cacheDescriptorList != null) { IIterator iter = new ILOG.J2CsMapping.Collections.IteratorAdapter(cacheDescriptorList.GetEnumerator()); while (iter.HasNext()) { String desc = (String)iter.Next(); if (DEBUG) { System.Console.Out.WriteLine(name + " adding descriptor: '" + desc + "' for actual: '" + result.actualDescriptor + "'"); } ILOG.J2CsMapping.Collections.Collections.Put(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. cacheref = cref; } if (actualReturn != null) { // strip null prefix if (result.actualDescriptor.IndexOf("/") == 0) { actualReturn[0] = result.actualDescriptor.Substring(1); } else { actualReturn[0] = result.actualDescriptor; } } if (DEBUG) { System.Console.Out.WriteLine("found in service: " + name); } return(result.service); } } finally { factoryLock.ReleaseRead(); } } if (DEBUG) { System.Console.Out.WriteLine("not found in service: " + name); } return(HandleDefault(key, actualReturn)); }
/// <summary> /// <p> /// Given a key, return a service object, and, if actualReturn is not null, /// the descriptor with which it was found in the first element of /// actualReturn. If no service object matches this key, return null, and /// leave actualReturn unchanged. /// </p> /// <p> /// This queries the cache using the key's descriptor, and if no object in /// the cache matches it, tries the key on each registered factory, in order. /// If none generates a service object for the key, repeats the process with /// each fallback of the key, until either one returns a service object, or /// the key has no fallback. /// </p> /// <p> /// If key is null, just returns null. /// </p> /// </summary> /// public Object GetKey(ICUService.Key key, String[] actualReturn) { return(GetKey(key, actualReturn, null)); }
/// <summary> /// Convenience override for get(Key, String[]). /// </summary> /// public Object GetKey(ICUService.Key key) { return(GetKey(key, null)); }