public static Object getConvertedValue( FacesContext facesContext, UIComponent component, Object val) throws ConverterException { String[] values = (val == null) ? new String[0] : (String[]) val; Converter converter = SelectManyHelper.getItemConverter(facesContext, component); ValueExpression ve = component.getValueExpression("value"); Object targetForConvertedValues = null; if (ve != null) { // If the component has a ValueExpression for value, let modelType be the type of the value // expression Class<?> modelType = ve.getType(facesContext.getELContext()); if (modelType.isArray()) { // If the component has a ValueExpression for value and the type of the expression is an // array, let targetForConvertedValues be a new array of the expected type. Class<?> arrayComponentType = modelType.getComponentType(); targetForConvertedValues = Array.newInstance(arrayComponentType, values.length); } else if (Collection.class.isAssignableFrom(modelType) || Object.class.equals(modelType)) { // If modelType is a Collection, do the following to arrive at targetForConvertedValues: // Ask the component for its attribute under the key "collectionType" String collectionType = (String) component.getAttributes().get("collectionType"); if (collectionType != null) { // Let targetForConvertedValues be a new instance of Collection implemented by the // concrete class specified in collectionType Class<?> collectionClass = getCollectionClass(collectionType); try { targetForConvertedValues = collectionClass.newInstance(); } catch (Exception e) { throw new FacesException(e); } } else { // If there is no "collectionType" attribute, call getValue() on the component // The result will implement Collection. Collection value = (Collection) ((EditableValueHolder) component).getValue(); if (value instanceof Cloneable) { // If the result also implements Cloneable, let targetForConvertedValues be the result // of calling its clone() method, // then calling clear() on the cloned Collection. try { targetForConvertedValues = (Collection) value.getClass().getMethod("clone").invoke(value); ((Collection) targetForConvertedValues).clear(); } catch (Exception e) { // If unable to clone the value for any reason, log a message LOG.log(Logger.Level.WARNING, "Unable to clone collection"); } } if (targetForConvertedValues == null) { // and proceed to the next step Class<?> collectionClass = value == null ? modelType : value.getClass(); try { // If modelType is a concrete class, let targetForConvertedValues be a new instance of // that class. targetForConvertedValues = collectionClass.newInstance(); ((Collection) targetForConvertedValues).clear(); } catch (Exception e) { // Otherwise, the concrete type for targetForConvertedValues is taken from the // following table if (Collection.class.isAssignableFrom(modelType)) { if (SortedSet.class.isAssignableFrom(modelType)) { targetForConvertedValues = new TreeSet(); } else if (Queue.class.isAssignableFrom(modelType)) { targetForConvertedValues = new LinkedList(); } else if (Set.class.isAssignableFrom(modelType)) { targetForConvertedValues = new HashSet(values.length); } else { targetForConvertedValues = new ArrayList(values.length); } } } } } } else { throw new FacesException("ValueExpression must be either an Array, or a Collection"); } } else { // If the component does not have a ValueExpression for value, let targetForConvertedValues be // an array of type Object. targetForConvertedValues = new Object[values.length]; } for (int i = 0; i < values.length; i++) { Object value; if (converter == null) { value = values[i]; } else { value = converter.getAsObject(facesContext, component, values[i]); } if (targetForConvertedValues.getClass().isArray()) { Array.set(targetForConvertedValues, i, value); } else { ((Collection) targetForConvertedValues).add(value); } } return targetForConvertedValues; }