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