/* Labels.java
Purpose:
Description:
History:
Tue Sep 21 10:55:09 2004, Created by tomyeh
Copyright (C) 2004 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under LGPL Version 2.1 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.util.resource;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.lang.Classes;
import org.zkoss.lang.Library;
import org.zkoss.lang.SystemException;
import org.zkoss.util.resource.impl.LabelLoader;
import org.zkoss.util.resource.impl.LabelLoaderImpl;
import org.zkoss.text.MessageFormats;
import org.zkoss.xel.VariableResolver;
/**
* Utilities to access labels. A label is a Locale-dependent string
* that is stored in a Locale-dependent file (*.properties).
* <p> Specify the library property of <code>org.zkoss.util.resource.LabelLoader.class</code>
* in zk.xml to provide a customized label loader for debugging purpose. (since 7.0.1)
*
* @author tomyeh
*/
public class Labels {
private static final Logger log = LoggerFactory.getLogger(Labels.class);
private Labels() {} //prevent form misuse
private static LabelLoader _loader;
static {
try {
_loader = (LabelLoader) Classes.newInstanceByThread(Library.getProperty("org.zkoss.util.resource.LabelLoader.class", "org.zkoss.util.resource.impl.LabelLoaderImpl"));
} catch (Exception e) {
log.warn("", e);
if (_loader == null)
_loader = new LabelLoaderImpl();
}
}
/** Returns the label of the specified key based
* on the current Locale, or null if no found.
*
* <p>The current locale is given by {@link org.zkoss.util.Locales#getCurrent}.
* @see #getSegmentedLabels
*/
public static final String getLabel(String key) {
return _loader.getLabel(key);
}
/** Returns the label of the specified key and formats it
* with the specified argument, or null if not found.
*
* <p>It first uses {@link #getLabel(String)} to load the label.
* Then, it, if not null, invokes {@link MessageFormats#format} to format it.
*
* <p>The current locale is given by {@link org.zkoss.util.Locales#getCurrent}.
* @since 3.0.6
*/
public static final String getLabel(String key, Object[] args) {
final String s = getLabel(key);
return s != null ? MessageFormats.format(s, args, null): null;
}
/** Returns the label of the specified key based
* on the current Locale, or the default value if no found.
*
* <p>The current locale is given by {@link org.zkoss.util.Locales#getCurrent}.
*
* @param defValue the value being returned if the key is not found
* @since 3.6.0
*/
public static final String getLabel(String key, String defValue) {
final String s = _loader.getLabel(key);
return s != null ? s: defValue;
}
/** Returns the label of the specified key and formats it
* with the specified argument, or the default value if not found.
*
* <p>It first uses {@link #getLabel(String, String)} to load the label.
* Then, it, if not null, invokes {@link MessageFormats#format} to format it.
*
* <p>The current locale is given by {@link org.zkoss.util.Locales#getCurrent}.
* @param defValue the value being returned if the key is not found
* @since 3.6.0
*/
public static final String getLabel(String key, String defValue, Object[] args) {
final String s = getLabel(key, defValue);
return s != null ? MessageFormats.format(s, args, null): null;
}
/** Returns the label or a map of labels associated with the key.
* Unlike {@link #getLabel}, if a key of the label contains dot, it will
* be split into multiple keys and then grouped into map.
* For example, the following property file will parsed into a couple of maps,
* and <code>getSegmentedLabels()</code> returns a map containing
* a single entry. The entry's key is <code>"a"</code> and the value
* is another map with two entries <code>"b"</code> and <code>"c"</code>.
* And, the value for <code>"b"</code> is another two-entries map (containing
* <code>"c"</code> and <code>"d"</code>).
* <pre><code>
* a.b.c=1
* a.b.d=2
* a.e=3</pre></code>
* <p>This method is designed to make labels easier to be accessed in
* EL expressions.
* <p>On the other hand, {@link #getLabel} does not split them, and
* you could access them by, say, <code>getLabel("a.b.d")</code>.
* @since 5.0.7
*/
public static final Map<String, Object> getSegmentedLabels() {
return _loader.getSegmentedLabels();
}
/** Returns the label of the specified key based on the current locale.
* Unlike {@link #getLabel(String)}, it throws an exception if not found.
*
* @exception SystemException if no such label
* @since 3.0.6
*/
public static final String getRequiredLabel(String key)
throws SystemException {
final String s = getLabel(key);
if (s == null)
throw new SystemException("label not found: "+key);
return s;
}
/** Returns the label of the specified key and formats it
* with the specified argument, or null if not found.
* Unlike {@link #getLabel(String, Object[])}, it throws an exception if not found.
*
* <p>The current locale is given by {@link org.zkoss.util.Locales#getCurrent}.
* @exception SystemException if no such label
* @since 3.0.6
*/
public static final String getRequiredLabel(String key, Object[] args) {
final String s = getLabel(key);
if (s == null)
throw new SystemException("label not found: "+key);
return MessageFormats.format(s, args, null);
}
/** Resets all cached labels and next call to {@link #getLabel(String)}
* will cause re-loading the Locale dependent files.
*/
public static final void reset() {
_loader.reset();
}
/** Sets the variable resolver, which is used if an EL expression
* is specified.
*
* <p>Default: no resolver at all.
*
* @return the previous resolver, or null if no resolver.
*/
public static final
VariableResolver setVariableResolver(VariableResolver resolv) {
return _loader.setVariableResolver(resolv);
}
/** Registers a locator which is used to load the Locale-dependent
* labels from other resource, such as servlet contexts.
*/
public static final void register(LabelLocator locator) {
_loader.register(locator);
}
/** Registers a locator which is used to load the Locale-dependent
* labels from other resource, such as database.
* @since 5.0.5
*/
public static final void register(LabelLocator2 locator) {
_loader.register(locator);
}
}