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.OnComponentPopulated;
23  import org.apache.myfaces.tobago.component.SupportsAccessKey;
24  import org.apache.myfaces.tobago.component.Visual;
25  import org.apache.myfaces.tobago.event.CollapsibleActionListener;
26  import org.apache.myfaces.tobago.internal.util.AuthorizationHelper;
27  import org.apache.myfaces.tobago.util.ComponentUtils;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  import javax.el.MethodExpression;
32  import javax.faces.component.UICommand;
33  import javax.faces.component.UIComponent;
34  import javax.faces.component.UIInput;
35  import javax.faces.component.behavior.ClientBehaviorHolder;
36  import javax.faces.context.FacesContext;
37  import javax.faces.event.FacesEvent;
38  import javax.faces.event.PhaseId;
39  import java.util.Arrays;
40  import java.util.Collection;
41  import java.util.Iterator;
42  import java.util.List;
43  
44  public abstract class AbstractUICommand extends UICommand
45      implements SupportsAccessKey, OnComponentPopulated, Visual, ClientBehaviorHolder {
46  
47    private static final Logger LOG = LoggerFactory.getLogger(AbstractUICommand.class);
48  
49    // todo generate
50    private static final Collection<String> EVENT_NAMES = Arrays.asList("click", "change");
51  
52    enum PropertyKeys {
53      disabled,
54    }
55  
56    // todo: transient
57    private Boolean parentOfCommands;
58  
59    @Override
60    public void onComponentPopulated(final FacesContext facesContext, final UIComponent parent) {
61  
62      final List<AbstractUIOperation> list = ComponentUtils.findDescendantList(this, AbstractUIOperation.class);
63      for (AbstractUIOperation operation : list) {
64        addActionListener(new CollapsibleActionListener(operation.getFor()));
65      }
66    }
67  
68    @Override
69    public void processDecodes(final FacesContext context) {
70      if (context == null) {
71        throw new NullPointerException();
72      }
73  
74      // Skip processing if our rendered flag is false
75      if (!isRendered()) {
76        return;
77      }
78  
79      // Process this component itself
80      try {
81        decode(context);
82      } catch (final RuntimeException e) {
83        context.renderResponse();
84        throw e;
85      }
86  
87      final Iterator kids = getFacetsAndChildren();
88      while (kids.hasNext()) {
89        final UIComponent kid = (UIComponent) kids.next();
90        kid.processDecodes(context);
91      }
92    }
93  
94    @Override
95    public void queueEvent(final FacesEvent facesEvent) {
96      // fix for TOBAGO-262
97      super.queueEvent(facesEvent);
98      if (this == facesEvent.getSource()) {
99        if (isImmediate()) {
100         facesEvent.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
101       } else {
102         facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
103       }
104     }
105   }
106 
107   public boolean isParentOfCommands() {
108     if (parentOfCommands == null) {
109       parentOfCommands = false;
110       for (UIComponent child : getChildren()) {
111         if (child instanceof UICommand || child instanceof UIInput) {
112           parentOfCommands = true;
113           break;
114         }
115       }
116     }
117     return parentOfCommands;
118   }
119 
120   /**
121    Flag indicating that this element is disabled.
122    <br>Default: <code>false</code>
123    */
124   public boolean isDisabled() {
125 
126     final FacesContext facesContext = getFacesContext();
127     // todo: get from configuration tobago-config.xml
128     if (true) {
129       final AuthorizationHelper authorizationHelper = AuthorizationHelper.getInstance(facesContext);
130       final MethodExpression actionExpression = getActionExpression();
131       if (actionExpression != null) {
132         final boolean authorized =
133             authorizationHelper.isAuthorized(facesContext, actionExpression.getExpressionString());
134         if (!authorized) {
135           return true;
136         }
137       }
138     }
139 
140     Boolean bool = (Boolean) getStateHelper().eval(PropertyKeys.disabled);
141     if (bool != null) {
142       return bool;
143     }
144     return false;
145   }
146 
147   public void setDisabled(boolean disabled) {
148     getStateHelper().put(PropertyKeys.disabled, disabled);
149   }
150 
151   // todo generate
152   @Override
153   public String getDefaultEventName() {
154     return "click";
155   }
156 
157   // todo generate
158   @Override
159   public Collection<String> getEventNames() {
160     return EVENT_NAMES;
161   }
162 
163   @Override
164   public abstract String getLabel();
165 
166   public abstract boolean isJsfResource();
167 
168   public abstract String getResource();
169 
170   public abstract String getLink();
171 
172   public abstract String getTarget();
173 
174   public abstract boolean isTransition();
175 
176   public abstract boolean isOmit();
177 
178   public abstract String getTip();
179 
180   public abstract String getConfirmation();
181 
182 //  public abstract Integer getTabIndex();
183 }