/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package javax.faces.context; import java.util.Map; import javax.faces.event.PostKeepFlashValueEvent; import javax.faces.event.PostPutFlashValueEvent; /** * <p class="changed_added_2_0"><span * class="changed_modified_2_2">The</span> <strong>Flash</strong> * concept is taken from Ruby on Rails and provides a way to pass * temporary objects between the user views generated by the faces * lifecycle. As in Rails, anything one places in the flash will be * exposed to the next view encountered by the same user session and * then cleared out. It is important to note that “next * view” may have the same view id as the previous view.</p> * * <div class="changed_added_2_0"> * * <p><b>Implementation Requirements</b></p> * * <p>The flash is a <span class="changed_modified_2_0_a">session</span> * scoped object that must be thread safe.</p> * <p>The implementation requirements will be described in terms of the * runtime traversing the JSF lifecycle. The flash exposes a * <code>Map</code> interface over two logical maps. The choice of * which logical map is accessed depends on the current faces lifecycle * phase. One logical map is for the current traversal and the other is * for the next traversal. During the execute portion of the lifecycle, * all flash accesses are sent to the current traversal map. During the * render portion of the lifecycle, all flash accesses are sent to the * next traversal map. On the next traversal through the lifecycle, the * implementation must ensure that the current traversal map is the next * traversal map of the previous traversal. Here is an example for * illustration purposes only.</p> * * <blockquote> * * <p>Consider an initial request to the faces lifecycle</p> * * <p>Traversal N, execute phase: skipped on initial request.</p> * * <p>Traversal N, render phase: flash access goes to flash[N].</p> * * <p>Traversal N+1, execute phase: flash access goes to flash[N].</p> * * <p>Traversal N+1, render phase: flash access goes to flash[N+1].</p> * * </blockquote> * * <p>The implementation must ensure the proper behaviour of the flash * is preserved even in the case of a * <code><navigation-case></code> that contains a * <code><redirect /></code>. The implementation must ensure the * proper behavior of the flash is preserved even in the case of * adjacent GET requests on the same session. This allows Faces * applications to fully utilize the “Post/Redirect/Get” * design pattern.</p> * * <p>The implementation must allow the user to access the flash via the * EL implicit object <code>flash</code> and also via {@link * javax.faces.context.ExternalContext#getFlash}. The implementation must * ensure that the flash is usable from both JSP and from Facelets for * JSF 2. In addition to exposing the <code>Map</code> interface, there * are several features exposed as methods on the <code>Flash</code> * itself. Each of these features may be accessed via the EL as well, * as described in the javadocs.</p> * * <p>EL Usage Example</p> * <blockquote> * * <p>First page</p> * <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"> <!-- extra code removed --> <c:set target="#{flash}" property="foo" value="fooValue" /> </code></pre> * <p>Next page</p> * <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <!-- extra code removed --> <h:outputText value="#{flash.foo}" /> will be "fooValue" without the quotes. </code></pre> * </blockquote> * * <p>The same usage syntax must be available in JSP.</p> * <p>Note that extra action must be taken when using the flash in * concert with output components that cause the browser to issue a GET * request when clicked, such as <code>h:button</code> and * <code>h:link</code>. The following example illustrates one way to * use the flash in such circumstances.</p> * <blockquote> * <p>First page</p> <pre><code> <h:button id="nextButton" value="Next (button)" outcome="next.xhtml"> <f:param name="foo" value="bar"/> </h:button> </code></pre> * <p>Next page</p> <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html"> <f:metadata> <f:viewParam name="foo" id="foo" value="#{flash.now.foo}" /> </f:metadata> <head /><body> foo = #{flash.foo} </body> </html> </code></pre> * </blockquote> * <p>Note that this example uses <code>#{flash.now}</code> on the * second page. This is because the value doesn't actuall enter the * flash until the server is processing the GET request sent by the * browser due to the button being clicked.</p> * </div> * * @since 2.0 */ public abstract class Flash implements Map<String, Object> { /** <p class="changed_added_2_2">Because <code>null</code> * values are not allowed as the source for subclasses of <code>EventObject</code>, * such as {@link PostKeepFlashValueEvent} and {@link PostPutFlashValueEvent}, * this value is substituted for <code>null</code> as the source in the case when a * <code>null</code> value is put to or kept in the flash. */ public static final String NULL_VALUE = "javax.faces.context.Flash.NULL_VALUE"; /** * <p class="changed_added_2_0">Return the value of this JavaBeans * property for the flash for this session. This value determines * whether or not any {@link javax.faces.application.FacesMessage} * instances queued in the current {@link * javax.faces.context.FacesContext} must be preserved so they are * accessible on the next traversal of the lifecycle on this * session, regardless of the request being a redirect after post, * or a normal postback. <code>Map</code> accesses for the special * key “<code>keepMessages</code>” must return the value * of this JavaBeans property.</p> * <div class="changed_added_2_0"> * * <p>EL Usage Example</p> * <blockquote> * * <p>First page</p> * <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"> <!-- extra code removed --> <c:set target="#{flash}" property="keepMessages" value="true" /> </code></pre> * <p>Next page</p> * <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <!-- extra code removed --> <h:messages /> Any messages present on the first page must be displayed on this page. </code></pre> * </blockquote> * * </div> * * @return the boolean flag whether keeping messages or not. * * @since 2.0 * */ public abstract boolean isKeepMessages(); /** * <p class="changed_added_2_0">Setter for <code>keepMessages</code> * JavaBeans property. See {@link #isKeepMessages}.</p> * * @param newValue the new value for this property on this session. * * @since 2.0 */ public abstract void setKeepMessages(boolean newValue); /** * <p class="changed_added_2_0">Return the value of this property * for the flash for this session. This must be <code>false</code> * unless:</p> * <div class="changed_added_2_0"> * * <ul> * * <li><p>{@link #setRedirect} was called for the current * lifecycle traversal with <code>true</code> as the * argument.</p></li> * * <li><p>The current lifecycle traversal for this session is in the * “execute” phase and the previous traversal had {@link * #setRedirect} called with <code>true</code> as the * argument.</p></li> * </ul> * </div> * * @return the value of this property for the flash for this session. * */ public abstract boolean isRedirect(); /** * <p class="changed_added_2_0">Setting this property to * <code>true</code> indicates that the next request on this session * will be a redirect. Recall that on a redirect, the server sends * a special response to the client instructing it to issue a new * request to a specific URI. The implementation must insure that * reading the value of this property on that request will return * <code>true</code>. </p> * <div class="changed_added_2_0"> * <p>EL Usage Example</p> * <blockquote> * <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"> <!-- extra code removed --> <c:set target="#{flash}" property="redirect" value="true" /> </code></pre> * </blockquote> * * </div> * * @param newValue the new value for this property on this session. * * @since 2.0 * */ public abstract void setRedirect(boolean newValue); /** * <p class="changed_added_2_0">Puts a value in the flash so that it * can be accessed on this traversal of the lifecycle, rather than * on the next traversal. This is simply an alias for putting a * value in the request map.</p> * * <div class="changed_added_2_0"> * <p>EL Usage Example</p> * <blockquote> * <pre><code> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"> <!-- extra code removed --> <c:set target="#{flash.now}" property="bar" value="barValue" /> <p>Value of \#{flash.now.bar}, should be barValue.</p> <h:outputText value="#{flash.now.bar}" /> </code></pre> * </blockquote> * * </div> * * @param key the key for this entry * @param value the value for this entry * @since 2.0 */ public abstract void putNow(String key, Object value); /** * <p class="changed_added_2_0">Causes a value stored with a * previous call to {@link #putNow}, its EL equivalent, or to the * request <code>Map</code>, to be promoted to the flash so that is * available on the next traversal through the lifecycle on this * session.</p> * * @param key if argument <code>key</code> is the name of an entry * previously stored to the flash on this traversal through the * lifecycle via a call to {@link #putNow}, or to a set to the EL * expression <code>#{flash.now.<i><key></i>}</code>, or to the * request <code>Map</code>, to be promoted to the flash as if a call * to <code>put()</code> or a set to the expression * <code>#{flash.<i><key></i>}</code> was being called. */ public abstract void keep(String key); /** * <p class="changed_added_2_0">Called before the execution of every * lifecycle phase, this method allows implementations to take the * necessary actions to provide the Flash scope contract as it * applies to the request procesing lifecycle. </p> * * @param ctx the <code>FacesContext</code> for this request. */ public abstract void doPrePhaseActions(FacesContext ctx); /** * <p class="changed_added_2_0">Called after the execution of every * lifecycle phase, this method allows implementations to take the * necessary actions to provide the Flash scope contract as it * applies to the request procesing lifecycle. </p> * * @param ctx the <code>FacesContext</code> for this request. */ public abstract void doPostPhaseActions(FacesContext ctx); }