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

org.omnifaces.component.input.ViewAction Maven / Gradle / Ivy

There is a newer version: 4.4.1
Show newest version
/*
 * Copyright OmniFaces
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.omnifaces.component.input;

import static org.omnifaces.util.Messages.addFlashGlobalWarn;
import static org.omnifaces.util.Utils.isEmpty;

import java.io.IOException;

import jakarta.faces.component.FacesComponent;
import jakarta.faces.component.UIViewAction;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.ExternalContextWrapper;
import jakarta.faces.context.FacesContext;
import jakarta.faces.context.FacesContextWrapper;
import jakarta.faces.event.ActionEvent;
import jakarta.faces.event.FacesEvent;

import org.omnifaces.util.State;

/**
 * 

* The <o:viewAction> is a component that extends the standard <f:viewAction> and * changes the if attribute to be evaluated during INVOKE_APPLICATION phase instead of the * APPLY_REQUEST_VALUES phase. This allows developers to let the if attribute check the * converted and validated model values before performing the view action, which results in much more intuitive behavior. *

* In below example, the FooConverter may convert a non-null parameter to null without causing * a validation or conversion error, and the intent is to redirect the current page to otherpage.xhtml when * the converted result is null. *

 * <f:viewParam name="foo" value="#{bean.foo}" converter="fooConverter" />
 * <f:viewAction action="otherpage" if="#{bean.foo eq null}" />
 * 
*

* This is however not possible with standard <f:viewAction> as it evaluates the if * attribute already before the conversion has taken place. This component solves that by postponing the evaluation of * the if attribute to the INVOKE_APPLICATION phase. *

 * <f:viewParam name="foo" value="#{bean.foo}" converter="fooConverter" />
 * <o:viewAction action="otherpage" if="#{bean.foo eq null}" />
 * 
*

* Only when you set immediate="true", then it will behave the same as the standard * <f:viewAction>. * *

Usage

*

* You can use it the same way as <f:viewAction>, you only need to change f: to * o:. *

 * <o:viewAction action="otherpage" if="#{bean.property eq null}" />
 * 
* *

Messaging

*

* You can use the message attribute to add a global flash warning message. *

 * <o:viewAction ... message="Please use a valid link from within the site" />
 * 
*

* Note that the message will only be shown when the redirect has actually taken place. The support was added in * OmniFaces 3.2. * * @author Bauke Scholtz * @since 2.2 */ @FacesComponent(ViewAction.COMPONENT_TYPE) public class ViewAction extends UIViewAction { // Constants ------------------------------------------------------------------------------------------------------ /** The component type, which is {@value org.omnifaces.component.input.ViewAction#COMPONENT_TYPE}. */ public static final String COMPONENT_TYPE = "org.omnifaces.component.input.ViewAction"; enum PropertyKeys { message } // Variables ------------------------------------------------------------------------------------------------------ private final State state = new State(getStateHelper()); // Actions -------------------------------------------------------------------------------------------------------- /** * Only broadcast the action event when {@link UIViewAction#isRendered()} returns true. The default * implementation will always broadcast. The {@link UIViewAction#isRendered()} is by default only considered during * {@link #decode(jakarta.faces.context.FacesContext)}. *

* If the action event performs any redirect, then add any {@link #getMessage()} as a global flash warning message. */ @Override public void broadcast(FacesEvent event) { if (super.isRendered()) { String message = getMessage(); super.broadcast(isEmpty(message) ? event : new RedirectMessageEvent(event, message)); } } private static class RedirectMessageEvent extends ActionEvent { private static final long serialVersionUID = 1L; private FacesEvent wrapped; private String message; public RedirectMessageEvent(FacesEvent wrapped, String message) { super(wrapped.getComponent()); this.wrapped = wrapped; this.message = message; } @Override public FacesContext getFacesContext() { return new RedirectMessageFacesContext(wrapped.getFacesContext(), message); } } private static class RedirectMessageFacesContext extends FacesContextWrapper { private String message; public RedirectMessageFacesContext(FacesContext wrapped, String message) { super(wrapped); this.message = message; } @Override public ExternalContext getExternalContext() { return new RedirectMessageExternalContext(getWrapped().getExternalContext(), message); } } private static class RedirectMessageExternalContext extends ExternalContextWrapper { private String message; public RedirectMessageExternalContext(ExternalContext wrapped, String message) { super(wrapped); this.message = message; } @Override public void redirect(String url) throws IOException { addFlashGlobalWarn(message); super.redirect(url); } } // Getters/setters ------------------------------------------------------------------------------------------------ /** * Returns true if the immediate="true" attribute is not set, otherwise * delegate to super, hereby maintaining the original behavior of immediate="true". */ @Override public boolean isRendered() { return !isImmediate() || super.isRendered(); } /** * Returns the global flash warning message to be shown in the redirected page. * @return The global flash warning message to be shown in the redirected page. * @since 3.2 */ public String getMessage() { return state.get(PropertyKeys.message); } /** * Sets the global flash warning message to be shown in the redirected page. * @param message The global flash warning message to be shown in the redirected page. * @since 3.2 */ public void setMessage(String message) { state.put(PropertyKeys.message, message); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy