/* */ package com.ibm.icu.impl; /* */ /* */ import com.ibm.icu.util.ULocale; /* */ import com.ibm.icu.util.ULocale.Category; /* */ import java.io.PrintStream; /* */ import java.lang.ref.SoftReference; /* */ import java.util.ArrayList; /* */ import java.util.Collections; /* */ import java.util.Comparator; /* */ import java.util.EventListener; /* */ import java.util.HashMap; /* */ import java.util.HashSet; /* */ import java.util.Iterator; /* */ import java.util.List; /* */ import java.util.ListIterator; /* */ import java.util.Map; /* */ import java.util.Map.Entry; /* */ import java.util.Set; /* */ import java.util.SortedMap; /* */ import java.util.TreeMap; /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public class ICUService /* */ extends ICUNotifier /* */ { /* */ protected final String name; /* */ /* */ public ICUService() /* */ { /* 102 */ this.name = ""; /* */ } /* */ /* 105 */ private static final boolean DEBUG = ICUDebug.enabled("service"); /* */ /* */ /* */ public ICUService(String name) /* */ { /* 110 */ this.name = name; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* 118 */ private final ICURWLock factoryLock = new ICURWLock(); /* */ /* */ /* */ /* */ /* 123 */ private final List<Factory> factories = new ArrayList(); /* */ /* */ /* */ /* */ /* */ /* 129 */ private int defaultSize = 0; /* */ /* */ /* */ /* */ /* */ private SoftReference<Map<String, CacheEntry>> cacheref; /* */ /* */ /* */ /* */ /* */ private SoftReference<Map<String, Factory>> idref; /* */ /* */ /* */ /* */ private LocaleRef dnref; /* */ /* */ /* */ /* */ /* */ public static class Key /* */ { /* */ private final String id; /* */ /* */ /* */ /* */ /* */ public Key(String id) /* */ { /* 157 */ this.id = id; /* */ } /* */ /* */ /* */ /* */ public final String id() /* */ { /* 164 */ return this.id; /* */ } /* */ /* */ /* */ /* */ /* */ public String canonicalID() /* */ { /* 172 */ return this.id; /* */ } /* */ /* */ /* */ /* */ /* */ public String currentID() /* */ { /* 180 */ return canonicalID(); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public String currentDescriptor() /* */ { /* 193 */ return "/" + currentID(); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public boolean fallback() /* */ { /* 204 */ return false; /* */ } /* */ /* */ /* */ /* */ /* */ public boolean isFallbackOf(String idToCheck) /* */ { /* 212 */ return canonicalID().equals(idToCheck); /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public static abstract interface Factory /* */ { /* */ public abstract Object create(ICUService.Key paramKey, ICUService paramICUService); /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public abstract void updateVisibleIDs(Map<String, Factory> paramMap); /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public abstract String getDisplayName(String paramString, ULocale paramULocale); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public static class SimpleFactory /* */ implements ICUService.Factory /* */ { /* */ protected Object instance; /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected String id; /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected boolean visible; /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public SimpleFactory(Object instance, String id) /* */ { /* 277 */ this(instance, id, true); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public SimpleFactory(Object instance, String id, boolean visible) /* */ { /* 286 */ if ((instance == null) || (id == null)) { /* 287 */ throw new IllegalArgumentException("Instance or id is null"); /* */ } /* 289 */ this.instance = instance; /* 290 */ this.id = id; /* 291 */ this.visible = visible; /* */ } /* */ /* */ /* */ /* */ /* */ public Object create(ICUService.Key key, ICUService service) /* */ { /* 299 */ if (this.id.equals(key.currentID())) { /* 300 */ return this.instance; /* */ } /* 302 */ return null; /* */ } /* */ /* */ /* */ /* */ /* */ public void updateVisibleIDs(Map<String, ICUService.Factory> result) /* */ { /* 310 */ if (this.visible) { /* 311 */ result.put(this.id, this); /* */ } else { /* 313 */ result.remove(this.id); /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public String getDisplayName(String identifier, ULocale locale) /* */ { /* 323 */ return (this.visible) && (this.id.equals(identifier)) ? identifier : null; /* */ } /* */ /* */ /* */ /* */ public String toString() /* */ { /* 330 */ StringBuilder buf = new StringBuilder(super.toString()); /* 331 */ buf.append(", id: "); /* 332 */ buf.append(this.id); /* 333 */ buf.append(", visible: "); /* 334 */ buf.append(this.visible); /* 335 */ return buf.toString(); /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ public Object get(String descriptor) /* */ { /* 344 */ return getKey(createKey(descriptor), null); /* */ } /* */ /* */ /* */ /* */ /* */ public Object get(String descriptor, String[] actualReturn) /* */ { /* 352 */ if (descriptor == null) { /* 353 */ throw new NullPointerException("descriptor must not be null"); /* */ } /* 355 */ return getKey(createKey(descriptor), actualReturn); /* */ } /* */ /* */ /* */ /* */ public Object getKey(Key key) /* */ { /* 362 */ return getKey(key, null); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Object getKey(Key key, String[] actualReturn) /* */ { /* 381 */ return getKey(key, actualReturn, null); /* */ } /* */ /* */ /* */ /* */ public Object getKey(Key key, String[] actualReturn, Factory factory) /* */ { /* 388 */ if (this.factories.size() == 0) { /* 389 */ return handleDefault(key, actualReturn); /* */ } /* */ /* 392 */ if (DEBUG) { System.out.println("Service: " + this.name + " key: " + key.canonicalID()); /* */ } /* 394 */ CacheEntry result = null; /* 395 */ if (key != null) /* */ { /* */ try /* */ { /* */ /* 400 */ this.factoryLock.acquireRead(); /* */ /* 402 */ Map<String, CacheEntry> cache = null; /* 403 */ SoftReference<Map<String, CacheEntry>> cref = this.cacheref; /* 404 */ if (cref != null) { /* 405 */ if (DEBUG) System.out.println("Service " + this.name + " ref exists"); /* 406 */ cache = (Map)cref.get(); /* */ } /* 408 */ if (cache == null) { /* 409 */ if (DEBUG) { System.out.println("Service " + this.name + " cache was empty"); /* */ } /* */ /* 412 */ cache = Collections.synchronizedMap(new HashMap()); /* */ /* 414 */ cref = new SoftReference(cache); /* */ } /* */ /* 417 */ String currentDescriptor = null; /* 418 */ ArrayList<String> cacheDescriptorList = null; /* 419 */ boolean putInCache = false; /* */ /* 421 */ int NDebug = 0; /* */ /* 423 */ int startIndex = 0; /* 424 */ int limit = this.factories.size(); /* 425 */ boolean cacheResult = true; /* 426 */ if (factory != null) { /* 427 */ for (int i = 0; i < limit; i++) { /* 428 */ if (factory == this.factories.get(i)) { /* 429 */ startIndex = i + 1; /* 430 */ break; /* */ } /* */ } /* 433 */ if (startIndex == 0) { /* 434 */ throw new IllegalStateException("Factory " + factory + "not registered with service: " + this); /* */ } /* 436 */ cacheResult = false; /* */ } /* */ /* */ do /* */ { /* 441 */ currentDescriptor = key.currentDescriptor(); /* 442 */ if (DEBUG) System.out.println(this.name + "[" + NDebug++ + "] looking for: " + currentDescriptor); /* 443 */ result = (CacheEntry)cache.get(currentDescriptor); /* 444 */ if (result != null) { /* 445 */ if (!DEBUG) break; System.out.println(this.name + " found with descriptor: " + currentDescriptor); break; /* */ } /* */ /* 448 */ if (DEBUG) { System.out.println("did not find: " + currentDescriptor + " in cache"); /* */ } /* */ /* */ /* */ /* */ /* 454 */ putInCache = cacheResult; /* */ /* */ /* 457 */ int index = startIndex; /* 458 */ while (index < limit) { /* 459 */ Factory f = (Factory)this.factories.get(index++); /* 460 */ if (DEBUG) System.out.println("trying factory[" + (index - 1) + "] " + f.toString()); /* 461 */ Object service = f.create(key, this); /* 462 */ if (service != null) { /* 463 */ result = new CacheEntry(currentDescriptor, service); /* 464 */ if (!DEBUG) break label704; System.out.println(this.name + " factory supported: " + currentDescriptor + ", caching"); /* */ break label704; /* */ } /* 467 */ if (DEBUG) { System.out.println("factory did not support: " + currentDescriptor); /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* 476 */ if (cacheDescriptorList == null) { /* 477 */ cacheDescriptorList = new ArrayList(5); /* */ } /* 479 */ cacheDescriptorList.add(currentDescriptor); /* */ } /* 481 */ while (key.fallback()); /* */ label704: /* 483 */ if (result != null) { /* 484 */ if (putInCache) { /* 485 */ if (DEBUG) System.out.println("caching '" + result.actualDescriptor + "'"); /* 486 */ cache.put(result.actualDescriptor, result); /* 487 */ if (cacheDescriptorList != null) { /* 488 */ for (String desc : cacheDescriptorList) { /* 489 */ if (DEBUG) { System.out.println(this.name + " adding descriptor: '" + desc + "' for actual: '" + result.actualDescriptor + "'"); /* */ } /* 491 */ cache.put(desc, result); /* */ } /* */ } /* */ /* */ /* */ /* */ /* 498 */ this.cacheref = cref; /* */ } /* */ /* 501 */ if (actualReturn != null) /* */ { /* 503 */ if (result.actualDescriptor.indexOf("/") == 0) { /* 504 */ actualReturn[0] = result.actualDescriptor.substring(1); /* */ } else { /* 506 */ actualReturn[0] = result.actualDescriptor; /* */ } /* */ } /* */ /* 510 */ if (DEBUG) { System.out.println("found in service: " + this.name); /* */ } /* 512 */ return result.service; /* */ } /* */ } /* */ finally { /* 516 */ this.factoryLock.releaseRead(); /* */ } /* */ } /* */ /* 520 */ if (DEBUG) { System.out.println("not found in service: " + this.name); /* */ } /* 522 */ return handleDefault(key, actualReturn); /* */ } /* */ /* */ private static final class CacheEntry /* */ { /* */ final String actualDescriptor; /* */ final Object service; /* */ /* */ CacheEntry(String actualDescriptor, Object service) /* */ { /* 532 */ this.actualDescriptor = actualDescriptor; /* 533 */ this.service = service; /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ protected Object handleDefault(Key key, String[] actualIDReturn) /* */ { /* 543 */ return null; /* */ } /* */ /* */ /* */ /* */ /* */ public Set<String> getVisibleIDs() /* */ { /* 551 */ return getVisibleIDs(null); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Set<String> getVisibleIDs(String matchID) /* */ { /* 566 */ Set<String> result = getVisibleIDMap().keySet(); /* */ /* 568 */ Key fallbackKey = createKey(matchID); /* */ /* 570 */ if (fallbackKey != null) { /* 571 */ Set<String> temp = new HashSet(result.size()); /* 572 */ for (String id : result) { /* 573 */ if (fallbackKey.isFallbackOf(id)) { /* 574 */ temp.add(id); /* */ } /* */ } /* 577 */ result = temp; /* */ } /* 579 */ return result; /* */ } /* */ /* */ /* */ /* */ private Map<String, Factory> getVisibleIDMap() /* */ { /* 586 */ Map<String, Factory> idcache = null; /* 587 */ SoftReference<Map<String, Factory>> ref = this.idref; /* 588 */ if (ref != null) { /* 589 */ idcache = (Map)ref.get(); /* */ } /* 591 */ while (idcache == null) { /* 592 */ synchronized (this) { /* 593 */ if ((ref == this.idref) || (this.idref == null)) /* */ { /* */ try /* */ { /* 597 */ this.factoryLock.acquireRead(); /* 598 */ idcache = new HashMap(); /* 599 */ ListIterator<Factory> lIter = this.factories.listIterator(this.factories.size()); /* 600 */ while (lIter.hasPrevious()) { /* 601 */ Factory f = (Factory)lIter.previous(); /* 602 */ f.updateVisibleIDs(idcache); /* */ } /* 604 */ idcache = Collections.unmodifiableMap(idcache); /* 605 */ this.idref = new SoftReference(idcache); /* */ } /* */ finally { /* 608 */ this.factoryLock.releaseRead(); /* */ } /* */ /* */ } /* */ else /* */ { /* 614 */ ref = this.idref; /* 615 */ idcache = (Map)ref.get(); /* */ } /* */ } /* */ } /* */ /* 620 */ return idcache; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public String getDisplayName(String id) /* */ { /* 629 */ return getDisplayName(id, ULocale.getDefault(ULocale.Category.DISPLAY)); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public String getDisplayName(String id, ULocale locale) /* */ { /* 638 */ Map<String, Factory> m = getVisibleIDMap(); /* 639 */ Factory f = (Factory)m.get(id); /* 640 */ if (f != null) { /* 641 */ return f.getDisplayName(id, locale); /* */ } /* */ /* 644 */ Key key = createKey(id); /* 645 */ while (key.fallback()) { /* 646 */ f = (Factory)m.get(key.currentID()); /* 647 */ if (f != null) { /* 648 */ return f.getDisplayName(id, locale); /* */ } /* */ } /* */ /* 652 */ return null; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public SortedMap<String, String> getDisplayNames() /* */ { /* 661 */ ULocale locale = ULocale.getDefault(ULocale.Category.DISPLAY); /* 662 */ return getDisplayNames(locale, null, null); /* */ } /* */ /* */ /* */ /* */ /* */ public SortedMap<String, String> getDisplayNames(ULocale locale) /* */ { /* 670 */ return getDisplayNames(locale, null, null); /* */ } /* */ /* */ /* */ /* */ /* */ public SortedMap<String, String> getDisplayNames(ULocale locale, Comparator<Object> com) /* */ { /* 678 */ return getDisplayNames(locale, com, null); /* */ } /* */ /* */ /* */ /* */ /* */ public SortedMap<String, String> getDisplayNames(ULocale locale, String matchID) /* */ { /* 686 */ return getDisplayNames(locale, null, matchID); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public SortedMap<String, String> getDisplayNames(ULocale locale, Comparator<Object> com, String matchID) /* */ { /* 700 */ SortedMap<String, String> dncache = null; /* 701 */ LocaleRef ref = this.dnref; /* */ /* 703 */ if (ref != null) { /* 704 */ dncache = ref.get(locale, com); /* */ } /* */ /* 707 */ while (dncache == null) { /* 708 */ synchronized (this) { /* 709 */ if ((ref == this.dnref) || (this.dnref == null)) { /* 710 */ dncache = new TreeMap(com); /* */ /* 712 */ Map<String, Factory> m = getVisibleIDMap(); /* 713 */ Iterator<Map.Entry<String, Factory>> ei = m.entrySet().iterator(); /* 714 */ while (ei.hasNext()) { /* 715 */ Map.Entry<String, Factory> e = (Map.Entry)ei.next(); /* 716 */ String id = (String)e.getKey(); /* 717 */ Factory f = (Factory)e.getValue(); /* 718 */ dncache.put(f.getDisplayName(id, locale), id); /* */ } /* */ /* 721 */ dncache = Collections.unmodifiableSortedMap(dncache); /* 722 */ this.dnref = new LocaleRef(dncache, locale, com); /* */ } else { /* 724 */ ref = this.dnref; /* 725 */ dncache = ref.get(locale, com); /* */ } /* */ } /* */ } /* */ /* 730 */ Key matchKey = createKey(matchID); /* 731 */ if (matchKey == null) { /* 732 */ return dncache; /* */ } /* */ /* 735 */ SortedMap<String, String> result = new TreeMap(dncache); /* 736 */ Iterator<Map.Entry<String, String>> iter = result.entrySet().iterator(); /* 737 */ while (iter.hasNext()) { /* 738 */ Map.Entry<String, String> e = (Map.Entry)iter.next(); /* 739 */ if (!matchKey.isFallbackOf((String)e.getValue())) { /* 740 */ iter.remove(); /* */ } /* */ } /* 743 */ return result; /* */ } /* */ /* */ private static class LocaleRef /* */ { /* */ private final ULocale locale; /* */ private SoftReference<SortedMap<String, String>> ref; /* */ private Comparator<Object> com; /* */ /* */ LocaleRef(SortedMap<String, String> dnCache, ULocale locale, Comparator<Object> com) /* */ { /* 754 */ this.locale = locale; /* 755 */ this.com = com; /* 756 */ this.ref = new SoftReference(dnCache); /* */ } /* */ /* */ SortedMap<String, String> get(ULocale loc, Comparator<Object> comp) /* */ { /* 761 */ SortedMap<String, String> m = (SortedMap)this.ref.get(); /* 762 */ if ((m != null) && (this.locale.equals(loc)) && ((this.com == comp) || ((this.com != null) && (this.com.equals(comp))))) /* */ { /* */ /* */ /* 766 */ return m; /* */ } /* 768 */ return null; /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public final List<Factory> factories() /* */ { /* */ try /* */ { /* 780 */ this.factoryLock.acquireRead(); /* 781 */ return new ArrayList(this.factories); /* */ } /* */ finally { /* 784 */ this.factoryLock.releaseRead(); /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ public Factory registerObject(Object obj, String id) /* */ { /* 793 */ return registerObject(obj, id, true); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public Factory registerObject(Object obj, String id, boolean visible) /* */ { /* 802 */ String canonicalID = createKey(id).canonicalID(); /* 803 */ return registerFactory(new SimpleFactory(obj, canonicalID, visible)); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public final Factory registerFactory(Factory factory) /* */ { /* 812 */ if (factory == null) { /* 813 */ throw new NullPointerException(); /* */ } /* */ try { /* 816 */ this.factoryLock.acquireWrite(); /* 817 */ this.factories.add(0, factory); /* 818 */ clearCaches(); /* */ } /* */ finally { /* 821 */ this.factoryLock.releaseWrite(); /* */ } /* 823 */ notifyChanged(); /* 824 */ return factory; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public final boolean unregisterFactory(Factory factory) /* */ { /* 833 */ if (factory == null) { /* 834 */ throw new NullPointerException(); /* */ } /* */ /* 837 */ boolean result = false; /* */ try { /* 839 */ this.factoryLock.acquireWrite(); /* 840 */ if (this.factories.remove(factory)) { /* 841 */ result = true; /* 842 */ clearCaches(); /* */ } /* */ } /* */ finally { /* 846 */ this.factoryLock.releaseWrite(); /* */ } /* */ /* 849 */ if (result) { /* 850 */ notifyChanged(); /* */ } /* 852 */ return result; /* */ } /* */ /* */ /* */ /* */ public final void reset() /* */ { /* */ try /* */ { /* 861 */ this.factoryLock.acquireWrite(); /* 862 */ reInitializeFactories(); /* 863 */ clearCaches(); /* */ } /* */ finally { /* 866 */ this.factoryLock.releaseWrite(); /* */ } /* 868 */ notifyChanged(); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected void reInitializeFactories() /* */ { /* 879 */ this.factories.clear(); /* */ } /* */ /* */ /* */ /* */ /* */ public boolean isDefault() /* */ { /* 887 */ return this.factories.size() == this.defaultSize; /* */ } /* */ /* */ /* */ /* */ /* */ protected void markDefault() /* */ { /* 895 */ this.defaultSize = this.factories.size(); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public Key createKey(String id) /* */ { /* 904 */ return id == null ? null : new Key(id); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected void clearCaches() /* */ { /* 918 */ this.cacheref = null; /* 919 */ this.idref = null; /* 920 */ this.dnref = null; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected void clearServiceCache() /* */ { /* 930 */ this.cacheref = null; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ protected boolean acceptsListener(EventListener l) /* */ { /* 950 */ return l instanceof ServiceListener; /* */ } /* */ /* */ /* */ /* */ /* */ protected void notifyListener(EventListener l) /* */ { /* 958 */ ((ServiceListener)l).serviceChanged(this); /* */ } /* */ /* */ /* */ /* */ /* */ public String stats() /* */ { /* 966 */ ICURWLock.Stats stats = this.factoryLock.resetStats(); /* 967 */ if (stats != null) { /* 968 */ return stats.toString(); /* */ } /* 970 */ return "no stats"; /* */ } /* */ /* */ /* */ /* */ public String getName() /* */ { /* 977 */ return this.name; /* */ } /* */ /* */ /* */ /* */ public String toString() /* */ { /* 984 */ return super.toString() + "{" + this.name + "}"; /* */ } /* */ /* */ public static abstract interface ServiceListener /* */ extends EventListener /* */ { /* */ public abstract void serviceChanged(ICUService paramICUService); /* */ } /* */ } /* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\impl\ICUService.class * Java compiler version: 5 (49.0) * JD-Core Version: 0.7.1 */