You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2013/04/22 01:32:31 UTC
git commit: DELTASPIKE-345 integration of @InitView, @PreViewAction,
@PreRenderView, @PostRenderView
Updated Branches:
refs/heads/master 382bce8cb -> b280ad9dc
DELTASPIKE-345 integration of @InitView, @PreViewAction, @PreRenderView, @PostRenderView
(first step)
Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/b280ad9d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/b280ad9d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/b280ad9d
Branch: refs/heads/master
Commit: b280ad9dc692f3ca41af77091a90ead1b281d9b6
Parents: 382bce8
Author: gpetracek <gp...@apache.org>
Authored: Mon Apr 22 01:10:00 2013 +0200
Committer: gpetracek <gp...@apache.org>
Committed: Mon Apr 22 01:23:07 2013 +0200
----------------------------------------------------------------------
.../config/view/ViewControllerActionListener.java | 65 ++++++++
.../listener/action/DeltaSpikeActionListener.java | 68 ++++++++
.../listener/phase/DeltaSpikePhaseListener.java | 128 ++++++++++++++-
.../jsf/impl/listener/phase/WindowMetaData.java | 41 +++++
.../jsf/impl/util/ViewControllerUtils.java | 45 +++++
.../src/main/resources/META-INF/faces-config.xml | 1 +
6 files changed, 339 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b280ad9d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewControllerActionListener.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewControllerActionListener.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewControllerActionListener.java
new file mode 100644
index 0000000..3971fb8
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewControllerActionListener.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * http://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.apache.deltaspike.jsf.impl.config.view;
+
+import org.apache.deltaspike.core.api.config.view.controller.PreViewAction;
+import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor;
+import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.jsf.impl.util.ViewControllerUtils;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+
+/**
+ * ActionListener which invokes {@link PreViewAction} callbacks of page-beans
+ */
+public class ViewControllerActionListener implements ActionListener, Deactivatable
+{
+ private final ActionListener wrapped;
+
+ private final boolean activated;
+
+ /**
+ * Constructor for wrapping the given {@link ActionListener}
+ * @param wrapped action-listener which should be wrapped
+ */
+ public ViewControllerActionListener(ActionListener wrapped)
+ {
+ this.wrapped = wrapped;
+ this.activated = ClassDeactivationUtils.isActivated(getClass());
+ }
+
+ @Override
+ public void processAction(ActionEvent actionEvent)
+ {
+ if (this.activated)
+ {
+ ViewConfigDescriptor viewConfigDescriptor = BeanProvider.getContextualReference(ViewConfigResolver.class)
+ .getViewConfigDescriptor(FacesContext.getCurrentInstance().getViewRoot().getViewId());
+
+ ViewControllerUtils.executeViewControllerCallback(viewConfigDescriptor, PreViewAction.class);
+ }
+
+ this.wrapped.processAction(actionEvent);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b280ad9d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/action/DeltaSpikeActionListener.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/action/DeltaSpikeActionListener.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/action/DeltaSpikeActionListener.java
new file mode 100644
index 0000000..4cc48e0
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/action/DeltaSpikeActionListener.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * http://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.apache.deltaspike.jsf.impl.listener.action;
+
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.jsf.impl.config.view.ViewControllerActionListener;
+
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+
+/**
+ * Aggregates {@link ActionListener} implementations provided by DeltaSpike to ensure a deterministic behaviour
+ */
+public class DeltaSpikeActionListener implements ActionListener, Deactivatable
+{
+ private final ActionListener wrapped;
+ private final boolean activated;
+
+ /**
+ * Constructor for wrapping the given {@link ActionListener}
+ * @param wrapped action-listener which should be wrapped
+ */
+ public DeltaSpikeActionListener(ActionListener wrapped)
+ {
+ this.wrapped = wrapped;
+ this.activated = ClassDeactivationUtils.isActivated(getClass());
+ }
+
+ @Override
+ public void processAction(ActionEvent actionEvent)
+ {
+ if (this.activated)
+ {
+ getWrappedActionListener().processAction(actionEvent);
+ }
+ else
+ {
+ this.wrapped.processAction(actionEvent);
+ }
+ }
+
+ private ActionListener getWrappedActionListener()
+ {
+ //TODO re-visit it
+ //was:
+ //SecurityViolationAwareActionListener securityViolationAwareActionListener =
+ // new SecurityViolationAwareActionListener(this.wrapped);
+
+ return new ViewControllerActionListener(this.wrapped);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b280ad9d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/DeltaSpikePhaseListener.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/DeltaSpikePhaseListener.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/DeltaSpikePhaseListener.java
index 4de5fd0..efc07ea 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/DeltaSpikePhaseListener.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/DeltaSpikePhaseListener.java
@@ -18,15 +18,23 @@
*/
package org.apache.deltaspike.jsf.impl.listener.phase;
+import org.apache.deltaspike.core.api.config.view.controller.InitView;
+import org.apache.deltaspike.core.api.config.view.controller.PostRenderView;
+import org.apache.deltaspike.core.api.config.view.controller.PreRenderView;
+import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor;
+import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver;
import org.apache.deltaspike.core.api.provider.BeanProvider;
import org.apache.deltaspike.core.spi.activation.Deactivatable;
import org.apache.deltaspike.core.util.ClassDeactivationUtils;
import org.apache.deltaspike.jsf.impl.security.ViewRootAccessHandler;
import org.apache.deltaspike.jsf.impl.util.SecurityUtils;
+import org.apache.deltaspike.jsf.impl.util.ViewControllerUtils;
import org.apache.deltaspike.security.api.authorization.ErrorViewAwareAccessDeniedException;
import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext;
+import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.inject.Typed;
+import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
@@ -43,6 +51,8 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
private final PhaseListener jsfRequestLifecyclePhaseListener = new JsfRequestLifecyclePhaseListener();
+ private ViewConfigResolver viewConfigResolver;
+
public DeltaSpikePhaseListener()
{
this.activated = ClassDeactivationUtils.isActivated(getClass());
@@ -56,6 +66,13 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
return;
}
+ if (this.viewConfigResolver == null)
+ {
+ lazyInit();
+ }
+
+ processInitView(phaseEvent);
+
if (PhaseId.RENDER_RESPONSE.equals(phaseEvent.getPhaseId()))
{
onBeforeRenderResponse(phaseEvent.getFacesContext());
@@ -68,7 +85,7 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
private void onBeforeRenderResponse(FacesContext facesContext)
{
checkSecuredView(facesContext);
- //TODO call pre-render-view callbacks
+ processPreRenderView(facesContext);
}
@Override
@@ -79,18 +96,25 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
return;
}
- if (PhaseId.RESTORE_VIEW.equals(phaseEvent.getPhaseId()))
+ if (this.viewConfigResolver == null)
{
- onAfterRestoreView(phaseEvent.getFacesContext());
+ lazyInit();
+ }
+
+ processInitView(phaseEvent);
+
+ if (PhaseId.RENDER_RESPONSE.equals(phaseEvent.getPhaseId()))
+ {
+ onAfterRenderResponse(phaseEvent.getFacesContext());
}
//delegate to JsfRequestLifecyclePhaseListener as a last step
this.jsfRequestLifecyclePhaseListener.afterPhase(phaseEvent);
}
- private void onAfterRestoreView(FacesContext facesContext)
+ private void onAfterRenderResponse(FacesContext facesContext)
{
- //TODO call init-view callbacks
+ processPostRenderView(facesContext);
}
@Override
@@ -101,10 +125,6 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
private void checkSecuredView(FacesContext facesContext)
{
- if (this.securityModuleActivated == null)
- {
- lazyInit();
- }
if (!this.securityModuleActivated)
{
return;
@@ -126,6 +146,8 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
this.securityModuleActivated =
BeanProvider.getContextualReference(EditableAccessDecisionVoterContext.class, true) != null;
+ this.viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class);
+
if (!this.securityModuleActivated)
{
Logger.getLogger(getClass().getName()) //it's the only case for which a logger is needed in this class
@@ -133,4 +155,92 @@ public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable
"#checkSecuredView gets deactivated");
}
}
+
+ private void processInitView(PhaseEvent event)
+ {
+ if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW) && !isRedirectRequest(event.getFacesContext()))
+ {
+ return;
+ }
+
+ //TODO check if we have to restrict the other callbacks as well
+ //leads to a call of @BeforePhase but not the corresponding @AfterPhase call of the corresponding callbacks
+
+ //TODO don't call the callbacks in case of an initial redirct
+ //was:
+ /*
+ if(Boolean.TRUE.equals(event.getFacesContext().getExternalContext().getRequestMap()
+ .get(WindowContextManagerObserver.INITIAL_REDIRECT_PERFORMED_KEY)))
+ {
+ return;
+ }
+ */
+
+ FacesContext facesContext = event.getFacesContext();
+ if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getViewId() != null)
+ {
+ processInitView(event.getFacesContext().getViewRoot().getViewId());
+ }
+ }
+
+ private void processInitView(String viewId)
+ {
+ try
+ {
+ WindowMetaData windowMetaData = BeanProvider.getContextualReference(WindowMetaData.class);
+
+ //view already initialized in this or any prev. request
+ if (viewId.equals(windowMetaData.getInitializedViewId()))
+ {
+ return;
+ }
+
+ //override the view-id if we have a new view
+ windowMetaData.setInitializedViewId(viewId);
+
+ ViewConfigDescriptor viewDefinitionEntry = this.viewConfigResolver.getViewConfigDescriptor(viewId);
+
+ if (viewDefinitionEntry == null)
+ {
+ return;
+ }
+
+ ViewControllerUtils.executeViewControllerCallback(viewDefinitionEntry, InitView.class);
+ }
+ catch (ContextNotActiveException e)
+ {
+ return; //TODO discuss how we handle it
+ }
+ }
+
+ private void processPreRenderView(FacesContext facesContext)
+ {
+ UIViewRoot uiViewRoot = facesContext.getViewRoot();
+
+ if (uiViewRoot != null)
+ {
+ ViewConfigDescriptor viewDefinitionEntry =
+ this.viewConfigResolver.getViewConfigDescriptor(uiViewRoot.getViewId());
+
+ ViewControllerUtils.executeViewControllerCallback(viewDefinitionEntry, PreRenderView.class);
+ }
+ }
+
+ private void processPostRenderView(FacesContext facesContext)
+ {
+ UIViewRoot uiViewRoot = facesContext.getViewRoot();
+
+ if (uiViewRoot != null)
+ {
+ ViewConfigDescriptor viewDefinitionEntry =
+ this.viewConfigResolver.getViewConfigDescriptor(uiViewRoot.getViewId());
+
+ ViewControllerUtils.executeViewControllerCallback(viewDefinitionEntry, PostRenderView.class);
+ }
+ }
+
+ private boolean isRedirectRequest(FacesContext facesContext)
+ {
+ return facesContext.getResponseComplete();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b280ad9d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/WindowMetaData.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/WindowMetaData.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/WindowMetaData.java
new file mode 100644
index 0000000..d7f1c83
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/WindowMetaData.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * http://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.apache.deltaspike.jsf.impl.listener.phase;
+
+import org.apache.deltaspike.core.api.scope.WindowScoped;
+
+import java.io.Serializable;
+
+@WindowScoped
+public class WindowMetaData implements Serializable
+{
+ private static final long serialVersionUID = -413165700186583037L;
+
+ private String initializedViewId;
+
+ public String getInitializedViewId()
+ {
+ return initializedViewId;
+ }
+
+ public void setInitializedViewId(String initializedViewId)
+ {
+ this.initializedViewId = initializedViewId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b280ad9d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ViewControllerUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ViewControllerUtils.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ViewControllerUtils.java
new file mode 100644
index 0000000..1798f9b
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ViewControllerUtils.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * http://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.apache.deltaspike.jsf.impl.util;
+
+import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef;
+import org.apache.deltaspike.core.api.config.view.metadata.SimpleCallbackDescriptor;
+import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor;
+
+import java.lang.annotation.Annotation;
+
+public abstract class ViewControllerUtils
+{
+ public static void executeViewControllerCallback(ViewConfigDescriptor viewDefinitionEntry,
+ Class<? extends Annotation> callbackType)
+ {
+ if (viewDefinitionEntry == null)
+ {
+ return;
+ }
+
+ SimpleCallbackDescriptor initViewCallbackDescriptor = viewDefinitionEntry.getExecutableCallbackDescriptor(
+ ViewControllerRef.class, callbackType, SimpleCallbackDescriptor.class);
+
+ if (initViewCallbackDescriptor != null)
+ {
+ initViewCallbackDescriptor.execute();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b280ad9d/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
index 6d951da..8b7b43a 100644
--- a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
+++ b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
@@ -31,6 +31,7 @@
<application>
<view-handler>org.apache.deltaspike.jsf.impl.view.DeltaSpikeViewHandler</view-handler>
<navigation-handler>org.apache.deltaspike.jsf.impl.navigation.DeltaSpikeNavigationHandler</navigation-handler>
+ <action-listener>org.apache.deltaspike.jsf.impl.listener.action.DeltaSpikeActionListener</action-listener>
</application>
<factory>