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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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
> > > > >
> > > >
> > > >
> > >
> > >
> >
>
>

Reply via email to