J2EE Java

/**
 * Licensed under the Common Development and Distribution License,
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.sun.com/cddl/
 *   
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIOutput;
import javax.faces.component.UISelectItem;
import javax.faces.component.UISelectItems;
import javax.faces.component.UISelectMany;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.el.ValueBinding;
import javax.faces.model.SelectItem;
/**
 * @author Maksim Kaszynski
 *
 */
public class SelectUtils {
  /**
   * Gathers all select items from specified component's children
   * @param context
   * @param component
   * @return list of {@link SelectItems} taken from f:selectItem and f:selectItems
   */
  public static List getSelectItems(FacesContext context, UIComponent component) {
        ArrayList list = new ArrayList();
    Iterator kids = component.getChildren().iterator();
    while (kids.hasNext()) {
      UIComponent kid = (UIComponent) kids.next();
      if (kid instanceof UISelectItem) {
        Object value = ((UISelectItem) kid).getValue();
        if (value == null) {
          UISelectItem item = (UISelectItem) kid;
          list.add(new SelectItem(item.getItemValue(), item.getItemLabel(), item.getItemDescription(), item.isItemDisabled()));
        } else if (value instanceof SelectItem) {
          list.add(value);
        } else {
          String valueClass = (value != null ? "'" + value.getClass().getName() + "'" : "");
          throw new IllegalArgumentException(Messages.getMessage(Messages.INVALID_ATTRIBUTE_VALUE, valueClass, ""));
        }
      } else if (kid instanceof UISelectItems && null != context) {
        Object value = ((UISelectItems) kid).getValue();
        if (value instanceof SelectItem) {
          list.add(value);
        } else if (value instanceof SelectItem[]) {
          SelectItem items[] = (SelectItem[]) value;
          for (int i = 0; i < items.length; i++) {
            list.add(items[i]);
          }
        } else if (value instanceof Collection) {
          Iterator elements = ((Collection) value).iterator();
          while (elements.hasNext()) {
            list.add(elements.next());
          }
        } else if (value instanceof Map) {
          Iterator keys = ((Map) value).keySet().iterator();
          while (keys.hasNext()) {
            Object key = keys.next();
            if (key == null) {
              continue;
            }
            Object val = ((Map) value).get(key);
            if (val == null) {
              continue;
            }
            list.add(new SelectItem(val.toString(), key.toString(),
                null));
          }
        } else {
          String valueClass = (value != null ? "'" + value.getClass().getName() + "'" : "");
          throw new IllegalArgumentException("INVALID_ATTRIBUTE_VALUE, valueClass");
        }
      }
    }
        return list;
  }
  
  /**
   * Converts UISelectMany submitted value to converted value
   * 
   * @author Manfred Geiler
   * @param facesContext
   * @param component
   * @param submittedValue
   * @return
   * @throws ConverterException
   */
  public static Object getConvertedUISelectManyValue(
      FacesContext facesContext, UISelectMany component,
      String[] submittedValue) throws ConverterException {
    // Attention!
    // This code is duplicated in jsfapi component package.
    // If you change something here please do the same in the other class!
    if (submittedValue == null)
      throw new NullPointerException("submittedValue");
    ValueBinding vb = component.getValueBinding("value");
    Class valueType = null;
    Class arrayComponentType = null;
    if (vb != null) {
      valueType = vb.getType(facesContext);
      if (valueType != null && valueType.isArray()) {
        arrayComponentType = valueType.getComponentType();
      }
    }
    Converter converter = component.getConverter();
    if (converter == null) {
      if (valueType == null) {
        // No converter, and no idea of expected type
        // --> return the submitted String array
        return submittedValue;
      }
      if (List.class.isAssignableFrom(valueType)) {
        // expected type is a List
        // --> according to javadoc of UISelectMany we assume that the
        // element type
        // is java.lang.String, and copy the String array to a new List
        int len = submittedValue.length;
        List lst = new ArrayList(len);
        for (int i = 0; i < len; i++) {
          lst.add(submittedValue[i]);
        }
        return lst;
      }
      if (arrayComponentType == null) {
        throw new IllegalArgumentException(Messages.getMessage(Messages.VALUE_BINDING_TYPE_ERROR));
      }
      if (String.class.equals(arrayComponentType))
        return submittedValue; // No conversion needed for String type
      if (Object.class.equals(arrayComponentType))
        return submittedValue; // No conversion for Object class
      try {
        converter = facesContext.getApplication().createConverter(
            arrayComponentType);
      } catch (FacesException e) {
        System.out.println("NO_CONVERTER_FOUND_ERROR");
        return submittedValue;
      }
    }
    // Now, we have a converter...
    if (valueType == null) {
      // ...but have no idea of expected type
      // --> so let's convert it to an Object array
      int len = submittedValue.length;
      Object[] convertedValues = (Object[]) Array.newInstance(
          arrayComponentType == null ? Object.class
              : arrayComponentType, len);
      for (int i = 0; i < len; i++) {
        convertedValues[i] = converter.getAsObject(facesContext,
            component, submittedValue[i]);
      }
      return convertedValues;
    }
    if (List.class.isAssignableFrom(valueType)) {
      // Curious case: According to specs we should assume, that the
      // element type
      // of this List is java.lang.String. But there is a Converter set
      // for this
      // component. Because the user must know what he is doing, we will
      // convert the values.
      int len = submittedValue.length;
      List lst = new ArrayList(len);
      for (int i = 0; i < len; i++) {
        lst.add(converter.getAsObject(facesContext, component,
            submittedValue[i]));
      }
      return lst;
    }
    if (arrayComponentType == null) {
      throw new IllegalArgumentException("VALUE_BINDING_TYPE_ERROR");
    }
    if (arrayComponentType.isPrimitive()) {
      // primitive array
      int len = submittedValue.length;
      Object convertedValues = Array.newInstance(arrayComponentType, len);
      for (int i = 0; i < len; i++) {
        Array.set(convertedValues, i, converter.getAsObject(
            facesContext, component, submittedValue[i]));
      }
      return convertedValues;
    } else {
      // Object array
      int len = submittedValue.length;
      ArrayList convertedValues = new ArrayList(len);
      for (int i = 0; i < len; i++) {
        convertedValues.add(i, converter.getAsObject(facesContext,
            component, submittedValue[i]));
      }
      return convertedValues.toArray((Object[]) Array.newInstance(
          arrayComponentType, len));
    }
  }
  public static Object getConvertedUIInputValue(
      FacesContext facesContext, UIInput component,
      String submittedValue) throws ConverterException{
    Object convertedValue = null;
    
    /*
    if (submittedValue == null)
      throw new NullPointerException("submittedValue");
    */
    if(InputUtils.EMPTY_STRING.equals(submittedValue)){
      return null;
    }
    Converter converter = getConverterForProperty(facesContext, component, "value");
    if(converter != null){
      convertedValue = converter.getAsObject(facesContext, component, submittedValue);
    } else {
      convertedValue = submittedValue;
    }
    
    return convertedValue;
  }
  /**
   * 
   * @param facesContext
   * @param component
   * @param property
   * @return converter for specified component attribute
   */
  public static Converter getConverterForProperty(FacesContext facesContext, UIOutput component, String property){
    Converter converter = component.getConverter();
    if(converter == null){
      ValueBinding valueBinding = component.getValueBinding(property);
      if(valueBinding != null){
        Class valueType = valueBinding.getType(facesContext);
        if(valueType == null || String.class.equals(valueType) || Object.class.equals(valueType)){
          //No converter needed
        } else {
          converter = facesContext.getApplication().createConverter(valueType);
          if(converter == null){
            throw new ConverterException("NO_CONVERTER_FOUND_ERROR");
          }
        }
      }
    } 
    return converter;
  }
  
}