// $HeadURL$
// $Id$
//
// Copyright © 2006, 2010, 2011, 2012 by the President and Fellows of Harvard College.
//
// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.
package edu.harvard.med.screensaver.ui.arch.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.faces.application.FacesMessage;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import edu.harvard.med.screensaver.util.Pair;
/**
* Spring-related utility methods for use by the web user interface. Provides access to
* messages. Queues message requests for display by the next rendered view, using {@link #getMessagesAndDequeue()}.
*
* @author <a mailto="john_sullivan@hms.harvard.edu">John Sullivan</a>
* @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a>
*/
public class Messages
{
private static final long serialVersionUID = 7593034897039616028L;
private static final Logger log = Logger.getLogger(Messages.class);
private static final Object [] EMPTY_ARGS = new Object[] {};
private static final String DEFAULT_MESSAGE = "<UNKNOWN MESSAGE>";
private MessageSource _messageSource;
// TODO: parameterize via Spring bean definition
private Locale _locale = Locale.ENGLISH;
private List<Pair<String,FacesMessage>> queuedFacesMessages;
/**
* Attach a <code>FacesMessage</code> to a specific UI component, based on the
* <code>message.properties</code> resource.
*
* @param messageKey the message key
* @param clientId the client ID of the UI component
* @param args arguments to the message
* @return the <code>FacesMessage</code>
*/
public FacesMessage setFacesMessageForComponent(String messageKey,
String clientId,
Object... args)
{
FacesMessage message = getFacesMessage(messageKey, args);
assert message != null : "expected non-null FacesMessage";
enqueueMessage(clientId, message);
return message;
}
public void enqueueMessage(String clientId, FacesMessage message)
{
getQueuedMessages().add(new Pair<String,FacesMessage>(clientId, message));
log.info("enqueued user message: " + message.getSummary());
}
public Locale getLocale()
{
return _locale;
}
public void setLocale(Locale locale)
{
_locale = locale;
}
public MessageSource getMessageSource()
{
return _messageSource;
}
public void setMessageSource(MessageSource messageSource)
{
_messageSource = messageSource;
}
public List<Pair<String,FacesMessage>> getQueuedMessages()
{
if (queuedFacesMessages == null) {
queuedFacesMessages = Lists.newArrayList();
}
return queuedFacesMessages;
}
public List<FacesMessage> getMessagesAndDequeue()
{
ArrayList<FacesMessage> facesMessages = Lists.newArrayList(Iterables.transform(getQueuedMessages(), Pair.<String,FacesMessage>toSecond()));
getQueuedMessages().clear();
return facesMessages;
}
/**
* Create and return a <code>FacesMessage</code> based on the <code>message.properties</code>
* resource.
*
* @param messageKey the message key
* @param args arguments to the message
* @return the <code>FacesMessage</code>
*/
FacesMessage getFacesMessage(String messageKey, Object[] args)
{
return getFacesMessage(FacesMessage.SEVERITY_ERROR, messageKey, args);
}
/**
* Create and return a <code>FacesMessage</code> based on the <code>message.properties</code>
* resource.
*
* @param severity the severity of the message
* @param messageKey the message key
* @param args arguments to the message
* @return the <code>FacesMessage</code>
*/
private FacesMessage getFacesMessage(
FacesMessage.Severity severity,
String messageKey,
Object[] args)
{
String message = _messageSource.getMessage(messageKey, args, DEFAULT_MESSAGE, _locale);
if (message.equals(DEFAULT_MESSAGE)) {
log.error("message not found for key '" + messageKey + "'");
message = "???"+ messageKey +"???";
}
// if detail is null, FacesMessage repeats summary when asked for detail! :(
return new FacesMessage(severity, message, "");
}
/**
* Create and return a formatted message based on the <code>message.properties</code>
* resource.
*
* @param messageKey the message key
* @param args arguments to the message
*/
public String getMessage(String messageKey, Object... args)
{
return _messageSource.getMessage(messageKey, args, "???" + messageKey +
"???", _locale);
}
}