MessageConveyor xref

View Javadoc

    1   /*
    2    * Copyright (c) 2009 QOS.ch All rights reserved.
    3    *
    4    * Permission is hereby granted, free of charge, to any person obtaining a copy
    5    * of this software and associated documentation files (the "Software"), to deal
    6    * in the Software without restriction, including without limitation the rights
    7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    8    * copies of the Software, and to permit persons to whom the Software is
    9    * furnished to do so, subject to the following conditions:
    10   *
    11   * The above copyright notice and this permission notice shall be included in
    12   * all copies or substantial portions of the Software.
    13   *
    14   * THE SOFTWARE IS PROVIDED "AS  IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   * SOFTWARE.
    21   */
    22
    23  package ch.qos.cal10n;
    24
    25  import java.text.MessageFormat;
    26  import java.util.Locale;
    27  import java.util.Map;
    28  import java.util.concurrent.ConcurrentHashMap;
    29
    30  import ch.qos.cal10n.util.AnnotationExtractor;
    31  import ch.qos.cal10n.util.CAL10NResourceBundle;
    32  import ch.qos.cal10n.util.CAL10NResourceBundleFinder;
    33
    34  /**
    35   * The default implementation for {@link IMessageConveyor} based on resource
    36   * bundles.
    37   *
    38   * <p>
    39   * See also {@link #getMessage(Enum, Object...)} for details.
    40   *
    41   * @author Ceki G&uuml;lc&uuml;
    42   */
    43  public class MessageConveyor implements IMessageConveyor {
    44
    45  	final Locale locale;
    46
    47  	final Map<String, CAL10NResourceBundle> cache = new ConcurrentHashMap<String, CAL10NResourceBundle>();
    48
    49  	/**
    50  	 * The {@link Locale} associated with this instance.
    51  	 *
    52  	 * @param locale
    53  	 */
    54  	public MessageConveyor(Locale locale) {
    55  		this.locale = locale;
    56  	}
    57
    58  	/**
    59  	 * Given an enum as key, find the corresponding resource bundle and return
    60  	 * the corresponding internationalized.
    61  	 *
    62  	 * <p>
    63  	 * The name of the resource bundle is defined via the {@link BaseName}
    64  	 * annotation whereas the locale is specified in this MessageConveyor
    65  	 * instance's constructor.
    66  	 *
    67  	 * @param key
    68  	 *            an enum instance used as message key
    69  	 *
    70  	 */
    71  	public <E extends Enum<?>> String getMessage(E key, Object... args)
    72  			throws MessageConveyorException {
    73
    74  		String declararingClassName = key.getDeclaringClass().getName();
    75  		CAL10NResourceBundle rb = cache.get(declararingClassName);
    76  		if (rb == null || rb.hasChanged()) {
    77  			rb = lookup(key);
    78  			cache.put(declararingClassName, rb);
    79  		}
    80
    81  		String keyAsStr = key.toString();
    82  		String value = rb.getString(keyAsStr);
    83  		if (value == null) {
    84  			return "No key found for " + keyAsStr;
    85  		} else {
    86  			if (args == null || args.length == 0) {
    87  				return value;
    88  			} else {
    89  				return MessageFormat.format(value, args);
    90  			}
    91  		}
    92  	}
    93
    94  	private <E extends Enum<?>> CAL10NResourceBundle lookup(E key)
    95  			throws MessageConveyorException {
    96  		Class<?> declaringClass = key.getDeclaringClass();
    97
    98  		String baseName = AnnotationExtractor.getBaseName(key
    99  				.getDeclaringClass());
    100 		if (baseName == null) {
    101 			throw new MessageConveyorException(
    102 					"Missing @BaseName annotation in enum type ["
    103 							+ key.getClass().getName() + "]. See also "
    104 							+ Cal10nConstants.MISSING_BN_ANNOTATION_URL);
    105 		}
    106
    107 		String charset = AnnotationExtractor.getCharset(declaringClass, locale);
    108 		// use the declaring class' loader instead of
    109 		// this.getClass().getClassLoader()
    110 		// see also http://jira.qos.ch/browse/CAL-8
    111 		CAL10NResourceBundle rb = CAL10NResourceBundleFinder.getBundle(
    112 				declaringClass.getClassLoader(), baseName, locale, charset);
    113
    114 		if (rb == null) {
    115 			throw new MessageConveyorException(
    116 					"Failed to locate resource bundle [" + baseName
    117 							+ "] for locale [" + locale + "] for enum type ["
    118 							+ key.getDeclaringClass().getName() + "]");
    119 		}
    120 		return rb;
    121 	}
    122
    123 	public String getMessage(MessageParameterObj mpo)
    124 			throws MessageConveyorException {
    125 		if (mpo == null) {
    126 			throw new IllegalArgumentException(
    127 					"MessageParameterObj argumument cannot be null");
    128 		}
    129 		return getMessage(mpo.getKey(), mpo.getArgs());
    130 	}
    131 }