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.

Reply via email to