package org.gluu.jsf2.message;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;

import org.xdi.service.el.ExpressionEvaluator;

/**
 * @author Yuriy Movchan
 * @version 05/06/2017
 */
@RequestScoped
public class FacesMessages implements Serializable {

    private static final long serialVersionUID = -6408439483194578659L;

    @Inject
    private FacesContext facesContext;

    @Inject
    private ExternalContext externalContext;

    @Inject
    private ExpressionEvaluator expressionEvaluator;

    public void add(Severity severity, String message) {
        add(null, severity, message);
    }

    public void add(String clientId, Severity severity, String message) {
        if (facesContext == null) {
            return;
        }

        String evaluatedMessage = evalAsString(message);
        facesContext.addMessage(clientId, new FacesMessage(severity, evaluatedMessage, evaluatedMessage));
        setKeepMessages();
    }

    public void add(Severity severity, String message, Object ... params) {
        String fomrattedMessage = String.format(message, params);

        add(severity, fomrattedMessage);
        setKeepMessages();
    }

    public void setKeepMessages() {
        if (externalContext == null) {
            return;
        }

        externalContext.getFlash().setKeepMessages(true);
    }

    public void clear() {
        if (facesContext == null) {
            return;
        }

        Iterator<FacesMessage> messages = facesContext.getMessages();
        while (messages.hasNext()) {
            messages.next();
            messages.remove();
        }
    }

    public String evalAsString(String expression) {
        if (facesContext == null) {
            return expression;
        }

        ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
        ELContext elContext = facesContext.getELContext();
        ValueExpression valueExpression = expressionFactory.createValueExpression(elContext, expression, String.class);
        String result = (String) valueExpression.getValue(elContext);

        return result;
    }

    public String evalResourceAsString(String resource) {
        // Get resource message
        String resourceMessage = evalAsString(resource);

        // Evaluate resource message
        String message = evalAsString(resourceMessage);

        return message;
    }

    public String evalAsString(String expression, Map<String, Object> parameters) {
        return expressionEvaluator.evaluateValueExpression(expression, String.class, parameters);
    }

}

@@ -54,16 +54,42 @@
 izable;%0A
+import java.util.HashMap;%0A
 import j
@@ -130,16 +130,55 @@
 l.Map;%0A%0A
+import javax.annotation.PostConstruct;%0A
 import j
@@ -944,16 +944,186 @@
 aluator;
+%0A    %0A    private HashMap%3CString, FacesMessage%3E messages;%0A%0A    @PostConstruct%0A    private void init() %7B%0A        this.messages = new HashMap%3CString, FacesMessage%3E();%0A    %7D
 %0A%0A    pu
@@ -1428,41 +1428,35 @@
     
-f
+F
 aces
-Context.addMessage(clientId,
+Message facesMessage =
  new
@@ -1514,16 +1514,127 @@
 Message)
+;%0A        facesContext.addMessage(clientId, facesMessage);%0A        %0A        messages.put(clientId, facesMessage
 );%0A     
@@ -2073,24 +2073,51 @@
 d clear() %7B%0A
+        messages.clear();%0A%0A
         if (
@@ -3327,10 +3327,99 @@
 %0A    %7D%0A%0A
+    public HashMap%3CString, FacesMessage%3E getMessages() %7B%0A        return messages;%0A    %7D%0A%0A
 %7D%0A

Store added messages