DELTASPIKE-524 preserve view-parameters
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/e88f2901 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/e88f2901 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/e88f2901 Branch: refs/heads/master Commit: e88f2901c5bac5195768ad5e1b5e0af724f0d9f6 Parents: 6734367 Author: gpetracek <[email protected]> Authored: Thu Feb 20 08:58:33 2014 +0100 Committer: gpetracek <[email protected]> Committed: Thu Feb 20 09:38:21 2014 +0100 ---------------------------------------------------------------------- .../InjectionAwareApplicationWrapper.java | 26 ++++++++++++++- .../request/DeltaSpikeFacesContextWrapper.java | 19 +++++++---- .../impl/security/SecurityAwareViewHandler.java | 35 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e88f2901/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java index 531a675..2a76447 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java @@ -19,11 +19,15 @@ package org.apache.deltaspike.jsf.impl.injection; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; +import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler; import javax.faces.FacesException; import javax.faces.application.Application; import javax.faces.application.ApplicationWrapper; +import javax.faces.context.FacesContext; import javax.faces.convert.Converter; +import javax.faces.event.PreDestroyViewMapEvent; +import javax.faces.event.SystemEvent; import javax.faces.validator.Validator; public class InjectionAwareApplicationWrapper extends ApplicationWrapper @@ -31,12 +35,15 @@ public class InjectionAwareApplicationWrapper extends ApplicationWrapper private final Application wrapped; private final boolean containerManagedConvertersEnabled; private final boolean containerManagedValidatorsEnabled; + private final boolean preDestroyViewMapEventFilterMode; - public InjectionAwareApplicationWrapper(Application wrapped, JsfModuleConfig jsfModuleConfig) + public InjectionAwareApplicationWrapper( + Application wrapped, JsfModuleConfig jsfModuleConfig, boolean preDestroyViewMapEventFilterMode) { this.wrapped = wrapped; this.containerManagedConvertersEnabled = jsfModuleConfig.isContainerManagedConvertersEnabled(); this.containerManagedValidatorsEnabled = jsfModuleConfig.isContainerManagedValidatorsEnabled(); + this.preDestroyViewMapEventFilterMode = preDestroyViewMapEventFilterMode; } @Override @@ -104,6 +111,23 @@ public class InjectionAwareApplicationWrapper extends ApplicationWrapper } @Override + public void publishEvent(FacesContext facesContext, Class<? extends SystemEvent> systemEventClass, Object source) + { + if (!PreDestroyViewMapEvent.class.isAssignableFrom(systemEventClass) || + isPreDestroyViewMapEventAllowed(facesContext)) + { + super.publishEvent(facesContext, systemEventClass, source); + } + } + + private boolean isPreDestroyViewMapEventAllowed(FacesContext facesContext) + { + return !this.preDestroyViewMapEventFilterMode || + !Boolean.TRUE.equals(facesContext.getExternalContext().getRequestMap().get( + SecurityAwareViewHandler.PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED)); + } + + @Override public Application getWrapped() { return wrapped; http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e88f2901/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java index 5229b73..2ad8a54 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java @@ -35,6 +35,8 @@ import javax.faces.context.FacesContextWrapper; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindow; class DeltaSpikeFacesContextWrapper extends FacesContextWrapper @@ -51,6 +53,8 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper private volatile Boolean initialized; + private boolean preDestroyViewMapEventFilterMode; + DeltaSpikeFacesContextWrapper(FacesContext wrappedFacesContext, ClientWindow clientWindow) { this.wrappedFacesContext = wrappedFacesContext; @@ -117,8 +121,10 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper private synchronized void init() { // switch into paranoia mode - if (initialized == null) + if (this.initialized == null) { + this.jsfModuleConfig = BeanProvider.getContextualReference(JsfModuleConfig.class); + if (ClassDeactivationUtils.isActivated(BeforeAfterJsfRequestBroadcaster.class)) { this.beforeAfterJsfRequestBroadcaster = @@ -131,6 +137,9 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper this.defaultErrorViewExceptionHandlerActivated = viewConfigResolver.getDefaultErrorViewConfigDescriptor() != null && ClassDeactivationUtils.isActivated(DefaultErrorViewAwareExceptionHandlerWrapper.class); + + this.preDestroyViewMapEventFilterMode = ClassDeactivationUtils.isActivated(SecurityAwareViewHandler.class); + this.initialized = true; } } @@ -170,12 +179,10 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper @Override public Application getApplication() { - if (this.jsfModuleConfig == null) - { - this.jsfModuleConfig = BeanProvider.getContextualReference(JsfModuleConfig.class); - } + lazyInit(); - return new InjectionAwareApplicationWrapper(this.wrappedFacesContext.getApplication(), this.jsfModuleConfig); + return new InjectionAwareApplicationWrapper( + this.wrappedFacesContext.getApplication(), this.jsfModuleConfig, this.preDestroyViewMapEventFilterMode); } @Override http://git-wip-us.apache.org/repos/asf/deltaspike/blob/e88f2901/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/SecurityAwareViewHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/SecurityAwareViewHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/SecurityAwareViewHandler.java index b0180c2..2d369b0 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/SecurityAwareViewHandler.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/SecurityAwareViewHandler.java @@ -34,10 +34,15 @@ import javax.faces.application.ViewHandler; import javax.faces.application.ViewHandlerWrapper; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; +import java.util.HashMap; +import java.util.Map; import java.util.logging.Logger; public class SecurityAwareViewHandler extends ViewHandlerWrapper implements Deactivatable { + public static final String PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED = + SecurityAwareViewHandler.class.getName() + "#PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED"; + protected final ViewHandler wrapped; private final boolean activated; @@ -82,6 +87,21 @@ public class SecurityAwareViewHandler extends ViewHandlerWrapper implements Deac UIViewRoot originalViewRoot = context.getViewRoot(); + Map<String, Object> viewMap = null; + if (originalViewRoot != null) + { + Map<String, Object> originalViewMap = originalViewRoot.getViewMap(false); + + if (originalViewMap != null && !originalViewMap.isEmpty()) + { + viewMap = new HashMap<String, Object>(); + viewMap.putAll(originalViewMap); + } + } + + //workaround for PreDestroyViewMapEvent which would be caused by the security check + deactivatePreDestroyViewMapEvent(context); + //we have to use it as current view if an AccessDecisionVoter uses the JSF API to check access to the view-id context.setViewRoot(result); @@ -118,9 +138,14 @@ public class SecurityAwareViewHandler extends ViewHandlerWrapper implements Deac } finally { + activatePreDestroyViewMapEvent(context); if (originalViewRoot != null) { context.setViewRoot(originalViewRoot); + if (viewMap != null) + { + originalViewRoot.getViewMap().putAll(viewMap); + } } } @@ -138,4 +163,14 @@ public class SecurityAwareViewHandler extends ViewHandlerWrapper implements Deac .info("security-module-impl isn't used -> " + getClass().getName() + " gets deactivated"); } } + + private void deactivatePreDestroyViewMapEvent(FacesContext facesContext) + { + facesContext.getExternalContext().getRequestMap().put(PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED, Boolean.TRUE); + } + + private void activatePreDestroyViewMapEvent(FacesContext facesContext) + { + facesContext.getExternalContext().getRequestMap().put(PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED, Boolean.FALSE); + } }
