From seam-commits at lists.jboss.org Fri Apr 30 16:27:10 2010 Content-Type: multipart/mixed; boundary="===============7647811130887409129==" MIME-Version: 1.0 From: seam-commits at lists.jboss.org To: seam-commits at lists.jboss.org Subject: [seam-commits] Seam SVN: r12669 - in modules/faces/trunk: api/src/main/java/org/jboss/seam/faces/display and 3 other directories. Date: Fri, 30 Apr 2010 16:27:10 -0400 Message-ID: <201004302027.o3UKRApr019506@svn01.web.mwc.hst.phx2.redhat.com> --===============7647811130887409129== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: lincolnthree Date: 2010-04-30 16:27:09 -0400 (Fri, 30 Apr 2010) New Revision: 12669 Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Level= .java modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Messa= ge.java modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Messa= ges.java modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/Seam= Message.java modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/Seam= Messages.java Modified: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/Flas= hScopedContext.java modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml Log: Fixed the flash scope Implemented first generation Messages API Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/L= evel.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Leve= l.java (rev 0) +++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Leve= l.java 2010-04-30 20:27:09 UTC (rev 12669) @@ -0,0 +1,28 @@ +/** + * = + */ +package org.jboss.seam.faces.display; + +import javax.faces.application.FacesMessage; +import javax.faces.application.FacesMessage.Severity; + +/** + * @author Lincoln Baxter, II= I + * = + */ +public enum Level +{ + INFO(FacesMessage.SEVERITY_INFO), WARN(FacesMessage.SEVERITY_WARN), ERR= OR(FacesMessage.SEVERITY_ERROR), FATAL(FacesMessage.SEVERITY_FATAL); + + private Severity severity; + + Level(final Severity severity) + { + this.severity =3D severity; + } + + public Severity getSeverity() + { + return severity; + } +} \ No newline at end of file Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/M= essage.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Mess= age.java (rev 0) +++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Mess= age.java 2010-04-30 20:27:09 UTC (rev 12669) @@ -0,0 +1,47 @@ +package org.jboss.seam.faces.display; + +import java.io.Serializable; + +/** + * A convenient message to be displayed to the user as Feedback, Toast, Al= erts, + * etc... See {@link Messages} for usage. + * = + * @author Lincoln Baxter, II= I + */ +public interface Message extends Serializable +{ + /** + * Set the message summary to be displayed if the output component is e= nabled + * to display summary. This is the primary text of the message. + * = + * @param message + * @return The builder pattern {@link Message} + */ + Message summary(String message); + + /** + * Set the message details to be displayed if the output component is e= nabled + * to display detail. This is the secondary text of the message. + * = + * @return The builder pattern {@link Message} + */ + Message details(String details); + + /** + * Specifies that this message should be displayed by the corresponding + * <h:message for=3D"clientId" /> tag, where clientI= d is the + * ID of the component to which this message belongs. + * = + * @param The clientId of the component to which this message should be + * attached/displayed + */ + Message component(String clientId); + + public Level getLevel(); + + public String getMessage(); + + public String getDetails(); + + public String getClientId(); +} \ No newline at end of file Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/M= essages.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Mess= ages.java (rev 0) +++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/display/Mess= ages.java 2010-04-30 20:27:09 UTC (rev 12669) @@ -0,0 +1,36 @@ +package org.jboss.seam.faces.display; + +import java.util.Set; + +/** + * A convenient way to add messages to be displayed to the user as Feedback + * messages, Toast, Alerts, etc... + * = + * Messages can be displayed by using the <h:messages /> tag + * in any given View. + * = + * @author Lincoln Baxter, II= I + */ +public interface Messages +{ + /** + * Create a new {@link Message} object and add it to the pending message + * cache. Messages remain pending until the Render Response phase is ne= xt + * invoked. E.g: If a redirect is issued before Render Response occurs, + * messages will be displayed during the next Render Response phase unl= ess + * {@link Messages#clear()} is called, or the user's Session expires. + *

+ * Note: Duplicate messages are ignored. + */ + Message add(Level level); + + /** + * Retrieve all pending messages. + */ + Set getAll(); + + /** + * Clears all pending messages. + */ + void clear(); +} \ No newline at end of file Modified: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/conte= xt/FlashScopedContext.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/Fla= shScopedContext.java 2010-04-30 16:11:01 UTC (rev 12668) +++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/context/Fla= shScopedContext.java 2010-04-30 20:27:09 UTC (rev 12669) @@ -21,6 +21,7 @@ */ package org.jboss.seam.faces.context; = +import java.io.IOException; import java.lang.annotation.Annotation; import java.util.Map; import java.util.Map.Entry; @@ -30,6 +31,7 @@ import javax.enterprise.context.spi.Context; import javax.enterprise.context.spi.Contextual; import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.event.Observes; import javax.faces.bean.FlashScoped; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; @@ -37,6 +39,9 @@ import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; +import javax.faces.event.PreRenderViewEvent; +import javax.inject.Inject; +import javax.servlet.ServletRequest; = /** * This class provides the lifecycle for the new JSF 2 Flash Context @@ -45,157 +50,183 @@ */ public class FlashScopedContext implements Context, PhaseListener { - private static final long serialVersionUID =3D -1580689204988513798L; + private static final long serialVersionUID =3D -1580689204988513798L; = - private final static String COMPONENT_MAP_NAME =3D "org.jboss.seam.fac= es.flash.componentInstanceMap"; - private final static String CREATIONAL_MAP_NAME =3D "org.jboss.seam.fa= ces.flash.creationalInstanceMap"; - private final ThreadLocal, Object>> lastComponentIns= tanceMap =3D new ThreadLocal, Object>>(); - private final ThreadLocal, CreationalContext>> la= stCreationalContextMap =3D new ThreadLocal, CreationalCon= text>>(); + final static String COMPONENT_MAP_NAME =3D "org.jboss.seam.faces.flash.= componentInstanceMap"; + final static String CREATIONAL_MAP_NAME =3D "org.jboss.seam.faces.flash= .creationalInstanceMap"; = - @SuppressWarnings("unchecked") - public T get(final Contextual component) - { - assertActive(); - return (T) getComponentInstanceMap().get(component); - } + @SuppressWarnings("unchecked") + public T get(final Contextual component) + { + assertActive(); + return (T) getComponentInstanceMap().get(component); + } = - @SuppressWarnings("unchecked") - public T get(final Contextual component, final CreationalContex= t creationalContext) - { - assertActive(); + @SuppressWarnings("unchecked") + public T get(final Contextual component, final CreationalContext= creationalContext) + { + assertActive(); = - T instance =3D get(component); + T instance =3D get(component); = - if (instance =3D=3D null) - { - Map, CreationalContext> creationalContextMap = =3D getCreationalContextMap(); - Map, Object> componentInstanceMap =3D getCompone= ntInstanceMap(); + if (instance =3D=3D null) + { + Map, CreationalContext> creationalContextMap =3D= getCreationalContextMap(); + Map, Object> componentInstanceMap =3D getComponentI= nstanceMap(); = - synchronized (componentInstanceMap) + synchronized (componentInstanceMap) + { + instance =3D (T) componentInstanceMap.get(component); + if (instance =3D=3D null) { - instance =3D (T) componentInstanceMap.get(component); - if (instance =3D=3D null) - { - instance =3D component.create(creationalContext); + instance =3D component.create(creationalContext); = - if (instance !=3D null) - { - componentInstanceMap.put(component, instance); - creationalContextMap.put(component, creationalCont= ext); - } - } + if (instance !=3D null) + { + componentInstanceMap.put(component, instance); + creationalContextMap.put(component, creationalContext); + } } - } + } + } = - return instance; - } + return instance; + } = - public Class getScope() - { - return FlashScoped.class; - } + public Class getScope() + { + return FlashScoped.class; + } = - public boolean isActive() - { - return getFlash() !=3D null; - } + public boolean isActive() + { + return getFlash() !=3D null; + } = - /** - * This method should, **in theory**, catch the current instanceMap (w= hich - * is the previous lifecycle's next instanceMap.) These are the object= s that - * we want cleaned up at the end of the current render-response phase,= so we - * save them here until after the RENDER_RESPONSE phase, because other= wise - * they would have been destroyed by the Flash, and we would no longer= have - * access to them. - */ - public void beforePhase(final PhaseEvent event) - { - this.lastComponentInstanceMap.set(getComponentInstanceMap()); - this.lastCreationalContextMap.set(getCreationalContextMap()); - } + @Inject + FacesContext context; = - /** - * Do the object cleanup using our saved references. - */ - @SuppressWarnings("unchecked") - public void afterPhase(final PhaseEvent event) - { - // TODO verify that this is actually destroying the beans we want = to be - // destroyed... flash is confusing, tests will make sense of it - Map, Object> componentInstanceMap =3D lastComponentI= nstanceMap.get(); - Map, CreationalContext> creationalContextMap =3D = lastCreationalContextMap.get(); + /** + * This method ensures that the contextual maps are populated before + * rendering occurs (thus, before any contextual objects are created du= ring + * the Render Response phase.) + *

+ * This method also ensures that the maps are available after Flash.cle= ar() + * is called immediately before Render Response is complete. + * = + * @param event + * @throws IOException + */ + public void retrieveContextualMaps(@Observes final PreRenderViewEvent e= vent) throws IOException + { + ExternalContext externalContext =3D context.getExternalContext(); + Object temp =3D externalContext.getRequest(); + if (temp instanceof ServletRequest) + { + Object componentMap =3D getComponentInstanceMap(); + Object creationalMap =3D getCreationalContextMap(); = - if (componentInstanceMap !=3D null) - { - for (Entry, Object> componentEntry : componentIn= stanceMap.entrySet()) + ServletRequest request =3D (ServletRequest) temp; + request.setAttribute(FlashScopedContext.COMPONENT_MAP_NAME, compo= nentMap); + request.setAttribute(FlashScopedContext.CREATIONAL_MAP_NAME, crea= tionalMap); + } + } + + public void beforePhase(final PhaseEvent event) + { + } + + /** + * This method saves the current scope metadata into the Flash after Re= store + * View, then destroys the metadata after Render Response. Since the cu= rrent + * request's execution Flash is swapped with the last requests execution + * flash for the Render Response phase, the last request's execution fl= ash is + * actually the one that gets cleaned up. + *

+ * Preserve this request's new metadata. Do the object cleanup using our + * saved references from last request. + */ + @SuppressWarnings("unchecked") + public void afterPhase(final PhaseEvent event) + { + if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId())) + { + ExternalContext externalContext =3D event.getFacesContext().getEx= ternalContext(); + Object temp =3D externalContext.getRequest(); + if (temp instanceof ServletRequest) + { + ServletRequest request =3D (ServletRequest) temp; + + Map, Object> componentInstanceMap =3D (Map, Object>) request.getAttribute(FlashScopedContext.COMPONENT_MAP_NA= ME); + Map, CreationalContext> creationalContextMap = =3D (Map, CreationalContext>) request.getAttribute(FlashSc= opedContext.CREATIONAL_MAP_NAME); + + if ((componentInstanceMap !=3D null) && (creationalContextMap = !=3D null)) { - Contextual contextual =3D componentEntry.getKey(); - Object instance =3D componentEntry.getValue(); - CreationalContext creational =3D creationalContextMap.get(= contextual); + for (Entry, Object> componentEntry : componen= tInstanceMap.entrySet()) + { + Contextual contextual =3D componentEntry.getKey(); + Object instance =3D componentEntry.getValue(); + CreationalContext creational =3D creationalContextMap.ge= t(contextual); = - contextual.destroy(instance, creational); + contextual.destroy(instance, creational); + } } - } + } + } + } = - this.lastComponentInstanceMap.remove(); - this.lastCreationalContextMap.remove(); - } + public PhaseId getPhaseId() + { + return PhaseId.ANY_PHASE; + } = - public PhaseId getPhaseId() - { - return PhaseId.RENDER_RESPONSE; - } + private Flash getFlash() + { + FacesContext currentInstance =3D FacesContext.getCurrentInstance(); + if (currentInstance !=3D null) + { + ExternalContext externalContext =3D currentInstance.getExternalCo= ntext(); + return externalContext.getFlash(); + } + return null; + } = - private Flash getFlash() - { - FacesContext currentInstance =3D FacesContext.getCurrentInstance(); - if (currentInstance !=3D null) - { - ExternalContext externalContext =3D currentInstance.getExterna= lContext(); - return externalContext.getFlash(); - } - return null; - } + private void assertActive() + { + if (!isActive()) + { + throw new ContextNotActiveException("Seam context with scope anno= tation @FlashScoped is not active with respect to the current thread"); + } + } = - private void assertActive() - { - if (!isActive()) - { - throw new ContextNotActiveException( - "Seam context with scope annotation @FlashScoped is no= t active with respect to the current thread"); - } - } + @SuppressWarnings("unchecked") + private Map, Object> getComponentInstanceMap() + { + Flash flash =3D getFlash(); + ConcurrentHashMap, Object> map =3D (ConcurrentHashMap<= Contextual, Object>) flash.get(COMPONENT_MAP_NAME); = - @SuppressWarnings("unchecked") - private Map, Object> getComponentInstanceMap() - { - Flash flash =3D getFlash(); - ConcurrentHashMap, Object> map =3D (ConcurrentHashMa= p, Object>) flash - .get(COMPONENT_MAP_NAME); + if (map =3D=3D null) + { + map =3D new ConcurrentHashMap, Object>(); + flash.put(COMPONENT_MAP_NAME, map); + } = - if (map =3D=3D null) - { - map =3D new ConcurrentHashMap, Object>(); - flash.put(COMPONENT_MAP_NAME, map); - } + return map; + } = - return map; - } + @SuppressWarnings("unchecked") + private Map, CreationalContext> getCreationalContextMa= p() + { + Flash flash =3D getFlash(); + Map, CreationalContext> map =3D (ConcurrentHashMap<= Contextual, CreationalContext>) flash.get(CREATIONAL_MAP_NAME); = - @SuppressWarnings("unchecked") - private Map, CreationalContext> getCreationalContextM= ap() - { - Flash flash =3D getFlash(); - Map, CreationalContext> map =3D (ConcurrentHashMa= p, CreationalContext>) flash - .get(CREATIONAL_MAP_NAME); + if (map =3D=3D null) + { + map =3D new ConcurrentHashMap, CreationalContext= >(); + flash.put(CREATIONAL_MAP_NAME, map); + } = - if (map =3D=3D null) - { - map =3D new ConcurrentHashMap, CreationalContext= >(); - flash.put(CREATIONAL_MAP_NAME, map); - } + return map; + } = - return map; - } - } Added: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/= SeamMessage.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/Sea= mMessage.java (rev 0) +++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/Sea= mMessage.java 2010-04-30 20:27:09 UTC (rev 12669) @@ -0,0 +1,159 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2010, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This 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 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.seam.faces.display; + +/** + * @author Lincoln Baxter, III= + * = + */ +public class SeamMessage implements Message +{ + private static final long serialVersionUID =3D 6650116552438358826L; + + private String message; + private String details; + private String clientId; + private final Level level; + + public SeamMessage(final Level level) + { + this.level =3D level; + } + + public Message component(final String clientId) + { + this.clientId =3D clientId; + return this; + } + + public Message details(final String details) + { + this.details =3D details; + return this; + } + + public Message summary(final String message) + { + this.message =3D message; + return this; + } + + /* + * Getters & Setters + */ + public Level getLevel() + { + return level; + } + + public String getMessage() + { + return message; + } + + public String getDetails() + { + return details; + } + + public String getClientId() + { + return clientId; + } + + @Override + public int hashCode() + { + final int prime =3D 31; + int result =3D 1; + result =3D prime * result + ((clientId =3D=3D null) ? 0 : clientId.h= ashCode()); + result =3D prime * result + ((details =3D=3D null) ? 0 : details.has= hCode()); + result =3D prime * result + ((level =3D=3D null) ? 0 : level.hashCod= e()); + result =3D prime * result + ((message =3D=3D null) ? 0 : message.has= hCode()); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this =3D=3D obj) + { + return true; + } + if (obj =3D=3D null) + { + return false; + } + if (getClass() !=3D obj.getClass()) + { + return false; + } + SeamMessage other =3D (SeamMessage) obj; + if (clientId =3D=3D null) + { + if (other.clientId !=3D null) + { + return false; + } + } + else if (!clientId.equals(other.clientId)) + { + return false; + } + if (details =3D=3D null) + { + if (other.details !=3D null) + { + return false; + } + } + else if (!details.equals(other.details)) + { + return false; + } + if (level =3D=3D null) + { + if (other.level !=3D null) + { + return false; + } + } + else if (!level.equals(other.level)) + { + return false; + } + if (message =3D=3D null) + { + if (other.message !=3D null) + { + return false; + } + } + else if (!message.equals(other.message)) + { + return false; + } + return true; + } + +} Added: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/= SeamMessages.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/Sea= mMessages.java (rev 0) +++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/display/Sea= mMessages.java 2010-04-30 20:27:09 UTC (rev 12669) @@ -0,0 +1,80 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2010, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This 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 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.seam.faces.display; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Observes; +import javax.faces.application.FacesMessage; +import javax.faces.event.PhaseEvent; + +import org.jboss.seam.faces.event.qualifier.Before; +import org.jboss.seam.faces.event.qualifier.RenderResponse; + +/** + * @author Lincoln Baxter, III= + * = + */ +(a)SessionScoped +public class SeamMessages implements Messages, Serializable +{ + private static final long serialVersionUID =3D -2908193057765795662L; + private final Set messages =3D Collections.synchronizedSet(new= HashSet()); + + @SuppressWarnings("unused") + private void convert(@Observes @Before @RenderResponse final PhaseEvent= event) + { + for (Message m : messages) + { + event.getFacesContext().addMessage(m.getClientId(), new FacesMess= age(m.getLevel().getSeverity(), m.getMessage(), m.getDetails())); + } + clear(); + } + + public void clear() + { + messages.clear(); + } + + public Message add(final Level level) + { + Message result =3D new SeamMessage(level); + messages.add(result); + return result; + } + + public Set getAll() + { + Set result; + synchronized (messages) + { + result =3D Collections.unmodifiableSet(messages); + } + return result; + } + +} Modified: modules/faces/trunk/impl/src/main/resources/META-INF/faces-config= .xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml 2= 010-04-30 16:11:01 UTC (rev 12668) +++ modules/faces/trunk/impl/src/main/resources/META-INF/faces-config.xml 2= 010-04-30 20:27:09 UTC (rev 12669) @@ -42,6 +42,10 @@ org.jboss.seam.faces.event.DelegatingSyste= mEventListener javax.faces.event.PreDestroyCustomScopeEvent + + org.jboss.seam.faces.event.DelegatingSyste= mEventListener + javax.faces.event.PreRenderViewEvent + = --===============7647811130887409129==--