EnumConverter for multi-select lists
pgmjsd May 17, 2007 6:20 AMHi everyone. I'd like to contribute the following converter. It allows you to use a multi-select list with enum values. I just took the existing EnumConverter and added come code to look for the s:selectItems control that has a value which is a list or array of enums.
I put something up on my own wiki about it here:
http://shrubbery.mynetgear.net/wiki/Select_lists_with_Seam#Multi-select_from_an_enum
And here's the code:
package eg; import javax.faces.component.*; import javax.faces.context.*; import javax.faces.convert.*; import javax.faces.el.ValueBinding; import java.util.List; import java.util.Collection; /** * Converter for enum multi-selects. * <br>User: Joshua Davis * Date: May 16, 2007 * Time: 7:25:58 AM */ public class EnumListConverter implements Converter { @SuppressWarnings({"unchecked"}) public Object getAsObject(FacesContext context, UIComponent comp, String value) throws ConverterException { ValueBinding binding = comp.getValueBinding("value"); Class enumType = binding.getType(context); if (enumType.isEnum()) // Single enum? return Enum.valueOf(enumType, value); else // List of enums. { // Find the s:selectItems so we can get the enum. List children = comp.getChildren(); for (Object child : children) { if (child instanceof UIComponent) { UIComponent c = (UIComponent) child; ValueBinding b = c.getValueBinding("value"); Class t = b.getType(context); // Array of enums: use the component type. if (t.isArray() && t.getComponentType().isEnum()) { t = t.getComponentType(); return Enum.valueOf(t,value); } else { Object v = b.getValue(context); // Collection of enum values, get the type of the first element. if (v instanceof Collection) { t = ((Collection) v).iterator().next().getClass(); return Enum.valueOf(t,value); } } } } throw new ConverterException("Unable to find selectItems with enum values!"); } } public String getAsString(FacesContext context, UIComponent component, Object object) throws ConverterException { if (object == null) { return null; } return ((Enum) object).name(); } }
After registering it with facelets, it can be used like this:
<h:selectManyCheckbox id="roles" layout="pageDirection" value="#{person.roles}" required="true"> <s:selectItems value="#{enumLists.roleArray}" var="role" label="#{role}"/> <s:convertEnum/> </h:selectManyCheckbox>