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 org.apache.commons.logging.Log;
021    import org.apache.commons.logging.LogFactory;
022    
023    import javax.faces.context.FacesContext;
024    import javax.faces.el.ValueBinding;
025    
026    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_IMAGE;
027    
028    public class UISelectItem extends javax.faces.component.UISelectItem implements SupportsMarkup {
029    
030      private static final Log LOG = LogFactory.getLog(UISelectItem.class);
031    
032      public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.SelectItem";
033    
034      private String itemImage;
035      private String[] markup;
036    
037      private boolean itemValueLiteral;
038    
039      @Override
040      public void setItemValue(Object itemValue) {
041        if (itemValue instanceof String) {
042        itemValueLiteral = true;
043        } else if (itemValue == null) {
044          // ignore
045        } else {
046          LOG.warn("Unexpected type of literal for attribute 'itemValue': "
047              + "type=" + itemValue.getClass().getName() + " value='" + itemValue + "'.");
048        }
049        super.setItemValue(itemValue);
050      }
051    
052      @Override
053      public Object getItemValue() {
054        Object itemValue = super.getItemValue();
055        if (itemValueLiteral) {
056          // this is to make it possible to use values directly in the page.
057          itemValue = ComponentUtil.getConvertedValue(
058              FacesContext.getCurrentInstance(), (javax.faces.component.UIInput) getParent(), (String) itemValue);
059        }
060        return itemValue;
061      }
062    
063      public void restoreState(FacesContext context, Object state) {
064        Object[] values = (Object[]) state;
065        super.restoreState(context, values[0]);
066        itemImage = (String) values[1];
067        markup = (String[]) values[2];
068        itemValueLiteral = (Boolean) values[3];
069      }
070    
071      public Object saveState(FacesContext context) {
072        Object[] values = new Object[4];
073        values[0] = super.saveState(context);
074        values[1] = itemImage;
075        values[2] = markup;
076        values[3] = itemValueLiteral;
077        return values;
078      }
079    
080      public String[] getMarkup() {
081        if (markup != null) {
082          return markup;
083        }
084        return ComponentUtil.getMarkupBinding(getFacesContext(), this);
085      }
086    
087      public void setMarkup(String[] markup) {
088        this.markup = markup;
089      }
090    
091      public void setImage(String image) {
092        setItemImage(image);
093      }
094    
095      public String getItemImage() {
096        if (itemImage != null) {
097          return itemImage;
098        }
099    
100        ValueBinding vb = getValueBinding(ATTR_IMAGE);
101        if (vb != null) {
102          return ((String) vb.getValue(getFacesContext()));
103        } else {
104          return null;
105        }
106      }
107    
108      public void setItemImage(String itemImage) {
109        this.itemImage = itemImage;
110      }
111    
112    }