I'll see if I can come up with a fairly self-contained example.

As far as the value set, I think I can argue that the set of values is
consistent, especially when taking into account the associated converter.
Matter of fact, we're expecting the serialization/deserialization of the
converter to *keep* the values consistent by only allowing valid EJB values
to be selected, and not even allowing null. Internally, the value is always
a non-null EJB. Externally, the value representations are the valid EJB's
plus one representation of a "nothing has been selected" state. We want the
"nothing has been selected" representation to force an error, either through
required="true" or some other mechanism.


Mike Kienenberger wrote:
> 
> Not really sure how much more I can add.   I've posted examples of
> similar code I have, but without seeing a simplified (but erroring)
> example demonstrating why your setup isn't working, I'm not sure what
> else to suggest.    getAsObject has to return a homogenious set of
> objects.   But as long as your converter translates the string values,
> I think you can have a heterogenious collection of SelectItem
> itemValues fed into the renderer.   I know I've mixed marker Strings
> (representing null and disabled selections) with actual
> ProjectTypeLocal-esque objects on my page code.
> 
> 
> On 4/2/07, fastbob <[EMAIL PROTECTED]> wrote:
>>
>> Usually the selectItem values are EJB's, but in a couple of instances
>> they
>> strings that just happen to be the serialized form of the EJB. The
>> prototypical code looks like:
>>
>>          ArrayList projectTypes = new ArrayList(
>> projectTypeHome.findAll()
>> );
>>          for( int i = 0; i < projectTypes.size(); i++ )
>>          {
>>             ProjectTypeLocal projectType =
>> (ProjectTypeLocal)projectTypes.get( i );
>>             m_projectTypes.add( new SelectItem( projectType,
>> projectType.getName() ) );
>>          }
>>
>> What this means is when we get to the following lines in
>> _SelectItemsUtil,
>> the equals() method of the EJB is called with the empty ("") string (in
>> 1.1.5):
>>
>>                  [item is class SelectItem]
>>                  Object itemValue = item.getValue();
>>                  if (value==itemValue || value.equals(itemValue))
>>
>> It appears that the 1.1.3 code handled the case of any String being
>> passed.
>> Since our converters look for an empty string, this results in the EJB
>> equals() being passed null:
>>
>>                 Object itemValue = item.getValue();
>>                 if(converter != null && itemValue instanceof String)
>>                 {
>>                     itemValue = converter.getConvertedValue(context,
>> (String)itemValue);
>>                 }
>>                 if (value==itemValue || value.equals(itemValue))
>>
>> But I guess this circles back to non-standard conversion that was taken
>> out.
>>
>> I'm pretty ignorant of all the JSF lifecycle semantics, but since this
>> practice is always used with required="true", would an earlier check for
>> a
>> non-null, non-empty string fix this?
>>
>> I'm open to suggestions.
>>
>>
>> Mike Kienenberger wrote:
>> >
>> > Yes, I think you're right.  It's not the form String -> Object that's
>> > causing the issue.
>> > It looks like it's the contents of the selectItem values.  What are
>> > you initializing the selectItem value fields with?
>> >
>> > What's the contents of selectItem.value when it's of type String?
>> >
>> > On 3/30/07, fastbob <[EMAIL PROTECTED]> wrote:
>> >>
>> >> Hmmm. I must be missing something. Other than parameterization,
>> including
>> >> your use of disable and null values, I don't see any significant
>> >> differences
>> >> (I also tried moving the converter into the h:selectOneMenu - no
>> effect).
>> >> In
>> >> fact, the Tomahawk example uses "" as a nothing -selected value, just
>> as
>> >> we
>> >> do. And the converter code is essentially identical - we start with:
>> >>
>> >>       if( string == null || string.trim().length() == 0 )
>> >>          return null;
>> >>
>> >> So why are we getting an exception during the validation phase?
>> >>
>> >> Bob
>> >>
>> >>
>> >> Mike Kienenberger wrote:
>> >> >
>> >> > Here's how the tomahawk examples do it:
>> >> >
>> >> >                 <h:selectOneMenu id="selone_menu_colors"
>> >> > value="#{carconf.color}" styleClass="selectOneMenu"
>> >> > converter="#{carconf.colorConverter}">
>> >> >                     <f:selectItem itemValue=""
>> >> > itemLabel="#{example_messages['empty_selitem']}" />
>> >> >
>> >> >
>> >> >
>> >> >         public Object getAsObject(FacesContext facesContext,
>> >> > UIComponent component, String string) throws ConverterException
>> >> >         {
>> >> >             if(string==null)
>> >> >                 return null;
>> >> >
>> >> >
>> >> > Here's how I do it on my own projects:
>> >> >
>> >> >     public final static String DISABLED_OPTION_VALUE =
>> >> > "com.xyz.utilities.web.jsf.converter.DISABLED_OPTION_VALUE";
>> >> >     public final static String NULL_OPTION_VALUE =
>> >> > "com.xyz.utilities.web.jsf.converter.NULL_OPTION_VALUE";
>> >> >
>> >> >     public String getNullSelectItemOptionValue() {
>> >> >         return
>> >> >
>> com.xyz.utilities.web.jsf.converter.ConverterOptions.NULL_OPTION_VALUE;
>> >> >     }
>> >> >
>> >> > <f:selectItem
>> >> >       itemValue="#{myPage.nullSelectItemOptionValue}"
>> >> >       itemLabel="&lt;No selection&gt;" />
>> >> >
>> >> >     public Object getAsObject(FacesContext context, UIComponent
>> >> > component, String value) throws ConverterException
>> >> >     {
>> >> >       if (null == value)  return null;
>> >> >         if (ConverterOptions.DISABLED_OPTION_VALUE.equals(value))
>> >> return
>> >> > null;
>> >> >         if (ConverterOptions.NULL_OPTION_VALUE.equals(value)) 
>> return
>> >> > null;
>> >> >
>> >> > On 3/30/07, fastbob <[EMAIL PROTECTED]> wrote:
>> >> >>
>> >> >>
>> >> >> Mike Kienenberger wrote:
>> >> >> >
>> >> >> > Yes, that's how I would do it.  If you specify an itemValue, then
>> >> that
>> >> >> > value must be of the correct type.  Ie, " " is not a
>> containerType
>> >> >> > (Srinivas) and "0" is not a region (Carl).
>> >> >> >
>> >> >> Ouch. The assumption is that there is a one-one correspondence
>> between
>> >> >> the
>> >> >> list items and the type in the model. This isn't always the case.
>> >> >>
>> >> >> We had a number of JSP's under 1.1.3 with the following sequence,
>> for
>> >> >> several different types of lists:
>> >> >>
>> >> >>          <h:selectOneMenu id="client"
>> value="#{myPage.projectType}">
>> >> >>              <f:converter converterId="x.y.ProjectTypeConverter"/>
>> >> >>              <f:selectItem itemValue="" itemLabel="--- Select
>> Project
>> >> >> Type---"/>
>> >> >>              <f:selectItems value="#{myPage.projectTypeList}"/>
>> >> >>          </h:selectOneMenu>
>> >> >>
>> >> >> The values in the type are fixed (essentially an enumeration, but
>> not
>> >> >> implemented that way), and there is no "empty" value available.
>> >> Instead,
>> >> >> if
>> >> >> the converters are passed a null or empty string for conversion to
>> the
>> >> >> underlying type, they immediately return null. So in this case null
>> is
>> >> >> used
>> >> >> to indicate no value has been selected by the user, and they get an
>> >> >> error.
>> >> >>
>> >> >> With 1.1.5, we get the following exception:
>> >> >>
>> >> >> java.lang.ClassCastException: java.lang.String cannot be cast to
>> >> >> javax.ejb.EJBLocalObject
>> >> >>             at
>> >> >>
>> >>
>> org.jboss.ejb.plugins.local.LocalProxy.isIdentical(LocalProxy.java:124)
>> >> >>             at
>> >> >> org.jboss.ejb.plugins.local.LocalProxy.invoke(LocalProxy.java:174)
>> >> >>             at
>> >> >> org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:40)
>> >> >>             at
>> >> >> org.jboss.ejb.plugins.local.LocalProxy.invoke(LocalProxy.java:155)
>> >> >>             at
>> >> >> org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:40)
>> >> >>            at $Proxy262.equals(Unknown Source)
>> >> >>             at
>> >> >>
>> >>
>> javax.faces.component._SelectItemsUtil.matchValue(_SelectItemsUtil.java:65)
>> >> >>             at
>> >> >>
>> javax.faces.component.UISelectOne.validateValue(UISelectOne.java:56)
>> >> >>             at
>> >> javax.faces.component.UIInput.validate(UIInput.java:354)
>> >> >>             at
>> >> >> javax.faces.component.UIInput.processValidators(UIInput.java:184)
>> >> >>             […]
>> >> >>
>> >> >> Here are the relevant lines from _SelectItemsUtil.MatchValue():
>> >> >>
>> >> >>                 [item is class SelectItem]
>> >> >>                 Object itemValue = item.getValue();
>> >> >>                 if (value==itemValue || value.equals(itemValue))
>> >> >>
>> >> >> The exception is thrown by the call to equals in an EJB.
>> >> >>
>> >> >> I haven't come up with a low-cost way to fix this.
>> >> >>
>> >> >> Bob
>> >> >> --
>> >> >> View this message in context:
>> >> >>
>> >>
>> http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9762021
>> >> >> Sent from the MyFaces - Users mailing list archive at Nabble.com.
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >>
>> >> --
>> >> View this message in context:
>> >>
>> http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9762503
>> >> Sent from the MyFaces - Users mailing list archive at Nabble.com.
>> >>
>> >>
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9797466
>> Sent from the MyFaces - Users mailing list archive at Nabble.com.
>>
>>
> 
> 

-- 
View this message in context: 
http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9798897
Sent from the MyFaces - Users mailing list archive at Nabble.com.

Reply via email to