Hi John, As it turns out, it is only working in Mojarra, because it violates the JSF specification's conversion rules. MyFaces does things right and thus it is not working here as you expected.
However I think the enum problem is by all means a specification issue. As you pointed out before every other standard-converter passes through String values in getAsString() whereas the EnumConverter does not do it. Thus I will file a spec issue about this! As this will take some time until the EG decides what to do about this problem, I think it is the best solution to introduce a config parameter to enable the pass through mechanism on EnumConverter, because we won't get problems with the TCK but the functionality is available. Regards, Jakob 2010/5/28 John Wu <[email protected]> > > > If 2.) is to be incorporated in the impl, the original exception message is > then appropriate. > > > John Wu wrote: > > > > Hi Jakob, > > > > Suggestions: > > 1. Exception message: The value 'CardNumber' (type java.lang.String) is > > not an instance of the Enum type. > > 2. In the case the value is a String, check if it equals to one of Enum > > Constants' name, then ... > > > > Cheers, > > > > John Wu > > > > > > Jakob Korherr wrote: > >> > >> Hi John, > >> > >> On my opinion this is not a workaround, but rather how it really should > >> be > >> done. However I agree that this could/should be easier. > >> > >> To your points: > >> 1. Yes this is really confusing. IMO it should say "The String > >> 'CardNumber' > >> has to be an enum". > >> 2. The problem here is that we somehow have to check if the String > >> provided > >> in the f:selectItem is a valid enum constant or not. If we just pass > >> through > >> the String value, it may end up in weird behavior on the postback, > >> because > >> we can't create an enum value out of a wrong name. > >> 3. I also had a look at them and you're right. However the specification > >> javadoc does not mention this fact on the EnumConverter (see [1]), but > it > >> says that we have to throw a ConverterException if the value is no valid > >> enum and this is exactly what MyFaces does. So we must not change this > >> behavior, since it is not in the spec. > >> > >> I also did some tests with Mojarra and they allow this scenario, however > >> they seem to handle it in another way (not in the EnumConverter, because > >> a > >> blackbox test revealed that they also throw a ConverterException in that > >> case). I will do some further tests here and try to figure out how this > >> should be handled in the right way. > >> > >> Regards, > >> Jakob > >> > >> [1] > >> > https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/convert/EnumConverter.html#getAsString%28javax.faces.context.FacesContext,%20javax.faces.component.UIComponent,%20java.lang.Object%29 > >> > >> > >> 2010/5/27 John Wu <[email protected]> > >> > >>> > >>> I've thought about the type mis-match right after I posted the message. > >>> But > >>> I'd rather call that a workaround, not a real solution. > >>> > >>> Still, there are a few things I want to point out: > >>> 1. The exception message ('CardNumber' must be convertible to an enum.) > >>> is > >>> confusion. In fact, 'CardNumber' is indeed convertible to an enum. > >>> 2. The purpose of the rendering (and > >>> > >>> > org.apache.myfaces.shared_impl.renderkit.RendererUtils.getConvertedStringValue(..)) > >>> is to get the text representation of the specified value. Here in this > >>> case, > >>> the value is already an instance of String. I don't think it's a bad > >>> idea > >>> of > >>> just returning the String value, either by > >>> RendererUtils.getConvertedStringValue(..) or by > >>> javax.faces.convert.EnumConverter.getAsString(..). > >>> 3. I've further checked all implementations of > >>> javax.faces.convert.Converter.getAsString(..). They all (except > >>> EnumConverter.getAsString(..)) simply return the specified value if > it's > >>> an > >>> instance of String. > >>> > >>> So, my suggestion after further investigation is to change > >>> EnumConverter.getAsString(..) to follow that convention, that is, to > >>> simply > >>> return the specified value if it's an instance of String. > >>> > >>> Cheers, > >>> > >>> John Wu > >>> > >>> > >>> Jakob Korherr wrote: > >>> > > >>> > Hi John, > >>> > > >>> > The problem is that on <f:selectItem /> the attribute itemValue has > to > >>> be > >>> > of > >>> > the same type as the property in the managed bean. In your case this > >>> is > >>> > ClientIdType. > >>> > > >>> > However you are providing the String "CardNumber" as the value which > >>> is > >>> > definitely not the same as the enum value ClientIdType.CardNumber. > >>> Thus > >>> > you > >>> > get the Exception. > >>> > > >>> > Try using the following: > >>> > > >>> > <f:selectItem itemValue="#{bean.propertyThatResolvesToCardNumber}" > >>> > itemLabel="#{msgs['labelCardNumber.full']}:" /> > >>> > > >>> > with Bean.getPropertyThatResolvesToCardNumber() returning the enum > >>> value > >>> > ClientIdType.CardNumber. > >>> > > >>> > Regards, > >>> > Jakob > >>> > > >>> > > >>> > 2010/5/26 John Wu <[email protected]> > >>> > > >>> >> > >>> >> I'd say the issue exist in > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.getConvertedStringValue(FacesContext > >>> >> context, UIComponent component, Converter converter, Object value). > >>> In > >>> >> the > >>> >> case of rendering a selectRadio and the underlying model property > >>> type > >>> is > >>> >> an > >>> >> Enum, this method is called with the converter be an instance of > >>> >> javax.faces.convert.EnumConverter and the value be an instance of > >>> >> java.lang.String. Then, ideally, it may just return the value (No > >>> >> conversion > >>> >> is needed). But it delegates to > >>> >> javax.faces.convert.EnumConverter.getAsString(..) which expects the > >>> value > >>> >> to > >>> >> be an instance of the Enum, thus the following exception is thrown. > >>> >> > >>> >> javax.faces.convert.ConverterException: form:clientIdType: > >>> 'CardNumber' > >>> >> must > >>> >> be convertible to an enum. > >>> >> at > >>> >> javax.faces.convert.EnumConverter.getAsString(EnumConverter.java:82) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.RendererUtils.getConvertedStringValue(RendererUtils.java:640) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.html.HtmlRadioRendererBase.renderGroupOrItemRadio(HtmlRadioRendererBase.java:200) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.html.HtmlRadioRendererBase.encodeEnd(HtmlRadioRendererBase.java:106) > >>> >> at > >>> >> > >>> > javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:486) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.RendererUtils.renderChild(RendererUtils.java:527) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.html.HtmlGridRendererBase.renderChildren(HtmlGridRendererBase.java:296) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.shared_impl.renderkit.html.HtmlGridRendererBase.encodeEnd(HtmlGridRendererBase.java:131) > >>> >> at > >>> >> > >>> > javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:486) > >>> >> at > >>> >> javax.faces.component.UIComponent.encodeAll(UIComponent.java:618) > >>> >> at > >>> >> javax.faces.component.UIComponent.encodeAll(UIComponent.java:614) > >>> >> at > >>> >> javax.faces.component.UIComponent.encodeAll(UIComponent.java:614) > >>> >> at > >>> >> javax.faces.component.UIComponent.encodeAll(UIComponent.java:614) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1117) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:231) > >>> >> at > >>> >> > >>> >> > >>> > org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:122) > >>> >> at > >>> >> > >>> > org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:207) > >>> >> at > >>> javax.faces.webapp.FacesServlet.service(FacesServlet.java:191) > >>> >> > >>> >> > >>> >> My code snippets: > >>> >> > >>> >> In clientId.xhtml > >>> >> <h:selectOneRadio id="clientIdType" > >>> value="#{model.clientIdType}"> > >>> >> <f:selectItem itemValue="CardNumber" > >>> >> itemLabel="#{msgs['labelCardNumber.full']}:" /> > >>> >> <f:selectItem itemValue="UserId" > >>> >> itemLabel="#{msgs['labelUserId.full']}:" /> > >>> >> </h:selectOneRadio> > >>> >> > >>> >> In MyModel.java > >>> >> private ClientIdType clientIdType; > >>> >> > >>> >> public ClientIdType getClientIdType() { > >>> >> return clientIdType; > >>> >> } > >>> >> > >>> >> public void setClientIdType(ClientIdType clientIdType) { > >>> >> this.clientIdType = clientIdType; > >>> >> } > >>> >> > >>> >> In ClientIdType.java > >>> >> public enum ClientIdType { > >>> >> CardNumber("labelCardNumber.short", "labelCardNumber.full"), > >>> >> UserId("labelUserId.short", "labelUserId.full"); > >>> >> > >>> >> private final String shortLabelId; > >>> >> private final String fullLabelId; > >>> >> > >>> >> private ClientIdType(String shortLabelId, String fullLabelId) { > >>> >> this.shortLabelId = shortLabelId; > >>> >> this.fullLabelId = fullLabelId; > >>> >> } > >>> >> > >>> >> public String getShortLabelId() { > >>> >> return shortLabelId; > >>> >> } > >>> >> > >>> >> public String getFullLabelId() { > >>> >> return fullLabelId; > >>> >> } > >>> >> } > >>> >> > >>> >> -- > >>> >> View this message in context: > >>> >> > >>> > http://old.nabble.com/MyFaces-2.0.0---Problem-of-rendering-Enum-tp28681934p28681934.html > >>> >> Sent from the MyFaces - Users mailing list archive at Nabble.com. > >>> >> > >>> >> > >>> > > >>> > > >>> > -- > >>> > Jakob Korherr > >>> > > >>> > blog: http://www.jakobk.com > >>> > twitter: http://twitter.com/jakobkorherr > >>> > work: http://www.irian.at > >>> > > >>> > > >>> > >>> -- > >>> View this message in context: > >>> > http://old.nabble.com/MyFaces-2.0.0---Problem-of-rendering-Enum-tp28681934p28693696.html > >>> Sent from the MyFaces - Users mailing list archive at Nabble.com. > >>> > >>> > >> > >> > >> -- > >> Jakob Korherr > >> > >> blog: http://www.jakobk.com > >> twitter: http://twitter.com/jakobkorherr > >> work: http://www.irian.at > >> > >> > > > > > > -- > View this message in context: > http://old.nabble.com/MyFaces-2.0.0---Problem-of-rendering-Enum-tp28681934p28708291.html > Sent from the MyFaces - Users mailing list archive at Nabble.com. > > -- Jakob Korherr blog: http://www.jakobk.com twitter: http://twitter.com/jakobkorherr work: http://www.irian.at

