001/*
002  GRANITE DATA SERVICES
003  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005  This file is part of Granite Data Services.
006
007  Granite Data Services is free software; you can redistribute it and/or modify
008  it under the terms of the GNU Library General Public License as published by
009  the Free Software Foundation; either version 2 of the License, or (at your
010  option) any later version.
011
012  Granite Data Services is distributed in the hope that it will be useful, but
013  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015  for more details.
016
017  You should have received a copy of the GNU Library General Public License
018  along with this library; if not, see <http://www.gnu.org/licenses/>.
019*/
020
021package org.granite.tide.seam;
022
023import static org.jboss.seam.annotations.Install.FRAMEWORK;
024
025import java.util.ArrayList;
026import java.util.HashMap;
027import java.util.List;
028import java.util.Map;
029
030import javax.faces.application.FacesMessage;
031import javax.faces.application.FacesMessage.Severity;
032import javax.faces.context.FacesContext;
033
034import org.granite.context.GraniteContext;
035import org.jboss.seam.ScopeType;
036import org.jboss.seam.annotations.AutoCreate;
037import org.jboss.seam.annotations.Install;
038import org.jboss.seam.annotations.Name;
039import org.jboss.seam.annotations.Scope;
040import org.jboss.seam.annotations.intercept.BypassInterceptors;
041import org.jboss.seam.faces.FacesMessages;
042
043/**
044 * TideMessages override to avoid problem with UIComponent targetted messages
045 * Cannot be used with Seam 2.1.x
046 * 
047 * @author William DRAI
048 */
049@Scope(ScopeType.CONVERSATION)
050@Name("org.jboss.seam.faces.facesMessages")
051@AutoCreate
052@Install(precedence=FRAMEWORK, classDependencies="javax.faces.context.FacesContext")
053@BypassInterceptors
054public class TideMessages extends FacesMessages {
055
056    private static final long serialVersionUID = -5395975397632138270L;
057    
058    private List<FacesMessage> facesMessages = new ArrayList<FacesMessage>();
059    private Map<String, List<FacesMessage>> keyedFacesMessages = new HashMap<String, List<FacesMessage>>();
060    
061    
062    /**
063     * Add a FacesMessage that will be used
064     * the next time a page is rendered.
065     */
066    @Override
067    public void add(FacesMessage facesMessage) {
068        GraniteContext context = GraniteContext.getCurrentInstance();
069        if (context == null) {
070            super.add(facesMessage);
071            return;
072        }
073        
074        if (facesMessage != null)
075            facesMessages.add(facesMessage);
076    }
077    
078    /**
079     * Add a templated FacesMessage that will be used
080     * the next time a page is rendered.
081     */
082    @Override
083    public void add(Severity severity, String messageTemplate, Object... params) {
084        GraniteContext context = GraniteContext.getCurrentInstance();
085        if (context == null) {
086            super.add(severity, messageTemplate, params);
087            return;
088        }
089        
090        facesMessages.add(createFacesMessage(severity, messageTemplate, params));
091    }
092    
093
094    /**
095     * Add a FacesMessage instance to a particular component id
096     * @param clientId component client id (same as Flex component Id)
097     * @param facesMessage message to add
098     */
099    @Override
100    public void addToControl(String clientId, FacesMessage facesMessage) {
101        GraniteContext context = GraniteContext.getCurrentInstance();
102        if (context == null) {
103            super.addToControl(clientId, facesMessage);
104            return;
105        }
106        
107        if (facesMessage != null) {
108            List<FacesMessage> list = keyedFacesMessages.get(clientId);
109            if (list == null) {
110                list = new ArrayList<FacesMessage>();
111                keyedFacesMessages.put(clientId, list);
112            }
113            list.add(facesMessage);
114        }
115    }
116    
117    
118    /**
119     * Get all faces messages that have already been added
120     * to the context.
121     * 
122     * @return a list of messages
123     */
124    @Override
125    public List<FacesMessage> getCurrentMessages() {
126        GraniteContext context = GraniteContext.getCurrentInstance();
127        if (context == null)
128            return super.getCurrentMessages();
129        
130        List<FacesMessage> msgs = new ArrayList<FacesMessage>(facesMessages);
131        for (List<FacesMessage> km : keyedFacesMessages.values())
132            msgs.addAll(km);
133        return msgs;
134    }
135    
136    /**
137     * Get all faces global messages that have already been added
138     * to the context.
139     * 
140     * @return a list of global messages
141     */
142    @Override
143    public List<FacesMessage> getCurrentGlobalMessages() {
144        GraniteContext context = GraniteContext.getCurrentInstance();
145        if (context == null)
146            return super.getCurrentGlobalMessages();
147        
148        return new ArrayList<FacesMessage>(facesMessages);
149    }
150    
151    /**
152     * Get all faces messages that have already been added
153     * to the control.
154     * 
155     * @return a list of messages
156     */
157    @Override
158    public List<FacesMessage> getCurrentMessagesForControl(String clientId) {
159        GraniteContext context = GraniteContext.getCurrentInstance();
160        if (context == null)
161            return super.getCurrentMessagesForControl(clientId);
162        
163        return new ArrayList<FacesMessage>(keyedFacesMessages.get(clientId));
164    }
165    
166    
167    /**
168     * Clear facesMessages storing specific to Tide
169     */
170    public void clearTideMessages() {
171        //Clear facesMessages storing specific to Tide
172        if (facesMessages != null && facesMessages.size() > 0)
173            facesMessages.clear();
174
175        if (keyedFacesMessages != null && keyedFacesMessages.size() > 0)
176            keyedFacesMessages.clear();
177    }
178
179    
180    /**
181     * Get messages
182     */
183    @Override
184    public void beforeRenderResponse() {
185        GraniteContext context = GraniteContext.getCurrentInstance();
186        if (context != null) {
187            for (Map.Entry<String, List<FacesMessage>> entry : keyedFacesMessages.entrySet()) {
188                for (FacesMessage msg: entry.getValue())
189                    FacesContext.getCurrentInstance().addMessage(entry.getKey(), msg);
190            }
191        }
192        
193        super.beforeRenderResponse();
194    }
195}