https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1449
Issue: 1449
SECTION: Modified Files
----------------------------
M jsf-ri/src/com/sun/faces/context/flash/ELFlash.java
M jsf-ri/src/com/sun/faces/config/WebConfiguration.java
- Store the flash in session by default.
M jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/model/Bean.java
M jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/systest/FlashTestCase.java
M jsf-ri/systest-per-webapp/flash/web/index.xhtml
M jsf-ri/systest-per-webapp/flash/web/WEB-INF/web.xml
M jsf-ri/systest/src/com/sun/faces/systest/FlashMessagesTestCase.java
M jsf-ri/systest/src/com/sun/faces/systest/flash/FlashMessagesBean.java
M jsf-ri/systest/web/flash/flashKeepMessages01.xhtml
- Test both values for the context-param.
Index: jsf-api/src/main/java/javax/faces/context/Flash.java
===================================================================
--- jsf-api/src/main/java/javax/faces/context/Flash.java (revision 8290)
+++ jsf-api/src/main/java/javax/faces/context/Flash.java (working copy)
@@ -53,9 +53,12 @@
*
* <p><b>Implementation Requirements</b></p>
*
- * <p>The flash is an application scoped object that must be thread
- * safe, and provide a programming model that lets each session treat
- * the flash as if it was a session scoped object.</p>
+ * <p>The flash must be thread safe. By default, the flash is stored in
+ * the session, but applications wishing to use the flash without
+ * forcing the creation of a session may set the context param {_at_link
+ * #STORE_FLASH_IN_SESSION_SCOPE_PARAM_NAME} to <code>false</code> to
+ * prohibit the implementation from storing the flash in the session.
+ * </p>
* <p>The implementation requirements will be described in terms of the
* runtime traversing the JSF lifecycle. The flash exposes a
@@ -175,6 +178,24 @@
*/
public abstract class Flash implements Map<String, Object> {
+
+ /**
+ * <p>If this context param exists and is set to <code>false</code>,
+ * the implementation must not store the <code>Flash</code>
+ * singleton instance in session scope. Otherwise, the
+ * implementation is free to store the <code>Flash</code> singleton
+ * instance in session scope.</p>
+ */
+ public static final String STORE_FLASH_IN_SESSION_SCOPE_PARAM_NAME =
+ "javax.faces.STORE_FLASH_IN_SESSION_SCOPE";
+
+ /**
+ * <p>The default value of the {_at_link #STORE_FLASH_IN_SESSION_SCOPE}
+ * context param.</p>
+ */
+ public static final Boolean STORE_FLASH_IN_SESSION_SCOPE =
+ Boolean.TRUE;
+
/**
Index: jsf-ri/src/com/sun/faces/context/flash/ELFlash.java
===================================================================
--- jsf-ri/src/com/sun/faces/context/flash/ELFlash.java (revision 8290)
+++ jsf-ri/src/com/sun/faces/context/flash/ELFlash.java (working copy)
@@ -273,20 +273,43 @@
public static ELFlash getFlash(ExternalContext extContext, boolean create) {
Map<String, Object> appMap = extContext.getApplicationMap();
+ Map<String, Object> mapForFlash = null;
+ if (storeFlashInSession(appMap)) {
+ mapForFlash = extContext.getSessionMap();
+ } else {
+ mapForFlash = appMap;
+ }
+
ELFlash flash = (ELFlash)
- appMap.get(FLASH_ATTRIBUTE_NAME);
+ mapForFlash.get(FLASH_ATTRIBUTE_NAME);
if (null == flash && create) {
synchronized (extContext.getContext()) {
if (null == (flash = (ELFlash)
- appMap.get(FLASH_ATTRIBUTE_NAME))) {
+ mapForFlash.get(FLASH_ATTRIBUTE_NAME))) {
flash = new ELFlash();
- appMap.put(FLASH_ATTRIBUTE_NAME, flash);
+ mapForFlash.put(FLASH_ATTRIBUTE_NAME, flash);
}
}
}
return flash;
}
+ private static boolean storeFlashInSession(Map<String, Object> appMap) {
+ boolean result = false;
+ String key = WebConfiguration.BooleanWebContextInitParameter.
+ StoreFlashInSessionScope.getQualifiedName();
+ if (appMap.containsKey(key)) {
+ result = (Boolean) appMap.get(key);
+ } else {
+ result = WebConfiguration.getInstance().isOptionEnabled(WebConfiguration.
+ BooleanWebContextInitParameter.StoreFlashInSessionScope);
+
+ appMap.put(key, (Boolean) result);
+ }
+
+ return result;
+ }
+
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Abstract class overrides">
Index: jsf-ri/src/com/sun/faces/config/WebConfiguration.java
===================================================================
--- jsf-ri/src/com/sun/faces/config/WebConfiguration.java (revision 8290)
+++ jsf-ri/src/com/sun/faces/config/WebConfiguration.java (working copy)
@@ -60,6 +60,7 @@
import java.util.HashMap;
import javax.faces.component.UIInput;
+import javax.faces.context.Flash;
import javax.faces.validator.BeanValidator;
import javax.faces.view.facelets.ResourceResolver;
@@ -1065,6 +1066,10 @@
AllowTextChildren(
"com.sun.faces.allowTextChildren",
false
+ ),
+ StoreFlashInSessionScope(
+ Flash.STORE_FLASH_IN_SESSION_SCOPE_PARAM_NAME,
+ (boolean) Flash.STORE_FLASH_IN_SESSION_SCOPE
);
private BooleanWebContextInitParameter alternate;
Index: jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/model/Bean.java
===================================================================
--- jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/model/Bean.java (revision 8290)
+++ jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/model/Bean.java (working copy)
@@ -92,4 +92,9 @@
return "flash12?faces-redirect=true";
}
+ public boolean isFlashStoredInSessionScope() {
+ FacesContext context = FacesContext.getCurrentInstance();
+ return context.getExternalContext().getSessionMap().containsKey("csfcff");
+ }
+
}
Index: jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/systest/FlashTestCase.java
===================================================================
--- jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/systest/FlashTestCase.java (revision 8290)
+++ jsf-ri/systest-per-webapp/flash/src/java/com/sun/faces/systest/FlashTestCase.java (working copy)
@@ -115,6 +115,8 @@
// Get the first page
HtmlPage page = getPage("/faces/index.xhtml");
String pageText = page.asXml();
+
+ assertTrue(pageText.contains("Flash stored in session scope: false."));
// (?s) is an "embedded flag expression" for the "DOTALL" operator.
// It says, "let . match any character including line terminators."
// Because page.asXml() returns a big string with lots of \r\n chars
Index: jsf-ri/systest-per-webapp/flash/web/index.xhtml
===================================================================
--- jsf-ri/systest-per-webapp/flash/web/index.xhtml (revision 8290)
+++ jsf-ri/systest-per-webapp/flash/web/index.xhtml (working copy)
@@ -57,8 +57,10 @@
on this one as well, use either
<code>\#{flash.now.foo}</code> or
<code>\#{requestScope.foo}</code>. The former is simply
- an alias for the latter.
+ an alias for the latter. <br />
+ <p>Flash stored in session scope: #{bean.flashStoredInSessionScope}.</p>
+
<f:verbatim>
c:set target="\#{flash}" property="foo" value="fooValue"
</f:verbatim>
Index: jsf-ri/systest-per-webapp/flash/web/WEB-INF/web.xml
===================================================================
--- jsf-ri/systest-per-webapp/flash/web/WEB-INF/web.xml (revision 8290)
+++ jsf-ri/systest-per-webapp/flash/web/WEB-INF/web.xml (working copy)
@@ -44,6 +44,10 @@
<param-value>.xhtml</param-value>
</context-param>
<context-param>
+ <param-name>javax.faces.STORE_FLASH_IN_SESSION_SCOPE</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
Index: jsf-ri/systest/src/com/sun/faces/systest/FlashMessagesTestCase.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/systest/FlashMessagesTestCase.java (revision 8290)
+++ jsf-ri/systest/src/com/sun/faces/systest/FlashMessagesTestCase.java (working copy)
@@ -91,6 +91,9 @@
public void testBooleanCheckboxSubmittedValue() throws Exception {
HtmlPage page = getPage("/faces/flash/flashKeepMessages01.xhtml");
+
+ assertTrue(page.asText().contains("Flash stored in session scope: true."));
+
HtmlSubmitInput button = (HtmlSubmitInput) page.getElementById("nextButton");
page = button.click();
String pageText = page.asText();
Index: jsf-ri/systest/src/com/sun/faces/systest/flash/FlashMessagesBean.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/systest/flash/FlashMessagesBean.java (revision 8290)
+++ jsf-ri/systest/src/com/sun/faces/systest/flash/FlashMessagesBean.java (working copy)
@@ -76,5 +76,9 @@
}
+ public boolean isFlashStoredInSessionScope() {
+ return getFacesContext().getExternalContext().getSessionMap().containsKey("csfcff");
+ }
+
}
Index: jsf-ri/systest/web/flash/flashKeepMessages01.xhtml
===================================================================
--- jsf-ri/systest/web/flash/flashKeepMessages01.xhtml (revision 8290)
+++ jsf-ri/systest/web/flash/flashKeepMessages01.xhtml (working copy)
@@ -43,6 +43,9 @@
<title>Test that flash shows multiple messages: issue 1476</title>
</h:head>
<h:body>
+
+ <p>Flash stored in session scope: #{flashMessagesBean.flashStoredInSessionScope}.</p>
+
<h:form prependId="false">
<h:inputText value="#{flashMessagesBean.value}" />
--
| ed.burns_at_sun.com | office: 408 884 9519 OR x31640
| homepage: | http://ridingthecrest.com/