View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.application;
20  
21  import javax.el.MethodExpression;
22  import javax.faces.application.Application;
23  import javax.faces.application.ConfigurableNavigationHandler;
24  import javax.faces.application.NavigationCase;
25  import javax.faces.application.NavigationHandler;
26  import javax.faces.component.ActionSource;
27  import javax.faces.component.ActionSource2;
28  import javax.faces.component.UIComponent;
29  import javax.faces.component.UIViewRoot;
30  import javax.faces.context.FacesContext;
31  import javax.faces.el.MethodBinding;
32  import javax.faces.event.AbortProcessingException;
33  import javax.faces.event.ActionEvent;
34  import javax.faces.event.ActionListener;
35  import javax.faces.event.PhaseId;
36  import org.apache.myfaces.view.facelets.ViewPoolProcessor;
37  import org.apache.myfaces.view.facelets.pool.ViewPool;
38  
39  
40  /**
41   * @author Manfred Geiler (latest modification by $Author$)
42   * @author Anton Koinov
43   * @version $Revision$ $Date$
44   */
45  public class ActionListenerImpl implements ActionListener
46  {
47      public void processAction(ActionEvent actionEvent) throws AbortProcessingException
48      {
49          FacesContext facesContext = FacesContext.getCurrentInstance();
50          Application application = facesContext.getApplication();
51          UIComponent component = actionEvent.getComponent();
52          
53          MethodExpression methodExpression = null;
54          MethodBinding methodBinding = null;
55          
56          String fromAction = null;
57          String outcome = null;
58          
59          if (component instanceof ActionSource2)
60          {
61              // Must be an instance of ActionSource2, so don't look on action if the actionExpression is set 
62              methodExpression = ((ActionSource2) component).getActionExpression();            
63          }
64          if (methodExpression == null && component instanceof ActionSource)
65          {
66              // Backwards compatibility for pre-1.2.
67              methodBinding = ((ActionSource) component).getAction();
68          }
69          
70          if (methodExpression != null)
71          {
72              fromAction = methodExpression.getExpressionString();
73  
74              Object objOutcome = methodExpression.invoke(facesContext.getELContext(), null);
75              if (objOutcome != null)
76              {
77                  outcome = objOutcome.toString();
78              }
79              
80          }
81          
82          else if (methodBinding != null)
83          {
84              fromAction = methodBinding.getExpressionString();
85              Object objOutcome = methodBinding.invoke(facesContext, null);
86  
87              if (objOutcome != null)
88              {
89                  outcome = objOutcome.toString();
90              }
91  
92          }
93          
94          UIViewRoot root = facesContext.getViewRoot();
95          ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
96          ViewPool pool = (processor != null) ? processor.getViewPool(facesContext, root) : null;
97          if (pool != null && pool.isDeferredNavigationEnabled() && 
98              processor.isViewPoolStrategyAllowedForThisView(facesContext, root) &&
99              (PhaseId.INVOKE_APPLICATION.equals(facesContext.getCurrentPhaseId()) ||
100              PhaseId.APPLY_REQUEST_VALUES.equals(facesContext.getCurrentPhaseId())) )
101         {
102             NavigationHandler navigationHandler = application.getNavigationHandler();
103             if (navigationHandler instanceof ConfigurableNavigationHandler)
104             {
105                 NavigationCase navigationCase = ((ConfigurableNavigationHandler) navigationHandler).
106                     getNavigationCase(facesContext, fromAction, outcome);
107                 if (navigationCase != null)
108                 {
109                     // Deferred invoke navigation. The first one wins
110                     if (!facesContext.getAttributes().containsKey(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION))
111                     {
112                         String toFlowDocumentId = (component != null) ? 
113                             (String) component.getAttributes().get(ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME) : null;
114                         if (toFlowDocumentId != null)
115                         {
116                             facesContext.getAttributes().put(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION, 
117                                     new Object[]{fromAction, outcome, toFlowDocumentId});
118                         }
119                         else
120                         {
121                             facesContext.getAttributes().put(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION, 
122                                     new Object[]{fromAction, outcome});
123                         }
124                     }
125                 }
126             }
127         }
128         else
129         {
130             NavigationHandler navigationHandler = application.getNavigationHandler();
131             String toFlowDocumentId = (component != null) ? 
132                 (String) component.getAttributes().get(ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME) : null;
133 
134             if (toFlowDocumentId != null)
135             {
136                 navigationHandler.handleNavigation(facesContext, fromAction, outcome, toFlowDocumentId);
137             }
138             else
139             {
140                 navigationHandler.handleNavigation(facesContext, fromAction, outcome);
141             }
142             //Render Response if needed
143             facesContext.renderResponse();
144         }
145     }
146 }