diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java index eb505dff..f83ceb73 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java @@ -16,9 +16,7 @@ package org.springframework.faces.webflow; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import javax.el.ELContext; import javax.faces.FactoryFinder; @@ -33,14 +31,8 @@ import javax.faces.context.ResponseWriter; import javax.faces.lifecycle.Lifecycle; import javax.faces.render.RenderKit; -import org.springframework.binding.message.Message; -import org.springframework.binding.message.MessageBuilder; -import org.springframework.binding.message.MessageCriteria; -import org.springframework.binding.message.MessageResolver; -import org.springframework.binding.message.Severity; import org.springframework.context.MessageSource; import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; import org.springframework.webflow.execution.RequestContext; /** @@ -50,6 +42,7 @@ import org.springframework.webflow.execution.RequestContext; * requests in the case of the POST+REDIRECT+GET pattern being enabled. * * @author Jeremy Grelle + * @author Phil Webb */ public class FlowFacesContext extends FacesContext { @@ -58,21 +51,13 @@ public class FlowFacesContext extends FacesContext { */ static final String RENDER_RESPONSE_KEY = "flowRenderResponse"; - /** - * Key for identifying summary messages - */ - static final String SUMMARY_MESSAGE_KEY = "_summary"; - - /** - * Key for identifying detail messages - */ - static final String DETAIL_MESSAGE_KEY = "_detail"; - /** * The key for storing the renderResponse flag */ private RequestContext context; + private FlowFacesContextMessageDelegate messageDelegate; + /** * The base FacesContext delegate */ @@ -90,6 +75,7 @@ public class FlowFacesContext extends FacesContext { public FlowFacesContext(RequestContext context, FacesContext delegate) { this.context = context; this.delegate = delegate; + this.messageDelegate = new FlowFacesContextMessageDelegate(context); setCurrentInstance(this); } @@ -97,61 +83,14 @@ public class FlowFacesContext extends FacesContext { * Translates a FacesMessage to an SWF Message and adds it to the current MessageContext */ public void addMessage(String clientId, FacesMessage message) { - String source = null; - if (StringUtils.hasText(clientId)) { - source = clientId; - } - - StringBuffer summaryText = new StringBuffer(); - if (StringUtils.hasText(message.getSummary())) { - summaryText.append(message.getSummary()); - } - - String summarySource = source + SUMMARY_MESSAGE_KEY; - MessageResolver summaryResolver; - if (message.getSeverity() == FacesMessage.SEVERITY_INFO) { - summaryResolver = new MessageBuilder().source(summarySource).defaultText(summaryText.toString()).info() - .build(); - } else if (message.getSeverity() == FacesMessage.SEVERITY_WARN) { - summaryResolver = new MessageBuilder().source(summarySource).defaultText(summaryText.toString()).warning() - .build(); - } else if (message.getSeverity() == FacesMessage.SEVERITY_ERROR) { - summaryResolver = new MessageBuilder().source(summarySource).defaultText(summaryText.toString()).error() - .build(); - } else { - summaryResolver = new MessageBuilder().source(summarySource).defaultText(summaryText.toString()).fatal() - .build(); - } - context.getMessageContext().addMessage(summaryResolver); - - StringBuffer detailText = new StringBuffer(); - if (StringUtils.hasText(message.getDetail())) { - detailText.append(message.getDetail()); - } - String detailSource = source + DETAIL_MESSAGE_KEY; - MessageResolver detailResolver; - if (message.getSeverity() == FacesMessage.SEVERITY_INFO) { - detailResolver = new MessageBuilder().source(detailSource).defaultText(detailText.toString()).info() - .build(); - } else if (message.getSeverity() == FacesMessage.SEVERITY_WARN) { - detailResolver = new MessageBuilder().source(detailSource).defaultText(detailText.toString()).warning() - .build(); - } else if (message.getSeverity() == FacesMessage.SEVERITY_ERROR) { - detailResolver = new MessageBuilder().source(detailSource).defaultText(detailText.toString()).error() - .build(); - } else { - detailResolver = new MessageBuilder().source(detailSource).defaultText(detailText.toString()).fatal() - .build(); - } - context.getMessageContext().addMessage(detailResolver); - + messageDelegate.addMessage(clientId, message); } /** * Returns an Iterator for all component clientId's for which messages have been added. */ public Iterator getClientIdsWithMessages() { - return new ClientIdIterator(); + return messageDelegate.getClientIdsWithMessages(); } /** @@ -159,27 +98,14 @@ public class FlowFacesContext extends FacesContext { * associated with any specific UIComponent. If no such messages have been queued, return null. */ public FacesMessage.Severity getMaximumSeverity() { - if (context.getMessageContext().getAllMessages().length == 0) { - return null; - } - FacesMessage.Severity max = FacesMessage.SEVERITY_INFO; - Iterator i = getMessages(); - while (i.hasNext()) { - FacesMessage message = (FacesMessage) i.next(); - if (message.getSeverity().getOrdinal() > max.getOrdinal()) { - max = message.getSeverity(); - } - if (max.getOrdinal() == FacesMessage.SEVERITY_FATAL.getOrdinal()) - break; - } - return max; + return messageDelegate.getMaximumSeverity(); } /** * Returns an Iterator for all Messages in the current MessageContext that does translation to FacesMessages. */ public Iterator getMessages() { - return new FacesMessageIterator(); + return messageDelegate.getMessages(); } /** @@ -187,7 +113,7 @@ public class FlowFacesContext extends FacesContext { * to FacesMessages. */ public Iterator getMessages(String clientId) { - return new FacesMessageIterator(clientId); + return messageDelegate.getMessages(clientId); } public boolean getRenderResponse() { @@ -273,100 +199,6 @@ public class FlowFacesContext extends FacesContext { // ------------------ Private helper methods ----------------------// - private FacesMessage toFacesMessage(Message summaryMessage, Message detailMessage) { - if (summaryMessage.getSeverity() == Severity.INFO) { - return new FacesMessage(FacesMessage.SEVERITY_INFO, summaryMessage.getText(), detailMessage.getText()); - } else if (summaryMessage.getSeverity() == Severity.WARNING) { - return new FacesMessage(FacesMessage.SEVERITY_WARN, summaryMessage.getText(), detailMessage.getText()); - } else if (summaryMessage.getSeverity() == Severity.ERROR) { - return new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMessage.getText(), detailMessage.getText()); - } else { - return new FacesMessage(FacesMessage.SEVERITY_FATAL, summaryMessage.getText(), detailMessage.getText()); - } - } - - private class FacesMessageIterator implements Iterator { - - private Object[] messages; - - private int currentIndex = -1; - - protected FacesMessageIterator() { - Message[] summaryMessages = context.getMessageContext().getMessagesByCriteria(new SummaryMessageCriteria()); - Message[] detailMessages = context.getMessageContext().getMessagesByCriteria(new DetailMessageCriteria()); - Message[] userMessages = context.getMessageContext().getMessagesByCriteria(new UserMessageCriteria()); - - List translatedMessages = new ArrayList(); - for (int i = 0; i < summaryMessages.length; i++) { - translatedMessages.add(toFacesMessage(summaryMessages[i], detailMessages[i])); - } - for (int z = 0; z < userMessages.length; z++) { - translatedMessages.add(toFacesMessage(userMessages[z], userMessages[z])); - } - - this.messages = translatedMessages.toArray(); - } - - protected FacesMessageIterator(String clientId) { - Message[] summaryMessages = context.getMessageContext().getMessagesBySource(clientId + SUMMARY_MESSAGE_KEY); - Message[] detailMessages = context.getMessageContext().getMessagesBySource(clientId + DETAIL_MESSAGE_KEY); - Message[] userMessages = context.getMessageContext().getMessagesBySource(clientId); - - List translatedMessages = new ArrayList(); - for (int i = 0; i < summaryMessages.length; i++) { - translatedMessages.add(toFacesMessage(summaryMessages[i], detailMessages[i])); - } - for (int z = 0; z < userMessages.length; z++) { - translatedMessages.add(toFacesMessage(userMessages[z], userMessages[z])); - } - - this.messages = translatedMessages.toArray(); - } - - public boolean hasNext() { - return messages.length > currentIndex + 1; - } - - public Object next() { - currentIndex++; - return messages[currentIndex]; - } - - public void remove() { - throw new UnsupportedOperationException("Messages cannot be removed through this iterator."); - } - - } - - private class ClientIdIterator implements Iterator { - - private Message[] messages; - - int currentIndex = -1; - - protected ClientIdIterator() { - this.messages = context.getMessageContext().getMessagesByCriteria(new IdentifiedMessageCriteria()); - } - - public boolean hasNext() { - return messages.length > currentIndex + 1; - } - - public Object next() { - Message next = messages[++currentIndex]; - if (next.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY)) { - return next.getSource().toString().replaceAll(SUMMARY_MESSAGE_KEY, ""); - } else { - return next.getSource().toString(); - } - } - - public void remove() { - throw new UnsupportedOperationException("Messages cannot be removed through this iterator."); - } - - } - private class FlowExternalContext extends ExternalContextWrapper { private static final String CUSTOM_RESPONSE = "customResponse"; @@ -391,49 +223,4 @@ public class FlowFacesContext extends FacesContext { } } - - private class SummaryMessageCriteria implements MessageCriteria { - - public boolean test(Message message) { - if (message.getSource() == null) { - return false; - } - return message.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY); - } - } - - private class DetailMessageCriteria implements MessageCriteria { - - public boolean test(Message message) { - if (message.getSource() == null) { - return false; - } - return message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY); - } - } - - private class UserMessageCriteria implements MessageCriteria { - - public boolean test(Message message) { - if (message.getSource() == null) { - return true; - } - return !message.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY) - && !message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY); - } - } - - private class IdentifiedMessageCriteria implements MessageCriteria { - - String nullSummaryId = null + SUMMARY_MESSAGE_KEY; - - public boolean test(Message message) { - if (message.getSource() == null || message.getSource().equals("") - || message.getSource().equals(nullSummaryId) - || message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY)) { - return false; - } - return true; - } - } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java new file mode 100644 index 00000000..a4221199 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java @@ -0,0 +1,337 @@ +package org.springframework.faces.webflow; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; + +import org.springframework.binding.message.Message; +import org.springframework.binding.message.MessageCriteria; +import org.springframework.binding.message.MessageResolver; +import org.springframework.binding.message.Severity; +import org.springframework.context.MessageSource; +import org.springframework.core.style.ToStringCreator; +import org.springframework.util.StringUtils; +import org.springframework.webflow.execution.RequestContext; + +/** + * Helper delegate class for use with the {@link FlowFacesContext} that handles all faces message methods. + * + * @author Jeremy Grelle + * @author Phil Webb + */ +public class FlowFacesContextMessageDelegate { + + private RequestContext context; + + /** + * Key for identifying summary messages + */ + static final String SUMMARY_MESSAGE_KEY = "_summary"; + + /** + * Key for identifying detail messages + */ + static final String DETAIL_MESSAGE_KEY = "_detail"; + + /** + * Mappings between {@link FacesMessage} and {@link Severity}. + */ + private static final Map FACESSEVERITY_TO_SPRINGSEVERITY; + static { + FACESSEVERITY_TO_SPRINGSEVERITY = new HashMap(); + FACESSEVERITY_TO_SPRINGSEVERITY.put(FacesMessage.SEVERITY_INFO, Severity.INFO); + FACESSEVERITY_TO_SPRINGSEVERITY.put(FacesMessage.SEVERITY_WARN, Severity.WARNING); + FACESSEVERITY_TO_SPRINGSEVERITY.put(FacesMessage.SEVERITY_ERROR, Severity.ERROR); + } + + public FlowFacesContextMessageDelegate(RequestContext context) { + super(); + this.context = context; + } + + /** + * @see FlowFacesContext#addMessage(String, FacesMessage) + */ + public void addMessage(String clientId, FacesMessage message) { + String source = null; + if (StringUtils.hasText(clientId)) { + source = clientId; + } + context.getMessageContext().addMessage(new FlowFacesMessageAdapter(source, SUMMARY_MESSAGE_KEY, message)); + context.getMessageContext().addMessage(new FlowFacesMessageAdapter(source, DETAIL_MESSAGE_KEY, message)); + } + + /** + * @see FlowFacesContext#getClientIdsWithMessages + */ + public Iterator getClientIdsWithMessages() { + return new ClientIdIterator(); + } + + /** + * @see FlowFacesContext#getMaximumSeverity() + */ + public FacesMessage.Severity getMaximumSeverity() { + if (context.getMessageContext().getAllMessages().length == 0) { + return null; + } + FacesMessage.Severity max = FacesMessage.SEVERITY_INFO; + Iterator i = getMessages(); + while (i.hasNext()) { + FacesMessage message = (FacesMessage) i.next(); + if (message.getSeverity().getOrdinal() > max.getOrdinal()) { + max = message.getSeverity(); + } + if (max.getOrdinal() == FacesMessage.SEVERITY_FATAL.getOrdinal()) + break; + } + return max; + } + + /** + * @see FlowFacesContext#getMessages() + */ + public Iterator getMessages() { + return new FacesMessageIterator(); + } + + /** + * @see FlowFacesContext#getMessages(String) + */ + public Iterator getMessages(String clientId) { + return new FacesMessageIterator(clientId); + } + + // ------------------ Private helper methods ----------------------// + + private FacesMessage toFacesMessage(Message summaryMessage, Message detailMessage) { + + // If we can return the actual message instance. + if (summaryMessage instanceof FlowFacesMessageAdapter) { + return ((FlowFacesMessageAdapter) summaryMessage).getFacesMessage(); + } + if (detailMessage instanceof FlowFacesMessageAdapter) { + return ((FlowFacesMessageAdapter) detailMessage).getFacesMessage(); + } + + // If we have not got an actual instance adapt the message + if (summaryMessage.getSeverity() == Severity.INFO) { + return new FacesMessage(FacesMessage.SEVERITY_INFO, summaryMessage.getText(), detailMessage.getText()); + } else if (summaryMessage.getSeverity() == Severity.WARNING) { + return new FacesMessage(FacesMessage.SEVERITY_WARN, summaryMessage.getText(), detailMessage.getText()); + } else if (summaryMessage.getSeverity() == Severity.ERROR) { + return new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMessage.getText(), detailMessage.getText()); + } else { + return new FacesMessage(FacesMessage.SEVERITY_FATAL, summaryMessage.getText(), detailMessage.getText()); + } + } + + private class FacesMessageIterator implements Iterator { + + private Object[] messages; + + private int currentIndex = -1; + + protected FacesMessageIterator() { + Message[] summaryMessages = context.getMessageContext().getMessagesByCriteria(new SummaryMessageCriteria()); + Message[] detailMessages = context.getMessageContext().getMessagesByCriteria(new DetailMessageCriteria()); + Message[] userMessages = context.getMessageContext().getMessagesByCriteria(new UserMessageCriteria()); + + List translatedMessages = new ArrayList(); + for (int i = 0; i < summaryMessages.length; i++) { + translatedMessages.add(toFacesMessage(summaryMessages[i], detailMessages[i])); + } + for (int z = 0; z < userMessages.length; z++) { + translatedMessages.add(toFacesMessage(userMessages[z], userMessages[z])); + } + + this.messages = translatedMessages.toArray(); + } + + protected FacesMessageIterator(String clientId) { + Message[] summaryMessages = context.getMessageContext().getMessagesBySource(clientId + SUMMARY_MESSAGE_KEY); + Message[] detailMessages = context.getMessageContext().getMessagesBySource(clientId + DETAIL_MESSAGE_KEY); + Message[] userMessages = context.getMessageContext().getMessagesBySource(clientId); + + List translatedMessages = new ArrayList(); + for (int i = 0; i < summaryMessages.length; i++) { + translatedMessages.add(toFacesMessage(summaryMessages[i], detailMessages[i])); + } + for (int z = 0; z < userMessages.length; z++) { + translatedMessages.add(toFacesMessage(userMessages[z], userMessages[z])); + } + + this.messages = translatedMessages.toArray(); + } + + public boolean hasNext() { + return messages.length > currentIndex + 1; + } + + public Object next() { + currentIndex++; + return messages[currentIndex]; + } + + public void remove() { + throw new UnsupportedOperationException("Messages cannot be removed through this iterator."); + } + + } + + private class ClientIdIterator implements Iterator { + + private Message[] messages; + + int currentIndex = -1; + + protected ClientIdIterator() { + this.messages = context.getMessageContext().getMessagesByCriteria(new IdentifiedMessageCriteria()); + } + + public boolean hasNext() { + return messages.length > currentIndex + 1; + } + + public Object next() { + Message next = messages[++currentIndex]; + if (next.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY)) { + return next.getSource().toString().replaceAll(SUMMARY_MESSAGE_KEY, ""); + } else { + return next.getSource().toString(); + } + } + + public void remove() { + throw new UnsupportedOperationException("Messages cannot be removed through this iterator."); + } + + } + + private class SummaryMessageCriteria implements MessageCriteria { + + public boolean test(Message message) { + if (message.getSource() == null) { + return false; + } + return message.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY); + } + } + + private class DetailMessageCriteria implements MessageCriteria { + + public boolean test(Message message) { + if (message.getSource() == null) { + return false; + } + return message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY); + } + } + + private class UserMessageCriteria implements MessageCriteria { + + public boolean test(Message message) { + if (message.getSource() == null) { + return true; + } + return !message.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY) + && !message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY); + } + } + + private class IdentifiedMessageCriteria implements MessageCriteria { + + String nullSummaryId = null + SUMMARY_MESSAGE_KEY; + + private Set identifiedMessageSources = new HashSet(); + + public boolean test(Message message) { + if (message.getSource() == null || message.getSource().equals("") + || message.getSource().equals(nullSummaryId) + || message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY)) { + return false; + } + return identifiedMessageSources.add(message.getSource()); + } + } + + /** + * Adapter class to convert a {@link FacesMessage} to a Spring {@link Message}. This adapter is required to allow + * FacesMessages to be registered with spring while still retaining their mutable nature. It is not + * uncommon for FacesMessages to be changed after they gave been added to a FacesContext, for + * example, from a PhaseListener. + *

+ * For convenience this class also implements the {@link MessageResolver} interface. + */ + private static class FlowFacesMessageAdapter extends Message implements MessageResolver { + + private String key; + private FacesMessage facesMessage; + private String source; + + public FlowFacesMessageAdapter(String source, String key, FacesMessage message) { + super(null, null, null); + this.source = source; + this.key = key; + this.facesMessage = message; + } + + public Object getSource() { + return source + key; + } + + public String getText() { + String text = null; + if (DETAIL_MESSAGE_KEY.equals(key)) { + text = facesMessage.getDetail(); + } else if (SUMMARY_MESSAGE_KEY.equals(key)) { + text = facesMessage.getSummary(); + } else { + throw new RuntimeException("Unknown faces message type key"); + } + + if (StringUtils.hasText(text)) { + return text; + } + return ""; + } + + public Severity getSeverity() { + Severity severity = null; + if (facesMessage.getSeverity() != null) { + severity = (Severity) FACESSEVERITY_TO_SPRINGSEVERITY.get(facesMessage.getSeverity()); + } + return (severity == null ? Severity.INFO : severity); + } + + public String toString() { + ToStringCreator rtn = new ToStringCreator(this); + rtn.append("severity", getSeverity()); + if (FacesContext.getCurrentInstance() != null) { + // Only append text if running within a faces context + rtn.append("text", getText()); + } + return rtn.toString(); + } + + public Message resolveMessage(MessageSource messageSource, Locale locale) { + return this; + } + + /** + * @return The original {@link FacesMessage} adapted by this class. + */ + public FacesMessage getFacesMessage() { + return facesMessage; + } + + } +} diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/FlowFacesContextTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/FlowFacesContextTests.java index 4d9d0828..27f0c7bb 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/FlowFacesContextTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/FlowFacesContextTests.java @@ -12,9 +12,6 @@ import org.springframework.binding.message.DefaultMessageContext; import org.springframework.binding.message.Message; import org.springframework.binding.message.MessageBuilder; import org.springframework.binding.message.MessageContext; -import org.springframework.binding.message.MessageCriteria; -import org.springframework.binding.message.MessageResolver; -import org.springframework.binding.message.Severity; import org.springframework.webflow.execution.RequestContext; public class FlowFacesContextTests extends TestCase { @@ -92,6 +89,24 @@ public class FlowFacesContextTests extends TestCase { assertEquals("There should be 5 messages to iterate", 5, iterationCount); } + public final void testMutableGetMessages() { + messageContext = prepopulatedMessageContext; + EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext); + EasyMock.replay(new Object[] { requestContext }); + + facesContext.addMessage("TESTID", new FacesMessage("summary1")); + FacesMessage soruceMessage = (FacesMessage) facesContext.getMessages("TESTID").next(); + soruceMessage.setSummary("summary2"); + + // check that message sticks around even when the facesContext has been torn down and re-created during the + // processing of the current request + FacesContext newFacesContext = new FlowFacesContext(requestContext, jsf.facesContext()); + assertSame(FacesContext.getCurrentInstance(), newFacesContext); + + FacesMessage gotMessage = (FacesMessage) newFacesContext.getMessages("TESTID").next(); + assertEquals("summary2", gotMessage.getSummary()); + } + public final void testGetMessagesByClientId_ForComponent() { messageContext = prepopulatedMessageContext; EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext); @@ -180,46 +195,4 @@ public class FlowFacesContextTests extends TestCase { prepopulatedMessageContext.addMessage(new MessageBuilder().defaultText("Subzero Wins - Fatality").fatal() .build()); } - - private class TestGetMessagesContext implements MessageContext { - - Message[] messages; - - TestGetMessagesContext() { - messages = new Message[7]; - messages[0] = new Message("null_summary", "foo", Severity.INFO); - messages[1] = new Message("null_detail", "foo", Severity.INFO); - messages[2] = new Message("componentId_summary", "bar", Severity.WARNING); - messages[3] = new Message("componentId_detail", "bar", Severity.WARNING); - messages[4] = new Message("userMessage", "userMessage", Severity.INFO); - messages[5] = new Message("null_summary", "baz", Severity.ERROR); - messages[6] = new Message("null_detail", "baz", Severity.ERROR); - } - - public void addMessage(MessageResolver messageResolver) { - - } - - public Message[] getAllMessages() { - return messages; - } - - public Message[] getMessagesBySource(Object source) { - return new Message[] { messages[1] }; - } - - public Message[] getMessagesByCriteria(MessageCriteria criteria) { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - public boolean hasErrorMessages() { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - public void clearMessages() { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - } - }