package dev.lions.utils; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.ResourceBundle; import java.util.Locale; /** * Utilitaire pour la gestion des messages dans l'interface utilisateur. * Cette classe fournit des méthodes centralisées pour l'affichage de messages * et notifications avec support de la localisation. */ @Slf4j public final class MessageUtils { private static final String MESSAGE_BUNDLE = "messages"; private static final int MAX_MESSAGES = 10; // Constructeur privé pour empêcher l'instanciation private MessageUtils() { throw new AssertionError("Cette classe utilitaire ne doit pas être instanciée"); } /** * Ajoute un message de succès. * * @param summary Titre du message * @param detail Détail du message */ public static void addSuccessMessage(@NotBlank String summary, String detail) { log.debug("Ajout d'un message de succès : {}", summary); addMessage(FacesMessage.SEVERITY_INFO, summary, detail); } /** * Ajoute un message d'erreur. * * @param summary Titre du message * @param detail Détail du message */ public static void addErrorMessage(@NotBlank String summary, String detail) { log.warn("Ajout d'un message d'erreur : {}", summary); addMessage(FacesMessage.SEVERITY_ERROR, summary, detail); } /** * Ajoute un message d'avertissement. * * @param summary Titre du message * @param detail Détail du message */ public static void addWarningMessage(@NotBlank String summary, String detail) { log.debug("Ajout d'un message d'avertissement : {}", summary); addMessage(FacesMessage.SEVERITY_WARN, summary, detail); } /** * Ajoute un message avec clés de traduction. * * @param severity Niveau de gravité du message * @param summaryKey Clé de traduction du titre * @param detailKey Clé de traduction du détail */ public static void addMessageWithKey( @NotNull FacesMessage.Severity severity, @NotBlank String summaryKey, String detailKey) { ResourceBundle bundle = getMessageBundle(); String summary = getTranslation(bundle, summaryKey, summaryKey); String detail = detailKey != null ? getTranslation(bundle, detailKey, detailKey) : null; addMessage(severity, summary, detail); } /** * Ajoute un message avec paramètres de substitution. * * @param severity Niveau de gravité du message * @param summaryKey Clé de traduction du titre * @param detailKey Clé de traduction du détail * @param params Paramètres de substitution */ public static void addMessageWithParams( @NotNull FacesMessage.Severity severity, @NotBlank String summaryKey, String detailKey, Object... params) { ResourceBundle bundle = getMessageBundle(); String summary = formatMessage(getTranslation(bundle, summaryKey, summaryKey), params); String detail = detailKey != null ? formatMessage(getTranslation(bundle, detailKey, detailKey), params) : null; addMessage(severity, summary, detail); } /** * Vérifie s'il existe des messages d'erreur. * * @return true si des erreurs sont présentes */ public static boolean hasErrorMessages() { return FacesContext.getCurrentInstance() .getMessageList() .stream() .anyMatch(m -> m.getSeverity() == FacesMessage.SEVERITY_ERROR); } /** * Récupère tous les messages actuels. * * @return Liste des messages */ public static List getCurrentMessages() { return FacesContext.getCurrentInstance().getMessageList(); } /** * Efface tous les messages actuels. */ public static void clearMessages() { FacesContext.getCurrentInstance().getMessageList().clear(); } /** * Ajoute un message dans le contexte Faces. */ private static void addMessage( FacesMessage.Severity severity, String summary, String detail) { // Limite le nombre de messages pour éviter une surcharge if (getCurrentMessages().size() >= MAX_MESSAGES) { log.warn("Nombre maximum de messages atteint ({})", MAX_MESSAGES); return; } FacesMessage message = new FacesMessage(severity, summary, detail); FacesContext.getCurrentInstance().addMessage(null, message); } /** * Récupère le bundle de messages pour la locale courante. */ private static ResourceBundle getMessageBundle() { Locale locale = FacesContext.getCurrentInstance() .getViewRoot() .getLocale(); return ResourceBundle.getBundle(MESSAGE_BUNDLE, locale); } /** * Récupère une traduction avec fallback. */ private static String getTranslation( ResourceBundle bundle, String key, String defaultValue) { try { return bundle.getString(key); } catch (Exception e) { log.warn("Clé de traduction non trouvée : {}", key); return defaultValue; } } /** * Formate un message avec des paramètres. */ private static String formatMessage(String message, Object... params) { try { return String.format(message, params); } catch (Exception e) { log.warn("Erreur lors du formatage du message : {}", e.getMessage()); return message; } } }