I run into this issue some time ago and I solved it as you did, but then I realized at some point that I with that solution I could not use i18n because the strings were hardcoded in the enum class. So I modified my enumConverter to use messages
for rendering.
Also sometimes you may want to render the enum as some unique identifier and not as user readable text (for internal usage inside some components).
This is my converter:
import java.util.ResourceBundle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import com.eyeprevent.configuration.ConfigurationReader;
/**
* converts an enum in a way that makes the conversion reversible (sometimes)
* <ul>
* <li>input: uses its classname and ordinal, reversible<li>
* <li>else: uses its name, non reversible<li>
* </ul>
*/
public class EnumConverter implements Converter
{
@SuppressWarnings("unchecked")
public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException
{
if (value == null || value.length() < 1)
{
return null;
}
int pos = value.indexOf('@');
if (pos < 0)
{
throw new IllegalArgumentException(value + " do not point to an enum");
}
String className = value.substring(0, pos);
Class clazz;
int ordinal = Integer.parseInt(value.substring(pos+1), 10);
try
{
clazz = Class.forName( className, true, Thread.currentThread().getContextClassLoader() );
// if the clazz is not an enum it might be an enum which is inherited. In this case try to find the superclass.
while (clazz != null && !clazz.isEnum())
{
clazz = clazz.getSuperclass();
}
if (clazz == null)
{
throw new IllegalArgumentException("class " + className + " couldn't be treated as enum");
}
Enum[] enums = (Enum[]) clazz.getEnumConstants();
if (enums.length >= ordinal)
{
return enums[ordinal];
}
}
catch (ClassNotFoundException e1)
{
throw new RuntimeException(e1);
}
throw new IllegalArgumentException("ordinal " + ordinal + " not found in enum " + clazz);
}
public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException
{
if (value == null)
{
return "";
}
Enum<?> e = (Enum<?>) value;
if (component instanceof UIInput || UIInput.COMPONENT_FAMILY.equals(component.getFamily()))
{
return e.getClass().getName() + "@" + Integer.toString(e.ordinal(), 10);
}
ResourceBundle messages =ConfigurationReader.getMessages(context.getViewRoot().getLocale());
return messages.getString(e.name());
}
}