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