All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.context.flash.FlashELResolver Maven / Gradle / Ivy

Go to download

Jakarta Faces defines an MVC framework for building user interfaces for web applications, including UI components, state management, event handing, input validation, page navigation, and support for internationalization and accessibility.

There is a newer version: 4.1.2
Show newest version
/*
 * Copyright (c) 2023 Contributors to Eclipse Foundation.
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.faces.context.flash;

import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.PropertyNotFoundException;
import jakarta.el.PropertyNotWritableException;
import jakarta.faces.FactoryFinder;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.context.Flash;
import jakarta.faces.context.FlashFactory;
import java.util.Map;

/**
 * 

* Provide a feature semantically identical to the * "flash" concept in Ruby on * Rails. *

* *

* The feature is exposed to users via a custom ELResolver which introduces a new implicit object, * flash. The flash functions as Map and can be used in getValue( ) or * setValue( * ) expressions. *

* *

* Usage *

* *

* Consider three Faces views: viewA, viewB, and viewC. The user first views viewA, then clicks a button and is shown * viewB, where she clicks a button and is shown viewC. If values are stored into the flash during the rendering or * postback phases of viewA, they are available to during the rendering phase of viewB, but are not available during the * rendering or postback phases of viewC. In other words, values stored into the flash on "this" request are accessible * for the "next" request, but not thereafter. *

* *

* There are three ways to access the flash. *

* *
    *
  1. * Using an Expression Language Expression, such as using #{flash.foo} as the value of an attribute in a page. *
  2. *
  3. * Using the EL API, such as: * *

    * * FacesContext context = FacesContext.getCurrentInstance(); * ValueExpression flashExpression = context.getApplication(). * createValueExpression(context.getELContext(), "#{flash.foo}", * null, Object.class); * flashExpression.setValue(context.getELContext(), "Foo's new value"); * *

    * *
  4. *
  5. *

    * Using getting the {@link ELFlash} directly, such as: *

    * *

    * * Map<String,Object> flash = ELFlash.getFlash(); * flash.put("foo", "Foo's new value"); * *

    *
  6. *
* *

* The main entry point to this feature is the first one. This library includes a simple custom tag, jsfExt:set, that evaluates an expression and sets its value into * another expression. jsfExt:set can be used to store values into the flash from JSP pages, like this: *

* *

* <jsfExt:set var="#{flash.foo}" value="fooValue" * /> *

* *

* or this: *

* *

* <jsfExt:set var="#{flash.keep.bar}" value="#{user.name}" * /> *

* *

* or even this: *

* *

* * <jsfExt:set var="#{flash.now.baz}" value="#{cookie.userCookie}" /> * * <h:outputText value="#{flash.now.baz}" /> * * *

* *

* Related Classes *

* *

* The complete list of classes that make up this feature is *

* *
    *
  • FlashELResolver
  • *
  • {@link ELFlash}
  • *
*/ public class FlashELResolver extends ELResolver { /** *

* Not intended for manual invocation. Only called by the Faces Runtime. *

*/ public FlashELResolver() { } // ------------------------------------------------------ Manifest Constants private static final String FLASH_VARIABLE_NAME = "flash"; private static final String FLASH_NOW_VARIABLE_NAME = "now"; private static final String FLASH_KEEP_VARIABLE_NAME = "keep"; // ------------------------------------------------ VariableResolver Methods /** *

* Hook into the EL resolution process to introduce the flash implicit object. If property is * null, take no action and return null. if base is null, return null. If * base is an instance of ELFlash and property is the literal string "keep", set a ThreadLocal * property that will be inspected by the flash on the next link in the resolution chain and return the * ELFlash instance. If base is an instance of ELFlash and property * is the literal string "now", return the result of calling getRequestMap( ) on the * ExternalContext for the FacesContext for this request. Call * setPropertyResolved(true) on the ELContext where appropriate. *

* * @throws PropertyNotFoundException if property is null. */ @Override public Object getValue(ELContext elContext, Object base, Object property) { if (null == property) { // take no action. return null; } Object result = null; if (null == base) { return null; } // If the base argument is the flash itself... else if (base instanceof Flash) { FacesContext facesContext = (FacesContext) elContext.getContext(FacesContext.class); ExternalContext extCtx = facesContext.getExternalContext(); // and the property argument is "keep"... switch (property.toString()) { // Otherwise, if base is the flash, and property is "now"... case FLASH_KEEP_VARIABLE_NAME: elContext.setPropertyResolved(true); // then this is a request to promote the value // "property", which is assumed to have been previously // stored in request scope via the "flash.now" // expression, to flash scope. result = base; // Set a flag so the flash itself can look in the request // and promote the value to the next request FlashFactory ff = (FlashFactory) FactoryFinder.getFactory(FactoryFinder.FLASH_FACTORY); ff.getFlash(true); ELFlash.setKeepFlag(facesContext); break; case FLASH_NOW_VARIABLE_NAME: // PENDING(edburns): use FacesContext.getAttributes() instead of // request scope. Map requestMap = extCtx.getRequestMap(); requestMap.put(ELFlash.FLASH_NOW_REQUEST_KEY, property); elContext.setPropertyResolved(true); result = requestMap; break; default: result = null; break; } } return result; } /** *

* Return the valid Class for a future set operation, which will always be null because sets * happen via the MapELResolver operating on the {@link ELFlash} instance as a Map. *

* * @throws PropertyNotFoundException if property is null. */ @Override public Class getType(ELContext elContext, Object base, Object property) { if (null != base) { return null; } if (null == property) { String message = " base " + base + " property " + property; throw new PropertyNotFoundException(message); } if (property.toString().equals(FLASH_VARIABLE_NAME)) { elContext.setPropertyResolved(true); } return null; } /** *

* This method will throw PropertyNotWritableException if called with a null base * and a property value equal to the literal string "flash". This is because set operations normally go * through the MapELResolver via the ELFlash Map. *

* *

* In other words, do not call this method directly to set a value into the flash! The only way to access the flash is * via the EL API. *

* * @throws PropertyNotFoundException if base is null and property is * null. * @throws PropertyNotWritableException if base is null and property is the * literal string "flash". */ @Override public void setValue(ELContext elContext, Object base, Object property, Object value) { if (base != null) { return; } if (property == null) { String message = " base " + base + " property " + property; throw new PropertyNotFoundException(message); } if (property.toString().equals(FLASH_VARIABLE_NAME)) { elContext.setPropertyResolved(true); throw new PropertyNotWritableException(property.toString()); } } /** *

* Returns true because write operations take place via the MapELResolver on the actual * {@link ELFlash} instance. *

* * @throws PropertyNotFoundException if base is null and property is * null. */ @Override public boolean isReadOnly(ELContext elContext, Object base, Object property) { if (base != null) { return false; } if (property == null) { String message = " base " + base + " property " + property; throw new PropertyNotFoundException(message); } if (property.toString().equals(FLASH_VARIABLE_NAME)) { elContext.setPropertyResolved(true); return true; } return false; } /** *

* If base is non-null and is the literal string "flash", return Object.class. *

*/ @Override public Class getCommonPropertyType(ELContext context, Object base) { Class result = null; if (null != base) { if (FLASH_VARIABLE_NAME.equals(base.toString())) { result = Object.class; } } return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy