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 <johnwu....@gmail.com> > >> >> 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 <johnwu....@gmail.com> >> > >> >> >> >> 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-tp28681934p28707503.html Sent from the MyFaces - Users mailing list archive at Nabble.com.