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>