001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.myfaces.tobago.component;
021    
022    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_DEFAULT_COMMAND;
023    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_DISABLED;
024    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_RENDERED_PARTIALLY;
025    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TARGET;
026    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TRANSITION;
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    import org.apache.commons.lang.StringUtils;
030    
031    import javax.faces.component.UIComponent;
032    import javax.faces.context.FacesContext;
033    import javax.faces.el.ValueBinding;
034    import javax.faces.event.FacesEvent;
035    import javax.faces.event.PhaseId;
036    import java.io.IOException;
037    import java.util.Iterator;
038    
039    /*
040     * Date: Apr 4, 2005
041     * Time: 5:02:10 PM
042     * $Id: UICommand.java 1368577 2012-08-02 16:20:31Z lofwyr $
043     */
044    public class UICommand extends javax.faces.component.UICommand {
045    
046      public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Command";
047    
048      private static final Log LOG = LogFactory.getLog(UICommand.class);
049      private static final String[] RENDERED_PARTIALLY_DEFAULT = {};
050    
051      private Boolean defaultCommand;
052      private Boolean disabled;
053      private String[] renderedPartially;
054      private String target;
055      private Boolean transition;
056    
057      public boolean isDefaultCommand() {
058        if (defaultCommand != null) {
059          return defaultCommand;
060        }
061        ValueBinding vb = getValueBinding(ATTR_DEFAULT_COMMAND);
062        if (vb != null) {
063          return Boolean.TRUE.equals(vb.getValue(getFacesContext()));
064        } else {
065          return false;
066        }
067      }
068    
069      public void setDefaultCommand(boolean defaultCommand) {
070        this.defaultCommand = defaultCommand;
071      }
072    
073      public String[] getRenderedPartially() {
074        if (renderedPartially != null) {
075          return renderedPartially;
076        }
077        ValueBinding vb = getValueBinding(ATTR_RENDERED_PARTIALLY);
078        if (vb != null) {
079          Object value = vb.getValue(getFacesContext());
080          if (value != null) {
081            if (value instanceof String[]) {
082              return (String[]) value;
083            } else if (value instanceof String) {
084              return StringUtils.split((String) value, ",");
085            } else {
086              LOG.error("Ignoring RenderedPartially value binding. Unknown instance " + value.getClass().getName());
087            }
088          }
089        }
090        return RENDERED_PARTIALLY_DEFAULT;
091      }
092    
093      public void setRenderedPartially(String renderedPartially) {
094        if (renderedPartially != null) {
095          String[] components = StringUtils.split(renderedPartially, ",");
096          setRenderedPartially(components);
097        }
098      }
099    
100      public void setRenderedPartially(String[] renderedPartially) {
101        this.renderedPartially = renderedPartially;
102      }
103    
104      public boolean isDisabled() {
105        if (disabled != null) {
106          return disabled;
107        }
108        ValueBinding vb = getValueBinding(ATTR_DISABLED);
109        if (vb != null) {
110          return Boolean.TRUE.equals(vb.getValue(getFacesContext()));
111        } else {
112          return false;
113        }
114      }
115    
116      public void setDisabled(boolean disabled) {
117        this.disabled = disabled;
118      }
119    
120      public boolean isTransition() {
121        if (transition != null) {
122          return transition;
123        }
124        ValueBinding vb = getValueBinding(ATTR_TRANSITION);
125        if (vb != null) {
126          return Boolean.TRUE.equals(vb.getValue(getFacesContext()));
127        } else {
128          return true;
129        }
130      }
131    
132      public void setTransition(boolean transition) {
133        this.transition = transition;
134      }
135    
136      public String getTarget() {
137        if (target != null) {
138          return target;
139        }
140        ValueBinding vb = getValueBinding(ATTR_TARGET);
141        if (vb != null) {
142          return (String) vb.getValue(getFacesContext());
143        } else {
144          return null;
145        }
146      }
147    
148      public void setTarget(String target) {
149        this.target = target;
150      }
151    
152    
153      public Object saveState(FacesContext context) {
154        Object[] saveState = new Object[6];
155        saveState[0] = super.saveState(context);
156        saveState[1] = defaultCommand;
157        saveState[2] = disabled;
158        saveState[3] = renderedPartially;
159        saveState[4] = target;
160        saveState[5] = transition;
161        return saveState;
162      }
163    
164      public void restoreState(FacesContext context, Object savedState) {
165        Object[] values = (Object[]) savedState;
166        super.restoreState(context, values[0]);
167        defaultCommand = (Boolean) values[1];
168        disabled = (Boolean) values[2];
169        renderedPartially = (String[]) values[3];
170        target = (String) values[4];
171        transition = (Boolean) values[5];
172      }
173    
174    
175      public void processDecodes(FacesContext context) {
176        if (context == null) {
177          throw new NullPointerException();
178        }
179    
180        // Skip processing if our rendered flag is false
181        if (!isRendered()) {
182          return;
183        }
184    
185        // Process this component itself
186        try {
187          decode(context);
188        } catch (RuntimeException e) {
189          context.renderResponse();
190          throw e;
191        }
192    
193        Iterator kids = getFacetsAndChildren();
194        while (kids.hasNext()) {
195          UIComponent kid = (UIComponent) kids.next();
196          kid.processDecodes(context);
197        }
198    
199      }
200    
201      public void encodeChildren(FacesContext facesContext) throws IOException {
202        if (isRendered()) {
203          UILayout.getLayout(this).encodeChildrenOfComponent(facesContext, this);
204        }
205      }
206    
207      public void queueEvent(FacesEvent facesEvent) {
208        // fix for TOBAGO-262
209        super.queueEvent(facesEvent);
210        if (this == facesEvent.getSource()) {
211          if (isImmediate()) {
212            facesEvent.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
213          } else {
214            facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
215          }
216        }
217      }
218    }