You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by vlad10 <iv...@yahoo.com> on 2007/07/06 21:39:41 UTC

ValueChangeListener challenges

I'm fresh with JSF, 
just started building some prototypes with facelets 1.1.11, myfaces
1.1.3/tomahawk 1.1.3.

I'm getting this general feeling that the framework is missing some
important feature.
I may create an inputText and populate it with a null value, the framework
conviniently will convert it into an empty string and populate my page.
However, on submit the valueChangeListener will fire with the reason that
null is not the same as an empty string.
I have another example. This the initial value is not null. I may explicitly
add a converter to that field, so the value stored in POJO as jva.util.Date
or as a BigDecimal or anything else will be nicely displayed on the screen,
but I'll face again the unwanted behavior of my valueChangeListener.
For the time being, I'm trying to compensate this deficiency in my app by
adding some filtering in a utility class. At the moment it's in the
beginning, just checking null/empty string case:

    /**
     * UIInput value is never null when submitted, but the POJO is always 
     * initialized with nulls. This creates a false alarm by
valueChangeListeners.
     * This method tries to compensate this deficiency.
     * @param input
     * @param rec
     * @return
     */
    public static boolean isValueChanged(UIInput input, Object pojo) {
        String name = input.getId();
        Object val = BeanUtil.getBeanValue(pojo,name);
        if (val == null)
            if(StringUtils.isEmpty(input.getValue().toString()))
                return false;
            else
                return true;
        return (input.getValue().toString().compareTo(val.toString()) != 0);
    }

My question: am I missing something???? 
Do I really need to add another layer in my app, I may call it something
like JSF Frendly POJOs. I may perform all necessary conversions right there
when moving data from DB to the screen, and then on submit perform the
opposit conversion when moving data back. I hope I can avoid that.
Is not it possible for a framework to 'remember' not just an oldValue, but
also the conversion performed, so prior to comparing old/new values it would
apply that same converter to the old value???
I think, this part has been missed.

thanks
vlad
-- 
View this message in context: http://www.nabble.com/ValueChangeListener-challenges-tf4037711.html#a11471319
Sent from the MyFaces - Users mailing list archive at Nabble.com.


Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
The value change event will be fired if the converted value does not
equal the current value. So therefore, in your example, if you have a
converter that converts "" to null, and your current value is null,
there will be no event.

On 7/6/07, vlad10 <iv...@yahoo.com> wrote:
>
> I'm fresh with JSF,
> just started building some prototypes with facelets 1.1.11, myfaces
> 1.1.3/tomahawk 1.1.3.
>
> I'm getting this general feeling that the framework is missing some
> important feature.
> I may create an inputText and populate it with a null value, the framework
> conviniently will convert it into an empty string and populate my page.
> However, on submit the valueChangeListener will fire with the reason that
> null is not the same as an empty string.
> I have another example. This the initial value is not null. I may explicitly
> add a converter to that field, so the value stored in POJO as jva.util.Date
> or as a BigDecimal or anything else will be nicely displayed on the screen,
> but I'll face again the unwanted behavior of my valueChangeListener.
> For the time being, I'm trying to compensate this deficiency in my app by
> adding some filtering in a utility class. At the moment it's in the
> beginning, just checking null/empty string case:
>
>     /**
>      * UIInput value is never null when submitted, but the POJO is always
>      * initialized with nulls. This creates a false alarm by
> valueChangeListeners.
>      * This method tries to compensate this deficiency.
>      * @param input
>      * @param rec
>      * @return
>      */
>     public static boolean isValueChanged(UIInput input, Object pojo) {
>         String name = input.getId();
>         Object val = BeanUtil.getBeanValue(pojo,name);
>         if (val == null)
>             if(StringUtils.isEmpty(input.getValue().toString()))
>                 return false;
>             else
>                 return true;
>         return (input.getValue().toString().compareTo(val.toString()) != 0);
>     }
>
> My question: am I missing something????
> Do I really need to add another layer in my app, I may call it something
> like JSF Frendly POJOs. I may perform all necessary conversions right there
> when moving data from DB to the screen, and then on submit perform the
> opposit conversion when moving data back. I hope I can avoid that.
> Is not it possible for a framework to 'remember' not just an oldValue, but
> also the conversion performed, so prior to comparing old/new values it would
> apply that same converter to the old value???
> I think, this part has been missed.
>
> thanks
> vlad
> --
> View this message in context: http://www.nabble.com/ValueChangeListener-challenges-tf4037711.html#a11471319
> Sent from the MyFaces - Users mailing list archive at Nabble.com.
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
I was and am trying the second approach (saving rather list indexes). Just
have this problem with the Date type. Now I'm replacing j.u.Date with
j.u.Calendar - did not get it working yet. My hibernate throws exception on
first retrieve, I'm looking into it.

vlad

On 7/8/07, Andrew Robinson <an...@gmail.com> wrote:
>
> There is a package in sandbox:
>
> org.apache.myfaces.custom.valueChangeNotifier
>
> Looks like Mario Ivankovits is the author. I didn't see any
> documentation for it though.
>
> That will give you change events during the update model.
>
> Another choice, is to queue the results of the events in the backing
> bean (IDs of changed Objects for example) and then in an action or
> actionlistener, apply the changes to the DB.
>
> Anyone else with a better approach?
>
> On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Yes, this is  (about apples and oranges) what I'm trying to find. My
> backin
> > type is java.util.Date. May be this is a problem?
> > I just tried example with t:inputDate, and this is what I'm getting
> (much
> > nicer):
> >
> > INFO  %%%%%% entering APPLY_REQUEST_VALUES(2) in
> > org.apache.myfaces.lifecycle.LifecycleImpl
> > INFO  %%%%%% entering PROCESS_VALIDATIONS(3) in
> > org.apache.myfaces.lifecycle.LifecycleImpl
> > ...validate: submittedValue:
> > org.apache.myfaces.custom.date.HtmlInputDate$UserData@15e6d4a
> > ...validate: previousValue: Sun Jul 08 12:21:36 EDT 2007 convertedValue:
> Sun
> > Jul 08 12:21:36 EDT 2007
> > INFO  %%%%%% entering UPDATE_MODEL_VALUES(4) in
> > org.apache.myfaces.lifecycle.LifecycleImpl
> >
> > In the core of $UserData I see Calendar as a data holder.
> >
> > Also, I think I'm missing some important part of my JSF education. May
> be I
> > should not use valuechangeEvent at all and rather wait for the
> updateModel
> > phase, but this way how am I going to stop those not really updated rows
> > from being sent to DB.
> >
> > In my case there is a List<Customer> in my backing bean which is
> represented
> > by dataTable on the page. I'm using valueChangeEvent on every field for
> > catching those rows with updates, and then with my Submit button pointed
> to
> > save() method I'm sending only those rows to DB.
> >
> > vlad
> >
> >
> > On 7/8/07, Andrew Robinson <an...@gmail.com> wrote:
> > > BTW - a value change event does not mean the data has been changed.
> > > What I mean by this is that the valueChangeEvent is fired during
> > > validation, not updating. This means that there is no guarantee that
> > > the updateModel method of the component will ever be executed, and
> > > thus your database would now be corrupted with incorrect data.
> > >
> > > I think there is a sandbox component for value change events to be
> > > fired during the update model phase instead.
> > >
> > > Also, why not use your setter property to be "notified" of when data
> > changes?
> > >
> > > In terms of why you are getting the message, your dates are not the
> same.
> > >
> > > ..validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
> > > Jan 02 00:00:00 EST 2007
> > >
> > > As you can see, they are different. If they were the same, the *exact*
> > > same output would be displayed. It doesn't look like the previous
> > > value is a Date at all. Is it a java.sql.Date or something? Also does
> > > it have a timezone (odd that one isn't being printed).
> > >
> > > It looks as if you are comparing apples and oranges...
> > >
> > > -Andrew
> > >
> > > On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > Andrew,
> > > > I had no problem with 'correcting' null/"" valueChangeEvent issue in
> my
> > app,
> > > > but I'm facing a weird problem with date fields always firing
> > > > valueChangeEvent. What's wrong? I recall you as saying 'nobody is
> using
> > this
> > > > event'. Then what should I use? My goal is avoiding calls to DB for
> > every
> > > > row, only calling with really updated rows.
> > > > I have them inside dataTable, but for making it simpler, I'll use
> just
> > one
> > > > field in this code excerpt. On the page:
> > > >
> > > >                       <t:inputText value="#{ order.orderDate}"
> > > > valueChangeListener="#{ customers.orderChanged}" id="orderDate">
> > > >                             <f:convertDateTime type="date"
> > > > dateStyle="default" timeZone="EST"/>
> > > >                       </t:inputText>
> > > >
> > > > After placing some System.out in UIInput.validate() as follows:
> > > >
> > > >     public void validate(FacesContext context)
> > > >     {
> > > >         if (context == null) throw new
> > > > NullPointerException("context");
> > > >          Object submittedValue = getSubmittedValue();
> > > >         System.out.println("...validate: submittedValue:
> > "+submittedValue);
> > > >         if (submittedValue == null) return;
> > > >
> > > >         Object convertedValue = getConvertedValue(context,
> > submittedValue);
> > > >
> > > >         if (!isValid()) return;
> > > >
> > > >         validateValue(context, convertedValue);
> > > >
> > > >         if (!isValid()) return;
> > > >
> > > >          Object previousValue = getValue();
> > > >         System.out.println("...validate: previousValue:
> "+previousValue+
> > "
> > > > convertedValue: "+convertedValue);
> > > >          setValue(convertedValue);
> > > >         setSubmittedValue(null);
> > > >         if (compareValues(previousValue, convertedValue))
> > > >         {
> > > >             queueEvent(new ValueChangeEvent(this, previousValue,
> > > > convertedValue));
> > > >         }
> > > >     }
> > > >
> > > > I see in my log:
> > > >
> > > > ...validate: submittedValue: Jan 2, 2007
> > > > ...validate: previousValue: 2007-01-02 00:00:00.0 convertedValue:
> Tue
> > Jan 02
> > > > 00:00:00 EST 2007
> > > >
> > > > And as a result I'm gettin the valueChange Event.
> > > >
> > > > thanks
> > > >
> > > > vlad
> > > >
> > > > On 7/7/07, Andrew Robinson <andrew.rw.robinson@gmail.com > wrote:
> > > > > I you change a component's code and that component is reusable,
> then
> > > > > you will affect its behavior everywhere you use it. That was all I
> was
> > > > > saying.
> > > > >
> > > > > In terms of affecting the value change event for one component on
> a
> > > > > page, it wouldn't hurt anything that I am aware of. Most of the
> time
> > > > > valueChangeEvents are not used.
> > > > >
> > > > > On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > > > You've lost me. What you mean by 'Depends on who is listening
> for
> > the
> > > > > > events'? I thought - #{ myBean.someMethod} is.
> > > > > > Am I missing something?
> > > > > >
> > > > > > And there is no garantee from introducing a bug with any new
> code -
> > this
> > > > is
> > > > > > our life. Testing is always a part of dev. But how is it
> relevant to
> > > > what
> > > > > > we're discussing?
> > > > > >
> > > > > > vlad
> > > > > >
> > > > > >
> > > > > > On 7/7/07, Andrew Robinson < andrew.rw.robinson@gmail.com>
> wrote:
> > > > > > > Depends on who is listening for the events. Can you guarantee
> that
> > > > > > > there will be no bugs in your code from doing this?
> > > > > > >
> > > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > > Andrew,
> > > > > > > > could you give me an example (use case) when I'm sending out
> a
> > null
> > > > > > value,
> > > > > > > > then on submit get "" back, and there is any harm of
> stopping
> > > > > > > > valueChangeEvent from being fired.
> > > > > > > >
> > > > > > > > I can't come up with one.
> > > > > > > >
> > > > > > > > Sure, I may write some logic or a converter wraper in order
> to
> > > > prevent
> > > > > > this
> > > > > > > > unwanted event, I just was pointing to the fact that I was
> > expected
> > > > this
> > > > > > > > from non altered framework.
> > > > > > > >
> > > > > > > > vlad
> > > > > > > >
> > > > > > > > On 7/6/07, Andrew Robinson < andrew.rw.robinson@gmail.com>
> > wrote:
> > > > > > > > > null has a special meaning, and thus why null != "" in
> terms
> > of
> > > > > > > > > UIInput. Null means that the value was not submitted at
> all.
> > ""
> > > > means
> > > > > > > > > the value was submitted with no value. Thus why you need
> to
> > > > convert ""
> > > > > > > > > to null if that is what you wish. If the renderer
> converted ""
> > to
> > > > > > > > > null, then there would never be an update of the model.
> > > > > > > > >
> > > > > > > > > If you want, write a chain converter or a converter
> wrapper
> > that
> > > > > > > > > converts "" to null.
> > > > > > > > >
> > > > > > > > > It may look like:
> > > > > > > > >
> > > > > > > > > <h:inputText ...>
> > > > > > > > > <my:emptyToNullConverter wrapConverterId="
> javax.faces.Integer
> > " />
> > > > > > > > > </h:inputText>
> > > > > > > > >
> > > > > > > > > then you can first check for "" and convert it to null,
> and if
> > > > not,
> > > > > > > > > delegate the check to the "inner converter"
> > > > > > > > >
> > > > > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > > > > Although null and date are two separate issues, but I'm
> > gettin
> > > > the
> > > > > > > > picture.
> > > > > > > > > > I may create my own converters and attach them to all my
> > fields
> > > > as
> > > > > > I'm
> > > > > > > > > > pleased.  But I'm trying to have some common services
> (if
> > > > thay're
> > > > > > > > missing in
> > > > > > > > > > the framework) in a single place, well this may be
> arguable
> > > > what's
> > > > > > > > better.
> > > > > > > > > > Sorry for annoyance, but still, why JSF would not check
> for
> > > > nulls
> > > > > > for me
> > > > > > > > > > (you've pointed the right method to be changed).
> > > > > > > > > >
> > > > > > > > > > With the date conversion I'll postpone the issue, I have
> to
> > > > spend
> > > > > > more
> > > > > > > > time
> > > > > > > > > > tracing it.
> > > > > > > > > >
> > > > > > > > > > vlad
> > > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Fixed Calendar issue with hibernate but DateTimeConverter blew up, could not
convert:
javax.faces.convert.ConverterException: java.lang.IllegalArgumentException:
Cannot format given Object as a Date

On 7/8/07, Andrew Robinson <an...@gmail.com> wrote:
>
> There is a package in sandbox:
>
> org.apache.myfaces.custom.valueChangeNotifier
>
> Looks like Mario Ivankovits is the author. I didn't see any
> documentation for it though.
>
> That will give you change events during the update model.
>
> Another choice, is to queue the results of the events in the backing
> bean (IDs of changed Objects for example) and then in an action or
> actionlistener, apply the changes to the DB.
>
> Anyone else with a better approach?
>
> On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Yes, this is  (about apples and oranges) what I'm trying to find. My
> backin
> > type is java.util.Date. May be this is a problem?
> > I just tried example with t:inputDate, and this is what I'm getting
> (much
> > nicer):
> >
> > INFO  %%%%%% entering APPLY_REQUEST_VALUES(2) in
> > org.apache.myfaces.lifecycle.LifecycleImpl
> > INFO  %%%%%% entering PROCESS_VALIDATIONS(3) in
> > org.apache.myfaces.lifecycle.LifecycleImpl
> > ...validate: submittedValue:
> > org.apache.myfaces.custom.date.HtmlInputDate$UserData@15e6d4a
> > ...validate: previousValue: Sun Jul 08 12:21:36 EDT 2007 convertedValue:
> Sun
> > Jul 08 12:21:36 EDT 2007
> > INFO  %%%%%% entering UPDATE_MODEL_VALUES(4) in
> > org.apache.myfaces.lifecycle.LifecycleImpl
> >
> > In the core of $UserData I see Calendar as a data holder.
> >
> > Also, I think I'm missing some important part of my JSF education. May
> be I
> > should not use valuechangeEvent at all and rather wait for the
> updateModel
> > phase, but this way how am I going to stop those not really updated rows
> > from being sent to DB.
> >
> > In my case there is a List<Customer> in my backing bean which is
> represented
> > by dataTable on the page. I'm using valueChangeEvent on every field for
> > catching those rows with updates, and then with my Submit button pointed
> to
> > save() method I'm sending only those rows to DB.
> >
> > vlad
> >
> >
> > On 7/8/07, Andrew Robinson <an...@gmail.com> wrote:
> > > BTW - a value change event does not mean the data has been changed.
> > > What I mean by this is that the valueChangeEvent is fired during
> > > validation, not updating. This means that there is no guarantee that
> > > the updateModel method of the component will ever be executed, and
> > > thus your database would now be corrupted with incorrect data.
> > >
> > > I think there is a sandbox component for value change events to be
> > > fired during the update model phase instead.
> > >
> > > Also, why not use your setter property to be "notified" of when data
> > changes?
> > >
> > > In terms of why you are getting the message, your dates are not the
> same.
> > >
> > > ..validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
> > > Jan 02 00:00:00 EST 2007
> > >
> > > As you can see, they are different. If they were the same, the *exact*
> > > same output would be displayed. It doesn't look like the previous
> > > value is a Date at all. Is it a java.sql.Date or something? Also does
> > > it have a timezone (odd that one isn't being printed).
> > >
> > > It looks as if you are comparing apples and oranges...
> > >
> > > -Andrew
> > >
> > > On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > Andrew,
> > > > I had no problem with 'correcting' null/"" valueChangeEvent issue in
> my
> > app,
> > > > but I'm facing a weird problem with date fields always firing
> > > > valueChangeEvent. What's wrong? I recall you as saying 'nobody is
> using
> > this
> > > > event'. Then what should I use? My goal is avoiding calls to DB for
> > every
> > > > row, only calling with really updated rows.
> > > > I have them inside dataTable, but for making it simpler, I'll use
> just
> > one
> > > > field in this code excerpt. On the page:
> > > >
> > > >                       <t:inputText value="#{ order.orderDate}"
> > > > valueChangeListener="#{ customers.orderChanged}" id="orderDate">
> > > >                             <f:convertDateTime type="date"
> > > > dateStyle="default" timeZone="EST"/>
> > > >                       </t:inputText>
> > > >
> > > > After placing some System.out in UIInput.validate() as follows:
> > > >
> > > >     public void validate(FacesContext context)
> > > >     {
> > > >         if (context == null) throw new
> > > > NullPointerException("context");
> > > >          Object submittedValue = getSubmittedValue();
> > > >         System.out.println("...validate: submittedValue:
> > "+submittedValue);
> > > >         if (submittedValue == null) return;
> > > >
> > > >         Object convertedValue = getConvertedValue(context,
> > submittedValue);
> > > >
> > > >         if (!isValid()) return;
> > > >
> > > >         validateValue(context, convertedValue);
> > > >
> > > >         if (!isValid()) return;
> > > >
> > > >          Object previousValue = getValue();
> > > >         System.out.println("...validate: previousValue:
> "+previousValue+
> > "
> > > > convertedValue: "+convertedValue);
> > > >          setValue(convertedValue);
> > > >         setSubmittedValue(null);
> > > >         if (compareValues(previousValue, convertedValue))
> > > >         {
> > > >             queueEvent(new ValueChangeEvent(this, previousValue,
> > > > convertedValue));
> > > >         }
> > > >     }
> > > >
> > > > I see in my log:
> > > >
> > > > ...validate: submittedValue: Jan 2, 2007
> > > > ...validate: previousValue: 2007-01-02 00:00:00.0 convertedValue:
> Tue
> > Jan 02
> > > > 00:00:00 EST 2007
> > > >
> > > > And as a result I'm gettin the valueChange Event.
> > > >
> > > > thanks
> > > >
> > > > vlad
> > > >
> > > > On 7/7/07, Andrew Robinson <andrew.rw.robinson@gmail.com > wrote:
> > > > > I you change a component's code and that component is reusable,
> then
> > > > > you will affect its behavior everywhere you use it. That was all I
> was
> > > > > saying.
> > > > >
> > > > > In terms of affecting the value change event for one component on
> a
> > > > > page, it wouldn't hurt anything that I am aware of. Most of the
> time
> > > > > valueChangeEvents are not used.
> > > > >
> > > > > On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > > > You've lost me. What you mean by 'Depends on who is listening
> for
> > the
> > > > > > events'? I thought - #{ myBean.someMethod} is.
> > > > > > Am I missing something?
> > > > > >
> > > > > > And there is no garantee from introducing a bug with any new
> code -
> > this
> > > > is
> > > > > > our life. Testing is always a part of dev. But how is it
> relevant to
> > > > what
> > > > > > we're discussing?
> > > > > >
> > > > > > vlad
> > > > > >
> > > > > >
> > > > > > On 7/7/07, Andrew Robinson < andrew.rw.robinson@gmail.com>
> wrote:
> > > > > > > Depends on who is listening for the events. Can you guarantee
> that
> > > > > > > there will be no bugs in your code from doing this?
> > > > > > >
> > > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > > Andrew,
> > > > > > > > could you give me an example (use case) when I'm sending out
> a
> > null
> > > > > > value,
> > > > > > > > then on submit get "" back, and there is any harm of
> stopping
> > > > > > > > valueChangeEvent from being fired.
> > > > > > > >
> > > > > > > > I can't come up with one.
> > > > > > > >
> > > > > > > > Sure, I may write some logic or a converter wraper in order
> to
> > > > prevent
> > > > > > this
> > > > > > > > unwanted event, I just was pointing to the fact that I was
> > expected
> > > > this
> > > > > > > > from non altered framework.
> > > > > > > >
> > > > > > > > vlad
> > > > > > > >
> > > > > > > > On 7/6/07, Andrew Robinson < andrew.rw.robinson@gmail.com>
> > wrote:
> > > > > > > > > null has a special meaning, and thus why null != "" in
> terms
> > of
> > > > > > > > > UIInput. Null means that the value was not submitted at
> all.
> > ""
> > > > means
> > > > > > > > > the value was submitted with no value. Thus why you need
> to
> > > > convert ""
> > > > > > > > > to null if that is what you wish. If the renderer
> converted ""
> > to
> > > > > > > > > null, then there would never be an update of the model.
> > > > > > > > >
> > > > > > > > > If you want, write a chain converter or a converter
> wrapper
> > that
> > > > > > > > > converts "" to null.
> > > > > > > > >
> > > > > > > > > It may look like:
> > > > > > > > >
> > > > > > > > > <h:inputText ...>
> > > > > > > > > <my:emptyToNullConverter wrapConverterId="
> javax.faces.Integer
> > " />
> > > > > > > > > </h:inputText>
> > > > > > > > >
> > > > > > > > > then you can first check for "" and convert it to null,
> and if
> > > > not,
> > > > > > > > > delegate the check to the "inner converter"
> > > > > > > > >
> > > > > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > > > > Although null and date are two separate issues, but I'm
> > gettin
> > > > the
> > > > > > > > picture.
> > > > > > > > > > I may create my own converters and attach them to all my
> > fields
> > > > as
> > > > > > I'm
> > > > > > > > > > pleased.  But I'm trying to have some common services
> (if
> > > > thay're
> > > > > > > > missing in
> > > > > > > > > > the framework) in a single place, well this may be
> arguable
> > > > what's
> > > > > > > > better.
> > > > > > > > > > Sorry for annoyance, but still, why JSF would not check
> for
> > > > nulls
> > > > > > for me
> > > > > > > > > > (you've pointed the right method to be changed).
> > > > > > > > > >
> > > > > > > > > > With the date conversion I'll postpone the issue, I have
> to
> > > > spend
> > > > > > more
> > > > > > > > time
> > > > > > > > > > tracing it.
> > > > > > > > > >
> > > > > > > > > > vlad
> > > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
There is a package in sandbox:

org.apache.myfaces.custom.valueChangeNotifier

Looks like Mario Ivankovits is the author. I didn't see any
documentation for it though.

That will give you change events during the update model.

Another choice, is to queue the results of the events in the backing
bean (IDs of changed Objects for example) and then in an action or
actionlistener, apply the changes to the DB.

Anyone else with a better approach?

On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Yes, this is  (about apples and oranges) what I'm trying to find. My backin
> type is java.util.Date. May be this is a problem?
> I just tried example with t:inputDate, and this is what I'm getting (much
> nicer):
>
> INFO  %%%%%% entering APPLY_REQUEST_VALUES(2) in
> org.apache.myfaces.lifecycle.LifecycleImpl
> INFO  %%%%%% entering PROCESS_VALIDATIONS(3) in
> org.apache.myfaces.lifecycle.LifecycleImpl
> ...validate: submittedValue:
> org.apache.myfaces.custom.date.HtmlInputDate$UserData@15e6d4a
> ...validate: previousValue: Sun Jul 08 12:21:36 EDT 2007 convertedValue: Sun
> Jul 08 12:21:36 EDT 2007
> INFO  %%%%%% entering UPDATE_MODEL_VALUES(4) in
> org.apache.myfaces.lifecycle.LifecycleImpl
>
> In the core of $UserData I see Calendar as a data holder.
>
> Also, I think I'm missing some important part of my JSF education. May be I
> should not use valuechangeEvent at all and rather wait for the updateModel
> phase, but this way how am I going to stop those not really updated rows
> from being sent to DB.
>
> In my case there is a List<Customer> in my backing bean which is represented
> by dataTable on the page. I'm using valueChangeEvent on every field for
> catching those rows with updates, and then with my Submit button pointed to
> save() method I'm sending only those rows to DB.
>
> vlad
>
>
> On 7/8/07, Andrew Robinson <an...@gmail.com> wrote:
> > BTW - a value change event does not mean the data has been changed.
> > What I mean by this is that the valueChangeEvent is fired during
> > validation, not updating. This means that there is no guarantee that
> > the updateModel method of the component will ever be executed, and
> > thus your database would now be corrupted with incorrect data.
> >
> > I think there is a sandbox component for value change events to be
> > fired during the update model phase instead.
> >
> > Also, why not use your setter property to be "notified" of when data
> changes?
> >
> > In terms of why you are getting the message, your dates are not the same.
> >
> > ..validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
> > Jan 02 00:00:00 EST 2007
> >
> > As you can see, they are different. If they were the same, the *exact*
> > same output would be displayed. It doesn't look like the previous
> > value is a Date at all. Is it a java.sql.Date or something? Also does
> > it have a timezone (odd that one isn't being printed).
> >
> > It looks as if you are comparing apples and oranges...
> >
> > -Andrew
> >
> > On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > Andrew,
> > > I had no problem with 'correcting' null/"" valueChangeEvent issue in my
> app,
> > > but I'm facing a weird problem with date fields always firing
> > > valueChangeEvent. What's wrong? I recall you as saying 'nobody is using
> this
> > > event'. Then what should I use? My goal is avoiding calls to DB for
> every
> > > row, only calling with really updated rows.
> > > I have them inside dataTable, but for making it simpler, I'll use just
> one
> > > field in this code excerpt. On the page:
> > >
> > >                       <t:inputText value="#{ order.orderDate}"
> > > valueChangeListener="#{ customers.orderChanged}" id="orderDate">
> > >                             <f:convertDateTime type="date"
> > > dateStyle="default" timeZone="EST"/>
> > >                       </t:inputText>
> > >
> > > After placing some System.out in UIInput.validate() as follows:
> > >
> > >     public void validate(FacesContext context)
> > >     {
> > >         if (context == null) throw new
> > > NullPointerException("context");
> > >          Object submittedValue = getSubmittedValue();
> > >         System.out.println("...validate: submittedValue:
> "+submittedValue);
> > >         if (submittedValue == null) return;
> > >
> > >         Object convertedValue = getConvertedValue(context,
> submittedValue);
> > >
> > >         if (!isValid()) return;
> > >
> > >         validateValue(context, convertedValue);
> > >
> > >         if (!isValid()) return;
> > >
> > >          Object previousValue = getValue();
> > >         System.out.println("...validate: previousValue: "+previousValue+
> "
> > > convertedValue: "+convertedValue);
> > >          setValue(convertedValue);
> > >         setSubmittedValue(null);
> > >         if (compareValues(previousValue, convertedValue))
> > >         {
> > >             queueEvent(new ValueChangeEvent(this, previousValue,
> > > convertedValue));
> > >         }
> > >     }
> > >
> > > I see in my log:
> > >
> > > ...validate: submittedValue: Jan 2, 2007
> > > ...validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
> Jan 02
> > > 00:00:00 EST 2007
> > >
> > > And as a result I'm gettin the valueChange Event.
> > >
> > > thanks
> > >
> > > vlad
> > >
> > > On 7/7/07, Andrew Robinson <andrew.rw.robinson@gmail.com > wrote:
> > > > I you change a component's code and that component is reusable, then
> > > > you will affect its behavior everywhere you use it. That was all I was
> > > > saying.
> > > >
> > > > In terms of affecting the value change event for one component on a
> > > > page, it wouldn't hurt anything that I am aware of. Most of the time
> > > > valueChangeEvents are not used.
> > > >
> > > > On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > > You've lost me. What you mean by 'Depends on who is listening for
> the
> > > > > events'? I thought - #{ myBean.someMethod} is.
> > > > > Am I missing something?
> > > > >
> > > > > And there is no garantee from introducing a bug with any new code -
> this
> > > is
> > > > > our life. Testing is always a part of dev. But how is it relevant to
> > > what
> > > > > we're discussing?
> > > > >
> > > > > vlad
> > > > >
> > > > >
> > > > > On 7/7/07, Andrew Robinson < andrew.rw.robinson@gmail.com> wrote:
> > > > > > Depends on who is listening for the events. Can you guarantee that
> > > > > > there will be no bugs in your code from doing this?
> > > > > >
> > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > Andrew,
> > > > > > > could you give me an example (use case) when I'm sending out a
> null
> > > > > value,
> > > > > > > then on submit get "" back, and there is any harm of stopping
> > > > > > > valueChangeEvent from being fired.
> > > > > > >
> > > > > > > I can't come up with one.
> > > > > > >
> > > > > > > Sure, I may write some logic or a converter wraper in order to
> > > prevent
> > > > > this
> > > > > > > unwanted event, I just was pointing to the fact that I was
> expected
> > > this
> > > > > > > from non altered framework.
> > > > > > >
> > > > > > > vlad
> > > > > > >
> > > > > > > On 7/6/07, Andrew Robinson < andrew.rw.robinson@gmail.com>
> wrote:
> > > > > > > > null has a special meaning, and thus why null != "" in terms
> of
> > > > > > > > UIInput. Null means that the value was not submitted at all.
> ""
> > > means
> > > > > > > > the value was submitted with no value. Thus why you need to
> > > convert ""
> > > > > > > > to null if that is what you wish. If the renderer converted ""
> to
> > > > > > > > null, then there would never be an update of the model.
> > > > > > > >
> > > > > > > > If you want, write a chain converter or a converter wrapper
> that
> > > > > > > > converts "" to null.
> > > > > > > >
> > > > > > > > It may look like:
> > > > > > > >
> > > > > > > > <h:inputText ...>
> > > > > > > > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer
> " />
> > > > > > > > </h:inputText>
> > > > > > > >
> > > > > > > > then you can first check for "" and convert it to null, and if
> > > not,
> > > > > > > > delegate the check to the "inner converter"
> > > > > > > >
> > > > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > > > Although null and date are two separate issues, but I'm
> gettin
> > > the
> > > > > > > picture.
> > > > > > > > > I may create my own converters and attach them to all my
> fields
> > > as
> > > > > I'm
> > > > > > > > > pleased.  But I'm trying to have some common services (if
> > > thay're
> > > > > > > missing in
> > > > > > > > > the framework) in a single place, well this may be arguable
> > > what's
> > > > > > > better.
> > > > > > > > > Sorry for annoyance, but still, why JSF would not check for
> > > nulls
> > > > > for me
> > > > > > > > > (you've pointed the right method to be changed).
> > > > > > > > >
> > > > > > > > > With the date conversion I'll postpone the issue, I have to
> > > spend
> > > > > more
> > > > > > > time
> > > > > > > > > tracing it.
> > > > > > > > >
> > > > > > > > > vlad
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Yes, this is  (about apples and oranges) what I'm trying to find. My backin
type is java.util.Date. May be this is a problem?
I just tried example with t:inputDate, and this is what I'm getting (much
nicer):

INFO  %%%%%% entering APPLY_REQUEST_VALUES(2) in
org.apache.myfaces.lifecycle.LifecycleImpl
INFO  %%%%%% entering PROCESS_VALIDATIONS(3) in
org.apache.myfaces.lifecycle.LifecycleImpl
...validate: submittedValue:
org.apache.myfaces.custom.date.HtmlInputDate$UserData@15e6d4a
...validate: previousValue: Sun Jul 08 12:21:36 EDT 2007 convertedValue: Sun
Jul 08 12:21:36 EDT 2007
INFO  %%%%%% entering UPDATE_MODEL_VALUES(4) in
org.apache.myfaces.lifecycle.LifecycleImpl

In the core of $UserData I see Calendar as a data holder.

Also, I think I'm missing some important part of my JSF education. May be I
should not use valuechangeEvent at all and rather wait for the updateModel
phase, but this way how am I going to stop those not really updated rows
from being sent to DB.

In my case there is a List<Customer> in my backing bean which is represented
by dataTable on the page. I'm using valueChangeEvent on every field for
catching those rows with updates, and then with my Submit button pointed to
save() method I'm sending only those rows to DB.

vlad

On 7/8/07, Andrew Robinson <an...@gmail.com> wrote:
>
> BTW - a value change event does not mean the data has been changed.
> What I mean by this is that the valueChangeEvent is fired during
> validation, not updating. This means that there is no guarantee that
> the updateModel method of the component will ever be executed, and
> thus your database would now be corrupted with incorrect data.
>
> I think there is a sandbox component for value change events to be
> fired during the update model phase instead.
>
> Also, why not use your setter property to be "notified" of when data
> changes?
>
> In terms of why you are getting the message, your dates are not the same.
>
> ..validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
> Jan 02 00:00:00 EST 2007
>
> As you can see, they are different. If they were the same, the *exact*
> same output would be displayed. It doesn't look like the previous
> value is a Date at all. Is it a java.sql.Date or something? Also does
> it have a timezone (odd that one isn't being printed).
>
> It looks as if you are comparing apples and oranges...
>
> -Andrew
>
> On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Andrew,
> > I had no problem with 'correcting' null/"" valueChangeEvent issue in my
> app,
> > but I'm facing a weird problem with date fields always firing
> > valueChangeEvent. What's wrong? I recall you as saying 'nobody is using
> this
> > event'. Then what should I use? My goal is avoiding calls to DB for
> every
> > row, only calling with really updated rows.
> > I have them inside dataTable, but for making it simpler, I'll use just
> one
> > field in this code excerpt. On the page:
> >
> >                       <t:inputText value="#{order.orderDate}"
> > valueChangeListener="#{ customers.orderChanged}" id="orderDate">
> >                             <f:convertDateTime type="date"
> > dateStyle="default" timeZone="EST"/>
> >                       </t:inputText>
> >
> > After placing some System.out in UIInput.validate() as follows:
> >
> >     public void validate(FacesContext context)
> >     {
> >         if (context == null) throw new
> > NullPointerException("context");
> >          Object submittedValue = getSubmittedValue();
> >         System.out.println("...validate: submittedValue:
> "+submittedValue);
> >         if (submittedValue == null) return;
> >
> >         Object convertedValue = getConvertedValue(context,
> submittedValue);
> >
> >         if (!isValid()) return;
> >
> >         validateValue(context, convertedValue);
> >
> >         if (!isValid()) return;
> >
> >          Object previousValue = getValue();
> >         System.out.println("...validate: previousValue: "+previousValue+
> "
> > convertedValue: "+convertedValue);
> >          setValue(convertedValue);
> >         setSubmittedValue(null);
> >         if (compareValues(previousValue, convertedValue))
> >         {
> >             queueEvent(new ValueChangeEvent(this, previousValue,
> > convertedValue));
> >         }
> >     }
> >
> > I see in my log:
> >
> > ...validate: submittedValue: Jan 2, 2007
> > ...validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
> Jan 02
> > 00:00:00 EST 2007
> >
> > And as a result I'm gettin the valueChange Event.
> >
> > thanks
> >
> > vlad
> >
> > On 7/7/07, Andrew Robinson <an...@gmail.com> wrote:
> > > I you change a component's code and that component is reusable, then
> > > you will affect its behavior everywhere you use it. That was all I was
> > > saying.
> > >
> > > In terms of affecting the value change event for one component on a
> > > page, it wouldn't hurt anything that I am aware of. Most of the time
> > > valueChangeEvents are not used.
> > >
> > > On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > You've lost me. What you mean by 'Depends on who is listening for
> the
> > > > events'? I thought - #{myBean.someMethod} is.
> > > > Am I missing something?
> > > >
> > > > And there is no garantee from introducing a bug with any new code -
> this
> > is
> > > > our life. Testing is always a part of dev. But how is it relevant to
> > what
> > > > we're discussing?
> > > >
> > > > vlad
> > > >
> > > >
> > > > On 7/7/07, Andrew Robinson < andrew.rw.robinson@gmail.com> wrote:
> > > > > Depends on who is listening for the events. Can you guarantee that
> > > > > there will be no bugs in your code from doing this?
> > > > >
> > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > Andrew,
> > > > > > could you give me an example (use case) when I'm sending out a
> null
> > > > value,
> > > > > > then on submit get "" back, and there is any harm of stopping
> > > > > > valueChangeEvent from being fired.
> > > > > >
> > > > > > I can't come up with one.
> > > > > >
> > > > > > Sure, I may write some logic or a converter wraper in order to
> > prevent
> > > > this
> > > > > > unwanted event, I just was pointing to the fact that I was
> expected
> > this
> > > > > > from non altered framework.
> > > > > >
> > > > > > vlad
> > > > > >
> > > > > > On 7/6/07, Andrew Robinson < andrew.rw.robinson@gmail.com>
> wrote:
> > > > > > > null has a special meaning, and thus why null != "" in terms
> of
> > > > > > > UIInput. Null means that the value was not submitted at all.
> ""
> > means
> > > > > > > the value was submitted with no value. Thus why you need to
> > convert ""
> > > > > > > to null if that is what you wish. If the renderer converted ""
> to
> > > > > > > null, then there would never be an update of the model.
> > > > > > >
> > > > > > > If you want, write a chain converter or a converter wrapper
> that
> > > > > > > converts "" to null.
> > > > > > >
> > > > > > > It may look like:
> > > > > > >
> > > > > > > <h:inputText ...>
> > > > > > > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer" />
> > > > > > > </h:inputText>
> > > > > > >
> > > > > > > then you can first check for "" and convert it to null, and if
> > not,
> > > > > > > delegate the check to the "inner converter"
> > > > > > >
> > > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > > Although null and date are two separate issues, but I'm
> gettin
> > the
> > > > > > picture.
> > > > > > > > I may create my own converters and attach them to all my
> fields
> > as
> > > > I'm
> > > > > > > > pleased.  But I'm trying to have some common services (if
> > thay're
> > > > > > missing in
> > > > > > > > the framework) in a single place, well this may be arguable
> > what's
> > > > > > better.
> > > > > > > > Sorry for annoyance, but still, why JSF would not check for
> > nulls
> > > > for me
> > > > > > > > (you've pointed the right method to be changed).
> > > > > > > >
> > > > > > > > With the date conversion I'll postpone the issue, I have to
> > spend
> > > > more
> > > > > > time
> > > > > > > > tracing it.
> > > > > > > >
> > > > > > > > vlad
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
BTW - a value change event does not mean the data has been changed.
What I mean by this is that the valueChangeEvent is fired during
validation, not updating. This means that there is no guarantee that
the updateModel method of the component will ever be executed, and
thus your database would now be corrupted with incorrect data.

I think there is a sandbox component for value change events to be
fired during the update model phase instead.

Also, why not use your setter property to be "notified" of when data changes?

In terms of why you are getting the message, your dates are not the same.

..validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue
Jan 02 00:00:00 EST 2007

As you can see, they are different. If they were the same, the *exact*
same output would be displayed. It doesn't look like the previous
value is a Date at all. Is it a java.sql.Date or something? Also does
it have a timezone (odd that one isn't being printed).

It looks as if you are comparing apples and oranges...

-Andrew

On 7/8/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Andrew,
> I had no problem with 'correcting' null/"" valueChangeEvent issue in my app,
> but I'm facing a weird problem with date fields always firing
> valueChangeEvent. What's wrong? I recall you as saying 'nobody is using this
> event'. Then what should I use? My goal is avoiding calls to DB for every
> row, only calling with really updated rows.
> I have them inside dataTable, but for making it simpler, I'll use just one
> field in this code excerpt. On the page:
>
>                       <t:inputText value="#{order.orderDate}"
> valueChangeListener="#{ customers.orderChanged}" id="orderDate">
>                             <f:convertDateTime type="date"
> dateStyle="default" timeZone="EST"/>
>                       </t:inputText>
>
> After placing some System.out in UIInput.validate() as follows:
>
>     public void validate(FacesContext context)
>     {
>         if (context == null) throw new
> NullPointerException("context");
>          Object submittedValue = getSubmittedValue();
>         System.out.println("...validate: submittedValue: "+submittedValue);
>         if (submittedValue == null) return;
>
>         Object convertedValue = getConvertedValue(context, submittedValue);
>
>         if (!isValid()) return;
>
>         validateValue(context, convertedValue);
>
>         if (!isValid()) return;
>
>          Object previousValue = getValue();
>         System.out.println("...validate: previousValue: "+previousValue+ "
> convertedValue: "+convertedValue);
>          setValue(convertedValue);
>         setSubmittedValue(null);
>         if (compareValues(previousValue, convertedValue))
>         {
>             queueEvent(new ValueChangeEvent(this, previousValue,
> convertedValue));
>         }
>     }
>
> I see in my log:
>
> ...validate: submittedValue: Jan 2, 2007
> ...validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue Jan 02
> 00:00:00 EST 2007
>
> And as a result I'm gettin the valueChange Event.
>
> thanks
>
> vlad
>
> On 7/7/07, Andrew Robinson <an...@gmail.com> wrote:
> > I you change a component's code and that component is reusable, then
> > you will affect its behavior everywhere you use it. That was all I was
> > saying.
> >
> > In terms of affecting the value change event for one component on a
> > page, it wouldn't hurt anything that I am aware of. Most of the time
> > valueChangeEvents are not used.
> >
> > On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > You've lost me. What you mean by 'Depends on who is listening for the
> > > events'? I thought - #{myBean.someMethod} is.
> > > Am I missing something?
> > >
> > > And there is no garantee from introducing a bug with any new code - this
> is
> > > our life. Testing is always a part of dev. But how is it relevant to
> what
> > > we're discussing?
> > >
> > > vlad
> > >
> > >
> > > On 7/7/07, Andrew Robinson < andrew.rw.robinson@gmail.com> wrote:
> > > > Depends on who is listening for the events. Can you guarantee that
> > > > there will be no bugs in your code from doing this?
> > > >
> > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > Andrew,
> > > > > could you give me an example (use case) when I'm sending out a null
> > > value,
> > > > > then on submit get "" back, and there is any harm of stopping
> > > > > valueChangeEvent from being fired.
> > > > >
> > > > > I can't come up with one.
> > > > >
> > > > > Sure, I may write some logic or a converter wraper in order to
> prevent
> > > this
> > > > > unwanted event, I just was pointing to the fact that I was expected
> this
> > > > > from non altered framework.
> > > > >
> > > > > vlad
> > > > >
> > > > > On 7/6/07, Andrew Robinson < andrew.rw.robinson@gmail.com> wrote:
> > > > > > null has a special meaning, and thus why null != "" in terms of
> > > > > > UIInput. Null means that the value was not submitted at all. ""
> means
> > > > > > the value was submitted with no value. Thus why you need to
> convert ""
> > > > > > to null if that is what you wish. If the renderer converted "" to
> > > > > > null, then there would never be an update of the model.
> > > > > >
> > > > > > If you want, write a chain converter or a converter wrapper that
> > > > > > converts "" to null.
> > > > > >
> > > > > > It may look like:
> > > > > >
> > > > > > <h:inputText ...>
> > > > > > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer " />
> > > > > > </h:inputText>
> > > > > >
> > > > > > then you can first check for "" and convert it to null, and if
> not,
> > > > > > delegate the check to the "inner converter"
> > > > > >
> > > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > > Although null and date are two separate issues, but I'm gettin
> the
> > > > > picture.
> > > > > > > I may create my own converters and attach them to all my fields
> as
> > > I'm
> > > > > > > pleased.  But I'm trying to have some common services (if
> thay're
> > > > > missing in
> > > > > > > the framework) in a single place, well this may be arguable
> what's
> > > > > better.
> > > > > > > Sorry for annoyance, but still, why JSF would not check for
> nulls
> > > for me
> > > > > > > (you've pointed the right method to be changed).
> > > > > > >
> > > > > > > With the date conversion I'll postpone the issue, I have to
> spend
> > > more
> > > > > time
> > > > > > > tracing it.
> > > > > > >
> > > > > > > vlad
> > > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Andrew,
I had no problem with 'correcting' null/"" valueChangeEvent issue in my app,
but I'm facing a weird problem with date fields always firing
valueChangeEvent. What's wrong? I recall you as saying 'nobody is using this
event'. Then what should I use? My goal is avoiding calls to DB for every
row, only calling with really updated rows.
I have them inside dataTable, but for making it simpler, I'll use just one
field in this code excerpt. On the page:

                      <t:inputText value="#{order.orderDate}"
valueChangeListener="#{customers.orderChanged}" id="orderDate">
                            <f:convertDateTime type="date"
dateStyle="default" timeZone="EST"/>
                      </t:inputText>

After placing some System.out in UIInput.validate() as follows:

    public void validate(FacesContext context)
    {
        if (context == null) throw new NullPointerException("context");
        Object submittedValue = getSubmittedValue();
        System.out.println("...validate: submittedValue: "+submittedValue);
        if (submittedValue == null) return;

        Object convertedValue = getConvertedValue(context, submittedValue);

        if (!isValid()) return;

        validateValue(context, convertedValue);

        if (!isValid()) return;

        Object previousValue = getValue();
        System.out.println("...validate: previousValue: "+previousValue+ "
convertedValue: "+convertedValue);
        setValue(convertedValue);
        setSubmittedValue(null);
        if (compareValues(previousValue, convertedValue))
        {
            queueEvent(new ValueChangeEvent(this, previousValue,
convertedValue));
        }
    }

I see in my log:

...validate: submittedValue: Jan 2, 2007
...validate: previousValue: 2007-01-02 00:00:00.0 convertedValue: Tue Jan 02
00:00:00 EST 2007

And as a result I'm gettin the valueChange Event.

thanks
vlad

On 7/7/07, Andrew Robinson <an...@gmail.com> wrote:
>
> I you change a component's code and that component is reusable, then
> you will affect its behavior everywhere you use it. That was all I was
> saying.
>
> In terms of affecting the value change event for one component on a
> page, it wouldn't hurt anything that I am aware of. Most of the time
> valueChangeEvents are not used.
>
> On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > You've lost me. What you mean by 'Depends on who is listening for the
> > events'? I thought - #{myBean.someMethod} is.
> > Am I missing something?
> >
> > And there is no garantee from introducing a bug with any new code - this
> is
> > our life. Testing is always a part of dev. But how is it relevant to
> what
> > we're discussing?
> >
> > vlad
> >
> >
> > On 7/7/07, Andrew Robinson <an...@gmail.com> wrote:
> > > Depends on who is listening for the events. Can you guarantee that
> > > there will be no bugs in your code from doing this?
> > >
> > > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > Andrew,
> > > > could you give me an example (use case) when I'm sending out a null
> > value,
> > > > then on submit get "" back, and there is any harm of stopping
> > > > valueChangeEvent from being fired.
> > > >
> > > > I can't come up with one.
> > > >
> > > > Sure, I may write some logic or a converter wraper in order to
> prevent
> > this
> > > > unwanted event, I just was pointing to the fact that I was expected
> this
> > > > from non altered framework.
> > > >
> > > > vlad
> > > >
> > > > On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > > > > null has a special meaning, and thus why null != "" in terms of
> > > > > UIInput. Null means that the value was not submitted at all. ""
> means
> > > > > the value was submitted with no value. Thus why you need to
> convert ""
> > > > > to null if that is what you wish. If the renderer converted "" to
> > > > > null, then there would never be an update of the model.
> > > > >
> > > > > If you want, write a chain converter or a converter wrapper that
> > > > > converts "" to null.
> > > > >
> > > > > It may look like:
> > > > >
> > > > > <h:inputText ...>
> > > > > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer " />
> > > > > </h:inputText>
> > > > >
> > > > > then you can first check for "" and convert it to null, and if
> not,
> > > > > delegate the check to the "inner converter"
> > > > >
> > > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > > Although null and date are two separate issues, but I'm gettin
> the
> > > > picture.
> > > > > > I may create my own converters and attach them to all my fields
> as
> > I'm
> > > > > > pleased.  But I'm trying to have some common services (if
> thay're
> > > > missing in
> > > > > > the framework) in a single place, well this may be arguable
> what's
> > > > better.
> > > > > > Sorry for annoyance, but still, why JSF would not check for
> nulls
> > for me
> > > > > > (you've pointed the right method to be changed).
> > > > > >
> > > > > > With the date conversion I'll postpone the issue, I have to
> spend
> > more
> > > > time
> > > > > > tracing it.
> > > > > >
> > > > > > vlad
> > > > >
> > > >
> > > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
I you change a component's code and that component is reusable, then
you will affect its behavior everywhere you use it. That was all I was
saying.

In terms of affecting the value change event for one component on a
page, it wouldn't hurt anything that I am aware of. Most of the time
valueChangeEvents are not used.

On 7/7/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> You've lost me. What you mean by 'Depends on who is listening for the
> events'? I thought - #{myBean.someMethod} is.
> Am I missing something?
>
> And there is no garantee from introducing a bug with any new code - this is
> our life. Testing is always a part of dev. But how is it relevant to what
> we're discussing?
>
> vlad
>
>
> On 7/7/07, Andrew Robinson <an...@gmail.com> wrote:
> > Depends on who is listening for the events. Can you guarantee that
> > there will be no bugs in your code from doing this?
> >
> > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > Andrew,
> > > could you give me an example (use case) when I'm sending out a null
> value,
> > > then on submit get "" back, and there is any harm of stopping
> > > valueChangeEvent from being fired.
> > >
> > > I can't come up with one.
> > >
> > > Sure, I may write some logic or a converter wraper in order to prevent
> this
> > > unwanted event, I just was pointing to the fact that I was expected this
> > > from non altered framework.
> > >
> > > vlad
> > >
> > > On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > > > null has a special meaning, and thus why null != "" in terms of
> > > > UIInput. Null means that the value was not submitted at all. "" means
> > > > the value was submitted with no value. Thus why you need to convert ""
> > > > to null if that is what you wish. If the renderer converted "" to
> > > > null, then there would never be an update of the model.
> > > >
> > > > If you want, write a chain converter or a converter wrapper that
> > > > converts "" to null.
> > > >
> > > > It may look like:
> > > >
> > > > <h:inputText ...>
> > > > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer " />
> > > > </h:inputText>
> > > >
> > > > then you can first check for "" and convert it to null, and if not,
> > > > delegate the check to the "inner converter"
> > > >
> > > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > > Although null and date are two separate issues, but I'm gettin the
> > > picture.
> > > > > I may create my own converters and attach them to all my fields as
> I'm
> > > > > pleased.  But I'm trying to have some common services (if thay're
> > > missing in
> > > > > the framework) in a single place, well this may be arguable what's
> > > better.
> > > > > Sorry for annoyance, but still, why JSF would not check for nulls
> for me
> > > > > (you've pointed the right method to be changed).
> > > > >
> > > > > With the date conversion I'll postpone the issue, I have to spend
> more
> > > time
> > > > > tracing it.
> > > > >
> > > > > vlad
> > > >
> > >
> > >
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
You've lost me. What you mean by 'Depends on who is listening for the
events'? I thought - #{myBean.someMethod} is.
Am I missing something?

And there is no garantee from introducing a bug with any new code - this is
our life. Testing is always a part of dev. But how is it relevant to what
we're discussing?

vlad

On 7/7/07, Andrew Robinson <an...@gmail.com> wrote:
>
> Depends on who is listening for the events. Can you guarantee that
> there will be no bugs in your code from doing this?
>
> On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Andrew,
> > could you give me an example (use case) when I'm sending out a null
> value,
> > then on submit get "" back, and there is any harm of stopping
> > valueChangeEvent from being fired.
> >
> > I can't come up with one.
> >
> > Sure, I may write some logic or a converter wraper in order to prevent
> this
> > unwanted event, I just was pointing to the fact that I was expected this
> > from non altered framework.
> >
> > vlad
> >
> > On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > > null has a special meaning, and thus why null != "" in terms of
> > > UIInput. Null means that the value was not submitted at all. "" means
> > > the value was submitted with no value. Thus why you need to convert ""
> > > to null if that is what you wish. If the renderer converted "" to
> > > null, then there would never be an update of the model.
> > >
> > > If you want, write a chain converter or a converter wrapper that
> > > converts "" to null.
> > >
> > > It may look like:
> > >
> > > <h:inputText ...>
> > > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer " />
> > > </h:inputText>
> > >
> > > then you can first check for "" and convert it to null, and if not,
> > > delegate the check to the "inner converter"
> > >
> > > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > > Although null and date are two separate issues, but I'm gettin the
> > picture.
> > > > I may create my own converters and attach them to all my fields as
> I'm
> > > > pleased.  But I'm trying to have some common services (if thay're
> > missing in
> > > > the framework) in a single place, well this may be arguable what's
> > better.
> > > > Sorry for annoyance, but still, why JSF would not check for nulls
> for me
> > > > (you've pointed the right method to be changed).
> > > >
> > > > With the date conversion I'll postpone the issue, I have to spend
> more
> > time
> > > > tracing it.
> > > >
> > > > vlad
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
Depends on who is listening for the events. Can you guarantee that
there will be no bugs in your code from doing this?

On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Andrew,
> could you give me an example (use case) when I'm sending out a null value,
> then on submit get "" back, and there is any harm of stopping
> valueChangeEvent from being fired.
>
> I can't come up with one.
>
> Sure, I may write some logic or a converter wraper in order to prevent this
> unwanted event, I just was pointing to the fact that I was expected this
> from non altered framework.
>
> vlad
>
> On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > null has a special meaning, and thus why null != "" in terms of
> > UIInput. Null means that the value was not submitted at all. "" means
> > the value was submitted with no value. Thus why you need to convert ""
> > to null if that is what you wish. If the renderer converted "" to
> > null, then there would never be an update of the model.
> >
> > If you want, write a chain converter or a converter wrapper that
> > converts "" to null.
> >
> > It may look like:
> >
> > <h:inputText ...>
> > <my:emptyToNullConverter wrapConverterId="javax.faces.Integer " />
> > </h:inputText>
> >
> > then you can first check for "" and convert it to null, and if not,
> > delegate the check to the "inner converter"
> >
> > On 7/6/07, Vladimir Isakovich < ivlad10@gmail.com> wrote:
> > > Although null and date are two separate issues, but I'm gettin the
> picture.
> > > I may create my own converters and attach them to all my fields as I'm
> > > pleased.  But I'm trying to have some common services (if thay're
> missing in
> > > the framework) in a single place, well this may be arguable what's
> better.
> > > Sorry for annoyance, but still, why JSF would not check for nulls for me
> > > (you've pointed the right method to be changed).
> > >
> > > With the date conversion I'll postpone the issue, I have to spend more
> time
> > > tracing it.
> > >
> > > vlad
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Andrew,
could you give me an example (use case) when I'm sending out a null
value, then on submit get "" back, and there is any harm of stopping
valueChangeEvent from being fired.

I can't come up with one.

Sure, I may write some logic or a converter wraper in order to prevent this
unwanted event, I just was pointing to the fact that I was expected this
from non altered framework.

vlad

On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
>
> null has a special meaning, and thus why null != "" in terms of
> UIInput. Null means that the value was not submitted at all. "" means
> the value was submitted with no value. Thus why you need to convert ""
> to null if that is what you wish. If the renderer converted "" to
> null, then there would never be an update of the model.
>
> If you want, write a chain converter or a converter wrapper that
> converts "" to null.
>
> It may look like:
>
> <h:inputText ...>
> <my:emptyToNullConverter wrapConverterId="javax.faces.Integer" />
> </h:inputText>
>
> then you can first check for "" and convert it to null, and if not,
> delegate the check to the "inner converter"
>
> On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Although null and date are two separate issues, but I'm gettin the
> picture.
> > I may create my own converters and attach them to all my fields as I'm
> > pleased.  But I'm trying to have some common services (if thay're
> missing in
> > the framework) in a single place, well this may be arguable what's
> better.
> > Sorry for annoyance, but still, why JSF would not check for nulls for me
> > (you've pointed the right method to be changed).
> >
> > With the date conversion I'll postpone the issue, I have to spend more
> time
> > tracing it.
> >
> > vlad
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
null has a special meaning, and thus why null != "" in terms of
UIInput. Null means that the value was not submitted at all. "" means
the value was submitted with no value. Thus why you need to convert ""
to null if that is what you wish. If the renderer converted "" to
null, then there would never be an update of the model.

If you want, write a chain converter or a converter wrapper that
converts "" to null.

It may look like:

<h:inputText ...>
  <my:emptyToNullConverter wrapConverterId="javax.faces.Integer" />
</h:inputText>

then you can first check for "" and convert it to null, and if not,
delegate the check to the "inner converter"

On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Although null and date are two separate issues, but I'm gettin the picture.
> I may create my own converters and attach them to all my fields as I'm
> pleased.  But I'm trying to have some common services (if thay're missing in
> the framework) in a single place, well this may be arguable what's better.
> Sorry for annoyance, but still, why JSF would not check for nulls for me
> (you've pointed the right method to be changed).
>
> With the date conversion I'll postpone the issue, I have to spend more time
> tracing it.
>
> vlad

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Although null and date are two separate issues, but I'm gettin the picture.
I may create my own converters and attach them to all my fields as I'm
pleased.  But I'm trying to have some common services (if thay're missing in
the framework) in a single place, well this may be arguable what's better.
Sorry for annoyance, but still, why JSF would not check for nulls for me
(you've pointed the right method to be changed).

With the date conversion I'll postpone the issue, I have to spend more time
tracing it.

vlad

On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
>
> Convert an empty string in your converter to null. That way if the
> Date is null in the bean, the converter will convert the empty string
> to null, and since both will be null, you will get no change event.
>
> -Andrew
>
> On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Andrew,
> > thanks for pointing to the source. Aparently this is the exact place.
> >
> > Now I guess (sorry for guessing, I should take more time and learn the
> code)
> > getSubmittedValue() never returns null, the request parameter values
> > submitted from a page are never nulls; empty strings at the most.
> > So, should not this method convert them into nulls?
> >
> > Also, I clearly see here the call to getConvertedValue(context,
> > submittedValue), and just wonder why I am getting valueChangeEvent fired
> for
> > every date on my screen, when they are not changed. ( java.util.Date in
> > pojo)
> > I'm displaying oldValue/newValue from the event (toString of cause) and
> they
> > look different
> >
> >
> > vlad
> >
> > On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > > Best way to answer this is to point you to the UIInput code:
> > >
> > > public void validate(FacesContext context) {
> > > ...
> > > Object submittedValue = getSubmittedValue();
> > > if (submittedValue == null) return;
> > > Object convertedValue = getConvertedValue(context, submittedValue);
> > > ...
> > > Object previousValue = getValue();
> > > setValue(convertedValue);
> > > setSubmittedValue(null);
> > > if (compareValues(previousValue, convertedValue))
> > > {
> > >    queueEvent(new ValueChangeEvent(this, previousValue,
> convertedValue));
> > > }
> > > ...
> > > protected boolean compareValues(Object previous,
> > > Object value)
> > > {
> > > return
> > previous==null?(value!=null):(!previous.equals(value));
> > > }
> > >
> > > So, as you can see the value change event is generated if the
> > > component's "getValue()" returns an object that is not equal to the
> > > converted submitted value.
> > >
> > >
> > >
> > > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > Andrew,
> > > > Are you saying that if in the method called by valueChangeListener I
> > take:
> > > > event.getOldValue() - it's not the same as my 'original value' in my
> > pojo?
> > > > It's alredy has been converted from say Integer to String?
> > > >
> > > > The poin I'm trying to make is why I should add another layer of
> > protection
> > > > against valueChangeEvent, when it could be done in JSF.
> > > >
> > > > Also in your example: String str = converter.getAsString(value);
> > > > JSF API want
> > > > converter.getAsString(FacesContext,UIComponent,value).
> > > > Do you know why it needs two additional args, is it gonna plug this
> > value
> > > > into the component and then attach this component to the tree?
> > > >
> > > > I've just wrote this code for bloking the unwanted valueChangeEvent,
> but
> > > > have not tested it yet. I was the above mentioned getAsString(), but
> > with
> > > > the only purpose of getting converted value - not updating the tree.
> > > >
> > > >
> > > >
> > > >     public static boolean isValueChanged(ValueChangeEvent event) {
> > > >         if (event.getOldValue() == null) {
> > > >             if (StringUtils.isEmpty(event.getNewValue().toString()))
> > > >                 return false;
> > > >             else
> > > >                 return true;
> > > >         }
> > > >
> > > >         UIInput comp = (UIInput)event.getComponent();
> > > >         Converter conv = comp.getConverter();
> > > >         if (conv == null) {
> > > >             if
> > > > (event.getOldValue ().toString().equals(event.getNewValue
> ().toString()))
> > > >                 return false;
> > > >             else
> > > >                 return true;
> > > >         } else {
> > > >             Object oldVal =
> > > >                 conv.getAsString(FacesContext.getCurrentInstance(),
> > comp,
> > > >                                  event.getOldValue());
> > > >             if (oldVal.equals(event.getNewValue()))
> > > >                 return false;
> > > >             else
> > > >                 return true;
> > > >         }
> > > >     }
> > > >
> > > > vlad
> > > >
> > > >
> > > > On 7/6/07, Andrew Robinson <andrew.rw.robinson@gmail.com > wrote:
> > > > > The original value is already converted by specification. The
> purpose
> > > > > of a converter is to take an object from the back-end and change
> it to
> > > > > a view (HTML typically) compatible value and then change the view
> > > > > value back to a back-end value on submit.
> > > > >
> > > > > It is the back-end developer's job to ensure the back-end value is
> > > > > "converted". If you want the original value to be converted using
> a
> > > > > JSF converter, then use the Application object to create a
> converter
> > > > > from you backing bean when you load the data, and convert the
> value as
> > > > > you wish.
> > > > >
> > > > > The purpose of the value change event is to tell you if the user
> > > > > changed something. The user changed something if the value they
> submit
> > > > > after conversion is not the same as the value from the back-end.
> > > > >
> > > > > You keep saying "converted original value", but that is an
> oxymoron by
> > > > > JSF definition. If my component is a number input field, the
> converted
> > > > > value is type Integer and the client value is type String. So the
> > > > > converter converts between string and integer, not integer and
> > > > > integer.
> > > > >
> > > > > To be even more precise, for a converter to work properly the
> > > > > following must be true:
> > > > >
> > > > > Converter converter = ...
> > > > > Object value = component.getValue();
> > > > > String str = converter.getAsString(value);
> > > > > Object value2 = converter.getAsObject(str);
> > > > > if (value2.equals(value)) {
> > > > > // converter is valid
> > > > > }
> > > > >
> > > > > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > > > Null vs empty string is not the only one case, the point I'm
> trying
> > to
> > > > make
> > > > > > here:
> > > > > > whenever the JSF framework is applying some data conversion
> (either
> > the
> > > > > > converter was explicitly declared or not), it may (should)
> remember
> > that
> > > > > > conversion rule, so that when that same page is submitted, the
> > framework
> > > > (I
> > > > > > mean JSF) will compare ( for the purpose of firing
> changeValueEvent)
> > not
> > > > the
> > > > > > original value with the new value but the converted original
> value
> > with
> > > > the
> > > > > > new value.
> > > > > >
> > > > > > Yes this is an old issue with all previous frameworks, but I
> thought
> > JSF
> > > > > > could be better. And thinking of the declared converters, cann't
> I
> > find
> > > > all
> > > > > > converters for a given UIComponent using JSF API. I did not try
> but
> > I
> > > > > > thought it's doable.
> > > > > >
> > > > > > vlad
> > > > > >
> > > > > >
> > > > > > On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
> > > > > > > The problem you are experiencing is true for any Java/Web
> > > > > > > framework.  An HTTP request parameter does not understand
> > > > > > > what a Java null is but always uses the empty string "".  So
> > > > > > > somewhere in your application (or framework) you have to
> > > > > > > handle the conversion from "" to null.
> > > > > > >
> > > > > > > When it comes to String values, null is not the same as ""
> > > > > > > so I would recommend that your backing beans be populated
> > > > > > > with "" instead of null when dealing with JSF.  Alternatively,
> > > > > > > you could create a NullStringConverter which converts from
> > > > > > > "" to null.
> > > > > > >
> > > > > > > When it comes to non-String values, then your converter should
> > > > > > > return null from the getAsObject method when an "" is the
> > > > > > > request parameter.
> > > > > > >
> > > > > > > -Bryan
> > > > > > >
> > > > > > > vlad10 wrote:
> > > > > > > > I'm fresh with JSF,
> > > > > > > > just started building some prototypes with facelets 1.1.11 ,
> > myfaces
> > > > > > > > 1.1.3/tomahawk 1.1.3.
> > > > > > > >
> > > > > > > > I'm getting this general feeling that the framework is
> missing
> > some
> > > > > > > > important feature.
> > > > > > > > I may create an inputText and populate it with a null value,
> the
> > > > > > framework
> > > > > > > > conviniently will convert it into an empty string and
> populate
> > my
> > > > page.
> > > > > > > > However, on submit the valueChangeListener will fire with
> the
> > reason
> > > > > > that
> > > > > > > > null is not the same as an empty string.
> > > > > > > > I have another example. This the initial value is not null.
> I
> > may
> > > > > > explicitly
> > > > > > > > add a converter to that field, so the value stored in POJO
> as
> > > > > > jva.util.Date
> > > > > > > > or as a BigDecimal or anything else will be nicely displayed
> on
> > the
> > > > > > screen,
> > > > > > > > but I'll face again the unwanted behavior of my
> > valueChangeListener.
> > > > > > > > For the time being, I'm trying to compensate this deficiency
> in
> > my
> > > > app
> > > > > > by
> > > > > > > > adding some filtering in a utility class. At the moment it's
> in
> > the
> > > > > > > > beginning, just checking null/empty string case:
> > > > > > > >
> > > > > > > >     /**
> > > > > > > >      * UIInput value is never null when submitted, but the
> POJO
> > is
> > > > > > always
> > > > > > > >      * initialized with nulls. This creates a false alarm by
> > > > > > > > valueChangeListeners.
> > > > > > > >      * This method tries to compensate this deficiency.
> > > > > > > >      * @param input
> > > > > > > >      * @param rec
> > > > > > > >      * @return
> > > > > > > >      */
> > > > > > > >     public static boolean isValueChanged(UIInput input,
> Object
> > pojo)
> > > > {
> > > > > > > >         String name = input.getId();
> > > > > > > >         Object val = BeanUtil.getBeanValue (pojo,name);
> > > > > > > >         if (val == null)
> > > > > > > >             if(
> > StringUtils.isEmpty(input.getValue().toString()))
> > > > > > > >                 return false;
> > > > > > > >             else
> > > > > > > >                 return true;
> > > > > > > >         return (
> > > > input.getValue().toString().compareTo(val.toString())
> > > > > > != 0);
> > > > > > > >     }
> > > > > > > >
> > > > > > > > My question: am I missing something????
> > > > > > > > Do I really need to add another layer in my app, I may call
> it
> > > > something
> > > > > > > > like JSF Frendly POJOs. I may perform all necessary
> conversions
> > > > right
> > > > > > there
> > > > > > > > when moving data from DB to the screen, and then on submit
> > perform
> > > > the
> > > > > > > > opposit conversion when moving data back. I hope I can avoid
> > that.
> > > > > > > > Is not it possible for a framework to 'remember' not just an
> > > > oldValue,
> > > > > > but
> > > > > > > > also the conversion performed, so prior to comparing old/new
> > values
> > > > it
> > > > > > would
> > > > > > > > apply that same converter to the old value???
> > > > > > > > I think, this part has been missed.
> > > > > > > >
> > > > > > > > thanks
> > > > > > > > vlad
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
Convert an empty string in your converter to null. That way if the
Date is null in the bean, the converter will convert the empty string
to null, and since both will be null, you will get no change event.

-Andrew

On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Andrew,
> thanks for pointing to the source. Aparently this is the exact place.
>
> Now I guess (sorry for guessing, I should take more time and learn the code)
> getSubmittedValue() never returns null, the request parameter values
> submitted from a page are never nulls; empty strings at the most.
> So, should not this method convert them into nulls?
>
> Also, I clearly see here the call to getConvertedValue(context,
> submittedValue), and just wonder why I am getting valueChangeEvent fired for
> every date on my screen, when they are not changed. ( java.util.Date in
> pojo)
> I'm displaying oldValue/newValue from the event (toString of cause) and they
> look different
>
>
> vlad
>
> On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > Best way to answer this is to point you to the UIInput code:
> >
> > public void validate(FacesContext context) {
> > ...
> > Object submittedValue = getSubmittedValue();
> > if (submittedValue == null) return;
> > Object convertedValue = getConvertedValue(context, submittedValue);
> > ...
> > Object previousValue = getValue();
> > setValue(convertedValue);
> > setSubmittedValue(null);
> > if (compareValues(previousValue, convertedValue))
> > {
> >    queueEvent(new ValueChangeEvent(this, previousValue, convertedValue));
> > }
> > ...
> > protected boolean compareValues(Object previous,
> > Object value)
> > {
> > return
> previous==null?(value!=null):(!previous.equals(value));
> > }
> >
> > So, as you can see the value change event is generated if the
> > component's "getValue()" returns an object that is not equal to the
> > converted submitted value.
> >
> >
> >
> > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > Andrew,
> > > Are you saying that if in the method called by valueChangeListener I
> take:
> > > event.getOldValue() - it's not the same as my 'original value' in my
> pojo?
> > > It's alredy has been converted from say Integer to String?
> > >
> > > The poin I'm trying to make is why I should add another layer of
> protection
> > > against valueChangeEvent, when it could be done in JSF.
> > >
> > > Also in your example: String str = converter.getAsString(value);
> > > JSF API want
> > > converter.getAsString(FacesContext,UIComponent,value).
> > > Do you know why it needs two additional args, is it gonna plug this
> value
> > > into the component and then attach this component to the tree?
> > >
> > > I've just wrote this code for bloking the unwanted valueChangeEvent, but
> > > have not tested it yet. I was the above mentioned getAsString(), but
> with
> > > the only purpose of getting converted value - not updating the tree.
> > >
> > >
> > >
> > >     public static boolean isValueChanged(ValueChangeEvent event) {
> > >         if (event.getOldValue() == null) {
> > >             if (StringUtils.isEmpty(event.getNewValue().toString()))
> > >                 return false;
> > >             else
> > >                 return true;
> > >         }
> > >
> > >         UIInput comp = (UIInput)event.getComponent();
> > >         Converter conv = comp.getConverter();
> > >         if (conv == null) {
> > >             if
> > > (event.getOldValue ().toString().equals(event.getNewValue().toString()))
> > >                 return false;
> > >             else
> > >                 return true;
> > >         } else {
> > >             Object oldVal =
> > >                 conv.getAsString(FacesContext.getCurrentInstance(),
> comp,
> > >                                  event.getOldValue());
> > >             if (oldVal.equals(event.getNewValue()))
> > >                 return false;
> > >             else
> > >                 return true;
> > >         }
> > >     }
> > >
> > > vlad
> > >
> > >
> > > On 7/6/07, Andrew Robinson <andrew.rw.robinson@gmail.com > wrote:
> > > > The original value is already converted by specification. The purpose
> > > > of a converter is to take an object from the back-end and change it to
> > > > a view (HTML typically) compatible value and then change the view
> > > > value back to a back-end value on submit.
> > > >
> > > > It is the back-end developer's job to ensure the back-end value is
> > > > "converted". If you want the original value to be converted using a
> > > > JSF converter, then use the Application object to create a converter
> > > > from you backing bean when you load the data, and convert the value as
> > > > you wish.
> > > >
> > > > The purpose of the value change event is to tell you if the user
> > > > changed something. The user changed something if the value they submit
> > > > after conversion is not the same as the value from the back-end.
> > > >
> > > > You keep saying "converted original value", but that is an oxymoron by
> > > > JSF definition. If my component is a number input field, the converted
> > > > value is type Integer and the client value is type String. So the
> > > > converter converts between string and integer, not integer and
> > > > integer.
> > > >
> > > > To be even more precise, for a converter to work properly the
> > > > following must be true:
> > > >
> > > > Converter converter = ...
> > > > Object value = component.getValue();
> > > > String str = converter.getAsString(value);
> > > > Object value2 = converter.getAsObject(str);
> > > > if (value2.equals(value)) {
> > > > // converter is valid
> > > > }
> > > >
> > > > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > > Null vs empty string is not the only one case, the point I'm trying
> to
> > > make
> > > > > here:
> > > > > whenever the JSF framework is applying some data conversion (either
> the
> > > > > converter was explicitly declared or not), it may (should) remember
> that
> > > > > conversion rule, so that when that same page is submitted, the
> framework
> > > (I
> > > > > mean JSF) will compare ( for the purpose of firing changeValueEvent)
> not
> > > the
> > > > > original value with the new value but the converted original value
> with
> > > the
> > > > > new value.
> > > > >
> > > > > Yes this is an old issue with all previous frameworks, but I thought
> JSF
> > > > > could be better. And thinking of the declared converters, cann't I
> find
> > > all
> > > > > converters for a given UIComponent using JSF API. I did not try but
> I
> > > > > thought it's doable.
> > > > >
> > > > > vlad
> > > > >
> > > > >
> > > > > On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
> > > > > > The problem you are experiencing is true for any Java/Web
> > > > > > framework.  An HTTP request parameter does not understand
> > > > > > what a Java null is but always uses the empty string "".  So
> > > > > > somewhere in your application (or framework) you have to
> > > > > > handle the conversion from "" to null.
> > > > > >
> > > > > > When it comes to String values, null is not the same as ""
> > > > > > so I would recommend that your backing beans be populated
> > > > > > with "" instead of null when dealing with JSF.  Alternatively,
> > > > > > you could create a NullStringConverter which converts from
> > > > > > "" to null.
> > > > > >
> > > > > > When it comes to non-String values, then your converter should
> > > > > > return null from the getAsObject method when an "" is the
> > > > > > request parameter.
> > > > > >
> > > > > > -Bryan
> > > > > >
> > > > > > vlad10 wrote:
> > > > > > > I'm fresh with JSF,
> > > > > > > just started building some prototypes with facelets 1.1.11 ,
> myfaces
> > > > > > > 1.1.3/tomahawk 1.1.3.
> > > > > > >
> > > > > > > I'm getting this general feeling that the framework is missing
> some
> > > > > > > important feature.
> > > > > > > I may create an inputText and populate it with a null value, the
> > > > > framework
> > > > > > > conviniently will convert it into an empty string and populate
> my
> > > page.
> > > > > > > However, on submit the valueChangeListener will fire with the
> reason
> > > > > that
> > > > > > > null is not the same as an empty string.
> > > > > > > I have another example. This the initial value is not null. I
> may
> > > > > explicitly
> > > > > > > add a converter to that field, so the value stored in POJO as
> > > > > jva.util.Date
> > > > > > > or as a BigDecimal or anything else will be nicely displayed on
> the
> > > > > screen,
> > > > > > > but I'll face again the unwanted behavior of my
> valueChangeListener.
> > > > > > > For the time being, I'm trying to compensate this deficiency in
> my
> > > app
> > > > > by
> > > > > > > adding some filtering in a utility class. At the moment it's in
> the
> > > > > > > beginning, just checking null/empty string case:
> > > > > > >
> > > > > > >     /**
> > > > > > >      * UIInput value is never null when submitted, but the POJO
> is
> > > > > always
> > > > > > >      * initialized with nulls. This creates a false alarm by
> > > > > > > valueChangeListeners.
> > > > > > >      * This method tries to compensate this deficiency.
> > > > > > >      * @param input
> > > > > > >      * @param rec
> > > > > > >      * @return
> > > > > > >      */
> > > > > > >     public static boolean isValueChanged(UIInput input, Object
> pojo)
> > > {
> > > > > > >         String name = input.getId();
> > > > > > >         Object val = BeanUtil.getBeanValue (pojo,name);
> > > > > > >         if (val == null)
> > > > > > >             if(
> StringUtils.isEmpty(input.getValue().toString()))
> > > > > > >                 return false;
> > > > > > >             else
> > > > > > >                 return true;
> > > > > > >         return (
> > > input.getValue().toString().compareTo(val.toString())
> > > > > != 0);
> > > > > > >     }
> > > > > > >
> > > > > > > My question: am I missing something????
> > > > > > > Do I really need to add another layer in my app, I may call it
> > > something
> > > > > > > like JSF Frendly POJOs. I may perform all necessary conversions
> > > right
> > > > > there
> > > > > > > when moving data from DB to the screen, and then on submit
> perform
> > > the
> > > > > > > opposit conversion when moving data back. I hope I can avoid
> that.
> > > > > > > Is not it possible for a framework to 'remember' not just an
> > > oldValue,
> > > > > but
> > > > > > > also the conversion performed, so prior to comparing old/new
> values
> > > it
> > > > > would
> > > > > > > apply that same converter to the old value???
> > > > > > > I think, this part has been missed.
> > > > > > >
> > > > > > > thanks
> > > > > > > vlad
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Andrew,
thanks for pointing to the source. Aparently this is the exact place.

Now I guess (sorry for guessing, I should take more time and learn the code)
getSubmittedValue() never returns null, the request parameter values
submitted from a page are never nulls; empty strings at the most.
So, should not this method convert them into nulls?

Also, I clearly see here the call to getConvertedValue(context,
submittedValue), and just wonder why I am getting valueChangeEvent fired for
every date on my screen, when they are not changed. (java.util.Date in pojo)
I'm displaying oldValue/newValue from the event (toString of cause) and they
look different

vlad

On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
>
> Best way to answer this is to point you to the UIInput code:
>
> public void validate(FacesContext context) {
> ...
> Object submittedValue = getSubmittedValue();
> if (submittedValue == null) return;
> Object convertedValue = getConvertedValue(context, submittedValue);
> ...
> Object previousValue = getValue();
> setValue(convertedValue);
> setSubmittedValue(null);
> if (compareValues(previousValue, convertedValue))
> {
>    queueEvent(new ValueChangeEvent(this, previousValue, convertedValue));
> }
> ...
> protected boolean compareValues(Object previous,
> Object value)
> {
> return previous==null?(value!=null):(!previous.equals(value));
> }
>
> So, as you can see the value change event is generated if the
> component's "getValue()" returns an object that is not equal to the
> converted submitted value.
>
>
>
> On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Andrew,
> > Are you saying that if in the method called by valueChangeListener I
> take:
> > event.getOldValue() - it's not the same as my 'original value' in my
> pojo?
> > It's alredy has been converted from say Integer to String?
> >
> > The poin I'm trying to make is why I should add another layer of
> protection
> > against valueChangeEvent, when it could be done in JSF.
> >
> > Also in your example: String str = converter.getAsString(value);
> > JSF API want
> > converter.getAsString(FacesContext,UIComponent,value).
> > Do you know why it needs two additional args, is it gonna plug this
> value
> > into the component and then attach this component to the tree?
> >
> > I've just wrote this code for bloking the unwanted valueChangeEvent, but
> > have not tested it yet. I was the above mentioned getAsString(), but
> with
> > the only purpose of getting converted value - not updating the tree.
> >
> >
> >
> >     public static boolean isValueChanged(ValueChangeEvent event) {
> >         if (event.getOldValue() == null) {
> >             if (StringUtils.isEmpty(event.getNewValue().toString()))
> >                 return false;
> >             else
> >                 return true;
> >         }
> >
> >         UIInput comp = (UIInput)event.getComponent();
> >         Converter conv = comp.getConverter();
> >         if (conv == null) {
> >             if
> > (event.getOldValue().toString().equals(event.getNewValue().toString()))
> >                 return false;
> >             else
> >                 return true;
> >         } else {
> >             Object oldVal =
> >                 conv.getAsString(FacesContext.getCurrentInstance(),
> comp,
> >                                  event.getOldValue());
> >             if (oldVal.equals(event.getNewValue()))
> >                 return false;
> >             else
> >                 return true;
> >         }
> >     }
> >
> > vlad
> >
> >
> > On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > > The original value is already converted by specification. The purpose
> > > of a converter is to take an object from the back-end and change it to
> > > a view (HTML typically) compatible value and then change the view
> > > value back to a back-end value on submit.
> > >
> > > It is the back-end developer's job to ensure the back-end value is
> > > "converted". If you want the original value to be converted using a
> > > JSF converter, then use the Application object to create a converter
> > > from you backing bean when you load the data, and convert the value as
> > > you wish.
> > >
> > > The purpose of the value change event is to tell you if the user
> > > changed something. The user changed something if the value they submit
> > > after conversion is not the same as the value from the back-end.
> > >
> > > You keep saying "converted original value", but that is an oxymoron by
> > > JSF definition. If my component is a number input field, the converted
> > > value is type Integer and the client value is type String. So the
> > > converter converts between string and integer, not integer and
> > > integer.
> > >
> > > To be even more precise, for a converter to work properly the
> > > following must be true:
> > >
> > > Converter converter = ...
> > > Object value = component.getValue();
> > > String str = converter.getAsString(value);
> > > Object value2 = converter.getAsObject(str);
> > > if (value2.equals(value)) {
> > > // converter is valid
> > > }
> > >
> > > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > > Null vs empty string is not the only one case, the point I'm trying
> to
> > make
> > > > here:
> > > > whenever the JSF framework is applying some data conversion (either
> the
> > > > converter was explicitly declared or not), it may (should) remember
> that
> > > > conversion rule, so that when that same page is submitted, the
> framework
> > (I
> > > > mean JSF) will compare ( for the purpose of firing changeValueEvent)
> not
> > the
> > > > original value with the new value but the converted original value
> with
> > the
> > > > new value.
> > > >
> > > > Yes this is an old issue with all previous frameworks, but I thought
> JSF
> > > > could be better. And thinking of the declared converters, cann't I
> find
> > all
> > > > converters for a given UIComponent using JSF API. I did not try but
> I
> > > > thought it's doable.
> > > >
> > > > vlad
> > > >
> > > >
> > > > On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
> > > > > The problem you are experiencing is true for any Java/Web
> > > > > framework.  An HTTP request parameter does not understand
> > > > > what a Java null is but always uses the empty string "".  So
> > > > > somewhere in your application (or framework) you have to
> > > > > handle the conversion from "" to null.
> > > > >
> > > > > When it comes to String values, null is not the same as ""
> > > > > so I would recommend that your backing beans be populated
> > > > > with "" instead of null when dealing with JSF.  Alternatively,
> > > > > you could create a NullStringConverter which converts from
> > > > > "" to null.
> > > > >
> > > > > When it comes to non-String values, then your converter should
> > > > > return null from the getAsObject method when an "" is the
> > > > > request parameter.
> > > > >
> > > > > -Bryan
> > > > >
> > > > > vlad10 wrote:
> > > > > > I'm fresh with JSF,
> > > > > > just started building some prototypes with facelets 1.1.11 ,
> myfaces
> > > > > > 1.1.3/tomahawk 1.1.3.
> > > > > >
> > > > > > I'm getting this general feeling that the framework is missing
> some
> > > > > > important feature.
> > > > > > I may create an inputText and populate it with a null value, the
> > > > framework
> > > > > > conviniently will convert it into an empty string and populate
> my
> > page.
> > > > > > However, on submit the valueChangeListener will fire with the
> reason
> > > > that
> > > > > > null is not the same as an empty string.
> > > > > > I have another example. This the initial value is not null. I
> may
> > > > explicitly
> > > > > > add a converter to that field, so the value stored in POJO as
> > > > jva.util.Date
> > > > > > or as a BigDecimal or anything else will be nicely displayed on
> the
> > > > screen,
> > > > > > but I'll face again the unwanted behavior of my
> valueChangeListener.
> > > > > > For the time being, I'm trying to compensate this deficiency in
> my
> > app
> > > > by
> > > > > > adding some filtering in a utility class. At the moment it's in
> the
> > > > > > beginning, just checking null/empty string case:
> > > > > >
> > > > > >     /**
> > > > > >      * UIInput value is never null when submitted, but the POJO
> is
> > > > always
> > > > > >      * initialized with nulls. This creates a false alarm by
> > > > > > valueChangeListeners.
> > > > > >      * This method tries to compensate this deficiency.
> > > > > >      * @param input
> > > > > >      * @param rec
> > > > > >      * @return
> > > > > >      */
> > > > > >     public static boolean isValueChanged(UIInput input, Object
> pojo)
> > {
> > > > > >         String name = input.getId();
> > > > > >         Object val = BeanUtil.getBeanValue (pojo,name);
> > > > > >         if (val == null)
> > > > > >             if(StringUtils.isEmpty(input.getValue().toString()))
> > > > > >                 return false;
> > > > > >             else
> > > > > >                 return true;
> > > > > >         return (
> > input.getValue().toString().compareTo(val.toString())
> > > > != 0);
> > > > > >     }
> > > > > >
> > > > > > My question: am I missing something????
> > > > > > Do I really need to add another layer in my app, I may call it
> > something
> > > > > > like JSF Frendly POJOs. I may perform all necessary conversions
> > right
> > > > there
> > > > > > when moving data from DB to the screen, and then on submit
> perform
> > the
> > > > > > opposit conversion when moving data back. I hope I can avoid
> that.
> > > > > > Is not it possible for a framework to 'remember' not just an
> > oldValue,
> > > > but
> > > > > > also the conversion performed, so prior to comparing old/new
> values
> > it
> > > > would
> > > > > > apply that same converter to the old value???
> > > > > > I think, this part has been missed.
> > > > > >
> > > > > > thanks
> > > > > > vlad
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
Best way to answer this is to point you to the UIInput code:

public void validate(FacesContext context) {
...
Object submittedValue = getSubmittedValue();
if (submittedValue == null) return;
Object convertedValue = getConvertedValue(context, submittedValue);
...
Object previousValue = getValue();
setValue(convertedValue);
setSubmittedValue(null);
if (compareValues(previousValue, convertedValue))
{
    queueEvent(new ValueChangeEvent(this, previousValue, convertedValue));
}
...
protected boolean compareValues(Object previous,
Object value)
{
return previous==null?(value!=null):(!previous.equals(value));
}

So, as you can see the value change event is generated if the
component's "getValue()" returns an object that is not equal to the
converted submitted value.



On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Andrew,
> Are you saying that if in the method called by valueChangeListener I take:
> event.getOldValue() - it's not the same as my 'original value' in my pojo?
> It's alredy has been converted from say Integer to String?
>
> The poin I'm trying to make is why I should add another layer of protection
> against valueChangeEvent, when it could be done in JSF.
>
> Also in your example: String str = converter.getAsString(value);
> JSF API want
> converter.getAsString(FacesContext,UIComponent,value).
> Do you know why it needs two additional args, is it gonna plug this value
> into the component and then attach this component to the tree?
>
> I've just wrote this code for bloking the unwanted valueChangeEvent, but
> have not tested it yet. I was the above mentioned getAsString(), but with
> the only purpose of getting converted value - not updating the tree.
>
>
>
>     public static boolean isValueChanged(ValueChangeEvent event) {
>         if (event.getOldValue() == null) {
>             if (StringUtils.isEmpty(event.getNewValue().toString()))
>                 return false;
>             else
>                 return true;
>         }
>
>         UIInput comp = (UIInput)event.getComponent();
>         Converter conv = comp.getConverter();
>         if (conv == null) {
>             if
> (event.getOldValue().toString().equals(event.getNewValue().toString()))
>                 return false;
>             else
>                 return true;
>         } else {
>             Object oldVal =
>                 conv.getAsString(FacesContext.getCurrentInstance(), comp,
>                                  event.getOldValue());
>             if (oldVal.equals(event.getNewValue()))
>                 return false;
>             else
>                 return true;
>         }
>     }
>
> vlad
>
>
> On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
> > The original value is already converted by specification. The purpose
> > of a converter is to take an object from the back-end and change it to
> > a view (HTML typically) compatible value and then change the view
> > value back to a back-end value on submit.
> >
> > It is the back-end developer's job to ensure the back-end value is
> > "converted". If you want the original value to be converted using a
> > JSF converter, then use the Application object to create a converter
> > from you backing bean when you load the data, and convert the value as
> > you wish.
> >
> > The purpose of the value change event is to tell you if the user
> > changed something. The user changed something if the value they submit
> > after conversion is not the same as the value from the back-end.
> >
> > You keep saying "converted original value", but that is an oxymoron by
> > JSF definition. If my component is a number input field, the converted
> > value is type Integer and the client value is type String. So the
> > converter converts between string and integer, not integer and
> > integer.
> >
> > To be even more precise, for a converter to work properly the
> > following must be true:
> >
> > Converter converter = ...
> > Object value = component.getValue();
> > String str = converter.getAsString(value);
> > Object value2 = converter.getAsObject(str);
> > if (value2.equals(value)) {
> > // converter is valid
> > }
> >
> > On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > > Null vs empty string is not the only one case, the point I'm trying to
> make
> > > here:
> > > whenever the JSF framework is applying some data conversion (either the
> > > converter was explicitly declared or not), it may (should) remember that
> > > conversion rule, so that when that same page is submitted, the framework
> (I
> > > mean JSF) will compare ( for the purpose of firing changeValueEvent) not
> the
> > > original value with the new value but the converted original value with
> the
> > > new value.
> > >
> > > Yes this is an old issue with all previous frameworks, but I thought JSF
> > > could be better. And thinking of the declared converters, cann't I find
> all
> > > converters for a given UIComponent using JSF API. I did not try but I
> > > thought it's doable.
> > >
> > > vlad
> > >
> > >
> > > On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
> > > > The problem you are experiencing is true for any Java/Web
> > > > framework.  An HTTP request parameter does not understand
> > > > what a Java null is but always uses the empty string "".  So
> > > > somewhere in your application (or framework) you have to
> > > > handle the conversion from "" to null.
> > > >
> > > > When it comes to String values, null is not the same as ""
> > > > so I would recommend that your backing beans be populated
> > > > with "" instead of null when dealing with JSF.  Alternatively,
> > > > you could create a NullStringConverter which converts from
> > > > "" to null.
> > > >
> > > > When it comes to non-String values, then your converter should
> > > > return null from the getAsObject method when an "" is the
> > > > request parameter.
> > > >
> > > > -Bryan
> > > >
> > > > vlad10 wrote:
> > > > > I'm fresh with JSF,
> > > > > just started building some prototypes with facelets 1.1.11 , myfaces
> > > > > 1.1.3/tomahawk 1.1.3.
> > > > >
> > > > > I'm getting this general feeling that the framework is missing some
> > > > > important feature.
> > > > > I may create an inputText and populate it with a null value, the
> > > framework
> > > > > conviniently will convert it into an empty string and populate my
> page.
> > > > > However, on submit the valueChangeListener will fire with the reason
> > > that
> > > > > null is not the same as an empty string.
> > > > > I have another example. This the initial value is not null. I may
> > > explicitly
> > > > > add a converter to that field, so the value stored in POJO as
> > > jva.util.Date
> > > > > or as a BigDecimal or anything else will be nicely displayed on the
> > > screen,
> > > > > but I'll face again the unwanted behavior of my valueChangeListener.
> > > > > For the time being, I'm trying to compensate this deficiency in my
> app
> > > by
> > > > > adding some filtering in a utility class. At the moment it's in the
> > > > > beginning, just checking null/empty string case:
> > > > >
> > > > >     /**
> > > > >      * UIInput value is never null when submitted, but the POJO is
> > > always
> > > > >      * initialized with nulls. This creates a false alarm by
> > > > > valueChangeListeners.
> > > > >      * This method tries to compensate this deficiency.
> > > > >      * @param input
> > > > >      * @param rec
> > > > >      * @return
> > > > >      */
> > > > >     public static boolean isValueChanged(UIInput input, Object pojo)
> {
> > > > >         String name = input.getId();
> > > > >         Object val = BeanUtil.getBeanValue (pojo,name);
> > > > >         if (val == null)
> > > > >             if(StringUtils.isEmpty(input.getValue().toString()))
> > > > >                 return false;
> > > > >             else
> > > > >                 return true;
> > > > >         return (
> input.getValue().toString().compareTo(val.toString())
> > > != 0);
> > > > >     }
> > > > >
> > > > > My question: am I missing something????
> > > > > Do I really need to add another layer in my app, I may call it
> something
> > > > > like JSF Frendly POJOs. I may perform all necessary conversions
> right
> > > there
> > > > > when moving data from DB to the screen, and then on submit perform
> the
> > > > > opposit conversion when moving data back. I hope I can avoid that.
> > > > > Is not it possible for a framework to 'remember' not just an
> oldValue,
> > > but
> > > > > also the conversion performed, so prior to comparing old/new values
> it
> > > would
> > > > > apply that same converter to the old value???
> > > > > I think, this part has been missed.
> > > > >
> > > > > thanks
> > > > > vlad
> > > > >
> > > >
> > > >
> > >
> > >
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Andrew,
Are you saying that if in the method called by valueChangeListener I take:
event.getOldValue() - it's not the same as my 'original value' in my pojo?
It's alredy has been converted from say Integer to String?

The poin I'm trying to make is why I should add another layer of protection
against valueChangeEvent, when it could be done in JSF.

Also in your example: String str = converter.getAsString(value);
JSF API want converter.getAsString(FacesContext,UIComponent,value).
Do you know why it needs two additional args, is it gonna plug this value
into the component and then attach this component to the tree?

I've just wrote this code for bloking the unwanted valueChangeEvent, but
have not tested it yet. I was the above mentioned getAsString(), but with
the only purpose of getting converted value - not updating the tree.


    public static boolean isValueChanged(ValueChangeEvent event) {
        if (event.getOldValue() == null) {
            if (StringUtils.isEmpty(event.getNewValue().toString()))
                return false;
            else
                return true;
        }

        UIInput comp = (UIInput)event.getComponent();
        Converter conv = comp.getConverter();
        if (conv == null) {
            if (event.getOldValue().toString().equals(event.getNewValue
().toString()))
                return false;
            else
                return true;
        } else {
            Object oldVal =
                conv.getAsString(FacesContext.getCurrentInstance(), comp,
                                 event.getOldValue());
            if (oldVal.equals(event.getNewValue()))
                return false;
            else
                return true;
        }
    }

vlad

On 7/6/07, Andrew Robinson <an...@gmail.com> wrote:
>
> The original value is already converted by specification. The purpose
> of a converter is to take an object from the back-end and change it to
> a view (HTML typically) compatible value and then change the view
> value back to a back-end value on submit.
>
> It is the back-end developer's job to ensure the back-end value is
> "converted". If you want the original value to be converted using a
> JSF converter, then use the Application object to create a converter
> from you backing bean when you load the data, and convert the value as
> you wish.
>
> The purpose of the value change event is to tell you if the user
> changed something. The user changed something if the value they submit
> after conversion is not the same as the value from the back-end.
>
> You keep saying "converted original value", but that is an oxymoron by
> JSF definition. If my component is a number input field, the converted
> value is type Integer and the client value is type String. So the
> converter converts between string and integer, not integer and
> integer.
>
> To be even more precise, for a converter to work properly the
> following must be true:
>
> Converter converter = ...
> Object value = component.getValue();
> String str = converter.getAsString(value);
> Object value2 = converter.getAsObject(str);
> if (value2.equals(value)) {
> // converter is valid
> }
>
> On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> > Null vs empty string is not the only one case, the point I'm trying to
> make
> > here:
> > whenever the JSF framework is applying some data conversion (either the
> > converter was explicitly declared or not), it may (should) remember that
> > conversion rule, so that when that same page is submitted, the framework
> (I
> > mean JSF) will compare ( for the purpose of firing changeValueEvent) not
> the
> > original value with the new value but the converted original value with
> the
> > new value.
> >
> > Yes this is an old issue with all previous frameworks, but I thought JSF
> > could be better. And thinking of the declared converters, cann't I find
> all
> > converters for a given UIComponent using JSF API. I did not try but I
> > thought it's doable.
> >
> > vlad
> >
> >
> > On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
> > > The problem you are experiencing is true for any Java/Web
> > > framework.  An HTTP request parameter does not understand
> > > what a Java null is but always uses the empty string "".  So
> > > somewhere in your application (or framework) you have to
> > > handle the conversion from "" to null.
> > >
> > > When it comes to String values, null is not the same as ""
> > > so I would recommend that your backing beans be populated
> > > with "" instead of null when dealing with JSF.  Alternatively,
> > > you could create a NullStringConverter which converts from
> > > "" to null.
> > >
> > > When it comes to non-String values, then your converter should
> > > return null from the getAsObject method when an "" is the
> > > request parameter.
> > >
> > > -Bryan
> > >
> > > vlad10 wrote:
> > > > I'm fresh with JSF,
> > > > just started building some prototypes with facelets 1.1.11, myfaces
> > > > 1.1.3/tomahawk 1.1.3.
> > > >
> > > > I'm getting this general feeling that the framework is missing some
> > > > important feature.
> > > > I may create an inputText and populate it with a null value, the
> > framework
> > > > conviniently will convert it into an empty string and populate my
> page.
> > > > However, on submit the valueChangeListener will fire with the reason
> > that
> > > > null is not the same as an empty string.
> > > > I have another example. This the initial value is not null. I may
> > explicitly
> > > > add a converter to that field, so the value stored in POJO as
> > jva.util.Date
> > > > or as a BigDecimal or anything else will be nicely displayed on the
> > screen,
> > > > but I'll face again the unwanted behavior of my valueChangeListener.
> > > > For the time being, I'm trying to compensate this deficiency in my
> app
> > by
> > > > adding some filtering in a utility class. At the moment it's in the
> > > > beginning, just checking null/empty string case:
> > > >
> > > >     /**
> > > >      * UIInput value is never null when submitted, but the POJO is
> > always
> > > >      * initialized with nulls. This creates a false alarm by
> > > > valueChangeListeners.
> > > >      * This method tries to compensate this deficiency.
> > > >      * @param input
> > > >      * @param rec
> > > >      * @return
> > > >      */
> > > >     public static boolean isValueChanged(UIInput input, Object pojo)
> {
> > > >         String name = input.getId();
> > > >         Object val = BeanUtil.getBeanValue(pojo,name);
> > > >         if (val == null)
> > > >             if(StringUtils.isEmpty(input.getValue().toString()))
> > > >                 return false;
> > > >             else
> > > >                 return true;
> > > >         return ( input.getValue().toString().compareTo(val.toString
> ())
> > != 0);
> > > >     }
> > > >
> > > > My question: am I missing something????
> > > > Do I really need to add another layer in my app, I may call it
> something
> > > > like JSF Frendly POJOs. I may perform all necessary conversions
> right
> > there
> > > > when moving data from DB to the screen, and then on submit perform
> the
> > > > opposit conversion when moving data back. I hope I can avoid that.
> > > > Is not it possible for a framework to 'remember' not just an
> oldValue,
> > but
> > > > also the conversion performed, so prior to comparing old/new values
> it
> > would
> > > > apply that same converter to the old value???
> > > > I think, this part has been missed.
> > > >
> > > > thanks
> > > > vlad
> > > >
> > >
> > >
> >
> >
>

Re: ValueChangeListener challenges

Posted by Andrew Robinson <an...@gmail.com>.
The original value is already converted by specification. The purpose
of a converter is to take an object from the back-end and change it to
a view (HTML typically) compatible value and then change the view
value back to a back-end value on submit.

It is the back-end developer's job to ensure the back-end value is
"converted". If you want the original value to be converted using a
JSF converter, then use the Application object to create a converter
from you backing bean when you load the data, and convert the value as
you wish.

The purpose of the value change event is to tell you if the user
changed something. The user changed something if the value they submit
after conversion is not the same as the value from the back-end.

You keep saying "converted original value", but that is an oxymoron by
JSF definition. If my component is a number input field, the converted
value is type Integer and the client value is type String. So the
converter converts between string and integer, not integer and
integer.

To be even more precise, for a converter to work properly the
following must be true:

Converter converter = ...
Object value = component.getValue();
String str = converter.getAsString(value);
Object value2 = converter.getAsObject(str);
if (value2.equals(value)) {
  // converter is valid
}

On 7/6/07, Vladimir Isakovich <iv...@gmail.com> wrote:
> Null vs empty string is not the only one case, the point I'm trying to make
> here:
> whenever the JSF framework is applying some data conversion (either the
> converter was explicitly declared or not), it may (should) remember that
> conversion rule, so that when that same page is submitted, the framework (I
> mean JSF) will compare ( for the purpose of firing changeValueEvent) not the
> original value with the new value but the converted original value with the
> new value.
>
> Yes this is an old issue with all previous frameworks, but I thought JSF
> could be better. And thinking of the declared converters, cann't I find all
> converters for a given UIComponent using JSF API. I did not try but I
> thought it's doable.
>
> vlad
>
>
> On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
> > The problem you are experiencing is true for any Java/Web
> > framework.  An HTTP request parameter does not understand
> > what a Java null is but always uses the empty string "".  So
> > somewhere in your application (or framework) you have to
> > handle the conversion from "" to null.
> >
> > When it comes to String values, null is not the same as ""
> > so I would recommend that your backing beans be populated
> > with "" instead of null when dealing with JSF.  Alternatively,
> > you could create a NullStringConverter which converts from
> > "" to null.
> >
> > When it comes to non-String values, then your converter should
> > return null from the getAsObject method when an "" is the
> > request parameter.
> >
> > -Bryan
> >
> > vlad10 wrote:
> > > I'm fresh with JSF,
> > > just started building some prototypes with facelets 1.1.11, myfaces
> > > 1.1.3/tomahawk 1.1.3.
> > >
> > > I'm getting this general feeling that the framework is missing some
> > > important feature.
> > > I may create an inputText and populate it with a null value, the
> framework
> > > conviniently will convert it into an empty string and populate my page.
> > > However, on submit the valueChangeListener will fire with the reason
> that
> > > null is not the same as an empty string.
> > > I have another example. This the initial value is not null. I may
> explicitly
> > > add a converter to that field, so the value stored in POJO as
> jva.util.Date
> > > or as a BigDecimal or anything else will be nicely displayed on the
> screen,
> > > but I'll face again the unwanted behavior of my valueChangeListener.
> > > For the time being, I'm trying to compensate this deficiency in my app
> by
> > > adding some filtering in a utility class. At the moment it's in the
> > > beginning, just checking null/empty string case:
> > >
> > >     /**
> > >      * UIInput value is never null when submitted, but the POJO is
> always
> > >      * initialized with nulls. This creates a false alarm by
> > > valueChangeListeners.
> > >      * This method tries to compensate this deficiency.
> > >      * @param input
> > >      * @param rec
> > >      * @return
> > >      */
> > >     public static boolean isValueChanged(UIInput input, Object pojo) {
> > >         String name = input.getId();
> > >         Object val = BeanUtil.getBeanValue(pojo,name);
> > >         if (val == null)
> > >             if(StringUtils.isEmpty(input.getValue().toString()))
> > >                 return false;
> > >             else
> > >                 return true;
> > >         return ( input.getValue().toString().compareTo(val.toString())
> != 0);
> > >     }
> > >
> > > My question: am I missing something????
> > > Do I really need to add another layer in my app, I may call it something
> > > like JSF Frendly POJOs. I may perform all necessary conversions right
> there
> > > when moving data from DB to the screen, and then on submit perform the
> > > opposit conversion when moving data back. I hope I can avoid that.
> > > Is not it possible for a framework to 'remember' not just an oldValue,
> but
> > > also the conversion performed, so prior to comparing old/new values it
> would
> > > apply that same converter to the old value???
> > > I think, this part has been missed.
> > >
> > > thanks
> > > vlad
> > >
> >
> >
>
>

Re: ValueChangeListener challenges

Posted by Vladimir Isakovich <iv...@gmail.com>.
Null vs empty string is not the only one case, the point I'm trying to make
here:
whenever the JSF framework is applying some data conversion (either the
converter was explicitly declared or not), it may (should) remember that
conversion rule, so that when that same page is submitted, the framework (I
mean JSF) will compare (*for the purpose of firing changeValueEvent*) *not
the original valu*e with the new value but the* converted original
value*with the new value.

Yes this is an old issue with all previous frameworks, but I thought JSF
could be better. And thinking of the declared converters, cann't I find all
converters for a given UIComponent using JSF API. I did not try but I
thought it's doable.

vlad

On 7/6/07, Bryan Basham <bb...@stillsecure.com> wrote:
>
> The problem you are experiencing is true for any Java/Web
> framework.  An HTTP request parameter does not understand
> what a Java null is but always uses the empty string "".  So
> somewhere in your application (or framework) you have to
> handle the conversion from "" to null.
>
> When it comes to String values, null is not the same as ""
> so I would recommend that your backing beans be populated
> with "" instead of null when dealing with JSF.  Alternatively,
> you could create a NullStringConverter which converts from
> "" to null.
>
> When it comes to non-String values, then your converter should
> return null from the getAsObject method when an "" is the
> request parameter.
>
> -Bryan
>
> vlad10 wrote:
> > I'm fresh with JSF,
> > just started building some prototypes with facelets 1.1.11, myfaces
> > 1.1.3/tomahawk 1.1.3.
> >
> > I'm getting this general feeling that the framework is missing some
> > important feature.
> > I may create an inputText and populate it with a null value, the
> framework
> > conviniently will convert it into an empty string and populate my page.
> > However, on submit the valueChangeListener will fire with the reason
> that
> > null is not the same as an empty string.
> > I have another example. This the initial value is not null. I may
> explicitly
> > add a converter to that field, so the value stored in POJO as
> jva.util.Date
> > or as a BigDecimal or anything else will be nicely displayed on the
> screen,
> > but I'll face again the unwanted behavior of my valueChangeListener.
> > For the time being, I'm trying to compensate this deficiency in my app
> by
> > adding some filtering in a utility class. At the moment it's in the
> > beginning, just checking null/empty string case:
> >
> >     /**
> >      * UIInput value is never null when submitted, but the POJO is
> always
> >      * initialized with nulls. This creates a false alarm by
> > valueChangeListeners.
> >      * This method tries to compensate this deficiency.
> >      * @param input
> >      * @param rec
> >      * @return
> >      */
> >     public static boolean isValueChanged(UIInput input, Object pojo) {
> >         String name = input.getId();
> >         Object val = BeanUtil.getBeanValue(pojo,name);
> >         if (val == null)
> >             if(StringUtils.isEmpty(input.getValue().toString()))
> >                 return false;
> >             else
> >                 return true;
> >         return (input.getValue().toString().compareTo(val.toString()) !=
> 0);
> >     }
> >
> > My question: am I missing something????
> > Do I really need to add another layer in my app, I may call it something
> > like JSF Frendly POJOs. I may perform all necessary conversions right
> there
> > when moving data from DB to the screen, and then on submit perform the
> > opposit conversion when moving data back. I hope I can avoid that.
> > Is not it possible for a framework to 'remember' not just an oldValue,
> but
> > also the conversion performed, so prior to comparing old/new values it
> would
> > apply that same converter to the old value???
> > I think, this part has been missed.
> >
> > thanks
> > vlad
> >
>
>

Re: ValueChangeListener challenges

Posted by Bryan Basham <bb...@stillsecure.com>.
The problem you are experiencing is true for any Java/Web
framework.  An HTTP request parameter does not understand
what a Java null is but always uses the empty string "".  So
somewhere in your application (or framework) you have to
handle the conversion from "" to null.

When it comes to String values, null is not the same as ""
so I would recommend that your backing beans be populated
with "" instead of null when dealing with JSF.  Alternatively,
you could create a NullStringConverter which converts from
"" to null.

When it comes to non-String values, then your converter should
return null from the getAsObject method when an "" is the
request parameter.

-Bryan

vlad10 wrote:
> I'm fresh with JSF, 
> just started building some prototypes with facelets 1.1.11, myfaces
> 1.1.3/tomahawk 1.1.3.
>
> I'm getting this general feeling that the framework is missing some
> important feature.
> I may create an inputText and populate it with a null value, the framework
> conviniently will convert it into an empty string and populate my page.
> However, on submit the valueChangeListener will fire with the reason that
> null is not the same as an empty string.
> I have another example. This the initial value is not null. I may explicitly
> add a converter to that field, so the value stored in POJO as jva.util.Date
> or as a BigDecimal or anything else will be nicely displayed on the screen,
> but I'll face again the unwanted behavior of my valueChangeListener.
> For the time being, I'm trying to compensate this deficiency in my app by
> adding some filtering in a utility class. At the moment it's in the
> beginning, just checking null/empty string case:
>
>     /**
>      * UIInput value is never null when submitted, but the POJO is always 
>      * initialized with nulls. This creates a false alarm by
> valueChangeListeners.
>      * This method tries to compensate this deficiency.
>      * @param input
>      * @param rec
>      * @return
>      */
>     public static boolean isValueChanged(UIInput input, Object pojo) {
>         String name = input.getId();
>         Object val = BeanUtil.getBeanValue(pojo,name);
>         if (val == null)
>             if(StringUtils.isEmpty(input.getValue().toString()))
>                 return false;
>             else
>                 return true;
>         return (input.getValue().toString().compareTo(val.toString()) != 0);
>     }
>
> My question: am I missing something???? 
> Do I really need to add another layer in my app, I may call it something
> like JSF Frendly POJOs. I may perform all necessary conversions right there
> when moving data from DB to the screen, and then on submit perform the
> opposit conversion when moving data back. I hope I can avoid that.
> Is not it possible for a framework to 'remember' not just an oldValue, but
> also the conversion performed, so prior to comparing old/new values it would
> apply that same converter to the old value???
> I think, this part has been missed.
>
> thanks
> vlad
>