Details
-
Type: Bug
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: 1.7.2
-
Component/s: Framework
-
Labels:None
-
Environment:ICEfaces 1.7.2, SWF 2.0.3
-
ICEsoft Forum Reference:
Description
After some more debugging on the problem I have noticed that the BridgeFacesContext never hold any messages because they are added to the FlowFacesContext which is the Spring Web Flow version of the FacesContext. All phases of the JSF lifecycle except for RENDER_RESPONSE is handled by the FlowFacesContext.
When entering the RENDER_RESPONCE phase the FlowFacesContext is unwrapped to a BridgeFacesContext by the following code:
Code:
public static FacesContext unwrap(FacesContext facesContext) {
if (facesContext instanceof BridgeFacesContext) {
return facesContext;
}
FacesContext result = facesContext;
try {
Method delegateMethod = facesContext.getClass()
.getDeclaredMethod("getDelegate", new Class[]{});
delegateMethod.setAccessible(true);
Object delegate = delegateMethod
.invoke(facesContext, (Object[]) null);
if (delegate instanceof BridgeFacesContext) {
result = (FacesContext) delegate;
if (log.isDebugEnabled()) {
log.debug("BridgeFacesContext delegate of " + facesContext);
}
}
} catch (Exception e) {
}
return result;
}
The FacesMessages that were added to the FlowFacesContext are never passed on to the BridgeFacesContext.
I therefore made a small change to the unwrap method:
Code:
public static FacesContext unwrap(FacesContext facesContext) {
if (facesContext instanceof BridgeFacesContext) {
return facesContext;
}
FacesContext result = facesContext;
try {
Method delegateMethod = facesContext.getClass()
.getDeclaredMethod("getDelegate", new Class[]{});
delegateMethod.setAccessible(true);
Object delegate = delegateMethod
.invoke(facesContext, (Object[]) null);
if (delegate instanceof BridgeFacesContext) {
result = (FacesContext) delegate;
//patch start : getting the faces messages from the FlowFacesContext
Iterator clientIdIterator = facesContext.getClientIdsWithMessages();
while(clientIdIterator.hasNext()){
String clientId = (String)clientIdIterator.next();
Iterator facesMessagesForClientId = facesContext.getMessages(clientId);
while(facesMessagesForClientId.hasNext()){
FacesMessage message = (FacesMessage)facesMessagesForClientId.next();
result.addMessage(clientId, message);
}
}
// patch end.
if (log.isDebugEnabled()) {
log.debug("BridgeFacesContext delegate of " + facesContext);
}
}
} catch (Exception e) {
}
return result;
}
When entering the RENDER_RESPONCE phase the FlowFacesContext is unwrapped to a BridgeFacesContext by the following code:
Code:
public static FacesContext unwrap(FacesContext facesContext) {
if (facesContext instanceof BridgeFacesContext) {
return facesContext;
}
FacesContext result = facesContext;
try {
Method delegateMethod = facesContext.getClass()
.getDeclaredMethod("getDelegate", new Class[]{});
delegateMethod.setAccessible(true);
Object delegate = delegateMethod
.invoke(facesContext, (Object[]) null);
if (delegate instanceof BridgeFacesContext) {
result = (FacesContext) delegate;
if (log.isDebugEnabled()) {
log.debug("BridgeFacesContext delegate of " + facesContext);
}
}
} catch (Exception e) {
}
return result;
}
The FacesMessages that were added to the FlowFacesContext are never passed on to the BridgeFacesContext.
I therefore made a small change to the unwrap method:
Code:
public static FacesContext unwrap(FacesContext facesContext) {
if (facesContext instanceof BridgeFacesContext) {
return facesContext;
}
FacesContext result = facesContext;
try {
Method delegateMethod = facesContext.getClass()
.getDeclaredMethod("getDelegate", new Class[]{});
delegateMethod.setAccessible(true);
Object delegate = delegateMethod
.invoke(facesContext, (Object[]) null);
if (delegate instanceof BridgeFacesContext) {
result = (FacesContext) delegate;
//patch start : getting the faces messages from the FlowFacesContext
Iterator clientIdIterator = facesContext.getClientIdsWithMessages();
while(clientIdIterator.hasNext()){
String clientId = (String)clientIdIterator.next();
Iterator facesMessagesForClientId = facesContext.getMessages(clientId);
while(facesMessagesForClientId.hasNext()){
FacesMessage message = (FacesMessage)facesMessagesForClientId.next();
result.addMessage(clientId, message);
}
}
// patch end.
if (log.isDebugEnabled()) {
log.debug("BridgeFacesContext delegate of " + facesContext);
}
}
} catch (Exception e) {
}
return result;
}
Deryk, please assign the suggested patch for code review; on the surface it looks like a good fix.