/** Loads all labels from the specified URL. */ private static final void load(Map labels, URL url, String charset) throws IOException { log.info("Opening " + url); // don't use MCommon since Messages might call getLabel load(labels, url.openStream(), charset); }
// -- private utilities --// private final Map loadLabels(Locale locale) { WaitLock lock = null; for (; ; ) { final Object o; synchronized (_syncLabels) { o = _syncLabels.get(locale); if (o == null) _syncLabels.put(locale, lock = new WaitLock()); // lock it } if (o instanceof Map) return (Map) o; if (o == null) break; // go to load the page // wait because some one is creating the servlet if (!((WaitLock) o).waitUntilUnlock(5 * 60 * 1000)) log.warning( "Take too long to wait loading labels: " + locale + "\nTry to load again automatically..."); } // for(;;) if (_jarcharset == null) _jarcharset = Library.getProperty("org.zkoss.util.label.classpath.charset", "UTF-8"); if (_warcharset == null) { _warcharset = Library.getProperty("org.zkoss.util.label.web.charset", null); if (_warcharset == null) _warcharset = Library.getProperty( "org.zkoss.util.label.WEB-INF.charset", "UTF-8"); // backward compatible } try { // get the class name if (locale != null) log.info("Loading labels for " + locale); Map labels = new HashMap(512); // 1. load from modules final ClassLocator locator = new ClassLocator(); for (Enumeration en = locator.getResources( locale == null ? "metainfo/i3-label.properties" : "metainfo/i3-label_" + locale + ".properties"); en.hasMoreElements(); ) { final URL url = (URL) en.nextElement(); load(labels, url, _jarcharset); } // 2. load from extra resource final List locators; synchronized (_locators) { locators = new LinkedList(_locators); } for (Iterator it = locators.iterator(); it.hasNext(); ) { Object o = it.next(); if (o instanceof LabelLocator) { final URL url = ((LabelLocator) o).locate(locale); if (url != null) load(labels, url, _warcharset); } else { final LabelLocator2 loc = (LabelLocator2) o; final InputStream is = loc.locate(locale); if (is != null) { final String cs = loc.getCharset(); load(labels, is, cs != null ? cs : _warcharset); } } } // Convert values to ExValue toExValue(labels); // merge with labels from 'super' locale if (locale != null) { final String lang = locale.getLanguage(); final String cnty = locale.getCountry(); final String var = locale.getVariant(); final Map superlabels = loadLabels( var != null && var.length() > 0 ? new Locale(lang, cnty) : cnty != null && cnty.length() > 0 ? new Locale(lang, "") : null); if (labels.isEmpty()) { labels = superlabels.isEmpty() ? Collections.EMPTY_MAP : superlabels; } else if (!superlabels.isEmpty()) { Map combined = new HashMap(superlabels); combined.putAll(labels); labels = combined; } } // add to map synchronized (_syncLabels) { _syncLabels.put(locale, labels); cloneLables(); } return labels; } catch (Throwable ex) { synchronized (_syncLabels) { _syncLabels.remove(locale); cloneLables(); } throw SystemException.Aide.wrap(ex); } finally { lock.unlock(); // unlock (always unlock to avoid deadlock) } }