SWF-751 - FacesMessage.detail does not propagate through FlowFacesContext
This commit is contained in:
@@ -16,7 +16,9 @@
|
||||
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,6 +35,8 @@ 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;
|
||||
@@ -59,6 +63,16 @@ 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
|
||||
*/
|
||||
@@ -88,25 +102,48 @@ 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) {
|
||||
MessageBuilder builder = new MessageBuilder();
|
||||
StringBuffer msgText = new StringBuffer();
|
||||
if (StringUtils.hasText(message.getSummary())) {
|
||||
msgText.append(message.getSummary());
|
||||
}
|
||||
|
||||
String source = null;
|
||||
if (StringUtils.hasText(clientId)) {
|
||||
source = clientId;
|
||||
}
|
||||
|
||||
if (message.getSeverity() == FacesMessage.SEVERITY_INFO) {
|
||||
builder.source(source).defaultText(msgText.toString()).info();
|
||||
} else if (message.getSeverity() == FacesMessage.SEVERITY_WARN) {
|
||||
builder.source(source).defaultText(msgText.toString()).warning();
|
||||
} else {
|
||||
builder.source(source).defaultText(msgText.toString()).error();
|
||||
StringBuffer summaryText = new StringBuffer();
|
||||
if (StringUtils.hasText(message.getSummary())) {
|
||||
summaryText.append(message.getSummary());
|
||||
}
|
||||
context.getMessageContext().addMessage(builder.build());
|
||||
|
||||
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 {
|
||||
summaryResolver = new MessageBuilder().source(summarySource).defaultText(summaryText.toString()).error()
|
||||
.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 {
|
||||
detailResolver = new MessageBuilder().source(detailSource).defaultText(detailText.toString()).error()
|
||||
.build();
|
||||
}
|
||||
context.getMessageContext().addMessage(detailResolver);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,18 +274,54 @@ public class FlowFacesContext extends FacesContext {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
// ------------------ 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 {
|
||||
return new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMessage.getText(), detailMessage.getText());
|
||||
}
|
||||
}
|
||||
|
||||
private class FacesMessageIterator implements Iterator {
|
||||
|
||||
private Message[] messages;
|
||||
private Object[] messages;
|
||||
|
||||
private int currentIndex = -1;
|
||||
|
||||
protected FacesMessageIterator() {
|
||||
this.messages = context.getMessageContext().getAllMessages();
|
||||
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) {
|
||||
this.messages = context.getMessageContext().getMessagesBySource(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() {
|
||||
@@ -257,19 +330,7 @@ public class FlowFacesContext extends FacesContext {
|
||||
|
||||
public Object next() {
|
||||
currentIndex++;
|
||||
Message nextMessage = messages[currentIndex];
|
||||
FacesMessage facesMessage;
|
||||
if (nextMessage.getSeverity() == Severity.INFO) {
|
||||
facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, nextMessage.getText(), nextMessage
|
||||
.getText());
|
||||
} else if (nextMessage.getSeverity() == Severity.WARNING) {
|
||||
facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN, nextMessage.getText(), nextMessage
|
||||
.getText());
|
||||
} else {
|
||||
facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, nextMessage.getText(), nextMessage
|
||||
.getText());
|
||||
}
|
||||
return facesMessage;
|
||||
return messages[currentIndex];
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
@@ -285,26 +346,20 @@ public class FlowFacesContext extends FacesContext {
|
||||
int currentIndex = -1;
|
||||
|
||||
protected ClientIdIterator() {
|
||||
this.messages = context.getMessageContext().getAllMessages();
|
||||
this.messages = context.getMessageContext().getMessagesByCriteria(new IdentifiedMessageCriteria());
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
while (messages.length > currentIndex + 1) {
|
||||
Message next = messages[currentIndex + 1];
|
||||
if (next.getSource() != null && !"".equals(next.getSource())) {
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
return false;
|
||||
return messages.length > currentIndex + 1;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
Message next = messages[++currentIndex];
|
||||
while (next.getSource() == null || "".equals(next.getSource())) {
|
||||
next = messages[++currentIndex];
|
||||
if (next.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY)) {
|
||||
return next.getSource().toString().replaceAll(SUMMARY_MESSAGE_KEY, "");
|
||||
} else {
|
||||
return next.getSource().toString();
|
||||
}
|
||||
return next.getSource().toString();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
@@ -338,4 +393,48 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ import javax.faces.context.FacesContext;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
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;
|
||||
@@ -25,9 +27,13 @@ public class FlowFacesContextTests extends TestCase {
|
||||
|
||||
MessageContext messageContext;
|
||||
|
||||
MessageContext prepopulatedMessageContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
facesContext = new FlowFacesContext(requestContext, jsf.facesContext());
|
||||
|
||||
setupMessageContext();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
@@ -39,17 +45,41 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testAddMessage() {
|
||||
messageContext = new TestAddMessageContext();
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "foo"));
|
||||
facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
|
||||
assertEquals("Message count is incorrect", 1, ((TestAddMessageContext) messageContext).messageCount);
|
||||
assertEquals("Message count is incorrect", 2, messageContext.getAllMessages().length);
|
||||
Message summaryMessage = messageContext.getMessagesBySource("foo_summary")[0];
|
||||
assertEquals("foo", summaryMessage.getText());
|
||||
Message detailMessage = messageContext.getMessagesBySource("foo_detail")[0];
|
||||
assertEquals("bar", detailMessage.getText());
|
||||
|
||||
}
|
||||
|
||||
public final void testAddMessages_MultipleNullIds() {
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "zoo", "zar"));
|
||||
|
||||
assertEquals("Message count is incorrect", 4, messageContext.getAllMessages().length);
|
||||
Message summaryMessage1 = messageContext.getMessagesBySource("null_summary")[0];
|
||||
assertEquals("foo", summaryMessage1.getText());
|
||||
Message detailMessage1 = messageContext.getMessagesBySource("null_detail")[0];
|
||||
assertEquals("bar", detailMessage1.getText());
|
||||
Message summaryMessage2 = messageContext.getMessagesBySource("null_summary")[1];
|
||||
assertEquals("zoo", summaryMessage2.getText());
|
||||
Message detailMessage2 = messageContext.getMessagesBySource("null_detail")[1];
|
||||
assertEquals("zar", detailMessage2.getText());
|
||||
}
|
||||
|
||||
public final void testGetMessages() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
@@ -59,72 +89,94 @@ public class FlowFacesContextTests extends TestCase {
|
||||
assertNotNull(i.next());
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(3, iterationCount);
|
||||
assertEquals("There should be 4 messages to iterate", 4, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetMessagesByClientId() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
public final void testGetMessagesByClientId_ForComponent() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator i = facesContext.getMessages("componentId");
|
||||
while (i.hasNext()) {
|
||||
assertNotNull(i.next());
|
||||
FacesMessage message = (FacesMessage) i.next();
|
||||
assertNotNull(message);
|
||||
assertEquals("componentId_summary", message.getSummary());
|
||||
assertEquals("componentId_detail", message.getDetail());
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(1, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetMessagesByClientId_ForUserMessage() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator i = facesContext.getMessages("userMessage");
|
||||
while (i.hasNext()) {
|
||||
FacesMessage message = (FacesMessage) i.next();
|
||||
assertNotNull(message);
|
||||
assertEquals("userMessage", message.getSummary());
|
||||
assertEquals("userMessage", message.getDetail());
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(1, iterationCount);
|
||||
}
|
||||
|
||||
public final void testgetMessagesByClientId_InvalidId() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator i = facesContext.getMessages("unknown");
|
||||
while (i.hasNext()) {
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(0, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetClientIdsWithMessages() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator i = facesContext.getClientIdsWithMessages();
|
||||
while (i.hasNext()) {
|
||||
String id = (String) i.next();
|
||||
assertEquals("componentId", id);
|
||||
i.next();
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(1, iterationCount);
|
||||
assertEquals(2, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetMaximumSeverity() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
|
||||
assertEquals(FacesMessage.SEVERITY_ERROR, facesContext.getMaximumSeverity());
|
||||
}
|
||||
|
||||
private class TestAddMessageContext implements MessageContext {
|
||||
int messageCount = 0;
|
||||
|
||||
public void addMessage(MessageResolver messageResolver) {
|
||||
messageCount++;
|
||||
}
|
||||
|
||||
public Message[] getAllMessages() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Message[] getMessagesBySource(Object source) {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
private void setupMessageContext() {
|
||||
prepopulatedMessageContext = new DefaultMessageContext();
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_summary").defaultText("foo").info()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_detail").defaultText("foo").info()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("componentId_summary").defaultText(
|
||||
"componentId_summary").warning().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("componentId_detail").defaultText(
|
||||
"componentId_detail").warning().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("userMessage").defaultText("userMessage")
|
||||
.info().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_summary").defaultText("baz").error()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_detail").defaultText("baz").error()
|
||||
.build());
|
||||
}
|
||||
|
||||
private class TestGetMessagesContext implements MessageContext {
|
||||
@@ -132,10 +184,14 @@ public class FlowFacesContextTests extends TestCase {
|
||||
Message[] messages;
|
||||
|
||||
TestGetMessagesContext() {
|
||||
messages = new Message[3];
|
||||
messages[0] = new Message(null, "foo", Severity.INFO);
|
||||
messages[1] = new Message("componentId", "bar", Severity.WARNING);
|
||||
messages[2] = new Message(null, "baz", Severity.ERROR);
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user