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  
20  package org.apache.myfaces.tobago.internal.component;
21  
22  import org.apache.myfaces.tobago.component.SupportsDisabled;
23  import org.apache.myfaces.tobago.config.TobagoConfig;
24  import org.apache.myfaces.tobago.event.CollapsibleActionListener;
25  import org.apache.myfaces.tobago.internal.config.SecurityAnnotation;
26  import org.apache.myfaces.tobago.internal.util.AuthorizationHelper;
27  import org.apache.myfaces.tobago.util.ComponentUtils;
28  
29  import javax.el.MethodExpression;
30  import javax.faces.component.UICommand;
31  import javax.faces.component.UIComponent;
32  import javax.faces.context.FacesContext;
33  import javax.faces.event.ComponentSystemEvent;
34  import javax.faces.event.ComponentSystemEventListener;
35  import javax.faces.event.FacesEvent;
36  import javax.faces.event.ListenerFor;
37  import javax.faces.event.PhaseId;
38  import javax.faces.event.PostAddToViewEvent;
39  import java.util.Iterator;
40  import java.util.List;
41  
42  /**
43   * Base class for commands.
44   */
45  @ListenerFor(systemEventClass = PostAddToViewEvent.class)
46  public abstract class AbstractUICommandBase extends UICommand
47      implements ComponentSystemEventListener {
48  
49    @Override
50    public void processEvent(final ComponentSystemEvent event) {
51      super.processEvent(event);
52  
53      if (event instanceof PostAddToViewEvent) {
54        final List<AbstractUIOperation> list = ComponentUtils.findDescendantList(this, AbstractUIOperation.class);
55        for (final AbstractUIOperation operation : list) {
56          addActionListener(new CollapsibleActionListener(operation.getFor()));
57        }
58      }
59    }
60  
61    @Override
62    public void processDecodes(final FacesContext context) {
63      // Skip processing if our rendered flag is false
64      if (!isRendered()) {
65        return;
66      }
67  
68      // Process this component itself
69      try {
70        decode(context);
71      } catch (final RuntimeException e) {
72        context.renderResponse();
73        throw e;
74      }
75  
76      final Iterator kids = getFacetsAndChildren();
77      while (kids.hasNext()) {
78        final UIComponent kid = (UIComponent) kids.next();
79        kid.processDecodes(context);
80      }
81    }
82  
83    @Override
84    public void queueEvent(final FacesEvent facesEvent) {
85      // fix for TOBAGO-262
86      super.queueEvent(facesEvent);
87      if (this == facesEvent.getSource()) {
88        if (isImmediate()) {
89          facesEvent.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
90        } else {
91          facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
92        }
93      }
94    }
95  
96    @Override
97    public boolean isRendered() {
98      final FacesContext facesContext = getFacesContext();
99      final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
100     return super.isRendered()
101         && (tobagoConfig.getSecurityAnnotation() != SecurityAnnotation.hide || isAllowed());
102   }
103 
104   /**
105    * Flag indicating that this element is disabled.
106    * <br>Default: <code>false</code>
107    */
108   public boolean isDisabled() {
109     final FacesContext facesContext = getFacesContext();
110     final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
111     final Boolean disabled = (Boolean) getStateHelper().eval(AbstractUICommand.PropertyKeys.disabled);
112     if (disabled == null) {
113       SupportsDisabled parent =
114           ComponentUtils.findAncestor(getCurrentComponent(facesContext), SupportsDisabled.class);
115       if (parent != null && parent.isDisabled()) {
116         return true;
117       }
118     }
119     return disabled != null && disabled
120         || (tobagoConfig.getSecurityAnnotation() == SecurityAnnotation.disable && !isAllowed());
121   }
122 
123   private boolean isAllowed() {
124     final FacesContext facesContext = getFacesContext();
125     final AuthorizationHelper authorizationHelper = AuthorizationHelper.getInstance(facesContext);
126     final MethodExpression actionExpression = getActionExpression();
127     if (actionExpression != null) {
128       final boolean authorized =
129           authorizationHelper.isAuthorized(facesContext, actionExpression.getExpressionString());
130       if (!authorized) {
131         return false;
132       }
133     }
134     return true;
135   }
136 
137   public void setDisabled(final boolean disabled) {
138     getStateHelper().put(AbstractUICommand.PropertyKeys.disabled, disabled);
139   }
140 
141   public abstract String getTarget();
142 
143   public abstract boolean isTransition();
144 
145   public abstract boolean isOmit();
146 
147   public abstract void setOmit(boolean omit);
148 
149   public abstract String getConfirmation();
150 
151   public abstract String getLink();
152 
153   public abstract String getOutcome();
154 
155   public abstract String getFragment();
156 }