/*
* 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);
}