Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mojavelinux/322811 to your computer and use it in GitHub Desktop.
Save mojavelinux/322811 to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<!-- Not required if the @FacesComponent is used on the component class! -->
<component>
<component-type>javax.faces.ViewAction</component-type>
<component-class>javax.faces.component.UIViewAction</component-class>
</component>
</faces-config>
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. 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.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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.component;
import java.io.Serializable;
import javax.faces.component.StateHolder;
import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.MethodBinding;
import javax.el.MethodExpression;
import javax.el.MethodInfo;
import javax.el.ELException;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import java.util.Arrays;
import java.lang.reflect.Method;
/**
* <p>Wrap a MethodExpression instance and expose it as a MethodBinding</p>
*
*/
class MethodBindingMethodExpressionAdapter extends MethodBinding implements StateHolder,
Serializable {
private static final long serialVersionUID = 7334926223014401689L;
private MethodExpression methodExpression = null;
private boolean tranzient;
public MethodBindingMethodExpressionAdapter() {
} // for StateHolder
MethodBindingMethodExpressionAdapter(MethodExpression methodExpression) {
this.methodExpression = methodExpression;
}
@Override
public Object invoke(FacesContext context, Object params[])
throws javax.faces.el.EvaluationException, javax.faces.el.MethodNotFoundException {
assert (null != methodExpression);
if (context == null) {
throw new NullPointerException("FacesConext -> null");
}
Object result = null;
try {
result = methodExpression.invoke(context.getELContext(),
params);
} catch (javax.el.MethodNotFoundException e) {
throw new javax.faces.el.MethodNotFoundException(e);
} catch (javax.el.PropertyNotFoundException e) {
throw new EvaluationException(e);
} catch (ELException e) {
Throwable cause = e.getCause();
if (cause == null) {
cause = e;
}
throw new EvaluationException(cause);
} catch (NullPointerException e) {
throw new javax.faces.el.MethodNotFoundException(e);
}
return result;
}
@Override
public Class getType(FacesContext context) throws javax.faces.el.MethodNotFoundException {
assert (null != methodExpression);
if (context == null) {
throw new NullPointerException("FacesConext -> null");
}
Class result = null;
if (context == null) {
throw new NullPointerException();
}
try {
MethodInfo mi =
methodExpression.getMethodInfo(context.getELContext());
result = mi.getReturnType();
} catch (javax.el.PropertyNotFoundException e) {
throw new javax.faces.el.MethodNotFoundException(e);
} catch (javax.el.MethodNotFoundException e) {
throw new javax.faces.el.MethodNotFoundException(e);
} catch (ELException e) {
throw new javax.faces.el.MethodNotFoundException(e);
}
return result;
}
@Override
public String getExpressionString() {
assert (null != methodExpression);
return methodExpression.getExpressionString();
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof MethodBindingMethodExpressionAdapter) {
return methodExpression.equals(((MethodBindingMethodExpressionAdapter) other).getWrapped());
} else if (other instanceof MethodBinding) {
MethodBinding binding = (MethodBinding) other;
// We'll need to do a little leg work to determine
// if the MethodBinding is equivalent to the
// wrapped MethodExpression
String expr = binding.getExpressionString();
int idx = expr.indexOf('.');
String target = expr.substring(0, idx).substring(2);
String t = expr.substring(idx + 1);
String method = t.substring(0, (t.length() - 1));
FacesContext context = FacesContext.getCurrentInstance();
ELContext elContext = context.getELContext();
MethodInfo controlInfo = methodExpression.getMethodInfo(elContext);
// ensure the method names are the same
if (!controlInfo.getName().equals(method)) {
return false;
}
// Using the target, create an expression and evaluate
// it.
ExpressionFactory factory = context.getApplication().getExpressionFactory();
ValueExpression ve = factory.createValueExpression(elContext,
"#{" + target + '}',
Object.class);
if (ve == null) {
return false;
}
Object result = ve.getValue(elContext);
if (result == null) {
return false;
}
// Get all of the methods with the matching name and try
// to find a match based on controlInfo's return and parameter
// types
Class type = binding.getType(context);
Method[] methods = result.getClass().getMethods();
for (Method meth : methods) {
if (meth.getName().equals(method)
&& type.equals(controlInfo.getReturnType())
&& Arrays.equals(meth.getParameterTypes(),
controlInfo.getParamTypes())) {
return true;
}
}
}
return false;
}
@Override
public int hashCode() {
assert (null != methodExpression);
return methodExpression.hashCode();
}
@Override
public boolean isTransient() {
return this.tranzient;
}
@Override
public void setTransient(boolean tranzient) {
this.tranzient = tranzient;
}
@Override
public Object saveState(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
Object result = null;
if (!tranzient) {
if (methodExpression instanceof StateHolder) {
Object[] stateStruct = new Object[2];
// save the actual state of our wrapped methodExpression
stateStruct[0] = ((StateHolder) methodExpression).saveState(context);
// save the class name of the methodExpression impl
stateStruct[1] = methodExpression.getClass().getName();
result = stateStruct;
} else {
result = methodExpression;
}
}
return result;
}
@Override
public void restoreState(FacesContext context, Object state) {
if (context == null) {
throw new NullPointerException();
}
// if we have state
if (null == state) {
return;
}
if (!(state instanceof MethodExpression)) {
Object[] stateStruct = (Object[]) state;
Object savedState = stateStruct[0];
String className = stateStruct[1].toString();
MethodExpression result = null;
Class toRestoreClass = null;
if (null != className) {
try {
toRestoreClass = loadClass(className, this);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage());
}
if (null != toRestoreClass) {
try {
result =
(MethodExpression) toRestoreClass.newInstance();
} catch (InstantiationException e) {
throw new IllegalStateException(e.getMessage());
} catch (IllegalAccessException a) {
throw new IllegalStateException(a.getMessage());
}
}
if (null != result && null != savedState) {
// don't need to check transient, since that was
// done on the saving side.
((StateHolder) result).restoreState(context, savedState);
}
methodExpression = result;
}
} else {
methodExpression = (MethodExpression) state;
}
}
public MethodExpression getWrapped() {
return methodExpression;
}
//
// Helper methods for StateHolder
//
private static Class loadClass(String name,
Object fallbackClass) throws ClassNotFoundException {
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = fallbackClass.getClass().getClassLoader();
}
return Class.forName(name, true, loader);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facelettaglibary_2_0.xsd"
version="2.0">
<namespace>http://java.sun.com/jsf/core</namespace>
<tag>
<tag-name>viewAction</tag-name>
<component>
<component-type>javax.faces.ViewAction</component-type>
</component>
</tag>
</facelet-taglib>
package javax.faces.component;
import javax.el.MethodExpression;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.NavigationHandler;
import javax.faces.component.ActionSource2;
import javax.faces.component.FacesComponent;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UIViewParameter;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextWrapper;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PreRenderViewEvent;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.view.ViewMetadata;
import javax.faces.webapp.FacesServlet;
/**
* <p><strong>UIViewAction</strong> is an {@link ActionSource2} {@link
* UIComponent} that specifies an application-specific command (or
* action)--defined as an EL method expression--to be invoked during one of the
* JSF lifecycle phases that proceeds view rendering. This component must be
* declared as a child of the {@link ViewMetadata} facet of the {@link
* UIViewRoot} so that it gets incorporated into the JSF lifecycle on both
* non-faces (initial) requests and faces (postback) requests.</p>
*
* <p>The purpose of this component is to provide a light-weight
* front-controller solution for executing code upon the loading of a JSF view
* to support the integration of system services, content retrieval, view
* management, and navigation. This functionality is especially useful for
* non-faces (initial) requests.</p>
*
* <p>The {@link UIViewAction} component is closely tied to the {@link
* UIViewParameter} component. The {@link UIViewParameter} component binds a
* request parameter to a model property. Most of the time, this binding is used
* to populate the model with data that supports the method being invoked by a
* {@link UIViewAction} component, much like form inputs populate the model with
* data to support the method being invoked by a {@link UICommand}
* component.</p>
*
* <p>When the <literal>decode()</literal> method of the {@link UIViewAction} is
* invoked, it will queue an {@link ActionEvent} to be broadcast to all
* interested listeners when the <literal>broadcast()</literal> method is
* invoked.</p>
*
* <p>If the value of the component's <literal>immediate</literal> attribute is
* <literal>true</literal>, the action will be invoked during the Apply Request
* Values JSF lifecycle phase. Otherwise, the action will be invoked during the
* Invoke Application phase, the default behavior. The phase cannot be
* set explicitly in the <literal>phase</literal> attribute, which takes
* precedence over the <literal>immediate</literal> attribute.</p>
*
* <p>The invocation of the action is normally suppressed (meaning the {@link
* ActionEvent} is not queued) on a faces request. It can be enabled by setting
* the component's <literal>onPostback</literal> attribute to <literal>true</literal>.
* Execution of the method can be subject to a required condition for all requests by
* assigning an EL value expression of expected type boolean to the component's
* <literal>if</literal> attribute, which must evaluate to
* <literal>true</literal> for the action to be invoked.</p>
*
* <p>The {@link NavigationHandler} is consulted after the action is invoked to
* carry out the navigation case that matches the action signature and outcome.
* If a navigation case is matched, or the response is marked complete by the
* action, subsequent {@link UIViewAction} components associated with the
* current view are short-circuited. The lifecycle then advances
* appropriately.</p>
*
* <p>It's important to note that the full component tree is not built before
* the UIViewAction components are processed on an non-faces (initial) request.
* Rather, the component tree only contains the {@link ViewMetadata}, an
* important part of the optimization of this component and what sets it apart
* from a {@link PreRenderViewEvent} listener.</p>
*
* @author Dan Allen
* @author Andy Schwartz
*
* @see UIViewParameter
*/
@FacesComponent(
// tagName = "viewAction",
// namespace = "http://java.sun.com/jsf/core",
// (see https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=594)
value = UIViewAction.COMPONENT_TYPE)
public class UIViewAction extends UIComponentBase implements ActionSource2 {
// ------------------------------------------------------ Manifest Constants
/**
* <p>
* The standard component type for this component.
* </p>
*/
public static final String COMPONENT_TYPE = "javax.faces.ViewAction";
/**
* <p>
* The standard component family for this component.
* </p>
*/
public static final String COMPONENT_FAMILY = "javax.faces.ViewAction";
/**
* Properties that are tracked by state saving.
*/
enum PropertyKeys
{
onPostback, actionExpression, immediate, phase, ifAttr("if");
private String name;
PropertyKeys()
{
}
PropertyKeys(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name != null ? name : super.toString();
}
}
// ------------------------------------------------------------ Constructors
/**
* <p>
* Create a new {@link UIViewAction} instance with default property values.
* </p>
*/
public UIViewAction()
{
super();
setRendererType(null);
}
// -------------------------------------------------------------- Properties
@Override
public String getFamily()
{
return COMPONENT_FAMILY;
}
/**
* {@inheritDoc}
*
* @deprecated This has been replaced by {@link #getActionExpression}.
*/
@Override
public MethodBinding getAction() {
MethodBinding result = null;
MethodExpression me;
if (null != (me = getActionExpression())) {
result = new MethodBindingMethodExpressionAdapter(me);
}
return result;
}
/**
* {@inheritDoc}
*
* @deprecated This has been replaced by {@link #setActionExpression(javax.el.MethodExpression)}.
* @throws UnsupportedOperationException if called
*/
@Override
public void setAction(MethodBinding action) {
throw new UnsupportedOperationException("Not supported.");
}
/**
* Action listeners are not supported by the {@link UIViewAction} component.
*
* @throws UnsupportedOperationException if called
*/
@Override
public MethodBinding getActionListener() {
throw new UnsupportedOperationException("Not supported.");
}
/**
* Action listeners are not supported by the {@link UIViewAction} component.
*
* @throws UnsupportedOperationException if called
*/
@Override
public void setActionListener(MethodBinding actionListener) {
throw new UnsupportedOperationException("Not supported.");
}
/**
* Returns the value which dictates the JSF lifecycle phase in which the
* action is invoked. If the value of this attribute is
* <literal>true</literal>, the action will be invoked in the Apply Request
* Values phase. If the value of this attribute is <literal>true</literal>,
* the default, the action will be invoked in the Invoke Application Phase.
*/
@Override
public boolean isImmediate() {
return (Boolean) getStateHelper().eval(PropertyKeys.immediate, false);
}
/**
* Sets the immediate flag, which controls the JSF lifecycle in which
* the action is invoked.
*/
@Override
public void setImmediate(boolean immediate) {
getStateHelper().put(PropertyKeys.immediate, immediate);
}
/**
* <p>Returns the name of the phase in which the action is to be queued. Only
* the following phases are supported (case does not matter):</p>
* <ul>
* <li>APPLY_REQUEST_VALUES</li>
* <li>PROCESS_VALIDATIONS</li>
* <li>UPDATE_MODEL_VALUES</li>
* <li>INVOKE_APPLICATION</li>
* </ul>
* <p>If the phase is set, it takes precedence over the
* immediate flag.</p>
*/
public String getPhase() {
String phase = (String) getStateHelper().eval(PropertyKeys.phase);
if (phase != null) {
phase = phase.toUpperCase();
}
return phase;
}
/**
* Set the name of the phase in which the action is to be queued.
*/
public void setPhase(String phase) {
getStateHelper().put(PropertyKeys.phase, phase);
}
public PhaseId getPhaseId() {
String phase = getPhase();
if (phase == null) {
return null;
}
if ("APPLY_REQUEST_VALUES".equals(phase)) {
return PhaseId.APPLY_REQUEST_VALUES;
} else if ("PROCESS_VALIDATIONS".equals(phase)) {
return PhaseId.PROCESS_VALIDATIONS;
} else if ("UPDATE_MODEL_VALUES".equals(phase)) {
return PhaseId.UPDATE_MODEL_VALUES;
} else if ("INVOKE_APPLICATION".equals(phase)) {
return PhaseId.INVOKE_APPLICATION;
} else if ("ANY_PHASE".equals(phase) || "RESTORE_VIEW".equals(phase) || "RENDER_REPONSE".equals(phase)) {
throw new FacesException("View actions cannot be executed in specified phase: [" + phase + "]");
} else {
throw new FacesException("Not a valid phase [" + phase + "]");
}
}
/**
* Action listeners are not supported by the {@link UIViewAction} component.
*
* @throws UnsupportedOperationException if called
*/
@Override
public void addActionListener(ActionListener listener) {
throw new UnsupportedOperationException("Not supported.");
}
/**
* Action listeners are not supported by the {@link UIViewAction} component.
*/
@Override
public ActionListener[] getActionListeners() {
return new ActionListener[0];
}
/**
* Action listeners are not supported by the {@link UIViewAction} component.
*
* @throws UnsupportedOperationException if called
*/
@Override
public void removeActionListener(ActionListener listener) {
throw new UnsupportedOperationException("Not supported.");
}
/**
* Returns the action, represented as an EL method expression, to invoke.
*/
@Override
public MethodExpression getActionExpression()
{
return (MethodExpression) getStateHelper().get(PropertyKeys.actionExpression);
}
/**
* Sets the action, represented as an EL method expression, to invoke.
*/
@Override
public void setActionExpression(MethodExpression actionExpression)
{
getStateHelper().put(PropertyKeys.actionExpression, actionExpression);
}
/**
* Returns a boolean value that controls whether the action is invoked during
* faces (postback) request.
*/
public boolean isOnPostback()
{
return (Boolean) getStateHelper().eval(PropertyKeys.onPostback, false);
}
/**
* Set the bookean flag that controls whether the action is invoked during
* a faces (postback) request.
*/
public void setOnPostback(boolean onPostback)
{
getStateHelper().put(PropertyKeys.onPostback, onPostback);
}
/**
* Returns a condition, represented as an EL value expression, that must
* evaluate to true for the action to be invoked.
*/
public boolean isIf()
{
return (Boolean) getStateHelper().eval(PropertyKeys.ifAttr, true);
}
/**
* Sets the condition, represented as an EL value expression, that must
* evaluate to true for the action to be invoked.
*/
public void setIf(boolean condition)
{
getStateHelper().put(PropertyKeys.ifAttr, condition);
}
// ----------------------------------------------------- UIComponent Methods
/**
* <p>In addition to to the default {@link UIComponent#broadcast} processing,
* pass the {@link ActionEvent} being broadcast to the default {@link
* ActionListener} registered on the {@link
* javax.faces.application.Application}.</p>
*
* @param event {@link FacesEvent} to be broadcast
*
* @throws AbortProcessingException Signal the JavaServer Faces
* implementation that no further processing on the current event
* should be performed
* @throws IllegalArgumentException if the implementation class
* of this {@link FacesEvent} is not supported by this component
* @throws NullPointerException if <code>event</code> is
* <code>null</code>
*/
@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
super.broadcast(event);
FacesContext context = getFacesContext();
// only proceed if the response has not been marked complete and navigation to another view has not occurred
if (event instanceof ActionEvent && !context.getResponseComplete() &&
context.getViewRoot() == getViewRootOf(event)) {
ActionListener listener = context.getApplication().getActionListener();
if (listener != null) {
UIViewRoot viewRootBefore = context.getViewRoot();
InstrumentedFacesContext instrumentedContext = new InstrumentedFacesContext(context);
// defer the call to renderResponse() that happens in ActionListener#processAction(ActionEvent)
instrumentedContext.disableRenderResponseControl().set();
listener.processAction((ActionEvent) event);
instrumentedContext.restore();
// if the response is marked complete, the story is over
if (!context.getResponseComplete()) {
UIViewRoot viewRootAfter = context.getViewRoot();
// if the view id changed as a result of navigation, then execute the JSF lifecycle for the new view id
if (viewRootBefore != viewRootAfter) {
/*
// execute the JSF lifecycle by dispatching a forward request
// this approach is problematic because it throws a wrench in the event broadcasting
try {
context.getExternalContext().dispatch(context.getApplication()
.getViewHandler().getActionURL(context, viewRootAfter.getViewId())
.substring(context.getExternalContext().getRequestContextPath().length()));
// kill this lifecycle execution
context.responseComplete();
} catch (IOException e) {
throw new FacesException("Dispatch to viewId failed: " + viewRootAfter.getViewId(), e);
}
*/
// manually execute the JSF lifecycle on the new view id
// certain tweaks have to be made to the FacesContext to allow us to reset the lifecycle
Lifecycle lifecycle = getLifecycle(context);
instrumentedContext = new InstrumentedFacesContext(context);
instrumentedContext.pushViewIntoRequestMap().clearViewRoot().clearPostback().set();
lifecycle.execute(instrumentedContext);
instrumentedContext.restore();
}
else {
// apply the deferred call (relevant when immediate is true)
context.renderResponse();
}
}
}
}
}
/**
* First, determine if the action should be invoked by evaluating this
* components pre-conditions. If this is a faces (postback) request and the
* evaluated value of the postback attribute is false, take no action. If the
* evaluated value of the if attribute is false, take no action. If both
* conditions pass, proceed with creating an {@link ActionEvent}.
*
* Set the phaseId in which the queued {@link ActionEvent} should be
* broadcast by assigning the appropriate value to the phaseId property of
* the {@link ActionEvent} according to the evaluated value of the immediate
* attribute. If the value is <literal>true</literal>, set the phaseId to
* {@link PhaseId#APPLY_REQUEST_VALUES}. Otherwise, set the phaseId to to
* {@link PhaseId#INVOKE_APPLICATION}.
*
* Finally, queue the event by calling <literal>queueEvent()</literal> and
* passing the {@link ActionEvent} just created.
*/
@Override
public void decode(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
if ((context.isPostback() && !isOnPostback()) || !isIf()) {
return;
}
ActionEvent e = new ActionEvent(this);
PhaseId phaseId = getPhaseId();
if (phaseId != null) {
e.setPhaseId(phaseId);
}
else if (isImmediate()) {
e.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
}
else {
e.setPhaseId(PhaseId.INVOKE_APPLICATION);
}
queueEvent(e);
}
private UIViewRoot getViewRootOf(FacesEvent e) {
UIComponent c = e.getComponent();
do {
if (c instanceof UIViewRoot) {
return (UIViewRoot) c;
}
c = c.getParent();
} while (c != null);
return null;
}
private Lifecycle getLifecycle(FacesContext context) {
LifecycleFactory lifecycleFactory = (LifecycleFactory)
FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
String lifecycleId = context.getExternalContext()
.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
if (lifecycleId == null) {
lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
}
return lifecycleFactory.getLifecycle(lifecycleId);
}
/**
* A FacesContext delegator that gives us the necessary controls over the FacesContext
* to allow the execution of the lifecycle to accomodate the UIViewAction sequence.
*/
private class InstrumentedFacesContext extends FacesContextWrapper {
private FacesContext wrapped;
private boolean viewRootCleared = false;
private boolean renderedResponseControlDisabled = false;
private Boolean postback = null;
public InstrumentedFacesContext(FacesContext wrapped) {
this.wrapped = wrapped;
}
@Override
public FacesContext getWrapped() {
return wrapped;
}
@Override
public UIViewRoot getViewRoot() {
if (viewRootCleared) {
return null;
}
return wrapped.getViewRoot();
}
@Override
public void setViewRoot(UIViewRoot viewRoot) {
viewRootCleared = false;
wrapped.setViewRoot(viewRoot);
}
@Override
public boolean isPostback() {
return postback == null ? wrapped.isPostback() : postback;
}
@Override
public void renderResponse() {
if (!renderedResponseControlDisabled) {
wrapped.renderResponse();
}
}
/**
* Make it look like we have dispatched a request using the include method.
*/
public InstrumentedFacesContext pushViewIntoRequestMap() {
getExternalContext().getRequestMap()
.put("javax.servlet.include.servlet_path", wrapped.getViewRoot().getViewId());
return this;
}
public InstrumentedFacesContext clearPostback() {
postback = false;
return this;
}
public InstrumentedFacesContext clearViewRoot() {
viewRootCleared = true;
return this;
}
public InstrumentedFacesContext disableRenderResponseControl() {
renderedResponseControlDisabled = true;
return this;
}
public void set() {
setCurrentInstance(this);
}
public void restore() {
setCurrentInstance(wrapped);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment