/*
* Copyright (C) Heavy Lifting Software 2007.
*
* This file is part of MouseFeed.
*
* MouseFeed is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MouseFeed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with MouseFeed. If not, see <http://www.gnu.org/licenses/>.
*/
package com.mousefeed.client;
import static org.apache.commons.lang.StringUtils.isBlank;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Provides localized messages. Messages are retrieved with
* {@link #get(String, Object...)}. If it is be provided with a class to
* retrieve the messages for, one can drop this class name from the key names.
*
* @see #get(String, Object...)
* @author Andriy Palamarchuk
*/
public class Messages {
/**
* The base name of the messages properties file for {@link #BUNDLE}.
*/
private static final String MESSAGES_BASE = Messages.class.getPackage()
.getName() + ".messages";
/**
* The messages resource bundle.
*/
private static final ResourceBundle BUNDLE = ResourceBundle
.getBundle(MESSAGES_BASE);
/**
* The class to find messages for by using keys missing class name.
*/
private final Class<?> forClass;
/**
* Constructor. For an object created by this constructor it is necessary to
* pass full message key to {@link #get(String, Object...)}.
*
* @see #Messages(Class)
*/
public Messages() {
this(AbstractNoForClassIsSpecified.class);
}
/**
* Constructor. For an object created by this constructor the messages
* associated with the specified class can be retrieved by passing a key
* part after class base name as well as full message key to
* {@link #get(String, Object...)}.
*
* @param forClass
* the class to retrieve messages for. Passing <code>null</code>
* value is equivalent to {@link #Messages()}.
* @see #get(String, Object...)
*/
public Messages(final Class<?> forClass) {
this.forClass = forClass == null ? AbstractNoForClassIsSpecified.class
: forClass;
}
/**
* Returns the message for the defined key. If the object is provided with a
* class to retrieve messages for (e.g. is created with
* {@link #Messages(Class)}), this method tries to retrieve the message on a
* key composed with that class name and the provided key. If the message is
* not found, it finds the message using the provided key as is. If no class
* is provided, the method returns searches the message using the provided
* key.
*
* @param key
* the message id. Not <code>null</code> or empty string.
* @param arguments
* the message arguments when the message will be formatted by
* {@link MessageFormat#format}.
* @return the message for the defined key. Never <code>null</code>.
* @throws NullPointerException
* if the provided key is blank.
* @throws MissingResourceException
* if the provided key is not found.
*/
public String get(final String key, final Object... arguments)
throws NullPointerException, MissingResourceException {
if (isBlank(key)) {
throw new NullPointerException("Blank key was provided: '" + key
+ "'");
}
try {
final String forClassKey = forClass.getSimpleName() + "." + key;
return getFromBundle(forClassKey, arguments);
} catch (final MissingResourceException e) {
return getFromBundle(key, arguments);
}
}
/**
* Retrieves the string specified by the key from bundle.
*
* @param key
* the message key. Not blank.
* @return the message by the key. The message is formatted with
* {@link MessageFormat#format(Object)} if any arguments are
* provided.
*/
private String getFromBundle(final String key, final Object... arguments) {
final String pattern = BUNDLE.getString(key);
return arguments.length == 0 ? pattern : MessageFormat.format(pattern,
arguments);
}
/**
* A "null" class used to initialize {@link Messages#forClass} if no class
* is specified.
*/
private abstract static class AbstractNoForClassIsSpecified {
}
}