package org.richfaces.utils;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectMany;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import org.ajax4jsf.util.SelectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class PickListUtils {
private static final Log log = LogFactory.getLog(PickListUtils.class);
public static Converter findUISelectManyConverter(FacesContext context, UISelectMany component) {
Converter converter = component.getConverter();
if (converter != null) {
return converter;
}
ValueExpression ve = component.getValueExpression("value");
if (ve == null) {
return null;
}
Class valueType = ve.getType(context.getELContext());
if (valueType == null) {
return null;
}
if (List.class.isAssignableFrom(valueType)) {
List selectItems = SelectUtils.getSelectItems(context, component);
if (selectItems != null && selectItems.size() > 0) {
SelectItem selectItem = (SelectItem) selectItems.get(0);
Class listComponentType = selectItem.getValue().getClass();
if (!(String.class.equals(listComponentType))) {
try {
return context.getApplication().createConverter(listComponentType);
} catch (FacesException e) {
log.error("No Converter for type " + listComponentType.getName() + " found", e);
return null;
}
}
}
return null;
}
if (!valueType.isArray()) {
throw new IllegalArgumentException("ValueBinding for UISelectMany must be of type List or Array not " + valueType.getName());
}
Class arrayComponentType = valueType.getComponentType();
if (String.class.equals(arrayComponentType))
return null;
if (Object.class.equals(arrayComponentType))
return null;
try {
return context.getApplication().createConverter(arrayComponentType);
} catch (FacesException e) {
log.error("No Converter for type " + arrayComponentType.getName() + " found", e);
return null;
}
}
public static Converter findUISelectManyConverterFailsafe(FacesContext facesContext, UIComponent uiComponent) {
Converter converter;
try {
converter = findUISelectManyConverter(facesContext, (UISelectMany) uiComponent);
} catch (FacesException e) {
log.error("Error finding Converter for component with id " + uiComponent.getClientId(facesContext), e);
converter = null;
}
return converter;
}
public static List getValuesList(UIComponent uiComponent, FacesContext facesContext, Converter converter) {
List lookupList = null;
if (uiComponent instanceof UISelectMany) {
UISelectMany uiSelectMany = (UISelectMany) uiComponent;
lookupList = getSelectValuesList(facesContext, uiComponent, converter, uiSelectMany);
}
return lookupList;
}
public static List getSelectValuesList(FacesContext context, UIComponent component, Converter converter, UISelectMany uiSelectMany) {
Object selectedValues = uiSelectMany.getValue();
return internalSelectValuesList(context, component, converter, uiSelectMany, selectedValues);
}
private static List internalSelectValuesList(FacesContext context, UIComponent component, Converter converter, UISelectMany uiSelectMany, Object values) {
List valuesList = new ArrayList();
if (values == null || "".equals(values)) {
return valuesList;
} else if (values instanceof Object[]) {
Object[] ar = (Object[]) values;
if (ar.length == 0) {
return valuesList;
}
valuesList = new ArrayList();
for (int i = 0; i < ar.length; i++) {
valuesList.add(getConvertedStringValue(context, component, converter, ar[i]));
}
return valuesList;
} else if (values.getClass().isArray()) {
int len = Array.getLength(values);
valuesList = new ArrayList();
for (int i = 0; i < len; i++) {
valuesList.add(getConvertedStringValue(context, component, converter, Array.get(values, i)));
}
return valuesList;
} else if (values instanceof List) {
List lst = (List) values;
if (lst.size() == 0) {
return lst;
} else {
valuesList = new ArrayList();
for (Iterator i = lst.iterator(); i.hasNext();) {
valuesList.add(getConvertedStringValue(context, component, converter, i.next()));
}
return valuesList;
}
} else {
throw new IllegalArgumentException("Value of UISelectMany component : is not of type Array or List");
}
}
public static String getConvertedStringValue(FacesContext context, UIComponent component, Converter converter, Object value) {
if (converter == null) {
if (value == null) {
return "";
} else if (value instanceof String) {
return (String) value;
} else {
throw new IllegalArgumentException("Value is not String (class=" + value.getClass().getName() + ", value=" + value + ") and component "
+ component.getClientId(context) + " does not have a Converter");
}
}
return converter.getAsString(context, component, value);
}
}