Skip to content

Commit

Permalink
#469: add o:viewAction message
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Jul 22, 2018
1 parent 14fa7d6 commit ab446c0
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 2 deletions.
105 changes: 103 additions & 2 deletions src/main/java/org/omnifaces/component/input/ViewAction.java
Expand Up @@ -12,10 +12,22 @@
*/
package org.omnifaces.component.input;

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

import java.io.IOException;

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

import org.omnifaces.util.State;

/**
* <p>
* The <code>&lt;o:viewAction&gt;</code> is a component that extends the standard <code>&lt;f:viewAction&gt;</code> and
Expand Down Expand Up @@ -50,30 +62,101 @@
* &lt;o:viewAction action="otherpage" if="#{bean.property eq null}" /&gt;
* </pre>
*
* <h3>Messaging</h3>
* <p>
* You can use the <code>message</code> attribute to add a global flash warning message.
* <pre>
* &lt;o:viewAction ... message="Please use a valid link from within the site" /&gt;
* </pre>
* <p>
* 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 {

// Public constants -----------------------------------------------------------------------------------------------
// Constants ------------------------------------------------------------------------------------------------------

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 <code>true</code>. The default
* implementation will always broadcast. The {@link UIViewAction#isRendered()} is by default only considered during
* {@link #decode(javax.faces.context.FacesContext)}.
* <p>
* 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()) {
super.broadcast(event);
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 FacesContext facesContext;

public RedirectMessageEvent(FacesEvent wrapped, String message) {
super(wrapped.getComponent());
this.facesContext = new RedirectMessageFacesContext(wrapped.getFacesContext(), message);
}

@Override
public FacesContext getFacesContext() {
return facesContext;
}
}

private static class RedirectMessageFacesContext extends FacesContextWrapper {

private ExternalContext externalContext;

public RedirectMessageFacesContext(FacesContext wrapped, String message) {
super(wrapped);
this.externalContext = new RedirectMessageExternalContext(getWrapped().getExternalContext(), message);
}

@Override
public ExternalContext getExternalContext() {
return externalContext;
}
}

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 <code>true</code> if the <code>immediate="true"</code> attribute is <strong>not</strong> set, otherwise
* delegate to super, hereby maintaining the original behavior of <code>immediate="true"</code>.
Expand All @@ -83,4 +166,22 @@ 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);
}

}
19 changes: 19 additions & 0 deletions src/main/resources/META-INF/omnifaces-ui.taglib.xml
Expand Up @@ -2696,6 +2696,15 @@ If <code>#{bean.bar}</code> is any other value, then it will appear in the hash
<p>
Only when you set <code>immediate="true"</code>, then it will behave the same as the standard
<code>&lt;f:viewAction&gt;</code>.
<h3>Messaging</h3>
<p>
You can use the <code>message</code> attribute to add a global flash warning message.
<pre>
&lt;o:viewAction ... message="Please use a valid link from within the site" /&gt;
</pre>
<p>
Note that the message will only be shown when the redirect has actually taken place. The support was added in
OmniFaces 3.2.
]]>
</description>
<tag-name>viewAction</tag-name>
Expand Down Expand Up @@ -2777,6 +2786,16 @@ If <code>#{bean.bar}</code> is any other value, then it will appear in the hash
<required>false</required>
<type>boolean</type>
</attribute>
<attribute>
<description>
<![CDATA[
The message to send along with the redirect, if any.
]]>
</description>
<name>message</name>
<required>false</required>
<type>java.lang.String</type>
</attribute>
</tag>

<tag>
Expand Down

0 comments on commit ab446c0

Please sign in to comment.